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 TAG "NativeMedia"
21 #include <log/log.h>
22
23 #include <assert.h>
24 #include <jni.h>
25 #include <pthread.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include <unistd.h>
29 #include <semaphore.h>
30
31 #include <android/native_window_jni.h>
32 #include <EGL/egl.h>
33 #include <EGL/eglext.h>
34
35 #include "media/NdkMediaExtractor.h"
36 #include "media/NdkMediaCodec.h"
37 #include "media/NdkMediaCrypto.h"
38 #include "media/NdkMediaFormat.h"
39 #include "media/NdkMediaMuxer.h"
40
41 template <class T>
42 class simplevector {
43 T *storage;
44 int capacity;
45 int numfilled;
46 public:
simplevector()47 simplevector() {
48 capacity = 16;
49 numfilled = 0;
50 storage = new T[capacity];
51 }
~simplevector()52 ~simplevector() {
53 delete[] storage;
54 }
55
add(T item)56 void add(T item) {
57 if (numfilled == capacity) {
58 T *old = storage;
59 capacity *= 2;
60 storage = new T[capacity];
61 for (int i = 0; i < numfilled; i++) {
62 storage[i] = old[i];
63 }
64 delete[] old;
65 }
66 storage[numfilled] = item;
67 numfilled++;
68 }
69
size()70 int size() {
71 return numfilled;
72 }
73
data()74 T* data() {
75 return storage;
76 }
77 };
78
79
80
testExtractor(AMediaExtractor * ex,JNIEnv * env)81 jobject testExtractor(AMediaExtractor *ex, JNIEnv *env) {
82
83 simplevector<int> sizes;
84 int numtracks = AMediaExtractor_getTrackCount(ex);
85 sizes.add(numtracks);
86 for (int i = 0; i < numtracks; i++) {
87 AMediaFormat *format = AMediaExtractor_getTrackFormat(ex, i);
88 const char *s = AMediaFormat_toString(format);
89 ALOGI("track %d format: %s", i, s);
90 const char *mime;
91 if (!AMediaFormat_getString(format, AMEDIAFORMAT_KEY_MIME, &mime)) {
92 ALOGE("no mime type");
93 return NULL;
94 } else if (!strncmp(mime, "audio/", 6)) {
95 sizes.add(0);
96 int32_t val32;
97 int64_t val64;
98 AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_SAMPLE_RATE, &val32);
99 sizes.add(val32);
100 AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_CHANNEL_COUNT, &val32);
101 sizes.add(val32);
102 AMediaFormat_getInt64(format, AMEDIAFORMAT_KEY_DURATION, &val64);
103 sizes.add(val64);
104 } else if (!strncmp(mime, "video/", 6)) {
105 sizes.add(1);
106 int32_t val32;
107 int64_t val64;
108 AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_WIDTH, &val32);
109 sizes.add(val32);
110 AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_HEIGHT, &val32);
111 sizes.add(val32);
112 AMediaFormat_getInt64(format, AMEDIAFORMAT_KEY_DURATION, &val64);
113 sizes.add(val64);
114 } else {
115 ALOGE("expected audio or video mime type, got %s", mime);
116 }
117 AMediaFormat_delete(format);
118 AMediaExtractor_selectTrack(ex, i);
119 }
120 int bufsize = 1024*1024;
121 uint8_t *buf = new uint8_t[bufsize];
122 while(true) {
123 int n = AMediaExtractor_readSampleData(ex, buf, bufsize);
124 if (n < 0) {
125 break;
126 }
127 sizes.add(n);
128 sizes.add(AMediaExtractor_getSampleTrackIndex(ex));
129 sizes.add(AMediaExtractor_getSampleFlags(ex));
130 sizes.add(AMediaExtractor_getSampleTime(ex));
131 AMediaExtractor_advance(ex);
132 }
133
134 // allocate java int array for result and return it
135 int *data = sizes.data();
136 int numsamples = sizes.size();
137 jintArray ret = env->NewIntArray(numsamples);
138 jboolean isCopy;
139 jint *dst = env->GetIntArrayElements(ret, &isCopy);
140 for (int i = 0; i < numsamples; ++i) {
141 dst[i] = data[i];
142 }
143 env->ReleaseIntArrayElements(ret, dst, 0);
144
145 delete[] buf;
146 AMediaExtractor_delete(ex);
147 return ret;
148 }
149
150
151 // get the sample sizes for the file
Java_android_media_cts_NativeDecoderTest_getSampleSizesNative(JNIEnv * env,jclass,int fd,jlong offset,jlong size)152 extern "C" jobject Java_android_media_cts_NativeDecoderTest_getSampleSizesNative(JNIEnv *env,
153 jclass /*clazz*/, int fd, jlong offset, jlong size)
154 {
155 AMediaExtractor *ex = AMediaExtractor_new();
156 int err = AMediaExtractor_setDataSourceFd(ex, fd, offset, size);
157 if (err != 0) {
158 ALOGE("setDataSource error: %d", err);
159 return NULL;
160 }
161 return testExtractor(ex, env);
162 }
163
164 // get the sample sizes for the path
Java_android_media_cts_NativeDecoderTest_getSampleSizesNativePath(JNIEnv * env,jclass,jstring jpath)165 extern "C" jobject Java_android_media_cts_NativeDecoderTest_getSampleSizesNativePath(JNIEnv *env,
166 jclass /*clazz*/, jstring jpath)
167 {
168 AMediaExtractor *ex = AMediaExtractor_new();
169
170 const char *tmp = env->GetStringUTFChars(jpath, NULL);
171 if (tmp == NULL) { // Out of memory
172 return NULL;
173 }
174
175 int err = AMediaExtractor_setDataSource(ex, tmp);
176
177 env->ReleaseStringUTFChars(jpath, tmp);
178
179 if (err != 0) {
180 ALOGE("setDataSource error: %d", err);
181 return NULL;
182 }
183 return testExtractor(ex, env);
184 }
185
adler32(const uint8_t * input,int len)186 static int adler32(const uint8_t *input, int len) {
187
188 int a = 1;
189 int b = 0;
190 for (int i = 0; i < len; i++) {
191 a += input[i];
192 b += a;
193 }
194 a = a % 65521;
195 b = b % 65521;
196 int ret = b * 65536 + a;
197 ALOGV("adler %d/%d", len, ret);
198 return ret;
199 }
200
checksum(const uint8_t * in,int len,AMediaFormat * format)201 static int checksum(const uint8_t *in, int len, AMediaFormat *format) {
202 int width, stride, height;
203 if (!AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_WIDTH, &width)) {
204 width = len;
205 }
206 if (!AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_STRIDE, &stride)) {
207 stride = width;
208 }
209 if (!AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_HEIGHT, &height)) {
210 height = 1;
211 }
212 uint8_t *bb = new uint8_t[width * height];
213 for (int i = 0; i < height; i++) {
214 memcpy(bb + i * width, in + i * stride, width);
215 }
216 // bb is filled with data
217 int sum = adler32(bb, width * height);
218 delete[] bb;
219 return sum;
220 }
221
Java_android_media_cts_NativeDecoderTest_getDecodedDataNative(JNIEnv * env,jclass,int fd,jlong offset,jlong size)222 extern "C" jobject Java_android_media_cts_NativeDecoderTest_getDecodedDataNative(JNIEnv *env,
223 jclass /*clazz*/, int fd, jlong offset, jlong size) {
224 ALOGV("getDecodedDataNative");
225
226 AMediaExtractor *ex = AMediaExtractor_new();
227 int err = AMediaExtractor_setDataSourceFd(ex, fd, offset, size);
228 if (err != 0) {
229 ALOGE("setDataSource error: %d", err);
230 return NULL;
231 }
232
233 int numtracks = AMediaExtractor_getTrackCount(ex);
234
235 AMediaCodec **codec = new AMediaCodec*[numtracks];
236 AMediaFormat **format = new AMediaFormat*[numtracks];
237 bool *sawInputEOS = new bool[numtracks];
238 bool *sawOutputEOS = new bool[numtracks];
239 simplevector<int> *sizes = new simplevector<int>[numtracks];
240
241 ALOGV("input has %d tracks", numtracks);
242 for (int i = 0; i < numtracks; i++) {
243 AMediaFormat *format = AMediaExtractor_getTrackFormat(ex, i);
244 const char *s = AMediaFormat_toString(format);
245 ALOGI("track %d format: %s", i, s);
246 const char *mime;
247 if (!AMediaFormat_getString(format, AMEDIAFORMAT_KEY_MIME, &mime)) {
248 ALOGE("no mime type");
249 return NULL;
250 } else if (!strncmp(mime, "audio/", 6) || !strncmp(mime, "video/", 6)) {
251 codec[i] = AMediaCodec_createDecoderByType(mime);
252 AMediaCodec_configure(codec[i], format, NULL /* surface */, NULL /* crypto */, 0);
253 AMediaCodec_start(codec[i]);
254 sawInputEOS[i] = false;
255 sawOutputEOS[i] = false;
256 } else {
257 ALOGE("expected audio or video mime type, got %s", mime);
258 return NULL;
259 }
260 AMediaFormat_delete(format);
261 AMediaExtractor_selectTrack(ex, i);
262 }
263 int eosCount = 0;
264 while(eosCount < numtracks) {
265 int t = AMediaExtractor_getSampleTrackIndex(ex);
266 if (t >=0) {
267 ssize_t bufidx = AMediaCodec_dequeueInputBuffer(codec[t], 5000);
268 ALOGV("track %d, input buffer %zd", t, bufidx);
269 if (bufidx >= 0) {
270 size_t bufsize;
271 uint8_t *buf = AMediaCodec_getInputBuffer(codec[t], bufidx, &bufsize);
272 int sampleSize = AMediaExtractor_readSampleData(ex, buf, bufsize);
273 ALOGV("read %d", sampleSize);
274 if (sampleSize < 0) {
275 sampleSize = 0;
276 sawInputEOS[t] = true;
277 ALOGV("EOS");
278 //break;
279 }
280 int64_t presentationTimeUs = AMediaExtractor_getSampleTime(ex);
281
282 AMediaCodec_queueInputBuffer(codec[t], bufidx, 0, sampleSize, presentationTimeUs,
283 sawInputEOS[t] ? AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM : 0);
284 AMediaExtractor_advance(ex);
285 }
286 } else {
287 ALOGV("@@@@ no more input samples");
288 for (int tt = 0; tt < numtracks; tt++) {
289 if (!sawInputEOS[tt]) {
290 // we ran out of samples without ever signaling EOS to the codec,
291 // so do that now
292 int bufidx = AMediaCodec_dequeueInputBuffer(codec[tt], 5000);
293 if (bufidx >= 0) {
294 AMediaCodec_queueInputBuffer(codec[tt], bufidx, 0, 0, 0,
295 AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM);
296 sawInputEOS[tt] = true;
297 }
298 }
299 }
300 }
301
302 // check all codecs for available data
303 AMediaCodecBufferInfo info;
304 for (int tt = 0; tt < numtracks; tt++) {
305 if (!sawOutputEOS[tt]) {
306 int status = AMediaCodec_dequeueOutputBuffer(codec[tt], &info, 1);
307 ALOGV("dequeueoutput on track %d: %d", tt, status);
308 if (status >= 0) {
309 if (info.flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM) {
310 ALOGV("EOS on track %d", tt);
311 sawOutputEOS[tt] = true;
312 eosCount++;
313 }
314 ALOGV("got decoded buffer for track %d, size %d", tt, info.size);
315 if (info.size > 0) {
316 size_t bufsize;
317 uint8_t *buf = AMediaCodec_getOutputBuffer(codec[tt], status, &bufsize);
318 int adler = checksum(buf, info.size, format[tt]);
319 sizes[tt].add(adler);
320 }
321 AMediaCodec_releaseOutputBuffer(codec[tt], status, false);
322 } else if (status == AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED) {
323 ALOGV("output buffers changed for track %d", tt);
324 } else if (status == AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED) {
325 format[tt] = AMediaCodec_getOutputFormat(codec[tt]);
326 ALOGV("format changed for track %d: %s", tt, AMediaFormat_toString(format[tt]));
327 } else if (status == AMEDIACODEC_INFO_TRY_AGAIN_LATER) {
328 ALOGV("no output buffer right now for track %d", tt);
329 } else {
330 ALOGV("unexpected info code for track %d : %d", tt, status);
331 }
332 } else {
333 ALOGV("already at EOS on track %d", tt);
334 }
335 }
336 }
337 ALOGV("decoding loop done");
338
339 // allocate java int array for result and return it
340 int numsamples = 0;
341 for (int i = 0; i < numtracks; i++) {
342 numsamples += sizes[i].size();
343 }
344 ALOGV("checksums: %d", numsamples);
345 jintArray ret = env->NewIntArray(numsamples);
346 jboolean isCopy;
347 jint *org = env->GetIntArrayElements(ret, &isCopy);
348 jint *dst = org;
349 for (int i = 0; i < numtracks; i++) {
350 int *data = sizes[i].data();
351 int len = sizes[i].size();
352 ALOGV("copying %d", len);
353 for (int j = 0; j < len; j++) {
354 *dst++ = data[j];
355 }
356 }
357 env->ReleaseIntArrayElements(ret, org, 0);
358
359 delete[] sizes;
360 delete[] sawOutputEOS;
361 delete[] sawInputEOS;
362 for (int i = 0; i < numtracks; i++) {
363 AMediaFormat_delete(format[i]);
364 AMediaCodec_stop(codec[i]);
365 AMediaCodec_delete(codec[i]);
366 }
367 delete[] format;
368 delete[] codec;
369 AMediaExtractor_delete(ex);
370 return ret;
371 }
372
Java_android_media_cts_NativeDecoderTest_testPlaybackNative(JNIEnv * env,jclass,jobject surface,int fd,jlong offset,jlong size)373 extern "C" jboolean Java_android_media_cts_NativeDecoderTest_testPlaybackNative(JNIEnv *env,
374 jclass /*clazz*/, jobject surface, int fd, jlong offset, jlong size) {
375
376 ANativeWindow *window = ANativeWindow_fromSurface(env, surface);
377 ALOGI("@@@@ native window: %p", window);
378
379 AMediaExtractor *ex = AMediaExtractor_new();
380 int err = AMediaExtractor_setDataSourceFd(ex, fd, offset, size);
381 if (err != 0) {
382 ALOGE("setDataSource error: %d", err);
383 return false;
384 }
385
386 int numtracks = AMediaExtractor_getTrackCount(ex);
387
388 AMediaCodec *codec = NULL;
389 AMediaFormat *format = NULL;
390 bool sawInputEOS = false;
391 bool sawOutputEOS = false;
392
393 ALOGV("input has %d tracks", numtracks);
394 for (int i = 0; i < numtracks; i++) {
395 AMediaFormat *format = AMediaExtractor_getTrackFormat(ex, i);
396 const char *s = AMediaFormat_toString(format);
397 ALOGI("track %d format: %s", i, s);
398 const char *mime;
399 if (!AMediaFormat_getString(format, AMEDIAFORMAT_KEY_MIME, &mime)) {
400 ALOGE("no mime type");
401 return false;
402 } else if (!strncmp(mime, "video/", 6)) {
403 codec = AMediaCodec_createDecoderByType(mime);
404 AMediaCodec_configure(codec, format, window, NULL, 0);
405 AMediaCodec_start(codec);
406 AMediaExtractor_selectTrack(ex, i);
407 }
408 AMediaFormat_delete(format);
409 }
410
411 while (!sawOutputEOS) {
412 ssize_t bufidx = AMediaCodec_dequeueInputBuffer(codec, 5000);
413 ALOGV("input buffer %zd", bufidx);
414 if (bufidx >= 0) {
415 size_t bufsize;
416 uint8_t *buf = AMediaCodec_getInputBuffer(codec, bufidx, &bufsize);
417 int sampleSize = AMediaExtractor_readSampleData(ex, buf, bufsize);
418 ALOGV("read %d", sampleSize);
419 if (sampleSize < 0) {
420 sampleSize = 0;
421 sawInputEOS = true;
422 ALOGV("EOS");
423 }
424 int64_t presentationTimeUs = AMediaExtractor_getSampleTime(ex);
425
426 AMediaCodec_queueInputBuffer(codec, bufidx, 0, sampleSize, presentationTimeUs,
427 sawInputEOS ? AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM : 0);
428 AMediaExtractor_advance(ex);
429 }
430
431 AMediaCodecBufferInfo info;
432 int status = AMediaCodec_dequeueOutputBuffer(codec, &info, 1);
433 ALOGV("dequeueoutput returned: %d", status);
434 if (status >= 0) {
435 if (info.flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM) {
436 ALOGV("output EOS");
437 sawOutputEOS = true;
438 }
439 ALOGV("got decoded buffer size %d", info.size);
440 AMediaCodec_releaseOutputBuffer(codec, status, true);
441 usleep(20000);
442 } else if (status == AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED) {
443 ALOGV("output buffers changed");
444 } else if (status == AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED) {
445 format = AMediaCodec_getOutputFormat(codec);
446 ALOGV("format changed to: %s", AMediaFormat_toString(format));
447 } else if (status == AMEDIACODEC_INFO_TRY_AGAIN_LATER) {
448 ALOGV("no output buffer right now");
449 } else {
450 ALOGV("unexpected info code: %d", status);
451 }
452 }
453
454 AMediaCodec_stop(codec);
455 AMediaCodec_delete(codec);
456 AMediaExtractor_delete(ex);
457 return true;
458 }
459
Java_android_media_cts_NativeDecoderTest_testMuxerNative(JNIEnv *,jclass,int infd,jlong inoffset,jlong insize,int outfd,jboolean webm)460 extern "C" jboolean Java_android_media_cts_NativeDecoderTest_testMuxerNative(JNIEnv */*env*/,
461 jclass /*clazz*/, int infd, jlong inoffset, jlong insize, int outfd, jboolean webm) {
462
463
464 AMediaMuxer *muxer = AMediaMuxer_new(outfd,
465 webm ? AMEDIAMUXER_OUTPUT_FORMAT_WEBM : AMEDIAMUXER_OUTPUT_FORMAT_MPEG_4);
466
467 AMediaExtractor *ex = AMediaExtractor_new();
468 int err = AMediaExtractor_setDataSourceFd(ex, infd, inoffset, insize);
469 if (err != 0) {
470 ALOGE("setDataSource error: %d", err);
471 return false;
472 }
473
474 int numtracks = AMediaExtractor_getTrackCount(ex);
475 ALOGI("input tracks: %d", numtracks);
476 for (int i = 0; i < numtracks; i++) {
477 AMediaFormat *format = AMediaExtractor_getTrackFormat(ex, i);
478 const char *s = AMediaFormat_toString(format);
479 ALOGI("track %d format: %s", i, s);
480 const char *mime;
481 if (!AMediaFormat_getString(format, AMEDIAFORMAT_KEY_MIME, &mime)) {
482 ALOGE("no mime type");
483 return false;
484 } else if (!strncmp(mime, "audio/", 6) || !strncmp(mime, "video/", 6)) {
485 ssize_t tidx = AMediaMuxer_addTrack(muxer, format);
486 ALOGI("track %d -> %zd format %s", i, tidx, s);
487 AMediaExtractor_selectTrack(ex, i);
488 } else {
489 ALOGE("expected audio or video mime type, got %s", mime);
490 return false;
491 }
492 AMediaFormat_delete(format);
493 AMediaExtractor_selectTrack(ex, i);
494 }
495 AMediaMuxer_start(muxer);
496
497 int bufsize = 1024*1024;
498 uint8_t *buf = new uint8_t[bufsize];
499 AMediaCodecBufferInfo info;
500 while(true) {
501 int n = AMediaExtractor_readSampleData(ex, buf, bufsize);
502 if (n < 0) {
503 break;
504 }
505 info.offset = 0;
506 info.size = n;
507 info.presentationTimeUs = AMediaExtractor_getSampleTime(ex);
508 info.flags = AMediaExtractor_getSampleFlags(ex);
509
510 size_t idx = (size_t) AMediaExtractor_getSampleTrackIndex(ex);
511 AMediaMuxer_writeSampleData(muxer, idx, buf, &info);
512
513 AMediaExtractor_advance(ex);
514 }
515
516 AMediaExtractor_delete(ex);
517 AMediaMuxer_stop(muxer);
518 AMediaMuxer_delete(muxer);
519 return true;
520
521 }
522
Java_android_media_cts_NativeDecoderTest_testFormatNative(JNIEnv *,jclass)523 extern "C" jboolean Java_android_media_cts_NativeDecoderTest_testFormatNative(JNIEnv * /*env*/,
524 jclass /*clazz*/) {
525 AMediaFormat* format = AMediaFormat_new();
526 if (!format) {
527 return false;
528 }
529
530 AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_BIT_RATE, 8000);
531 int32_t bitrate = 0;
532 if (!AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_BIT_RATE, &bitrate) || bitrate != 8000) {
533 ALOGE("AMediaFormat_getInt32 fail: %d", bitrate);
534 return false;
535 }
536
537 AMediaFormat_setInt64(format, AMEDIAFORMAT_KEY_DURATION, 123456789123456789ll);
538 int64_t duration = 0;
539 if (!AMediaFormat_getInt64(format, AMEDIAFORMAT_KEY_DURATION, &duration)
540 || duration != 123456789123456789ll) {
541 ALOGE("AMediaFormat_getInt64 fail: %lld", (long long) duration);
542 return false;
543 }
544
545 AMediaFormat_setFloat(format, AMEDIAFORMAT_KEY_FRAME_RATE, 25.0f);
546 float framerate = 0.0f;
547 if (!AMediaFormat_getFloat(format, AMEDIAFORMAT_KEY_FRAME_RATE, &framerate)
548 || framerate != 25.0f) {
549 ALOGE("AMediaFormat_getFloat fail: %f", framerate);
550 return false;
551 }
552
553 const char* value = "audio/mpeg";
554 AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, value);
555 const char* readback = NULL;
556 if (!AMediaFormat_getString(format, AMEDIAFORMAT_KEY_MIME, &readback)
557 || strcmp(value, readback) || value == readback) {
558 ALOGE("AMediaFormat_getString fail");
559 return false;
560 }
561
562 uint32_t foo = 0xdeadbeef;
563 AMediaFormat_setBuffer(format, "csd-0", &foo, sizeof(foo));
564 foo = 0xabadcafe;
565 void *bytes;
566 size_t bytesize = 0;
567 if(!AMediaFormat_getBuffer(format, "csd-0", &bytes, &bytesize)
568 || bytesize != sizeof(foo) || *((uint32_t*)bytes) != 0xdeadbeef) {
569 ALOGE("AMediaFormat_getBuffer fail");
570 return false;
571 }
572
573 return true;
574 }
575
576
Java_android_media_cts_NativeDecoderTest_testPsshNative(JNIEnv *,jclass,int fd,jlong offset,jlong size)577 extern "C" jboolean Java_android_media_cts_NativeDecoderTest_testPsshNative(JNIEnv * /*env*/,
578 jclass /*clazz*/, int fd, jlong offset, jlong size) {
579
580 AMediaExtractor *ex = AMediaExtractor_new();
581 int err = AMediaExtractor_setDataSourceFd(ex, fd, offset, size);
582 if (err != 0) {
583 ALOGE("setDataSource error: %d", err);
584 return false;
585 }
586
587 PsshInfo* info = AMediaExtractor_getPsshInfo(ex);
588 if (info == NULL) {
589 ALOGI("null pssh");
590 return false;
591 }
592
593 ALOGI("pssh has %zd entries", info->numentries);
594 if (info->numentries != 2) {
595 return false;
596 }
597
598 for (size_t i = 0; i < info->numentries; i++) {
599 PsshEntry *entry = &info->entries[i];
600 ALOGI("entry uuid %02x%02x..%02x%02x, data size %zd",
601 entry->uuid[0],
602 entry->uuid[1],
603 entry->uuid[14],
604 entry->uuid[15],
605 entry->datalen);
606
607 AMediaCrypto *crypto = AMediaCrypto_new(entry->uuid, entry->data, entry->datalen);
608 if (crypto) {
609 ALOGI("got crypto");
610 AMediaCrypto_delete(crypto);
611 } else {
612 ALOGI("no crypto");
613 }
614 }
615 return true;
616 }
617
Java_android_media_cts_NativeDecoderTest_testCryptoInfoNative(JNIEnv *,jclass)618 extern "C" jboolean Java_android_media_cts_NativeDecoderTest_testCryptoInfoNative(JNIEnv * /*env*/,
619 jclass /*clazz*/) {
620
621 size_t numsubsamples = 4;
622 uint8_t key[16] = { 1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4 };
623 uint8_t iv[16] = { 4,3,2,1,4,3,2,1,4,3,2,1,4,3,2,1 };
624 size_t clearbytes[4] = { 5, 6, 7, 8 };
625 size_t encryptedbytes[4] = { 8, 7, 6, 5 };
626
627 AMediaCodecCryptoInfo *ci =
628 AMediaCodecCryptoInfo_new(numsubsamples, key, iv, AMEDIACODECRYPTOINFO_MODE_CLEAR, clearbytes, encryptedbytes);
629
630 if (AMediaCodecCryptoInfo_getNumSubSamples(ci) != 4) {
631 ALOGE("numsubsamples mismatch");
632 return false;
633 }
634 uint8_t bytes[16];
635 AMediaCodecCryptoInfo_getKey(ci, bytes);
636 if (memcmp(key, bytes, 16) != 0) {
637 ALOGE("key mismatch");
638 return false;
639 }
640 AMediaCodecCryptoInfo_getIV(ci, bytes);
641 if (memcmp(iv, bytes, 16) != 0) {
642 ALOGE("IV mismatch");
643 return false;
644 }
645 if (AMediaCodecCryptoInfo_getMode(ci) != AMEDIACODECRYPTOINFO_MODE_CLEAR) {
646 ALOGE("mode mismatch");
647 return false;
648 }
649 size_t sizes[numsubsamples];
650 AMediaCodecCryptoInfo_getClearBytes(ci, sizes);
651 if (memcmp(clearbytes, sizes, sizeof(size_t) * numsubsamples)) {
652 ALOGE("clear size mismatch");
653 return false;
654 }
655 AMediaCodecCryptoInfo_getEncryptedBytes(ci, sizes);
656 if (memcmp(encryptedbytes, sizes, sizeof(size_t) * numsubsamples)) {
657 ALOGE("encrypted size mismatch");
658 return false;
659 }
660 return true;
661 }
662
663 // === NdkMediaCodec
664
Java_android_media_cts_NdkMediaCodec_AMediaCodecCreateCodecByName(JNIEnv * env,jclass,jstring name)665 extern "C" jlong Java_android_media_cts_NdkMediaCodec_AMediaCodecCreateCodecByName(
666 JNIEnv *env, jclass /*clazz*/, jstring name) {
667
668 if (name == NULL) {
669 return 0;
670 }
671
672 const char *tmp = env->GetStringUTFChars(name, NULL);
673 if (tmp == NULL) {
674 return 0;
675 }
676
677 AMediaCodec *codec = AMediaCodec_createCodecByName(tmp);
678 if (codec == NULL) {
679 env->ReleaseStringUTFChars(name, tmp);
680 return 0;
681 }
682
683 env->ReleaseStringUTFChars(name, tmp);
684 return reinterpret_cast<jlong>(codec);
685
686 }
687
Java_android_media_cts_NdkMediaCodec_AMediaCodecDelete(JNIEnv *,jclass,jlong codec)688 extern "C" jboolean Java_android_media_cts_NdkMediaCodec_AMediaCodecDelete(
689 JNIEnv * /*env*/, jclass /*clazz*/, jlong codec) {
690 media_status_t err = AMediaCodec_delete(reinterpret_cast<AMediaCodec *>(codec));
691 return err == AMEDIA_OK;
692 }
693
Java_android_media_cts_NdkMediaCodec_AMediaCodecStart(JNIEnv *,jclass,jlong codec)694 extern "C" jboolean Java_android_media_cts_NdkMediaCodec_AMediaCodecStart(
695 JNIEnv * /*env*/, jclass /*clazz*/, jlong codec) {
696 media_status_t err = AMediaCodec_start(reinterpret_cast<AMediaCodec *>(codec));
697 return err == AMEDIA_OK;
698 }
699
Java_android_media_cts_NdkMediaCodec_AMediaCodecStop(JNIEnv *,jclass,jlong codec)700 extern "C" jboolean Java_android_media_cts_NdkMediaCodec_AMediaCodecStop(
701 JNIEnv * /*env*/, jclass /*clazz*/, jlong codec) {
702 media_status_t err = AMediaCodec_stop(reinterpret_cast<AMediaCodec *>(codec));
703 return err == AMEDIA_OK;
704 }
705
Java_android_media_cts_NdkMediaCodec_AMediaCodecConfigure(JNIEnv * env,jclass,jlong codec,jstring mime,jint width,jint height,jint colorFormat,jint bitRate,jint frameRate,jint iFrameInterval,jobject csd,jint flags)706 extern "C" jboolean Java_android_media_cts_NdkMediaCodec_AMediaCodecConfigure(
707 JNIEnv *env,
708 jclass /*clazz*/,
709 jlong codec,
710 jstring mime,
711 jint width,
712 jint height,
713 jint colorFormat,
714 jint bitRate,
715 jint frameRate,
716 jint iFrameInterval,
717 jobject csd,
718 jint flags) {
719
720 AMediaFormat* format = AMediaFormat_new();
721 if (format == NULL) {
722 return false;
723 }
724
725 const char *tmp = env->GetStringUTFChars(mime, NULL);
726 if (tmp == NULL) {
727 AMediaFormat_delete(format);
728 return false;
729 }
730
731 AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, tmp);
732 env->ReleaseStringUTFChars(mime, tmp);
733
734 const char *keys[] = {
735 AMEDIAFORMAT_KEY_WIDTH,
736 AMEDIAFORMAT_KEY_HEIGHT,
737 AMEDIAFORMAT_KEY_COLOR_FORMAT,
738 AMEDIAFORMAT_KEY_BIT_RATE,
739 AMEDIAFORMAT_KEY_FRAME_RATE,
740 AMEDIAFORMAT_KEY_I_FRAME_INTERVAL
741 };
742
743 jint values[] = {width, height, colorFormat, bitRate, frameRate, iFrameInterval};
744 for (size_t i = 0; i < sizeof(values) / sizeof(values[0]); i++) {
745 if (values[i] >= 0) {
746 AMediaFormat_setInt32(format, keys[i], values[i]);
747 }
748 }
749
750 if (csd != NULL) {
751 void *csdPtr = env->GetDirectBufferAddress(csd);
752 jlong csdSize = env->GetDirectBufferCapacity(csd);
753 AMediaFormat_setBuffer(format, "csd-0", csdPtr, csdSize);
754 }
755
756 media_status_t err = AMediaCodec_configure(
757 reinterpret_cast<AMediaCodec *>(codec),
758 format,
759 NULL,
760 NULL,
761 flags);
762
763 AMediaFormat_delete(format);
764 return err == AMEDIA_OK;
765
766 }
767
Java_android_media_cts_NdkMediaCodec_AMediaCodecSetInputSurface(JNIEnv * env,jclass,jlong codec,jobject surface)768 extern "C" jboolean Java_android_media_cts_NdkMediaCodec_AMediaCodecSetInputSurface(
769 JNIEnv* env, jclass /*clazz*/, jlong codec, jobject surface) {
770
771 media_status_t err = AMediaCodec_setInputSurface(
772 reinterpret_cast<AMediaCodec *>(codec),
773 ANativeWindow_fromSurface(env, surface));
774
775 return err == AMEDIA_OK;
776
777 }
778
Java_android_media_cts_NdkMediaCodec_AMediaCodecSetNativeInputSurface(JNIEnv *,jclass,jlong codec,jlong nativeWindow)779 extern "C" jboolean Java_android_media_cts_NdkMediaCodec_AMediaCodecSetNativeInputSurface(
780 JNIEnv* /*env*/, jclass /*clazz*/, jlong codec, jlong nativeWindow) {
781
782 media_status_t err = AMediaCodec_setInputSurface(
783 reinterpret_cast<AMediaCodec *>(codec),
784 reinterpret_cast<ANativeWindow *>(nativeWindow));
785
786 return err == AMEDIA_OK;
787
788 }
789
Java_android_media_cts_NdkMediaCodec_AMediaCodecCreateInputSurface(JNIEnv *,jclass,jlong codec)790 extern "C" jlong Java_android_media_cts_NdkMediaCodec_AMediaCodecCreateInputSurface(
791 JNIEnv* /*env*/, jclass /*clazz*/, jlong codec) {
792
793 ANativeWindow *nativeWindow;
794 media_status_t err = AMediaCodec_createInputSurface(
795 reinterpret_cast<AMediaCodec *>(codec),
796 &nativeWindow);
797
798 if (err == AMEDIA_OK) {
799 return reinterpret_cast<jlong>(nativeWindow);
800 }
801
802 return 0;
803
804 }
805
Java_android_media_cts_NdkMediaCodec_AMediaCodecCreatePersistentInputSurface(JNIEnv *,jclass)806 extern "C" jlong Java_android_media_cts_NdkMediaCodec_AMediaCodecCreatePersistentInputSurface(
807 JNIEnv* /*env*/, jclass /*clazz*/) {
808
809 ANativeWindow *nativeWindow;
810 media_status_t err = AMediaCodec_createPersistentInputSurface(&nativeWindow);
811
812 if (err == AMEDIA_OK) {
813 return reinterpret_cast<jlong>(nativeWindow);
814 }
815
816 return 0;
817
818 }
819
Java_android_media_cts_NdkMediaCodec_AMediaCodecGetOutputFormatString(JNIEnv * env,jclass,jlong codec)820 extern "C" jstring Java_android_media_cts_NdkMediaCodec_AMediaCodecGetOutputFormatString(
821 JNIEnv* env, jclass /*clazz*/, jlong codec) {
822
823 AMediaFormat *format = AMediaCodec_getOutputFormat(reinterpret_cast<AMediaCodec *>(codec));
824 const char *str = AMediaFormat_toString(format);
825 jstring jstr = env->NewStringUTF(str);
826 AMediaFormat_delete(format);
827 return jstr;
828
829 }
830
Java_android_media_cts_NdkMediaCodec_AMediaCodecSignalEndOfInputStream(JNIEnv *,jclass,jlong codec)831 extern "C" jboolean Java_android_media_cts_NdkMediaCodec_AMediaCodecSignalEndOfInputStream(
832 JNIEnv* /*env*/, jclass /*clazz*/, jlong codec) {
833
834 media_status_t err = AMediaCodec_signalEndOfInputStream(reinterpret_cast<AMediaCodec *>(codec));
835 return err == AMEDIA_OK;
836
837 }
838
Java_android_media_cts_NdkMediaCodec_AMediaCodecReleaseOutputBuffer(JNIEnv *,jclass,jlong codec,jint index,jboolean render)839 extern "C" jboolean Java_android_media_cts_NdkMediaCodec_AMediaCodecReleaseOutputBuffer(
840 JNIEnv* /*env*/, jclass /*clazz*/, jlong codec, jint index, jboolean render) {
841
842 media_status_t err = AMediaCodec_releaseOutputBuffer(
843 reinterpret_cast<AMediaCodec *>(codec),
844 index,
845 render);
846
847 return err == AMEDIA_OK;
848
849 }
850
AMediaCodecGetBuffer(JNIEnv * env,jlong codec,jint index,uint8_t * (* getBuffer)(AMediaCodec *,size_t,size_t *))851 static jobject AMediaCodecGetBuffer(
852 JNIEnv* env,
853 jlong codec,
854 jint index,
855 uint8_t *(*getBuffer)(AMediaCodec*, size_t, size_t*)) {
856
857 size_t bufsize;
858 uint8_t *buf = getBuffer(
859 reinterpret_cast<AMediaCodec *>(codec),
860 index,
861 &bufsize);
862
863 return env->NewDirectByteBuffer(buf, bufsize);
864
865 }
866
Java_android_media_cts_NdkMediaCodec_AMediaCodecGetOutputBuffer(JNIEnv * env,jclass,jlong codec,jint index)867 extern "C" jobject Java_android_media_cts_NdkMediaCodec_AMediaCodecGetOutputBuffer(
868 JNIEnv* env, jclass /*clazz*/, jlong codec, jint index) {
869
870 return AMediaCodecGetBuffer(env, codec, index, AMediaCodec_getOutputBuffer);
871
872 }
873
Java_android_media_cts_NdkMediaCodec_AMediaCodecDequeueOutputBuffer(JNIEnv * env,jclass,jlong codec,jlong timeoutUs)874 extern "C" jlongArray Java_android_media_cts_NdkMediaCodec_AMediaCodecDequeueOutputBuffer(
875 JNIEnv* env, jclass /*clazz*/, jlong codec, jlong timeoutUs) {
876
877 AMediaCodecBufferInfo info;
878 memset(&info, 0, sizeof(info));
879 int status = AMediaCodec_dequeueOutputBuffer(
880 reinterpret_cast<AMediaCodec *>(codec),
881 &info,
882 timeoutUs);
883
884 jlong ret[5] = {0};
885 ret[0] = status;
886 ret[1] = 0; // NdkMediaCodec calls ABuffer::data, which already adds offset
887 ret[2] = info.size;
888 ret[3] = info.presentationTimeUs;
889 ret[4] = info.flags;
890
891 jlongArray jret = env->NewLongArray(5);
892 env->SetLongArrayRegion(jret, 0, 5, ret);
893 return jret;
894
895 }
896
Java_android_media_cts_NdkMediaCodec_AMediaCodecGetInputBuffer(JNIEnv * env,jclass,jlong codec,jint index)897 extern "C" jobject Java_android_media_cts_NdkMediaCodec_AMediaCodecGetInputBuffer(
898 JNIEnv* env, jclass /*clazz*/, jlong codec, jint index) {
899
900 return AMediaCodecGetBuffer(env, codec, index, AMediaCodec_getInputBuffer);
901
902 }
903
Java_android_media_cts_NdkMediaCodec_AMediaCodecDequeueInputBuffer(JNIEnv *,jclass,jlong codec,jlong timeoutUs)904 extern "C" jint Java_android_media_cts_NdkMediaCodec_AMediaCodecDequeueInputBuffer(
905 JNIEnv* /*env*/, jclass /*clazz*/, jlong codec, jlong timeoutUs) {
906
907 return AMediaCodec_dequeueInputBuffer(
908 reinterpret_cast<AMediaCodec *>(codec),
909 timeoutUs);
910
911 }
912
Java_android_media_cts_NdkMediaCodec_AMediaCodecQueueInputBuffer(JNIEnv *,jclass,jlong codec,jint index,jint offset,jint size,jlong presentationTimeUs,jint flags)913 extern "C" jboolean Java_android_media_cts_NdkMediaCodec_AMediaCodecQueueInputBuffer(
914 JNIEnv* /*env*/,
915 jclass /*clazz*/,
916 jlong codec,
917 jint index,
918 jint offset,
919 jint size,
920 jlong presentationTimeUs,
921 jint flags) {
922
923 media_status_t err = AMediaCodec_queueInputBuffer(
924 reinterpret_cast<AMediaCodec *>(codec),
925 index,
926 offset,
927 size,
928 presentationTimeUs,
929 flags);
930
931 return err == AMEDIA_OK;
932
933 }
934
Java_android_media_cts_NdkMediaCodec_AMediaCodecSetParameter(JNIEnv * env,jclass,jlong codec,jstring jkey,jint value)935 extern "C" jboolean Java_android_media_cts_NdkMediaCodec_AMediaCodecSetParameter(
936 JNIEnv* env, jclass /*clazz*/, jlong codec, jstring jkey, jint value) {
937
938 AMediaFormat* params = AMediaFormat_new();
939 if (params == NULL) {
940 return false;
941 }
942
943 const char *key = env->GetStringUTFChars(jkey, NULL);
944 if (key == NULL) {
945 AMediaFormat_delete(params);
946 return false;
947 }
948
949 AMediaFormat_setInt32(params, key, value);
950 media_status_t err = AMediaCodec_setParameters(
951 reinterpret_cast<AMediaCodec *>(codec),
952 params);
953 env->ReleaseStringUTFChars(jkey, key);
954 AMediaFormat_delete(params);
955 return err == AMEDIA_OK;
956
957 }
958
959 // === NdkInputSurface
960
Java_android_media_cts_NdkInputSurface_eglGetDisplay(JNIEnv *,jclass)961 extern "C" jlong Java_android_media_cts_NdkInputSurface_eglGetDisplay(JNIEnv * /*env*/, jclass /*clazz*/) {
962
963 EGLDisplay eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
964 if (eglDisplay == EGL_NO_DISPLAY) {
965 return 0;
966 }
967
968 EGLint major, minor;
969 if (!eglInitialize(eglDisplay, &major, &minor)) {
970 return 0;
971 }
972
973 return reinterpret_cast<jlong>(eglDisplay);
974
975 }
976
Java_android_media_cts_NdkInputSurface_eglChooseConfig(JNIEnv *,jclass,jlong eglDisplay)977 extern "C" jlong Java_android_media_cts_NdkInputSurface_eglChooseConfig(
978 JNIEnv * /*env*/, jclass /*clazz*/, jlong eglDisplay) {
979
980 // Configure EGL for recordable and OpenGL ES 2.0. We want enough RGB bits
981 // to minimize artifacts from possible YUV conversion.
982 EGLint attribList[] = {
983 EGL_RED_SIZE, 8,
984 EGL_GREEN_SIZE, 8,
985 EGL_BLUE_SIZE, 8,
986 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
987 EGL_RECORDABLE_ANDROID, 1,
988 EGL_NONE
989 };
990
991 EGLConfig configs[1];
992 EGLint numConfigs[1];
993 if (!eglChooseConfig(reinterpret_cast<EGLDisplay>(eglDisplay), attribList, configs, 1, numConfigs)) {
994 return 0;
995 }
996 return reinterpret_cast<jlong>(configs[0]);
997
998 }
999
Java_android_media_cts_NdkInputSurface_eglCreateContext(JNIEnv *,jclass,jlong eglDisplay,jlong eglConfig)1000 extern "C" jlong Java_android_media_cts_NdkInputSurface_eglCreateContext(
1001 JNIEnv * /*env*/, jclass /*clazz*/, jlong eglDisplay, jlong eglConfig) {
1002
1003 // Configure context for OpenGL ES 2.0.
1004 int attrib_list[] = {
1005 EGL_CONTEXT_CLIENT_VERSION, 2,
1006 EGL_NONE
1007 };
1008
1009 EGLConfig eglContext = eglCreateContext(
1010 reinterpret_cast<EGLDisplay>(eglDisplay),
1011 reinterpret_cast<EGLConfig>(eglConfig),
1012 EGL_NO_CONTEXT,
1013 attrib_list);
1014
1015 if (eglGetError() != EGL_SUCCESS) {
1016 return 0;
1017 }
1018
1019 return reinterpret_cast<jlong>(eglContext);
1020
1021 }
1022
Java_android_media_cts_NdkInputSurface_createEGLSurface(JNIEnv *,jclass,jlong eglDisplay,jlong eglConfig,jlong nativeWindow)1023 extern "C" jlong Java_android_media_cts_NdkInputSurface_createEGLSurface(
1024 JNIEnv * /*env*/, jclass /*clazz*/, jlong eglDisplay, jlong eglConfig, jlong nativeWindow) {
1025
1026 int surfaceAttribs[] = {EGL_NONE};
1027 EGLSurface eglSurface = eglCreateWindowSurface(
1028 reinterpret_cast<EGLDisplay>(eglDisplay),
1029 reinterpret_cast<EGLConfig>(eglConfig),
1030 reinterpret_cast<EGLNativeWindowType>(nativeWindow),
1031 surfaceAttribs);
1032
1033 if (eglGetError() != EGL_SUCCESS) {
1034 return 0;
1035 }
1036
1037 return reinterpret_cast<jlong>(eglSurface);
1038
1039 }
1040
Java_android_media_cts_NdkInputSurface_eglMakeCurrent(JNIEnv *,jclass,jlong eglDisplay,jlong eglSurface,jlong eglContext)1041 extern "C" jboolean Java_android_media_cts_NdkInputSurface_eglMakeCurrent(
1042 JNIEnv * /*env*/, jclass /*clazz*/, jlong eglDisplay, jlong eglSurface, jlong eglContext) {
1043
1044 return eglMakeCurrent(
1045 reinterpret_cast<EGLDisplay>(eglDisplay),
1046 reinterpret_cast<EGLSurface>(eglSurface),
1047 reinterpret_cast<EGLSurface>(eglSurface),
1048 reinterpret_cast<EGLContext>(eglContext));
1049
1050 }
1051
Java_android_media_cts_NdkInputSurface_eglSwapBuffers(JNIEnv *,jclass,jlong eglDisplay,jlong eglSurface)1052 extern "C" jboolean Java_android_media_cts_NdkInputSurface_eglSwapBuffers(
1053 JNIEnv * /*env*/, jclass /*clazz*/, jlong eglDisplay, jlong eglSurface) {
1054
1055 return eglSwapBuffers(
1056 reinterpret_cast<EGLDisplay>(eglDisplay),
1057 reinterpret_cast<EGLSurface>(eglSurface));
1058
1059 }
1060
Java_android_media_cts_NdkInputSurface_eglPresentationTimeANDROID(JNIEnv *,jclass,jlong eglDisplay,jlong eglSurface,jlong nsecs)1061 extern "C" jboolean Java_android_media_cts_NdkInputSurface_eglPresentationTimeANDROID(
1062 JNIEnv * /*env*/, jclass /*clazz*/, jlong eglDisplay, jlong eglSurface, jlong nsecs) {
1063
1064 return eglPresentationTimeANDROID(
1065 reinterpret_cast<EGLDisplay>(eglDisplay),
1066 reinterpret_cast<EGLSurface>(eglSurface),
1067 reinterpret_cast<EGLnsecsANDROID>(nsecs));
1068
1069 }
1070
Java_android_media_cts_NdkInputSurface_eglGetWidth(JNIEnv *,jclass,jlong eglDisplay,jlong eglSurface)1071 extern "C" jint Java_android_media_cts_NdkInputSurface_eglGetWidth(
1072 JNIEnv * /*env*/, jclass /*clazz*/, jlong eglDisplay, jlong eglSurface) {
1073
1074 EGLint width;
1075 eglQuerySurface(
1076 reinterpret_cast<EGLDisplay>(eglDisplay),
1077 reinterpret_cast<EGLSurface>(eglSurface),
1078 EGL_WIDTH,
1079 &width);
1080
1081 return width;
1082
1083 }
1084
Java_android_media_cts_NdkInputSurface_eglGetHeight(JNIEnv *,jclass,jlong eglDisplay,jlong eglSurface)1085 extern "C" jint Java_android_media_cts_NdkInputSurface_eglGetHeight(
1086 JNIEnv * /*env*/, jclass /*clazz*/, jlong eglDisplay, jlong eglSurface) {
1087
1088 EGLint height;
1089 eglQuerySurface(
1090 reinterpret_cast<EGLDisplay>(eglDisplay),
1091 reinterpret_cast<EGLSurface>(eglSurface),
1092 EGL_HEIGHT,
1093 &height);
1094
1095 return height;
1096
1097 }
1098
Java_android_media_cts_NdkInputSurface_eglDestroySurface(JNIEnv *,jclass,jlong eglDisplay,jlong eglSurface)1099 extern "C" jboolean Java_android_media_cts_NdkInputSurface_eglDestroySurface(
1100 JNIEnv * /*env*/, jclass /*clazz*/, jlong eglDisplay, jlong eglSurface) {
1101
1102 return eglDestroySurface(
1103 reinterpret_cast<EGLDisplay>(eglDisplay),
1104 reinterpret_cast<EGLSurface>(eglSurface));
1105
1106 }
1107
Java_android_media_cts_NdkInputSurface_nativeRelease(JNIEnv *,jclass,jlong eglDisplay,jlong eglSurface,jlong eglContext,jlong nativeWindow)1108 extern "C" void Java_android_media_cts_NdkInputSurface_nativeRelease(
1109 JNIEnv * /*env*/, jclass /*clazz*/, jlong eglDisplay, jlong eglSurface, jlong eglContext, jlong nativeWindow) {
1110
1111 if (eglDisplay != 0) {
1112
1113 EGLDisplay _eglDisplay = reinterpret_cast<EGLDisplay>(eglDisplay);
1114 EGLSurface _eglSurface = reinterpret_cast<EGLSurface>(eglSurface);
1115 EGLContext _eglContext = reinterpret_cast<EGLContext>(eglContext);
1116
1117 eglDestroySurface(_eglDisplay, _eglSurface);
1118 eglDestroyContext(_eglDisplay, _eglContext);
1119 eglReleaseThread();
1120 eglTerminate(_eglDisplay);
1121
1122 }
1123
1124 ANativeWindow_release(reinterpret_cast<ANativeWindow *>(nativeWindow));
1125
1126 }
1127