android_media_MediaExtractor.cpp revision e92416dfeb115939231819c5edb593b8bb81cc6d
188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber/*
288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * Copyright 2012, The Android Open Source Project
388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber *
488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * you may not use this file except in compliance with the License.
688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * You may obtain a copy of the License at
788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber *
888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber *     http://www.apache.org/licenses/LICENSE-2.0
988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber *
1088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * Unless required by applicable law or agreed to in writing, software
1188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
1288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * See the License for the specific language governing permissions and
1488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * limitations under the License.
1588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber */
1688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
1788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber//#define LOG_NDEBUG 0
1888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#define LOG_TAG "MediaExtractor-JNI"
1988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <utils/Log.h>
2088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
2188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include "android_media_MediaExtractor.h"
2288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
2388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include "android_media_Utils.h"
2488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include "android_runtime/AndroidRuntime.h"
2587eac99a21772ae56018cb81db6966557b459554Ruben Brunk#include "android_runtime/Log.h"
2688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include "jni.h"
2788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include "JNIHelp.h"
2888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
29ab57d03bdb3010d4957fb88c8acb30575ca02ec9Andreas Huber#include <media/hardware/CryptoAPI.h>
3088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
3188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/ADebug.h>
3288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/AMessage.h>
3388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/DataSource.h>
3488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/MediaErrors.h>
3591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber#include <media/stagefright/MetaData.h>
3688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/NuMediaExtractor.h>
3788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
3888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Hubernamespace android {
3988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
4088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstruct fields_t {
4188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    jfieldID context;
4291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
4391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    jmethodID cryptoInfoSetID;
4488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber};
4588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
4688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic fields_t gFields;
4788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
48c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissenclass JavaDataSourceBridge : public DataSource {
49c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen    jmethodID mReadMethod;
50c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen    jmethodID mGetSizeMethod;
51c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen    jmethodID mCloseMethod;
52c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen    jobject   mDataSource;
53c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen public:
54c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen    JavaDataSourceBridge(JNIEnv *env, jobject source) {
55c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        mDataSource = env->NewGlobalRef(source);
56c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen
57c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        jclass datasourceclass = env->GetObjectClass(mDataSource);
58c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        CHECK(datasourceclass != NULL);
59c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen
60c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        mReadMethod = env->GetMethodID(datasourceclass, "readAt", "(J[BI)I");
61c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        CHECK(mReadMethod != NULL);
62c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen
63c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        mGetSizeMethod = env->GetMethodID(datasourceclass, "getSize", "()J");
64c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        CHECK(mGetSizeMethod != NULL);
65c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen
66c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        mCloseMethod = env->GetMethodID(datasourceclass, "close", "()V");
67c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        CHECK(mCloseMethod != NULL);
68c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen    }
69c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen
70c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen    ~JavaDataSourceBridge() {
71c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        JNIEnv *env = AndroidRuntime::getJNIEnv();
72c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        env->CallVoidMethod(mDataSource, mCloseMethod);
73c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        env->DeleteGlobalRef(mDataSource);
74c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen    }
75c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen
76c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen    virtual status_t initCheck() const {
77c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        return OK;
78c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen    }
79c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen
80c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen    virtual ssize_t readAt(off64_t offset, void* buffer, size_t size) {
81c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        JNIEnv *env = AndroidRuntime::getJNIEnv();
82c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen
83c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        // XXX could optimize this by reusing the same array
84c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        jbyteArray byteArrayObj = env->NewByteArray(size);
85c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        env->DeleteLocalRef(env->GetObjectClass(mDataSource));
86c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        env->DeleteLocalRef(env->GetObjectClass(byteArrayObj));
87c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        ssize_t numread = env->CallIntMethod(mDataSource, mReadMethod, offset, byteArrayObj, size);
88c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        env->GetByteArrayRegion(byteArrayObj, 0, size, (jbyte*) buffer);
89c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        env->DeleteLocalRef(byteArrayObj);
90c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        if (env->ExceptionCheck()) {
91075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat            ALOGW("Exception occurred while reading %zu at %lld", size, offset);
92c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen            LOGW_EX(env);
93c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen            env->ExceptionClear();
94c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen            return -1;
95c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        }
96c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        return numread;
97c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen    }
98c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen
99c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen    virtual status_t getSize(off64_t *size) {
100c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        JNIEnv *env = AndroidRuntime::getJNIEnv();
101c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen
102c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        CHECK(size != NULL);
103c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen
104c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        int64_t len = env->CallLongMethod(mDataSource, mGetSizeMethod);
105c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        if (len < 0) {
106c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen            *size = ERROR_UNSUPPORTED;
107c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        } else {
108c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen            *size = len;
109c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        }
110c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        return OK;
111c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen    }
112c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen};
113c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen
11488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber////////////////////////////////////////////////////////////////////////////////
11588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
11688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas HuberJMediaExtractor::JMediaExtractor(JNIEnv *env, jobject thiz)
11788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    : mClass(NULL),
11888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber      mObject(NULL) {
11988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    jclass clazz = env->GetObjectClass(thiz);
12088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    CHECK(clazz != NULL);
12188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
12288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    mClass = (jclass)env->NewGlobalRef(clazz);
12388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    mObject = env->NewWeakGlobalRef(thiz);
12488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
12588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    mImpl = new NuMediaExtractor;
12688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
12788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
12888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas HuberJMediaExtractor::~JMediaExtractor() {
12988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    JNIEnv *env = AndroidRuntime::getJNIEnv();
13088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
13188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    env->DeleteWeakGlobalRef(mObject);
13288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    mObject = NULL;
13388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    env->DeleteGlobalRef(mClass);
13488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    mClass = NULL;
13588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
13688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
13707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huberstatus_t JMediaExtractor::setDataSource(
13807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        const char *path, const KeyedVector<String8, String8> *headers) {
13907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    return mImpl->setDataSource(path, headers);
14007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber}
14107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
14207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huberstatus_t JMediaExtractor::setDataSource(int fd, off64_t offset, off64_t size) {
14307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    return mImpl->setDataSource(fd, offset, size);
14488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
14588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
146c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissenstatus_t JMediaExtractor::setDataSource(const sp<DataSource> &datasource) {
147c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen    return mImpl->setDataSource(datasource);
148c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen}
149c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen
15088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Hubersize_t JMediaExtractor::countTracks() const {
15188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return mImpl->countTracks();
15288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
15388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
15488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaExtractor::getTrackFormat(size_t index, jobject *format) const {
15588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<AMessage> msg;
15688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    status_t err;
15788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if ((err = mImpl->getTrackFormat(index, &msg)) != OK) {
15888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return err;
15988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
16088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
16188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    JNIEnv *env = AndroidRuntime::getJNIEnv();
16288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
16388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return ConvertMessageToMap(env, msg, format);
16488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
16588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
166e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissenstatus_t JMediaExtractor::getFileFormat(jobject *format) const {
167e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen    sp<AMessage> msg;
168e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen    status_t err;
169e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen    if ((err = mImpl->getFileFormat(&msg)) != OK) {
170e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen        return err;
171e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen    }
172e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen
173e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen    JNIEnv *env = AndroidRuntime::getJNIEnv();
174e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen
175e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen    return ConvertMessageToMap(env, msg, format);
176e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen}
177e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen
17888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaExtractor::selectTrack(size_t index) {
17988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return mImpl->selectTrack(index);
18088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
18188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
182f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huberstatus_t JMediaExtractor::unselectTrack(size_t index) {
183f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber    return mImpl->unselectTrack(index);
184f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber}
185f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber
186f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huberstatus_t JMediaExtractor::seekTo(
187f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber        int64_t timeUs, MediaSource::ReadOptions::SeekMode mode) {
188f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber    return mImpl->seekTo(timeUs, mode);
18988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
19088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
19188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaExtractor::advance() {
19288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return mImpl->advance();
19388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
19488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
19588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaExtractor::readSampleData(
19688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jobject byteBuf, size_t offset, size_t *sampleSize) {
19788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    JNIEnv *env = AndroidRuntime::getJNIEnv();
19888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
19988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    void *dst = env->GetDirectBufferAddress(byteBuf);
20088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
201075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    size_t dstSize;
202c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber    jbyteArray byteArray = NULL;
203c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber
20488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (dst == NULL) {
205c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber        jclass byteBufClass = env->FindClass("java/nio/ByteBuffer");
206c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber        CHECK(byteBufClass != NULL);
207c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber
208c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber        jmethodID arrayID =
209c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber            env->GetMethodID(byteBufClass, "array", "()[B");
210c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber        CHECK(arrayID != NULL);
211c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber
212c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber        byteArray =
213c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber            (jbyteArray)env->CallObjectMethod(byteBuf, arrayID);
214c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber
215c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber        if (byteArray == NULL) {
216c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber            return INVALID_OPERATION;
217c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber        }
21888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
219c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber        jboolean isCopy;
220c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber        dst = env->GetByteArrayElements(byteArray, &isCopy);
221c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber
222075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat        dstSize = (size_t) env->GetArrayLength(byteArray);
223c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber    } else {
224075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat        dstSize = (size_t) env->GetDirectBufferCapacity(byteBuf);
225c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber    }
22688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
22788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (dstSize < offset) {
228c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber        if (byteArray != NULL) {
229c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber            env->ReleaseByteArrayElements(byteArray, (jbyte *)dst, 0);
230c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber        }
231c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber
23288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return -ERANGE;
23388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
23488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
23588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<ABuffer> buffer = new ABuffer((char *)dst + offset, dstSize - offset);
23688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
23788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    status_t err = mImpl->readSampleData(buffer);
23888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
239c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber    if (byteArray != NULL) {
240c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber        env->ReleaseByteArrayElements(byteArray, (jbyte *)dst, 0);
241c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber    }
242c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber
24388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (err != OK) {
24488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return err;
24588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
24688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
24788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    *sampleSize = buffer->size();
24888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
24988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return OK;
25088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
25188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
25288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaExtractor::getSampleTrackIndex(size_t *trackIndex) {
25388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return mImpl->getSampleTrackIndex(trackIndex);
25488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
25588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
25688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaExtractor::getSampleTime(int64_t *sampleTimeUs) {
25788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return mImpl->getSampleTime(sampleTimeUs);
25888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
25988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
2609b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huberstatus_t JMediaExtractor::getSampleFlags(uint32_t *sampleFlags) {
26191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    *sampleFlags = 0;
26291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
26391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    sp<MetaData> meta;
26491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    status_t err = mImpl->getSampleMeta(&meta);
26591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
26691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    if (err != OK) {
26791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        return err;
26891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    }
26991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
27091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    int32_t val;
27191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    if (meta->findInt32(kKeyIsSyncFrame, &val) && val != 0) {
27291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        (*sampleFlags) |= NuMediaExtractor::SAMPLE_FLAG_SYNC;
27391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    }
27491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
27591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    uint32_t type;
27691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    const void *data;
27791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    size_t size;
27891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    if (meta->findData(kKeyEncryptedSizes, &type, &data, &size)) {
27991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        (*sampleFlags) |= NuMediaExtractor::SAMPLE_FLAG_ENCRYPTED;
28091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    }
28191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
28291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    return OK;
28391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber}
28491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
28591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huberstatus_t JMediaExtractor::getSampleMeta(sp<MetaData> *sampleMeta) {
28691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    return mImpl->getSampleMeta(sampleMeta);
2879b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber}
2889b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber
28974a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huberbool JMediaExtractor::getCachedDuration(int64_t *durationUs, bool *eos) const {
29074a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber    return mImpl->getCachedDuration(durationUs, eos);
29174a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber}
29274a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber
29388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}  // namespace android
29488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
29588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber////////////////////////////////////////////////////////////////////////////////
29688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
29788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberusing namespace android;
29888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
29988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic sp<JMediaExtractor> setMediaExtractor(
30088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        JNIEnv *env, jobject thiz, const sp<JMediaExtractor> &extractor) {
30188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaExtractor> old =
302075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat        (JMediaExtractor *)env->GetLongField(thiz, gFields.context);
30388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
30488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (extractor != NULL) {
30588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        extractor->incStrong(thiz);
30688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
30788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (old != NULL) {
30888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        old->decStrong(thiz);
30988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
310075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    env->SetLongField(thiz, gFields.context, (jlong)extractor.get());
31188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
31288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return old;
31388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
31488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
31588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic sp<JMediaExtractor> getMediaExtractor(JNIEnv *env, jobject thiz) {
316075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    return (JMediaExtractor *)env->GetLongField(thiz, gFields.context);
31788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
31888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
31988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaExtractor_release(JNIEnv *env, jobject thiz) {
32088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    setMediaExtractor(env, thiz, NULL);
32188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
32288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
32360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huberstatic jint android_media_MediaExtractor_getTrackCount(
32488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        JNIEnv *env, jobject thiz) {
32588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
32688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
32788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (extractor == NULL) {
32888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
32907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        return -1;
33088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
33188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
332075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    return (jint) extractor->countTracks();
33388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
33488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
33560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huberstatic jobject android_media_MediaExtractor_getTrackFormatNative(
33688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        JNIEnv *env, jobject thiz, jint index) {
33788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
33888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
33988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (extractor == NULL) {
34088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
34188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return NULL;
34288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
34388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
34488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    jobject format;
34588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    status_t err = extractor->getTrackFormat(index, &format);
34688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
34788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (err != OK) {
34888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
34988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return NULL;
35088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
35188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
35288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return format;
35388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
35488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
355e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissenstatic jobject android_media_MediaExtractor_getFileFormatNative(
356e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen        JNIEnv *env, jobject thiz) {
357e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen    sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
358e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen
359e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen    if (extractor == NULL) {
360e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen        jniThrowException(env, "java/lang/IllegalStateException", NULL);
361e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen        return NULL;
362e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen    }
363e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen
364e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen    jobject format;
365e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen    status_t err = extractor->getFileFormat(&format);
366e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen
367e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen    if (err != OK) {
368e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
369e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen        return NULL;
370e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen    }
371e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen
372e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen    return format;
373e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen}
374e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen
37588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaExtractor_selectTrack(
37688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        JNIEnv *env, jobject thiz, jint index) {
37788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
37888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
37988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (extractor == NULL) {
38088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
38188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return;
38288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
38388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
38488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    status_t err = extractor->selectTrack(index);
38588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
38688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (err != OK) {
38788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
38888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return;
38988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
39088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
39188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
392f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huberstatic void android_media_MediaExtractor_unselectTrack(
393f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber        JNIEnv *env, jobject thiz, jint index) {
394f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber    sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
395f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber
396f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber    if (extractor == NULL) {
397f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
398f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber        return;
399f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber    }
400f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber
401f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber    status_t err = extractor->unselectTrack(index);
402f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber
403f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber    if (err != OK) {
404f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
405f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber        return;
406f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber    }
407f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber}
408f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber
40988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaExtractor_seekTo(
410f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber        JNIEnv *env, jobject thiz, jlong timeUs, jint mode) {
41188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
41288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
41388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (extractor == NULL) {
41488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
41588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return;
41688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
41788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
418f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber    if (mode < MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC
419f86374adec8bd77af7b012f788ea59575296facbAndreas Huber            || mode >= MediaSource::ReadOptions::SEEK_CLOSEST) {
420f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
421f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber        return;
422f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber    }
423f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber
424f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber    extractor->seekTo(timeUs, (MediaSource::ReadOptions::SeekMode)mode);
42588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
42688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
42788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jboolean android_media_MediaExtractor_advance(
42888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        JNIEnv *env, jobject thiz) {
42988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
43088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
43188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (extractor == NULL) {
43288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
433075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat        return JNI_FALSE;
43488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
43588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
43688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    status_t err = extractor->advance();
43788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
43888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (err == ERROR_END_OF_STREAM) {
439075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat        return JNI_FALSE;
44088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    } else if (err != OK) {
44188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
442075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat        return JNI_FALSE;
44388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
44488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
445075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    return JNI_TRUE;
44688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
44788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
44888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jint android_media_MediaExtractor_readSampleData(
44988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        JNIEnv *env, jobject thiz, jobject byteBuf, jint offset) {
45088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
45188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
45288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (extractor == NULL) {
45388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
45488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return -1;
45588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
45688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
45788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    size_t sampleSize;
45888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    status_t err = extractor->readSampleData(byteBuf, offset, &sampleSize);
45988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
46088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (err == ERROR_END_OF_STREAM) {
46188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return -1;
46288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    } else if (err != OK) {
46388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
464075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat        return -1;
46588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
46688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
467075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    return (jint) sampleSize;
46888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
46988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
47088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jint android_media_MediaExtractor_getSampleTrackIndex(
47188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        JNIEnv *env, jobject thiz) {
47288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
47388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
47488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (extractor == NULL) {
47588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
47688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return -1;
47788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
47888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
47988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    size_t trackIndex;
48088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    status_t err = extractor->getSampleTrackIndex(&trackIndex);
48188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
48288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (err == ERROR_END_OF_STREAM) {
48388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return -1;
48488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    } else if (err != OK) {
48588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
486075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat        return -1;
48788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
48888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
489075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    return (jint) trackIndex;
49088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
49188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
49288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jlong android_media_MediaExtractor_getSampleTime(
49388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        JNIEnv *env, jobject thiz) {
49488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
49588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
49688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (extractor == NULL) {
49788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
49888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return -1ll;
49988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
50088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
50188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    int64_t sampleTimeUs;
50288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    status_t err = extractor->getSampleTime(&sampleTimeUs);
50388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
50488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (err == ERROR_END_OF_STREAM) {
50588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return -1ll;
50688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    } else if (err != OK) {
50788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
508075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat        return -1ll;
50988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
51088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
511075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    return (jlong) sampleTimeUs;
51288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
51388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
5149b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huberstatic jint android_media_MediaExtractor_getSampleFlags(
5159b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber        JNIEnv *env, jobject thiz) {
5169b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber    sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
5179b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber
5189b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber    if (extractor == NULL) {
5199b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
520075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat        return -1;
5219b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber    }
5229b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber
5239b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber    uint32_t sampleFlags;
5249b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber    status_t err = extractor->getSampleFlags(&sampleFlags);
5259b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber
5269b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber    if (err == ERROR_END_OF_STREAM) {
527075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat        return -1;
5289b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber    } else if (err != OK) {
5299b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
530075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat        return -1;
5319b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber    }
5329b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber
533075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    return (jint) sampleFlags;
5349b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber}
5359b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber
53691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huberstatic jboolean android_media_MediaExtractor_getSampleCryptoInfo(
53791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        JNIEnv *env, jobject thiz, jobject cryptoInfoObj) {
53891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
53991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
54091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    if (extractor == NULL) {
54191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
542075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat        return JNI_FALSE;
54391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    }
54491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
54591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    sp<MetaData> meta;
54691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    status_t err = extractor->getSampleMeta(&meta);
54791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
54891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    if (err != OK) {
549075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat        return JNI_FALSE;
55091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    }
55191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
55291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    uint32_t type;
55391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    const void *data;
55491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    size_t size;
55591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    if (!meta->findData(kKeyEncryptedSizes, &type, &data, &size)) {
556075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat        return JNI_FALSE;
55791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    }
55891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
559e92416dfeb115939231819c5edb593b8bb81cc6dAshok Bhat    size_t numSubSamples = size / sizeof(int32_t);
56091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
56191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    if (numSubSamples == 0) {
562075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat        return JNI_FALSE;
56391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    }
56491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
56591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    jintArray numBytesOfEncryptedDataObj = env->NewIntArray(numSubSamples);
56691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    jboolean isCopy;
56791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    jint *dst = env->GetIntArrayElements(numBytesOfEncryptedDataObj, &isCopy);
56891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    for (size_t i = 0; i < numSubSamples; ++i) {
569e92416dfeb115939231819c5edb593b8bb81cc6dAshok Bhat        dst[i] = ((const int32_t *)data)[i];
57091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    }
57191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    env->ReleaseIntArrayElements(numBytesOfEncryptedDataObj, dst, 0);
57291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    dst = NULL;
57391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
57491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    size_t encSize = size;
57591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    jintArray numBytesOfPlainDataObj = NULL;
576ab57d03bdb3010d4957fb88c8acb30575ca02ec9Andreas Huber    if (meta->findData(kKeyPlainSizes, &type, &data, &size)) {
57791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        if (size != encSize) {
57891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber            // The two must be of the same length.
579075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat            return JNI_FALSE;
58091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        }
58191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
58291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        numBytesOfPlainDataObj = env->NewIntArray(numSubSamples);
58391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        jboolean isCopy;
58491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        jint *dst = env->GetIntArrayElements(numBytesOfPlainDataObj, &isCopy);
58591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        for (size_t i = 0; i < numSubSamples; ++i) {
586e92416dfeb115939231819c5edb593b8bb81cc6dAshok Bhat            dst[i] = ((const int32_t *)data)[i];
58791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        }
58891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        env->ReleaseIntArrayElements(numBytesOfPlainDataObj, dst, 0);
58991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        dst = NULL;
59091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    }
59191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
59291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    jbyteArray keyObj = NULL;
59391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    if (meta->findData(kKeyCryptoKey, &type, &data, &size)) {
59491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        if (size != 16) {
59591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber            // Keys must be 16 bytes in length.
596075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat            return JNI_FALSE;
59791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        }
59891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
59991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        keyObj = env->NewByteArray(size);
60091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        jboolean isCopy;
60191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        jbyte *dst = env->GetByteArrayElements(keyObj, &isCopy);
60291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        memcpy(dst, data, size);
60391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        env->ReleaseByteArrayElements(keyObj, dst, 0);
60491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        dst = NULL;
60591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    }
60691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
60791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    jbyteArray ivObj = NULL;
60891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    if (meta->findData(kKeyCryptoIV, &type, &data, &size)) {
60991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        if (size != 16) {
61091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber            // IVs must be 16 bytes in length.
611075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat            return JNI_FALSE;
61291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        }
61391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
61491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        ivObj = env->NewByteArray(size);
61591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        jboolean isCopy;
61691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        jbyte *dst = env->GetByteArrayElements(ivObj, &isCopy);
61791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        memcpy(dst, data, size);
61891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        env->ReleaseByteArrayElements(ivObj, dst, 0);
61991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        dst = NULL;
62091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    }
62191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
62291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    int32_t mode;
62391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    if (!meta->findInt32(kKeyCryptoMode, &mode)) {
624ab57d03bdb3010d4957fb88c8acb30575ca02ec9Andreas Huber        mode = CryptoPlugin::kMode_AES_CTR;
62591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    }
62691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
62791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    env->CallVoidMethod(
62891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber            cryptoInfoObj,
62991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber            gFields.cryptoInfoSetID,
63091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber            numSubSamples,
63191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber            numBytesOfPlainDataObj,
63291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber            numBytesOfEncryptedDataObj,
63391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber            keyObj,
63491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber            ivObj,
63591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber            mode);
63691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
637075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    return JNI_TRUE;
63891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber}
63991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
64088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaExtractor_native_init(JNIEnv *env) {
64188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    jclass clazz = env->FindClass("android/media/MediaExtractor");
64288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    CHECK(clazz != NULL);
64388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
644075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    gFields.context = env->GetFieldID(clazz, "mNativeContext", "J");
64588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    CHECK(gFields.context != NULL);
64688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
64791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    clazz = env->FindClass("android/media/MediaCodec$CryptoInfo");
64891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    CHECK(clazz != NULL);
64991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
65091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    gFields.cryptoInfoSetID =
65191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        env->GetMethodID(clazz, "set", "(I[I[I[B[BI)V");
65291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
65388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    DataSource::RegisterDefaultSniffers();
65488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
65588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
65688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaExtractor_native_setup(
65707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        JNIEnv *env, jobject thiz) {
65888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaExtractor> extractor = new JMediaExtractor(env, thiz);
65907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    setMediaExtractor(env,thiz, extractor);
66007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber}
66188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
66207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huberstatic void android_media_MediaExtractor_setDataSource(
66307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        JNIEnv *env, jobject thiz,
66407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        jstring pathObj, jobjectArray keysArray, jobjectArray valuesArray) {
66507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
66607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
66707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    if (extractor == NULL) {
66807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
66907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        return;
67007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    }
67107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
67207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    if (pathObj == NULL) {
67388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
67488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return;
67588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
67688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
67707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    KeyedVector<String8, String8> headers;
67807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    if (!ConvertKeyValueArraysToKeyedVector(
67907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber                env, keysArray, valuesArray, &headers)) {
68007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        return;
68107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    }
68288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
68307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    const char *path = env->GetStringUTFChars(pathObj, NULL);
68407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
68507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    if (path == NULL) {
68688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return;
68788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
68888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
68907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    status_t err = extractor->setDataSource(path, &headers);
69088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
69107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    env->ReleaseStringUTFChars(pathObj, path);
69207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    path = NULL;
69388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
69488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (err != OK) {
69588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(
69688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber                env,
69788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber                "java/io/IOException",
69888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber                "Failed to instantiate extractor.");
69988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return;
70088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
70107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber}
70288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
70307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huberstatic void android_media_MediaExtractor_setDataSourceFd(
70407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        JNIEnv *env, jobject thiz,
70507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        jobject fileDescObj, jlong offset, jlong length) {
70607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
70707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
70807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    if (extractor == NULL) {
70907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
71007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        return;
71107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    }
71207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
71307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    if (fileDescObj == NULL) {
71407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
71507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        return;
71607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    }
71707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
71807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    int fd = jniGetFDFromFileDescriptor(env, fileDescObj);
71907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
72007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    status_t err = extractor->setDataSource(fd, offset, length);
72107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
72207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    if (err != OK) {
72307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        jniThrowException(
72407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber                env,
72507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber                "java/io/IOException",
72607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber                "Failed to instantiate extractor.");
72707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        return;
72807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    }
72988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
73088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
731c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissenstatic void android_media_MediaExtractor_setDataSourceCallback(
732c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        JNIEnv *env, jobject thiz,
733c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        jobject callbackObj) {
734c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen    sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
735c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen
736c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen    if (extractor == NULL) {
737c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        jniThrowException(env, "java/lang/IllegalStateException", NULL);
738c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        return;
739c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen    }
740c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen
741c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen    if (callbackObj == NULL) {
742c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
743c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        return;
744c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen    }
745c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen
746c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen    sp<JavaDataSourceBridge> bridge = new JavaDataSourceBridge(env, callbackObj);
747c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen    status_t err = extractor->setDataSource(bridge);
748c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen
749c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen    if (err != OK) {
750c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        jniThrowException(
751c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen                env,
752c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen                "java/io/IOException",
753c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen                "Failed to instantiate extractor.");
754c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        return;
755c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen    }
756c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen}
757c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen
75874a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huberstatic jlong android_media_MediaExtractor_getCachedDurationUs(
75974a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber        JNIEnv *env, jobject thiz) {
76074a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber    sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
76174a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber
76274a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber    if (extractor == NULL) {
76374a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
76474a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber        return -1ll;
76574a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber    }
76674a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber
76774a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber    int64_t cachedDurationUs;
76874a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber    bool eos;
76974a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber    if (!extractor->getCachedDuration(&cachedDurationUs, &eos)) {
77074a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber        return -1ll;
77174a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber    }
77274a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber
773075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    return (jlong) cachedDurationUs;
77474a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber}
77574a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber
77674a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huberstatic jboolean android_media_MediaExtractor_hasCacheReachedEOS(
77774a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber        JNIEnv *env, jobject thiz) {
77874a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber    sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
77974a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber
78074a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber    if (extractor == NULL) {
78174a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
782075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat        return JNI_TRUE;
78374a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber    }
78474a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber
78574a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber    int64_t cachedDurationUs;
78674a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber    bool eos;
78774a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber    if (!extractor->getCachedDuration(&cachedDurationUs, &eos)) {
788075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat        return JNI_TRUE;
78974a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber    }
79074a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber
791075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    return eos ? JNI_TRUE : JNI_FALSE;
79274a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber}
79374a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber
79488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaExtractor_native_finalize(
79588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        JNIEnv *env, jobject thiz) {
79688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    android_media_MediaExtractor_release(env, thiz);
79788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
79888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
79988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic JNINativeMethod gMethods[] = {
80088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    { "release", "()V", (void *)android_media_MediaExtractor_release },
80188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
80260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber    { "getTrackCount", "()I", (void *)android_media_MediaExtractor_getTrackCount },
80388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
804e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen    { "getFileFormatNative", "()Ljava/util/Map;",
805e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen        (void *)android_media_MediaExtractor_getFileFormatNative },
806e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen
80760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber    { "getTrackFormatNative", "(I)Ljava/util/Map;",
80860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        (void *)android_media_MediaExtractor_getTrackFormatNative },
80988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
81088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    { "selectTrack", "(I)V", (void *)android_media_MediaExtractor_selectTrack },
81188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
812f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber    { "unselectTrack", "(I)V",
813f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber        (void *)android_media_MediaExtractor_unselectTrack },
814f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber
815f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber    { "seekTo", "(JI)V", (void *)android_media_MediaExtractor_seekTo },
81688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
81788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    { "advance", "()Z", (void *)android_media_MediaExtractor_advance },
81888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
81988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    { "readSampleData", "(Ljava/nio/ByteBuffer;I)I",
82088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        (void *)android_media_MediaExtractor_readSampleData },
82188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
82288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    { "getSampleTrackIndex", "()I",
82388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        (void *)android_media_MediaExtractor_getSampleTrackIndex },
82488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
82588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    { "getSampleTime", "()J",
82688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        (void *)android_media_MediaExtractor_getSampleTime },
82788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
8289b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber    { "getSampleFlags", "()I",
8299b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber        (void *)android_media_MediaExtractor_getSampleFlags },
8309b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber
83191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    { "getSampleCryptoInfo", "(Landroid/media/MediaCodec$CryptoInfo;)Z",
83291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        (void *)android_media_MediaExtractor_getSampleCryptoInfo },
83391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
83488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    { "native_init", "()V", (void *)android_media_MediaExtractor_native_init },
83588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
83607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    { "native_setup", "()V",
83788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber      (void *)android_media_MediaExtractor_native_setup },
83888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
83988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    { "native_finalize", "()V",
84088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber      (void *)android_media_MediaExtractor_native_finalize },
84107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
84207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    { "setDataSource", "(Ljava/lang/String;[Ljava/lang/String;"
84307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber                       "[Ljava/lang/String;)V",
84407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber      (void *)android_media_MediaExtractor_setDataSource },
84507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
84607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    { "setDataSource", "(Ljava/io/FileDescriptor;JJ)V",
84707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber      (void *)android_media_MediaExtractor_setDataSourceFd },
84874a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber
849c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen    { "setDataSource", "(Landroid/media/DataSource;)V",
850c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen      (void *)android_media_MediaExtractor_setDataSourceCallback },
851c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen
85274a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber    { "getCachedDuration", "()J",
85374a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber      (void *)android_media_MediaExtractor_getCachedDurationUs },
85474a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber
85574a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber    { "hasCacheReachedEndOfStream", "()Z",
85674a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber      (void *)android_media_MediaExtractor_hasCacheReachedEOS },
85788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber};
85888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
85988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberint register_android_media_MediaExtractor(JNIEnv *env) {
86088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return AndroidRuntime::registerNativeMethods(env,
86188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber                "android/media/MediaExtractor", gMethods, NELEM(gMethods));
86288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
863