• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /* Original code copied from NDK Native-media sample code */
18 
19 //#define LOG_NDEBUG 0
20 #define LOG_TAG "NativeMedia"
21 #include <log/log.h>
22 
23 #include <assert.h>
24 #include <jni.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include <unistd.h>
28 
29 #include "media/NdkMediaExtractor.h"
30 #include "media/NdkMediaCrypto.h"
31 #include "media/NdkMediaDataSource.h"
32 #include "media/NdkMediaFormat.h"
33 
Java_android_media_misc_cts_NativeDecoderTest_testFormatNative(JNIEnv *,jclass)34 extern "C" jboolean Java_android_media_misc_cts_NativeDecoderTest_testFormatNative(JNIEnv * /*env*/,
35         jclass /*clazz*/) {
36     AMediaFormat* format = AMediaFormat_new();
37     if (!format) {
38         return false;
39     }
40 
41     AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_BIT_RATE, 8000);
42     int32_t bitrate = 0;
43     if (!AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_BIT_RATE, &bitrate) || bitrate != 8000) {
44         ALOGE("AMediaFormat_getInt32 fail: %d", bitrate);
45         return false;
46     }
47 
48     AMediaFormat_setInt64(format, AMEDIAFORMAT_KEY_DURATION, 123456789123456789LL);
49     int64_t duration = 0;
50     if (!AMediaFormat_getInt64(format, AMEDIAFORMAT_KEY_DURATION, &duration)
51             || duration != 123456789123456789LL) {
52         ALOGE("AMediaFormat_getInt64 fail: %lld", (long long) duration);
53         return false;
54     }
55 
56     AMediaFormat_setFloat(format, AMEDIAFORMAT_KEY_FRAME_RATE, 25.0f);
57     float framerate = 0.0f;
58     if (!AMediaFormat_getFloat(format, AMEDIAFORMAT_KEY_FRAME_RATE, &framerate)
59             || framerate != 25.0f) {
60         ALOGE("AMediaFormat_getFloat fail: %f", framerate);
61         return false;
62     }
63 
64     const char* value = "audio/mpeg";
65     AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, value);
66     const char* readback = NULL;
67     if (!AMediaFormat_getString(format, AMEDIAFORMAT_KEY_MIME, &readback)
68             || strcmp(value, readback) || value == readback) {
69         ALOGE("AMediaFormat_getString fail");
70         return false;
71     }
72 
73     uint32_t foo = 0xdeadbeef;
74     AMediaFormat_setBuffer(format, "csd-0", &foo, sizeof(foo));
75     foo = 0xabadcafe;
76     void *bytes;
77     size_t bytesize = 0;
78     if(!AMediaFormat_getBuffer(format, "csd-0", &bytes, &bytesize)
79             || bytesize != sizeof(foo) || *((uint32_t*)bytes) != 0xdeadbeef) {
80         ALOGE("AMediaFormat_getBuffer fail");
81         return false;
82     }
83 
84     return true;
85 }
86 
87 
Java_android_media_misc_cts_NativeDecoderTest_testPsshNative(JNIEnv *,jclass,int fd,jlong offset,jlong size)88 extern "C" jboolean Java_android_media_misc_cts_NativeDecoderTest_testPsshNative(JNIEnv * /*env*/,
89         jclass /*clazz*/, int fd, jlong offset, jlong size) {
90 
91     AMediaExtractor *ex = AMediaExtractor_new();
92     int err = AMediaExtractor_setDataSourceFd(ex, fd, offset, size);
93     if (err != 0) {
94         ALOGE("setDataSource error: %d", err);
95         return false;
96     }
97 
98     PsshInfo* info = AMediaExtractor_getPsshInfo(ex);
99     if (info == NULL) {
100         ALOGI("null pssh");
101         return false;
102     }
103 
104     ALOGI("pssh has %zd entries", info->numentries);
105     if (info->numentries != 2) {
106         return false;
107     }
108 
109     for (size_t i = 0; i < info->numentries; i++) {
110         PsshEntry *entry = &info->entries[i];
111         ALOGI("entry uuid %02x%02x..%02x%02x, data size %zd",
112                 entry->uuid[0],
113                 entry->uuid[1],
114                 entry->uuid[14],
115                 entry->uuid[15],
116                 entry->datalen);
117 
118         AMediaCrypto *crypto = AMediaCrypto_new(entry->uuid, entry->data, entry->datalen);
119         if (crypto) {
120             ALOGI("got crypto");
121             AMediaCrypto_delete(crypto);
122         } else {
123             ALOGI("no crypto");
124         }
125     }
126     return true;
127 }
128 
Java_android_media_misc_cts_NativeDecoderTest_testCryptoInfoNative(JNIEnv *,jclass)129 extern "C" jboolean Java_android_media_misc_cts_NativeDecoderTest_testCryptoInfoNative(JNIEnv * /*env*/,
130         jclass /*clazz*/) {
131 
132     size_t numsubsamples = 4;
133     uint8_t key[16] = { 1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4 };
134     uint8_t iv[16] = { 4,3,2,1,4,3,2,1,4,3,2,1,4,3,2,1 };
135     size_t clearbytes[4] = { 5, 6, 7, 8 };
136     size_t encryptedbytes[4] = { 8, 7, 6, 5 };
137 
138     AMediaCodecCryptoInfo *ci =
139             AMediaCodecCryptoInfo_new(numsubsamples, key, iv, AMEDIACODECRYPTOINFO_MODE_CLEAR, clearbytes, encryptedbytes);
140 
141     if (AMediaCodecCryptoInfo_getNumSubSamples(ci) != 4) {
142         ALOGE("numsubsamples mismatch");
143         return false;
144     }
145     uint8_t bytes[16];
146     AMediaCodecCryptoInfo_getKey(ci, bytes);
147     if (memcmp(key, bytes, 16) != 0) {
148         ALOGE("key mismatch");
149         return false;
150     }
151     AMediaCodecCryptoInfo_getIV(ci, bytes);
152     if (memcmp(iv, bytes, 16) != 0) {
153         ALOGE("IV mismatch");
154         return false;
155     }
156     if (AMediaCodecCryptoInfo_getMode(ci) != AMEDIACODECRYPTOINFO_MODE_CLEAR) {
157         ALOGE("mode mismatch");
158         return false;
159     }
160     size_t sizes[numsubsamples];
161     AMediaCodecCryptoInfo_getClearBytes(ci, sizes);
162     if (memcmp(clearbytes, sizes, sizeof(size_t) * numsubsamples)) {
163         ALOGE("clear size mismatch");
164         return false;
165     }
166     AMediaCodecCryptoInfo_getEncryptedBytes(ci, sizes);
167     if (memcmp(encryptedbytes, sizes, sizeof(size_t) * numsubsamples)) {
168         ALOGE("encrypted size mismatch");
169         return false;
170     }
171     return true;
172 }
173 
Java_android_media_misc_cts_NativeDecoderTest_createAMediaExtractor(JNIEnv *,jclass)174 extern "C" jlong Java_android_media_misc_cts_NativeDecoderTest_createAMediaExtractor(JNIEnv * /*env*/,
175         jclass /*clazz*/) {
176     AMediaExtractor *ex = AMediaExtractor_new();
177     return reinterpret_cast<jlong>(ex);
178 }
179 
Java_android_media_misc_cts_NativeDecoderTest_createAMediaDataSource(JNIEnv * env,jclass,jstring jurl)180 extern "C" jlong Java_android_media_misc_cts_NativeDecoderTest_createAMediaDataSource(JNIEnv * env,
181         jclass /*clazz*/, jstring jurl) {
182     const char *url = env->GetStringUTFChars(jurl, NULL);
183     if (url == NULL) {
184         ALOGE("GetStringUTFChars error");
185         return 0;
186     }
187 
188     AMediaDataSource *ds = AMediaDataSource_newUri(url, 0, NULL);
189     env->ReleaseStringUTFChars(jurl, url);
190     return reinterpret_cast<jlong>(ds);
191 }
192 
Java_android_media_misc_cts_NativeDecoderTest_setAMediaExtractorDataSource(JNIEnv *,jclass,jlong jex,jlong jds)193 extern "C" jint Java_android_media_misc_cts_NativeDecoderTest_setAMediaExtractorDataSource(JNIEnv * /*env*/,
194         jclass /*clazz*/, jlong jex, jlong jds) {
195     AMediaExtractor *ex = reinterpret_cast<AMediaExtractor *>(jex);
196     AMediaDataSource *ds = reinterpret_cast<AMediaDataSource *>(jds);
197     return AMediaExtractor_setDataSourceCustom(ex, ds);
198 }
199 
Java_android_media_misc_cts_NativeDecoderTest_closeAMediaDataSource(JNIEnv *,jclass,jlong ds)200 extern "C" void Java_android_media_misc_cts_NativeDecoderTest_closeAMediaDataSource(
201         JNIEnv * /*env*/, jclass /*clazz*/, jlong ds) {
202     AMediaDataSource_close(reinterpret_cast<AMediaDataSource *>(ds));
203 }
204 
Java_android_media_misc_cts_NativeDecoderTest_deleteAMediaExtractor(JNIEnv *,jclass,jlong ex)205 extern "C" void Java_android_media_misc_cts_NativeDecoderTest_deleteAMediaExtractor(
206         JNIEnv * /*env*/, jclass /*clazz*/, jlong ex) {
207     AMediaExtractor_delete(reinterpret_cast<AMediaExtractor *>(ex));
208 }
209 
Java_android_media_misc_cts_NativeDecoderTest_deleteAMediaDataSource(JNIEnv *,jclass,jlong ds)210 extern "C" void Java_android_media_misc_cts_NativeDecoderTest_deleteAMediaDataSource(
211         JNIEnv * /*env*/, jclass /*clazz*/, jlong ds) {
212     AMediaDataSource_delete(reinterpret_cast<AMediaDataSource *>(ds));
213 }
214 
Java_android_media_misc_cts_NativeDecoderTest_testMediaFormatNative(JNIEnv *,jclass)215 extern "C" jboolean Java_android_media_misc_cts_NativeDecoderTest_testMediaFormatNative(
216         JNIEnv * /*env*/, jclass /*clazz*/) {
217 
218     AMediaFormat *original = AMediaFormat_new();
219     AMediaFormat *copy = AMediaFormat_new();
220     jboolean ret = false;
221     while (true) {
222         AMediaFormat_setInt64(original, AMEDIAFORMAT_KEY_DURATION, 1234ll);
223         int64_t value = 0;
224         if (!AMediaFormat_getInt64(original, AMEDIAFORMAT_KEY_DURATION, &value) || value != 1234) {
225             ALOGE("format missing expected entry");
226             break;
227         }
228         AMediaFormat_copy(copy, original);
229         value = 0;
230         if (!AMediaFormat_getInt64(copy, AMEDIAFORMAT_KEY_DURATION, &value) || value != 1234) {
231             ALOGE("copied format missing expected entry");
232             break;
233         }
234         AMediaFormat_clear(original);
235         if (AMediaFormat_getInt64(original, AMEDIAFORMAT_KEY_DURATION, &value)) {
236             ALOGE("format still has entry after clear");
237             break;
238         }
239         value = 0;
240         if (!AMediaFormat_getInt64(copy, AMEDIAFORMAT_KEY_DURATION, &value) || value != 1234) {
241             ALOGE("copied format missing expected entry");
242             break;
243         }
244         ret = true;
245         break;
246     }
247     AMediaFormat_delete(original);
248     AMediaFormat_delete(copy);
249     return ret;
250 }
251