blob: 051833161c23d113cb7b606572833db3f9d8529f [file] [log] [blame]
Andreas Huber88572f72012-02-21 11:47:18 -08001/*
2 * Copyright 2012, 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//#define LOG_NDEBUG 0
18#define LOG_TAG "MediaExtractor-JNI"
19#include <utils/Log.h>
20
21#include "android_media_MediaExtractor.h"
22
23#include "android_media_Utils.h"
24#include "android_runtime/AndroidRuntime.h"
25#include "jni.h"
26#include "JNIHelp.h"
27
Andreas Huberab57d032012-04-18 15:59:43 -070028#include <media/hardware/CryptoAPI.h>
Andreas Huber88572f72012-02-21 11:47:18 -080029#include <media/stagefright/foundation/ABuffer.h>
30#include <media/stagefright/foundation/ADebug.h>
31#include <media/stagefright/foundation/AMessage.h>
32#include <media/stagefright/DataSource.h>
33#include <media/stagefright/MediaErrors.h>
Andreas Huber91befdc2012-04-18 12:19:51 -070034#include <media/stagefright/MetaData.h>
Andreas Huber88572f72012-02-21 11:47:18 -080035#include <media/stagefright/NuMediaExtractor.h>
36
37namespace android {
38
39struct fields_t {
40 jfieldID context;
Andreas Huber91befdc2012-04-18 12:19:51 -070041
42 jmethodID cryptoInfoSetID;
Andreas Huber88572f72012-02-21 11:47:18 -080043};
44
45static fields_t gFields;
46
47////////////////////////////////////////////////////////////////////////////////
48
49JMediaExtractor::JMediaExtractor(JNIEnv *env, jobject thiz)
50 : mClass(NULL),
51 mObject(NULL) {
52 jclass clazz = env->GetObjectClass(thiz);
53 CHECK(clazz != NULL);
54
55 mClass = (jclass)env->NewGlobalRef(clazz);
56 mObject = env->NewWeakGlobalRef(thiz);
57
58 mImpl = new NuMediaExtractor;
59}
60
61JMediaExtractor::~JMediaExtractor() {
62 JNIEnv *env = AndroidRuntime::getJNIEnv();
63
64 env->DeleteWeakGlobalRef(mObject);
65 mObject = NULL;
66 env->DeleteGlobalRef(mClass);
67 mClass = NULL;
68}
69
Andreas Huber07ea4262012-04-11 12:21:20 -070070status_t JMediaExtractor::setDataSource(
71 const char *path, const KeyedVector<String8, String8> *headers) {
72 return mImpl->setDataSource(path, headers);
73}
74
75status_t JMediaExtractor::setDataSource(int fd, off64_t offset, off64_t size) {
76 return mImpl->setDataSource(fd, offset, size);
Andreas Huber88572f72012-02-21 11:47:18 -080077}
78
79size_t JMediaExtractor::countTracks() const {
80 return mImpl->countTracks();
81}
82
83status_t JMediaExtractor::getTrackFormat(size_t index, jobject *format) const {
84 sp<AMessage> msg;
85 status_t err;
86 if ((err = mImpl->getTrackFormat(index, &msg)) != OK) {
87 return err;
88 }
89
90 JNIEnv *env = AndroidRuntime::getJNIEnv();
91
92 return ConvertMessageToMap(env, msg, format);
93}
94
95status_t JMediaExtractor::selectTrack(size_t index) {
96 return mImpl->selectTrack(index);
97}
98
99status_t JMediaExtractor::seekTo(int64_t timeUs) {
100 return mImpl->seekTo(timeUs);
101}
102
103status_t JMediaExtractor::advance() {
104 return mImpl->advance();
105}
106
107status_t JMediaExtractor::readSampleData(
108 jobject byteBuf, size_t offset, size_t *sampleSize) {
109 JNIEnv *env = AndroidRuntime::getJNIEnv();
110
111 void *dst = env->GetDirectBufferAddress(byteBuf);
112
Andreas Huberc52b9802012-03-12 14:04:01 -0700113 jlong dstSize;
114 jbyteArray byteArray = NULL;
115
Andreas Huber88572f72012-02-21 11:47:18 -0800116 if (dst == NULL) {
Andreas Huberc52b9802012-03-12 14:04:01 -0700117 jclass byteBufClass = env->FindClass("java/nio/ByteBuffer");
118 CHECK(byteBufClass != NULL);
119
120 jmethodID arrayID =
121 env->GetMethodID(byteBufClass, "array", "()[B");
122 CHECK(arrayID != NULL);
123
124 byteArray =
125 (jbyteArray)env->CallObjectMethod(byteBuf, arrayID);
126
127 if (byteArray == NULL) {
128 return INVALID_OPERATION;
129 }
130
131 jboolean isCopy;
132 dst = env->GetByteArrayElements(byteArray, &isCopy);
133
134 dstSize = env->GetArrayLength(byteArray);
135 } else {
136 dstSize = env->GetDirectBufferCapacity(byteBuf);
Andreas Huber88572f72012-02-21 11:47:18 -0800137 }
138
Andreas Huber88572f72012-02-21 11:47:18 -0800139 if (dstSize < offset) {
Andreas Huberc52b9802012-03-12 14:04:01 -0700140 if (byteArray != NULL) {
141 env->ReleaseByteArrayElements(byteArray, (jbyte *)dst, 0);
142 }
143
Andreas Huber88572f72012-02-21 11:47:18 -0800144 return -ERANGE;
145 }
146
147 sp<ABuffer> buffer = new ABuffer((char *)dst + offset, dstSize - offset);
148
149 status_t err = mImpl->readSampleData(buffer);
150
Andreas Huberc52b9802012-03-12 14:04:01 -0700151 if (byteArray != NULL) {
152 env->ReleaseByteArrayElements(byteArray, (jbyte *)dst, 0);
153 }
154
Andreas Huber88572f72012-02-21 11:47:18 -0800155 if (err != OK) {
156 return err;
157 }
158
159 *sampleSize = buffer->size();
160
161 return OK;
162}
163
164status_t JMediaExtractor::getSampleTrackIndex(size_t *trackIndex) {
165 return mImpl->getSampleTrackIndex(trackIndex);
166}
167
168status_t JMediaExtractor::getSampleTime(int64_t *sampleTimeUs) {
169 return mImpl->getSampleTime(sampleTimeUs);
170}
171
Andreas Huber9b8e4962012-03-26 11:13:27 -0700172status_t JMediaExtractor::getSampleFlags(uint32_t *sampleFlags) {
Andreas Huber91befdc2012-04-18 12:19:51 -0700173 *sampleFlags = 0;
174
175 sp<MetaData> meta;
176 status_t err = mImpl->getSampleMeta(&meta);
177
178 if (err != OK) {
179 return err;
180 }
181
182 int32_t val;
183 if (meta->findInt32(kKeyIsSyncFrame, &val) && val != 0) {
184 (*sampleFlags) |= NuMediaExtractor::SAMPLE_FLAG_SYNC;
185 }
186
187 uint32_t type;
188 const void *data;
189 size_t size;
190 if (meta->findData(kKeyEncryptedSizes, &type, &data, &size)) {
191 (*sampleFlags) |= NuMediaExtractor::SAMPLE_FLAG_ENCRYPTED;
192 }
193
194 return OK;
195}
196
197status_t JMediaExtractor::getSampleMeta(sp<MetaData> *sampleMeta) {
198 return mImpl->getSampleMeta(sampleMeta);
Andreas Huber9b8e4962012-03-26 11:13:27 -0700199}
200
Andreas Huber74a78b02012-04-19 16:24:32 -0700201bool JMediaExtractor::getCachedDuration(int64_t *durationUs, bool *eos) const {
202 return mImpl->getCachedDuration(durationUs, eos);
203}
204
Andreas Huber88572f72012-02-21 11:47:18 -0800205} // namespace android
206
207////////////////////////////////////////////////////////////////////////////////
208
209using namespace android;
210
211static sp<JMediaExtractor> setMediaExtractor(
212 JNIEnv *env, jobject thiz, const sp<JMediaExtractor> &extractor) {
213 sp<JMediaExtractor> old =
214 (JMediaExtractor *)env->GetIntField(thiz, gFields.context);
215
216 if (extractor != NULL) {
217 extractor->incStrong(thiz);
218 }
219 if (old != NULL) {
220 old->decStrong(thiz);
221 }
222 env->SetIntField(thiz, gFields.context, (int)extractor.get());
223
224 return old;
225}
226
227static sp<JMediaExtractor> getMediaExtractor(JNIEnv *env, jobject thiz) {
228 return (JMediaExtractor *)env->GetIntField(thiz, gFields.context);
229}
230
231static void android_media_MediaExtractor_release(JNIEnv *env, jobject thiz) {
232 setMediaExtractor(env, thiz, NULL);
233}
234
235static jint android_media_MediaExtractor_countTracks(
236 JNIEnv *env, jobject thiz) {
237 sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
238
239 if (extractor == NULL) {
240 jniThrowException(env, "java/lang/IllegalStateException", NULL);
Andreas Huber07ea4262012-04-11 12:21:20 -0700241 return -1;
Andreas Huber88572f72012-02-21 11:47:18 -0800242 }
243
244 return extractor->countTracks();
245}
246
247static jobject android_media_MediaExtractor_getTrackFormat(
248 JNIEnv *env, jobject thiz, jint index) {
249 sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
250
251 if (extractor == NULL) {
252 jniThrowException(env, "java/lang/IllegalStateException", NULL);
253 return NULL;
254 }
255
256 jobject format;
257 status_t err = extractor->getTrackFormat(index, &format);
258
259 if (err != OK) {
260 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
261 return NULL;
262 }
263
264 return format;
265}
266
267static void android_media_MediaExtractor_selectTrack(
268 JNIEnv *env, jobject thiz, jint index) {
269 sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
270
271 if (extractor == NULL) {
272 jniThrowException(env, "java/lang/IllegalStateException", NULL);
273 return;
274 }
275
276 status_t err = extractor->selectTrack(index);
277
278 if (err != OK) {
279 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
280 return;
281 }
282}
283
284static void android_media_MediaExtractor_seekTo(
285 JNIEnv *env, jobject thiz, jlong timeUs) {
286 sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
287
288 if (extractor == NULL) {
289 jniThrowException(env, "java/lang/IllegalStateException", NULL);
290 return;
291 }
292
Andreas Huber2b9d6bd2012-04-17 15:02:22 -0700293 extractor->seekTo(timeUs);
Andreas Huber88572f72012-02-21 11:47:18 -0800294}
295
296static jboolean android_media_MediaExtractor_advance(
297 JNIEnv *env, jobject thiz) {
298 sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
299
300 if (extractor == NULL) {
301 jniThrowException(env, "java/lang/IllegalStateException", NULL);
302 return false;
303 }
304
305 status_t err = extractor->advance();
306
307 if (err == ERROR_END_OF_STREAM) {
308 return false;
309 } else if (err != OK) {
310 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
311 return false;
312 }
313
314 return true;
315}
316
317static jint android_media_MediaExtractor_readSampleData(
318 JNIEnv *env, jobject thiz, jobject byteBuf, jint offset) {
319 sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
320
321 if (extractor == NULL) {
322 jniThrowException(env, "java/lang/IllegalStateException", NULL);
323 return -1;
324 }
325
326 size_t sampleSize;
327 status_t err = extractor->readSampleData(byteBuf, offset, &sampleSize);
328
329 if (err == ERROR_END_OF_STREAM) {
330 return -1;
331 } else if (err != OK) {
332 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
333 return false;
334 }
335
336 return sampleSize;
337}
338
339static jint android_media_MediaExtractor_getSampleTrackIndex(
340 JNIEnv *env, jobject thiz) {
341 sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
342
343 if (extractor == NULL) {
344 jniThrowException(env, "java/lang/IllegalStateException", NULL);
345 return -1;
346 }
347
348 size_t trackIndex;
349 status_t err = extractor->getSampleTrackIndex(&trackIndex);
350
351 if (err == ERROR_END_OF_STREAM) {
352 return -1;
353 } else if (err != OK) {
354 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
355 return false;
356 }
357
358 return trackIndex;
359}
360
361static jlong android_media_MediaExtractor_getSampleTime(
362 JNIEnv *env, jobject thiz) {
363 sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
364
365 if (extractor == NULL) {
366 jniThrowException(env, "java/lang/IllegalStateException", NULL);
367 return -1ll;
368 }
369
370 int64_t sampleTimeUs;
371 status_t err = extractor->getSampleTime(&sampleTimeUs);
372
373 if (err == ERROR_END_OF_STREAM) {
374 return -1ll;
375 } else if (err != OK) {
376 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
377 return false;
378 }
379
380 return sampleTimeUs;
381}
382
Andreas Huber9b8e4962012-03-26 11:13:27 -0700383static jint android_media_MediaExtractor_getSampleFlags(
384 JNIEnv *env, jobject thiz) {
385 sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
386
387 if (extractor == NULL) {
388 jniThrowException(env, "java/lang/IllegalStateException", NULL);
389 return -1ll;
390 }
391
392 uint32_t sampleFlags;
393 status_t err = extractor->getSampleFlags(&sampleFlags);
394
395 if (err == ERROR_END_OF_STREAM) {
396 return -1ll;
397 } else if (err != OK) {
398 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
399 return false;
400 }
401
402 return sampleFlags;
403}
404
Andreas Huber91befdc2012-04-18 12:19:51 -0700405static jboolean android_media_MediaExtractor_getSampleCryptoInfo(
406 JNIEnv *env, jobject thiz, jobject cryptoInfoObj) {
407 sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
408
409 if (extractor == NULL) {
410 jniThrowException(env, "java/lang/IllegalStateException", NULL);
411 return -1ll;
412 }
413
414 sp<MetaData> meta;
415 status_t err = extractor->getSampleMeta(&meta);
416
417 if (err != OK) {
418 return false;
419 }
420
421 uint32_t type;
422 const void *data;
423 size_t size;
424 if (!meta->findData(kKeyEncryptedSizes, &type, &data, &size)) {
425 return false;
426 }
427
428 size_t numSubSamples = size / sizeof(size_t);
429
430 if (numSubSamples == 0) {
431 return false;
432 }
433
434 jintArray numBytesOfEncryptedDataObj = env->NewIntArray(numSubSamples);
435 jboolean isCopy;
436 jint *dst = env->GetIntArrayElements(numBytesOfEncryptedDataObj, &isCopy);
437 for (size_t i = 0; i < numSubSamples; ++i) {
438 dst[i] = ((const size_t *)data)[i];
439 }
440 env->ReleaseIntArrayElements(numBytesOfEncryptedDataObj, dst, 0);
441 dst = NULL;
442
443 size_t encSize = size;
444 jintArray numBytesOfPlainDataObj = NULL;
Andreas Huberab57d032012-04-18 15:59:43 -0700445 if (meta->findData(kKeyPlainSizes, &type, &data, &size)) {
Andreas Huber91befdc2012-04-18 12:19:51 -0700446 if (size != encSize) {
447 // The two must be of the same length.
448 return false;
449 }
450
451 numBytesOfPlainDataObj = env->NewIntArray(numSubSamples);
452 jboolean isCopy;
453 jint *dst = env->GetIntArrayElements(numBytesOfPlainDataObj, &isCopy);
454 for (size_t i = 0; i < numSubSamples; ++i) {
455 dst[i] = ((const size_t *)data)[i];
456 }
457 env->ReleaseIntArrayElements(numBytesOfPlainDataObj, dst, 0);
458 dst = NULL;
459 }
460
461 jbyteArray keyObj = NULL;
462 if (meta->findData(kKeyCryptoKey, &type, &data, &size)) {
463 if (size != 16) {
464 // Keys must be 16 bytes in length.
465 return false;
466 }
467
468 keyObj = env->NewByteArray(size);
469 jboolean isCopy;
470 jbyte *dst = env->GetByteArrayElements(keyObj, &isCopy);
471 memcpy(dst, data, size);
472 env->ReleaseByteArrayElements(keyObj, dst, 0);
473 dst = NULL;
474 }
475
476 jbyteArray ivObj = NULL;
477 if (meta->findData(kKeyCryptoIV, &type, &data, &size)) {
478 if (size != 16) {
479 // IVs must be 16 bytes in length.
480 return false;
481 }
482
483 ivObj = env->NewByteArray(size);
484 jboolean isCopy;
485 jbyte *dst = env->GetByteArrayElements(ivObj, &isCopy);
486 memcpy(dst, data, size);
487 env->ReleaseByteArrayElements(ivObj, dst, 0);
488 dst = NULL;
489 }
490
491 int32_t mode;
492 if (!meta->findInt32(kKeyCryptoMode, &mode)) {
Andreas Huberab57d032012-04-18 15:59:43 -0700493 mode = CryptoPlugin::kMode_AES_CTR;
Andreas Huber91befdc2012-04-18 12:19:51 -0700494 }
495
496 env->CallVoidMethod(
497 cryptoInfoObj,
498 gFields.cryptoInfoSetID,
499 numSubSamples,
500 numBytesOfPlainDataObj,
501 numBytesOfEncryptedDataObj,
502 keyObj,
503 ivObj,
504 mode);
505
506 return true;
507}
508
Andreas Huber88572f72012-02-21 11:47:18 -0800509static void android_media_MediaExtractor_native_init(JNIEnv *env) {
510 jclass clazz = env->FindClass("android/media/MediaExtractor");
511 CHECK(clazz != NULL);
512
513 gFields.context = env->GetFieldID(clazz, "mNativeContext", "I");
514 CHECK(gFields.context != NULL);
515
Andreas Huber91befdc2012-04-18 12:19:51 -0700516 clazz = env->FindClass("android/media/MediaCodec$CryptoInfo");
517 CHECK(clazz != NULL);
518
519 gFields.cryptoInfoSetID =
520 env->GetMethodID(clazz, "set", "(I[I[I[B[BI)V");
521
Andreas Huber88572f72012-02-21 11:47:18 -0800522 DataSource::RegisterDefaultSniffers();
523}
524
525static void android_media_MediaExtractor_native_setup(
Andreas Huber07ea4262012-04-11 12:21:20 -0700526 JNIEnv *env, jobject thiz) {
Andreas Huber88572f72012-02-21 11:47:18 -0800527 sp<JMediaExtractor> extractor = new JMediaExtractor(env, thiz);
Andreas Huber07ea4262012-04-11 12:21:20 -0700528 setMediaExtractor(env,thiz, extractor);
529}
Andreas Huber88572f72012-02-21 11:47:18 -0800530
Andreas Huber07ea4262012-04-11 12:21:20 -0700531static void android_media_MediaExtractor_setDataSource(
532 JNIEnv *env, jobject thiz,
533 jstring pathObj, jobjectArray keysArray, jobjectArray valuesArray) {
534 sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
535
536 if (extractor == NULL) {
537 jniThrowException(env, "java/lang/IllegalStateException", NULL);
538 return;
539 }
540
541 if (pathObj == NULL) {
Andreas Huber88572f72012-02-21 11:47:18 -0800542 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
543 return;
544 }
545
Andreas Huber07ea4262012-04-11 12:21:20 -0700546 KeyedVector<String8, String8> headers;
547 if (!ConvertKeyValueArraysToKeyedVector(
548 env, keysArray, valuesArray, &headers)) {
Andreas Huber88572f72012-02-21 11:47:18 -0800549 return;
550 }
551
Andreas Huber07ea4262012-04-11 12:21:20 -0700552 const char *path = env->GetStringUTFChars(pathObj, NULL);
Andreas Huber88572f72012-02-21 11:47:18 -0800553
Andreas Huber07ea4262012-04-11 12:21:20 -0700554 if (path == NULL) {
555 return;
556 }
557
558 status_t err = extractor->setDataSource(path, &headers);
559
560 env->ReleaseStringUTFChars(pathObj, path);
561 path = NULL;
Andreas Huber88572f72012-02-21 11:47:18 -0800562
563 if (err != OK) {
564 jniThrowException(
565 env,
566 "java/io/IOException",
567 "Failed to instantiate extractor.");
568 return;
569 }
Andreas Huber07ea4262012-04-11 12:21:20 -0700570}
Andreas Huber88572f72012-02-21 11:47:18 -0800571
Andreas Huber07ea4262012-04-11 12:21:20 -0700572static void android_media_MediaExtractor_setDataSourceFd(
573 JNIEnv *env, jobject thiz,
574 jobject fileDescObj, jlong offset, jlong length) {
575 sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
576
577 if (extractor == NULL) {
578 jniThrowException(env, "java/lang/IllegalStateException", NULL);
579 return;
580 }
581
582 if (fileDescObj == NULL) {
583 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
584 return;
585 }
586
587 int fd = jniGetFDFromFileDescriptor(env, fileDescObj);
588
589 status_t err = extractor->setDataSource(fd, offset, length);
590
591 if (err != OK) {
592 jniThrowException(
593 env,
594 "java/io/IOException",
595 "Failed to instantiate extractor.");
596 return;
597 }
Andreas Huber88572f72012-02-21 11:47:18 -0800598}
599
Andreas Huber74a78b02012-04-19 16:24:32 -0700600static jlong android_media_MediaExtractor_getCachedDurationUs(
601 JNIEnv *env, jobject thiz) {
602 sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
603
604 if (extractor == NULL) {
605 jniThrowException(env, "java/lang/IllegalStateException", NULL);
606 return -1ll;
607 }
608
609 int64_t cachedDurationUs;
610 bool eos;
611 if (!extractor->getCachedDuration(&cachedDurationUs, &eos)) {
612 return -1ll;
613 }
614
615 return cachedDurationUs;
616}
617
618static jboolean android_media_MediaExtractor_hasCacheReachedEOS(
619 JNIEnv *env, jobject thiz) {
620 sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
621
622 if (extractor == NULL) {
623 jniThrowException(env, "java/lang/IllegalStateException", NULL);
624 return true;
625 }
626
627 int64_t cachedDurationUs;
628 bool eos;
629 if (!extractor->getCachedDuration(&cachedDurationUs, &eos)) {
630 return true;
631 }
632
633 return eos;
634}
635
Andreas Huber88572f72012-02-21 11:47:18 -0800636static void android_media_MediaExtractor_native_finalize(
637 JNIEnv *env, jobject thiz) {
638 android_media_MediaExtractor_release(env, thiz);
639}
640
641static JNINativeMethod gMethods[] = {
642 { "release", "()V", (void *)android_media_MediaExtractor_release },
643
644 { "countTracks", "()I", (void *)android_media_MediaExtractor_countTracks },
645
646 { "getTrackFormat", "(I)Ljava/util/Map;",
647 (void *)android_media_MediaExtractor_getTrackFormat },
648
649 { "selectTrack", "(I)V", (void *)android_media_MediaExtractor_selectTrack },
650
651 { "seekTo", "(J)V", (void *)android_media_MediaExtractor_seekTo },
652
653 { "advance", "()Z", (void *)android_media_MediaExtractor_advance },
654
655 { "readSampleData", "(Ljava/nio/ByteBuffer;I)I",
656 (void *)android_media_MediaExtractor_readSampleData },
657
658 { "getSampleTrackIndex", "()I",
659 (void *)android_media_MediaExtractor_getSampleTrackIndex },
660
661 { "getSampleTime", "()J",
662 (void *)android_media_MediaExtractor_getSampleTime },
663
Andreas Huber9b8e4962012-03-26 11:13:27 -0700664 { "getSampleFlags", "()I",
665 (void *)android_media_MediaExtractor_getSampleFlags },
666
Andreas Huber91befdc2012-04-18 12:19:51 -0700667 { "getSampleCryptoInfo", "(Landroid/media/MediaCodec$CryptoInfo;)Z",
668 (void *)android_media_MediaExtractor_getSampleCryptoInfo },
669
Andreas Huber88572f72012-02-21 11:47:18 -0800670 { "native_init", "()V", (void *)android_media_MediaExtractor_native_init },
671
Andreas Huber07ea4262012-04-11 12:21:20 -0700672 { "native_setup", "()V",
Andreas Huber88572f72012-02-21 11:47:18 -0800673 (void *)android_media_MediaExtractor_native_setup },
674
675 { "native_finalize", "()V",
676 (void *)android_media_MediaExtractor_native_finalize },
Andreas Huber07ea4262012-04-11 12:21:20 -0700677
678 { "setDataSource", "(Ljava/lang/String;[Ljava/lang/String;"
679 "[Ljava/lang/String;)V",
680 (void *)android_media_MediaExtractor_setDataSource },
681
682 { "setDataSource", "(Ljava/io/FileDescriptor;JJ)V",
683 (void *)android_media_MediaExtractor_setDataSourceFd },
Andreas Huber74a78b02012-04-19 16:24:32 -0700684
685 { "getCachedDuration", "()J",
686 (void *)android_media_MediaExtractor_getCachedDurationUs },
687
688 { "hasCacheReachedEndOfStream", "()Z",
689 (void *)android_media_MediaExtractor_hasCacheReachedEOS },
Andreas Huber88572f72012-02-21 11:47:18 -0800690};
691
692int register_android_media_MediaExtractor(JNIEnv *env) {
693 return AndroidRuntime::registerNativeMethods(env,
694 "android/media/MediaExtractor", gMethods, NELEM(gMethods));
695}