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
212659c2f16cf55d58f5b3817347340ae84f9eaabdChong Zhang#include "android_media_MediaDataSource.h"
2288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include "android_media_MediaExtractor.h"
23ba5ce2c0f8c8b7349225d7367a422cf505ff419eRay Essick#include "android_media_MediaMetricsJNI.h"
2488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include "android_media_Utils.h"
252659c2f16cf55d58f5b3817347340ae84f9eaabdChong Zhang#include "android_os_HwRemoteBinder.h"
2688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include "android_runtime/AndroidRuntime.h"
2787eac99a21772ae56018cb81db6966557b459554Ruben Brunk#include "android_runtime/Log.h"
282659c2f16cf55d58f5b3817347340ae84f9eaabdChong Zhang#include "android_util_Binder.h"
2988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include "jni.h"
3060cc6c03ff489169a6337f770ff06197ed17263cSteven Moreland#include <nativehelper/JNIHelp.h>
3188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
322659c2f16cf55d58f5b3817347340ae84f9eaabdChong Zhang#include <android/hardware/cas/1.0/BpHwCas.h>
332659c2f16cf55d58f5b3817347340ae84f9eaabdChong Zhang#include <android/hardware/cas/1.0/BnHwCas.h>
342659c2f16cf55d58f5b3817347340ae84f9eaabdChong Zhang#include <hidl/HybridInterface.h>
35d2506a506303ed94fd1991cf986b825b870a67c5Andreas Huber#include <media/IMediaHTTPService.h>
36ab57d03bdb3010d4957fb88c8acb30575ca02ec9Andreas Huber#include <media/hardware/CryptoAPI.h>
3788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
3888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/ADebug.h>
3988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/AMessage.h>
4070d2ba3c06829dd8d7316bea7bd1b8bfbf4b8123Dongwon Kang#include <media/DataSource.h>
4170d2ba3c06829dd8d7316bea7bd1b8bfbf4b8123Dongwon Kang#include <media/stagefright/InterfaceUtils.h>
4288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/MediaErrors.h>
4391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber#include <media/stagefright/MetaData.h>
4488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/NuMediaExtractor.h>
457be24522ce2e1821ad45e7ada7c3f91e6814889aLajos Molnar#include <nativehelper/ScopedLocalRef.h>
467be24522ce2e1821ad45e7ada7c3f91e6814889aLajos Molnar
4788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Hubernamespace android {
4888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
492659c2f16cf55d58f5b3817347340ae84f9eaabdChong Zhangusing namespace hardware::cas::V1_0;
502659c2f16cf55d58f5b3817347340ae84f9eaabdChong Zhang
5188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstruct fields_t {
5288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    jfieldID context;
5391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
5491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    jmethodID cryptoInfoSetID;
5597825a4fd01b8b79ca045ac971d3e6e77c906613Robert Shih    jmethodID cryptoInfoSetPatternID;
5688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber};
5788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
5888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic fields_t gFields;
5988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
6088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas HuberJMediaExtractor::JMediaExtractor(JNIEnv *env, jobject thiz)
6188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    : mClass(NULL),
6288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber      mObject(NULL) {
6388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    jclass clazz = env->GetObjectClass(thiz);
6488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    CHECK(clazz != NULL);
6588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
6688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    mClass = (jclass)env->NewGlobalRef(clazz);
6788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    mObject = env->NewWeakGlobalRef(thiz);
6888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
6988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    mImpl = new NuMediaExtractor;
7088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
7188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
7288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas HuberJMediaExtractor::~JMediaExtractor() {
7388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    JNIEnv *env = AndroidRuntime::getJNIEnv();
7488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
7588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    env->DeleteWeakGlobalRef(mObject);
7688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    mObject = NULL;
7788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    env->DeleteGlobalRef(mClass);
7888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    mClass = NULL;
7988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
8088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
8107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huberstatus_t JMediaExtractor::setDataSource(
82d2506a506303ed94fd1991cf986b825b870a67c5Andreas Huber        const sp<IMediaHTTPService> &httpService,
83d2506a506303ed94fd1991cf986b825b870a67c5Andreas Huber        const char *path,
84d2506a506303ed94fd1991cf986b825b870a67c5Andreas Huber        const KeyedVector<String8, String8> *headers) {
85d2506a506303ed94fd1991cf986b825b870a67c5Andreas Huber    return mImpl->setDataSource(httpService, path, headers);
8607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber}
8707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
8807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huberstatus_t JMediaExtractor::setDataSource(int fd, off64_t offset, off64_t size) {
8907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    return mImpl->setDataSource(fd, offset, size);
9088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
9188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
92c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissenstatus_t JMediaExtractor::setDataSource(const sp<DataSource> &datasource) {
93c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen    return mImpl->setDataSource(datasource);
94c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen}
95c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen
962659c2f16cf55d58f5b3817347340ae84f9eaabdChong Zhangstatus_t JMediaExtractor::setMediaCas(JNIEnv *env, jobject casBinderObj) {
972659c2f16cf55d58f5b3817347340ae84f9eaabdChong Zhang    if (casBinderObj == NULL) {
982659c2f16cf55d58f5b3817347340ae84f9eaabdChong Zhang        return BAD_VALUE;
992659c2f16cf55d58f5b3817347340ae84f9eaabdChong Zhang    }
1002659c2f16cf55d58f5b3817347340ae84f9eaabdChong Zhang
1012659c2f16cf55d58f5b3817347340ae84f9eaabdChong Zhang    sp<hardware::IBinder> hwBinder =
1022659c2f16cf55d58f5b3817347340ae84f9eaabdChong Zhang        JHwRemoteBinder::GetNativeContext(env, casBinderObj)->getBinder();
1032659c2f16cf55d58f5b3817347340ae84f9eaabdChong Zhang    if (hwBinder == NULL) {
1042659c2f16cf55d58f5b3817347340ae84f9eaabdChong Zhang        return BAD_VALUE;
1052659c2f16cf55d58f5b3817347340ae84f9eaabdChong Zhang    }
1062659c2f16cf55d58f5b3817347340ae84f9eaabdChong Zhang
1072659c2f16cf55d58f5b3817347340ae84f9eaabdChong Zhang    sp<ICas> cas = hardware::fromBinder<ICas, BpHwCas, BnHwCas>(hwBinder);
1082659c2f16cf55d58f5b3817347340ae84f9eaabdChong Zhang    if (cas == NULL) {
1092659c2f16cf55d58f5b3817347340ae84f9eaabdChong Zhang        return BAD_VALUE;
1102659c2f16cf55d58f5b3817347340ae84f9eaabdChong Zhang    }
1112659c2f16cf55d58f5b3817347340ae84f9eaabdChong Zhang
1122659c2f16cf55d58f5b3817347340ae84f9eaabdChong Zhang    HalToken halToken;
1132659c2f16cf55d58f5b3817347340ae84f9eaabdChong Zhang    if (!createHalToken(cas, &halToken)) {
1142659c2f16cf55d58f5b3817347340ae84f9eaabdChong Zhang        return BAD_VALUE;
1152659c2f16cf55d58f5b3817347340ae84f9eaabdChong Zhang    }
1162659c2f16cf55d58f5b3817347340ae84f9eaabdChong Zhang
1172659c2f16cf55d58f5b3817347340ae84f9eaabdChong Zhang    return mImpl->setMediaCas(halToken);
118d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang}
119d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang
12088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Hubersize_t JMediaExtractor::countTracks() const {
12188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return mImpl->countTracks();
12288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
12388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
12488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaExtractor::getTrackFormat(size_t index, jobject *format) const {
12588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<AMessage> msg;
12688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    status_t err;
12788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if ((err = mImpl->getTrackFormat(index, &msg)) != OK) {
12888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return err;
12988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
13088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
13188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    JNIEnv *env = AndroidRuntime::getJNIEnv();
13288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
13388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return ConvertMessageToMap(env, msg, format);
13488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
13588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
136e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissenstatus_t JMediaExtractor::getFileFormat(jobject *format) const {
137e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen    sp<AMessage> msg;
138e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen    status_t err;
139e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen    if ((err = mImpl->getFileFormat(&msg)) != OK) {
140e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen        return err;
141e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen    }
142e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen
143e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen    JNIEnv *env = AndroidRuntime::getJNIEnv();
144e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen
145e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen    return ConvertMessageToMap(env, msg, format);
146e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen}
147e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen
14888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaExtractor::selectTrack(size_t index) {
14988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return mImpl->selectTrack(index);
15088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
15188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
152f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huberstatus_t JMediaExtractor::unselectTrack(size_t index) {
153f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber    return mImpl->unselectTrack(index);
154f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber}
155f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber
156f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huberstatus_t JMediaExtractor::seekTo(
157f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber        int64_t timeUs, MediaSource::ReadOptions::SeekMode mode) {
158f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber    return mImpl->seekTo(timeUs, mode);
15988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
16088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
16188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaExtractor::advance() {
16288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return mImpl->advance();
16388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
16488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
16588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaExtractor::readSampleData(
16688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jobject byteBuf, size_t offset, size_t *sampleSize) {
16788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    JNIEnv *env = AndroidRuntime::getJNIEnv();
16888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
16988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    void *dst = env->GetDirectBufferAddress(byteBuf);
17088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
171075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    size_t dstSize;
172c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber    jbyteArray byteArray = NULL;
173c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber
1747be24522ce2e1821ad45e7ada7c3f91e6814889aLajos Molnar    ScopedLocalRef<jclass> byteBufClass(env, env->FindClass("java/nio/ByteBuffer"));
1757be24522ce2e1821ad45e7ada7c3f91e6814889aLajos Molnar    CHECK(byteBufClass.get() != NULL);
176c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber
1777be24522ce2e1821ad45e7ada7c3f91e6814889aLajos Molnar    if (dst == NULL) {
178c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber        jmethodID arrayID =
1797be24522ce2e1821ad45e7ada7c3f91e6814889aLajos Molnar            env->GetMethodID(byteBufClass.get(), "array", "()[B");
180c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber        CHECK(arrayID != NULL);
181c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber
182c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber        byteArray =
183c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber            (jbyteArray)env->CallObjectMethod(byteBuf, arrayID);
184c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber
185c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber        if (byteArray == NULL) {
186c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber            return INVALID_OPERATION;
187c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber        }
18888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
189c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber        jboolean isCopy;
190c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber        dst = env->GetByteArrayElements(byteArray, &isCopy);
191c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber
192075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat        dstSize = (size_t) env->GetArrayLength(byteArray);
193c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber    } else {
194075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat        dstSize = (size_t) env->GetDirectBufferCapacity(byteBuf);
195c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber    }
19688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
19788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (dstSize < offset) {
198c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber        if (byteArray != NULL) {
199c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber            env->ReleaseByteArrayElements(byteArray, (jbyte *)dst, 0);
200c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber        }
201c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber
20288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return -ERANGE;
20388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
20488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
20588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<ABuffer> buffer = new ABuffer((char *)dst + offset, dstSize - offset);
20688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
20788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    status_t err = mImpl->readSampleData(buffer);
20888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
209c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber    if (byteArray != NULL) {
210c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber        env->ReleaseByteArrayElements(byteArray, (jbyte *)dst, 0);
211c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber    }
212c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber
21388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (err != OK) {
21488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return err;
21588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
21688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
21788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    *sampleSize = buffer->size();
21888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
2197be24522ce2e1821ad45e7ada7c3f91e6814889aLajos Molnar    jmethodID positionID = env->GetMethodID(
2207be24522ce2e1821ad45e7ada7c3f91e6814889aLajos Molnar            byteBufClass.get(), "position", "(I)Ljava/nio/Buffer;");
2217be24522ce2e1821ad45e7ada7c3f91e6814889aLajos Molnar
2227be24522ce2e1821ad45e7ada7c3f91e6814889aLajos Molnar    CHECK(positionID != NULL);
2237be24522ce2e1821ad45e7ada7c3f91e6814889aLajos Molnar
2247be24522ce2e1821ad45e7ada7c3f91e6814889aLajos Molnar    jmethodID limitID = env->GetMethodID(
2257be24522ce2e1821ad45e7ada7c3f91e6814889aLajos Molnar            byteBufClass.get(), "limit", "(I)Ljava/nio/Buffer;");
2267be24522ce2e1821ad45e7ada7c3f91e6814889aLajos Molnar
2277be24522ce2e1821ad45e7ada7c3f91e6814889aLajos Molnar    CHECK(limitID != NULL);
2287be24522ce2e1821ad45e7ada7c3f91e6814889aLajos Molnar
2297be24522ce2e1821ad45e7ada7c3f91e6814889aLajos Molnar    jobject me = env->CallObjectMethod(
2307be24522ce2e1821ad45e7ada7c3f91e6814889aLajos Molnar            byteBuf, limitID, offset + *sampleSize);
2317be24522ce2e1821ad45e7ada7c3f91e6814889aLajos Molnar    env->DeleteLocalRef(me);
2327be24522ce2e1821ad45e7ada7c3f91e6814889aLajos Molnar    me = env->CallObjectMethod(
2337be24522ce2e1821ad45e7ada7c3f91e6814889aLajos Molnar            byteBuf, positionID, offset);
2347be24522ce2e1821ad45e7ada7c3f91e6814889aLajos Molnar    env->DeleteLocalRef(me);
2357be24522ce2e1821ad45e7ada7c3f91e6814889aLajos Molnar    me = NULL;
2367be24522ce2e1821ad45e7ada7c3f91e6814889aLajos Molnar
23788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return OK;
23888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
23988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
24088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaExtractor::getSampleTrackIndex(size_t *trackIndex) {
24188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return mImpl->getSampleTrackIndex(trackIndex);
24288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
24388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
24488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaExtractor::getSampleTime(int64_t *sampleTimeUs) {
24588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return mImpl->getSampleTime(sampleTimeUs);
24688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
24788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
248d908f38e19b4aaf16cbb9426d4c1dbf728b0ad58Robert Shihstatus_t JMediaExtractor::getSampleSize(size_t *sampleSize) {
249d908f38e19b4aaf16cbb9426d4c1dbf728b0ad58Robert Shih    return mImpl->getSampleSize(sampleSize);
250d908f38e19b4aaf16cbb9426d4c1dbf728b0ad58Robert Shih}
251d908f38e19b4aaf16cbb9426d4c1dbf728b0ad58Robert Shih
2529b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huberstatus_t JMediaExtractor::getSampleFlags(uint32_t *sampleFlags) {
25391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    *sampleFlags = 0;
25491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
25591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    sp<MetaData> meta;
25691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    status_t err = mImpl->getSampleMeta(&meta);
25791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
25891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    if (err != OK) {
25991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        return err;
26091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    }
26191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
26291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    int32_t val;
26391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    if (meta->findInt32(kKeyIsSyncFrame, &val) && val != 0) {
26491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        (*sampleFlags) |= NuMediaExtractor::SAMPLE_FLAG_SYNC;
26591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    }
26691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
26791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    uint32_t type;
26891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    const void *data;
26991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    size_t size;
27091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    if (meta->findData(kKeyEncryptedSizes, &type, &data, &size)) {
27191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        (*sampleFlags) |= NuMediaExtractor::SAMPLE_FLAG_ENCRYPTED;
27291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    }
27391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
27491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    return OK;
27591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber}
27691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
277ba5ce2c0f8c8b7349225d7367a422cf505ff419eRay Essickstatus_t JMediaExtractor::getMetrics(Parcel *reply) const {
278ba5ce2c0f8c8b7349225d7367a422cf505ff419eRay Essick
279ba5ce2c0f8c8b7349225d7367a422cf505ff419eRay Essick    status_t status = mImpl->getMetrics(reply);
280ba5ce2c0f8c8b7349225d7367a422cf505ff419eRay Essick    return status;
281ba5ce2c0f8c8b7349225d7367a422cf505ff419eRay Essick}
282ba5ce2c0f8c8b7349225d7367a422cf505ff419eRay Essick
283ba5ce2c0f8c8b7349225d7367a422cf505ff419eRay Essick
28491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huberstatus_t JMediaExtractor::getSampleMeta(sp<MetaData> *sampleMeta) {
28591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    return mImpl->getSampleMeta(sampleMeta);
2869b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber}
2879b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber
28874a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huberbool JMediaExtractor::getCachedDuration(int64_t *durationUs, bool *eos) const {
28974a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber    return mImpl->getCachedDuration(durationUs, eos);
29074a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber}
29174a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber
29288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}  // namespace android
29388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
29488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber////////////////////////////////////////////////////////////////////////////////
29588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
29688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberusing namespace android;
29788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
29888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic sp<JMediaExtractor> setMediaExtractor(
29988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        JNIEnv *env, jobject thiz, const sp<JMediaExtractor> &extractor) {
30088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaExtractor> old =
301075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat        (JMediaExtractor *)env->GetLongField(thiz, gFields.context);
30288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
30388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (extractor != NULL) {
30488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        extractor->incStrong(thiz);
30588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
30688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (old != NULL) {
30788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        old->decStrong(thiz);
30888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
309075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    env->SetLongField(thiz, gFields.context, (jlong)extractor.get());
31088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
31188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return old;
31288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
31388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
31488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic sp<JMediaExtractor> getMediaExtractor(JNIEnv *env, jobject thiz) {
315075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    return (JMediaExtractor *)env->GetLongField(thiz, gFields.context);
31688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
31788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
31888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaExtractor_release(JNIEnv *env, jobject thiz) {
31988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    setMediaExtractor(env, thiz, NULL);
32088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
32188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
32260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huberstatic jint android_media_MediaExtractor_getTrackCount(
32388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        JNIEnv *env, jobject thiz) {
32488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
32588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
32688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (extractor == NULL) {
32788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
32807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        return -1;
32988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
33088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
331075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    return (jint) extractor->countTracks();
33288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
33388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
33460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huberstatic jobject android_media_MediaExtractor_getTrackFormatNative(
33588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        JNIEnv *env, jobject thiz, jint index) {
33688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
33788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
33888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (extractor == NULL) {
33988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
34088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return NULL;
34188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
34288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
34388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    jobject format;
34488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    status_t err = extractor->getTrackFormat(index, &format);
34588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
34688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (err != OK) {
34788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
34888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return NULL;
34988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
35088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
35188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return format;
35288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
35388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
354e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissenstatic jobject android_media_MediaExtractor_getFileFormatNative(
355e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen        JNIEnv *env, jobject thiz) {
356e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen    sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
357e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen
358e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen    if (extractor == NULL) {
359e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen        jniThrowException(env, "java/lang/IllegalStateException", NULL);
360e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen        return NULL;
361e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen    }
362e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen
363e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen    jobject format;
364e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen    status_t err = extractor->getFileFormat(&format);
365e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen
366e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen    if (err != OK) {
367e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
368e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen        return NULL;
369e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen    }
370e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen
371e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen    return format;
372e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen}
373e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen
37488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaExtractor_selectTrack(
37588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        JNIEnv *env, jobject thiz, jint index) {
37688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
37788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
37888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (extractor == NULL) {
37988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
38088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return;
38188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
38288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
38388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    status_t err = extractor->selectTrack(index);
38488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
38588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (err != OK) {
38688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
38788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return;
38888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
38988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
39088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
391f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huberstatic void android_media_MediaExtractor_unselectTrack(
392f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber        JNIEnv *env, jobject thiz, jint index) {
393f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber    sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
394f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber
395f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber    if (extractor == NULL) {
396f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
397f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber        return;
398f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber    }
399f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber
400f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber    status_t err = extractor->unselectTrack(index);
401f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber
402f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber    if (err != OK) {
403f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
404f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber        return;
405f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber    }
406f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber}
407f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber
40888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaExtractor_seekTo(
409f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber        JNIEnv *env, jobject thiz, jlong timeUs, jint mode) {
41088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
41188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
41288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (extractor == NULL) {
41388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
41488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return;
41588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
41688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
417f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber    if (mode < MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC
418f86374adec8bd77af7b012f788ea59575296facbAndreas Huber            || mode >= MediaSource::ReadOptions::SEEK_CLOSEST) {
419f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
420f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber        return;
421f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber    }
422f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber
423f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber    extractor->seekTo(timeUs, (MediaSource::ReadOptions::SeekMode)mode);
42488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
42588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
42688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jboolean android_media_MediaExtractor_advance(
42788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        JNIEnv *env, jobject thiz) {
42888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
42988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
43088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (extractor == NULL) {
43188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
432075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat        return JNI_FALSE;
43388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
43488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
43588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    status_t err = extractor->advance();
43688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
43788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (err == ERROR_END_OF_STREAM) {
438075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat        return JNI_FALSE;
43988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    } else if (err != OK) {
44088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
441075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat        return JNI_FALSE;
44288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
44388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
444075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    return JNI_TRUE;
44588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
44688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
44788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jint android_media_MediaExtractor_readSampleData(
44888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        JNIEnv *env, jobject thiz, jobject byteBuf, jint offset) {
44988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
45088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
45188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (extractor == NULL) {
45288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
45388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return -1;
45488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
45588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
45688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    size_t sampleSize;
45788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    status_t err = extractor->readSampleData(byteBuf, offset, &sampleSize);
45888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
45988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (err == ERROR_END_OF_STREAM) {
46088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return -1;
46188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    } else if (err != OK) {
46288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
463075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat        return -1;
46488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
46588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
466075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    return (jint) sampleSize;
46788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
46888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
46988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jint android_media_MediaExtractor_getSampleTrackIndex(
47088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        JNIEnv *env, jobject thiz) {
47188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
47288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
47388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (extractor == NULL) {
47488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
47588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return -1;
47688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
47788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
47888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    size_t trackIndex;
47988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    status_t err = extractor->getSampleTrackIndex(&trackIndex);
48088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
48188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (err == ERROR_END_OF_STREAM) {
48288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return -1;
48388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    } else if (err != OK) {
48488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
485075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat        return -1;
48688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
48788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
488075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    return (jint) trackIndex;
48988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
49088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
49188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jlong android_media_MediaExtractor_getSampleTime(
49288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        JNIEnv *env, jobject thiz) {
49388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
49488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
49588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (extractor == NULL) {
49688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
49788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return -1ll;
49888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
49988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
50088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    int64_t sampleTimeUs;
50188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    status_t err = extractor->getSampleTime(&sampleTimeUs);
50288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
50388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (err == ERROR_END_OF_STREAM) {
50488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return -1ll;
50588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    } else if (err != OK) {
50688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
507075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat        return -1ll;
50888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
50988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
510075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    return (jlong) sampleTimeUs;
51188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
51288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
513d908f38e19b4aaf16cbb9426d4c1dbf728b0ad58Robert Shihstatic jlong android_media_MediaExtractor_getSampleSize(
514d908f38e19b4aaf16cbb9426d4c1dbf728b0ad58Robert Shih        JNIEnv *env, jobject thiz) {
515d908f38e19b4aaf16cbb9426d4c1dbf728b0ad58Robert Shih    sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
516d908f38e19b4aaf16cbb9426d4c1dbf728b0ad58Robert Shih
517d908f38e19b4aaf16cbb9426d4c1dbf728b0ad58Robert Shih    if (extractor == NULL) {
518d908f38e19b4aaf16cbb9426d4c1dbf728b0ad58Robert Shih        jniThrowException(env, "java/lang/IllegalStateException", NULL);
519d908f38e19b4aaf16cbb9426d4c1dbf728b0ad58Robert Shih        return -1ll;
520d908f38e19b4aaf16cbb9426d4c1dbf728b0ad58Robert Shih    }
521d908f38e19b4aaf16cbb9426d4c1dbf728b0ad58Robert Shih
522d908f38e19b4aaf16cbb9426d4c1dbf728b0ad58Robert Shih    size_t sampleSize;
523d908f38e19b4aaf16cbb9426d4c1dbf728b0ad58Robert Shih    status_t err = extractor->getSampleSize(&sampleSize);
524d908f38e19b4aaf16cbb9426d4c1dbf728b0ad58Robert Shih
525d908f38e19b4aaf16cbb9426d4c1dbf728b0ad58Robert Shih    if (err == ERROR_END_OF_STREAM) {
526d908f38e19b4aaf16cbb9426d4c1dbf728b0ad58Robert Shih        return -1ll;
527d908f38e19b4aaf16cbb9426d4c1dbf728b0ad58Robert Shih    } else if (err != OK) {
528d908f38e19b4aaf16cbb9426d4c1dbf728b0ad58Robert Shih        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
529d908f38e19b4aaf16cbb9426d4c1dbf728b0ad58Robert Shih        return -1ll;
530d908f38e19b4aaf16cbb9426d4c1dbf728b0ad58Robert Shih    }
531d908f38e19b4aaf16cbb9426d4c1dbf728b0ad58Robert Shih
532d908f38e19b4aaf16cbb9426d4c1dbf728b0ad58Robert Shih    return (jlong) sampleSize;
533d908f38e19b4aaf16cbb9426d4c1dbf728b0ad58Robert Shih}
534d908f38e19b4aaf16cbb9426d4c1dbf728b0ad58Robert Shih
5359b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huberstatic jint android_media_MediaExtractor_getSampleFlags(
5369b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber        JNIEnv *env, jobject thiz) {
5379b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber    sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
5389b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber
5399b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber    if (extractor == NULL) {
5409b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
541075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat        return -1;
5429b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber    }
5439b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber
5449b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber    uint32_t sampleFlags;
5459b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber    status_t err = extractor->getSampleFlags(&sampleFlags);
5469b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber
5479b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber    if (err == ERROR_END_OF_STREAM) {
548075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat        return -1;
5499b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber    } else if (err != OK) {
5509b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
551075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat        return -1;
5529b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber    }
5539b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber
554075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    return (jint) sampleFlags;
5559b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber}
5569b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber
55791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huberstatic jboolean android_media_MediaExtractor_getSampleCryptoInfo(
55891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        JNIEnv *env, jobject thiz, jobject cryptoInfoObj) {
55991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
56091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
56191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    if (extractor == NULL) {
56291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
563075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat        return JNI_FALSE;
56491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    }
56591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
56691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    sp<MetaData> meta;
56791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    status_t err = extractor->getSampleMeta(&meta);
56891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
56991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    if (err != OK) {
570075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat        return JNI_FALSE;
57191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    }
57291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
57391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    uint32_t type;
57491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    const void *data;
57591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    size_t size;
57691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    if (!meta->findData(kKeyEncryptedSizes, &type, &data, &size)) {
577075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat        return JNI_FALSE;
57891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    }
57991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
580e92416dfeb115939231819c5edb593b8bb81cc6dAshok Bhat    size_t numSubSamples = size / sizeof(int32_t);
58191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
58291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    if (numSubSamples == 0) {
583075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat        return JNI_FALSE;
58491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    }
58591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
58691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    jintArray numBytesOfEncryptedDataObj = env->NewIntArray(numSubSamples);
58791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    jboolean isCopy;
58891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    jint *dst = env->GetIntArrayElements(numBytesOfEncryptedDataObj, &isCopy);
58991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    for (size_t i = 0; i < numSubSamples; ++i) {
590e92416dfeb115939231819c5edb593b8bb81cc6dAshok Bhat        dst[i] = ((const int32_t *)data)[i];
59191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    }
59291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    env->ReleaseIntArrayElements(numBytesOfEncryptedDataObj, dst, 0);
59391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    dst = NULL;
59491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
59591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    size_t encSize = size;
59691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    jintArray numBytesOfPlainDataObj = NULL;
597ab57d03bdb3010d4957fb88c8acb30575ca02ec9Andreas Huber    if (meta->findData(kKeyPlainSizes, &type, &data, &size)) {
59891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        if (size != encSize) {
59991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber            // The two must be of the same length.
600075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat            return JNI_FALSE;
60191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        }
60291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
60391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        numBytesOfPlainDataObj = env->NewIntArray(numSubSamples);
60491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        jboolean isCopy;
60591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        jint *dst = env->GetIntArrayElements(numBytesOfPlainDataObj, &isCopy);
60691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        for (size_t i = 0; i < numSubSamples; ++i) {
607e92416dfeb115939231819c5edb593b8bb81cc6dAshok Bhat            dst[i] = ((const int32_t *)data)[i];
60891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        }
60991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        env->ReleaseIntArrayElements(numBytesOfPlainDataObj, dst, 0);
61091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        dst = NULL;
61191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    }
61291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
61391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    jbyteArray keyObj = NULL;
61491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    if (meta->findData(kKeyCryptoKey, &type, &data, &size)) {
61591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        if (size != 16) {
61691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber            // Keys must be 16 bytes in length.
617075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat            return JNI_FALSE;
61891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        }
61991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
62091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        keyObj = env->NewByteArray(size);
62191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        jboolean isCopy;
62291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        jbyte *dst = env->GetByteArrayElements(keyObj, &isCopy);
62391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        memcpy(dst, data, size);
62491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        env->ReleaseByteArrayElements(keyObj, dst, 0);
62591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        dst = NULL;
62691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    }
62791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
62891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    jbyteArray ivObj = NULL;
62991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    if (meta->findData(kKeyCryptoIV, &type, &data, &size)) {
63091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        if (size != 16) {
63191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber            // IVs must be 16 bytes in length.
632075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat            return JNI_FALSE;
63391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        }
63491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
63591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        ivObj = env->NewByteArray(size);
63691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        jboolean isCopy;
63791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        jbyte *dst = env->GetByteArrayElements(ivObj, &isCopy);
63891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        memcpy(dst, data, size);
63991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        env->ReleaseByteArrayElements(ivObj, dst, 0);
64091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        dst = NULL;
64191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    }
64291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
64391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    int32_t mode;
64491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    if (!meta->findInt32(kKeyCryptoMode, &mode)) {
645ab57d03bdb3010d4957fb88c8acb30575ca02ec9Andreas Huber        mode = CryptoPlugin::kMode_AES_CTR;
64691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    }
64791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
64891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    env->CallVoidMethod(
64991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber            cryptoInfoObj,
65091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber            gFields.cryptoInfoSetID,
651136c08a7d3678e9fcf22667e75b0904a94add6bbAshok Bhat            (jint)numSubSamples,
65291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber            numBytesOfPlainDataObj,
65391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber            numBytesOfEncryptedDataObj,
65491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber            keyObj,
65591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber            ivObj,
65691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber            mode);
65791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
65897825a4fd01b8b79ca045ac971d3e6e77c906613Robert Shih    int32_t encryptedByteBlock = 0, skipByteBlock = 0;
65997825a4fd01b8b79ca045ac971d3e6e77c906613Robert Shih    meta->findInt32(kKeyEncryptedByteBlock, &encryptedByteBlock);
66097825a4fd01b8b79ca045ac971d3e6e77c906613Robert Shih    meta->findInt32(kKeySkipByteBlock, &skipByteBlock);
66197825a4fd01b8b79ca045ac971d3e6e77c906613Robert Shih
66297825a4fd01b8b79ca045ac971d3e6e77c906613Robert Shih    env->CallVoidMethod(
66397825a4fd01b8b79ca045ac971d3e6e77c906613Robert Shih            cryptoInfoObj,
66497825a4fd01b8b79ca045ac971d3e6e77c906613Robert Shih            gFields.cryptoInfoSetPatternID,
66597825a4fd01b8b79ca045ac971d3e6e77c906613Robert Shih            encryptedByteBlock,
66697825a4fd01b8b79ca045ac971d3e6e77c906613Robert Shih            skipByteBlock);
66797825a4fd01b8b79ca045ac971d3e6e77c906613Robert Shih
668075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    return JNI_TRUE;
66991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber}
67091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
67188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaExtractor_native_init(JNIEnv *env) {
67288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    jclass clazz = env->FindClass("android/media/MediaExtractor");
67388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    CHECK(clazz != NULL);
67488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
675075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    gFields.context = env->GetFieldID(clazz, "mNativeContext", "J");
67688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    CHECK(gFields.context != NULL);
67788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
67891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    clazz = env->FindClass("android/media/MediaCodec$CryptoInfo");
67991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    CHECK(clazz != NULL);
68091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
68191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    gFields.cryptoInfoSetID =
68291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        env->GetMethodID(clazz, "set", "(I[I[I[B[BI)V");
68397825a4fd01b8b79ca045ac971d3e6e77c906613Robert Shih
68497825a4fd01b8b79ca045ac971d3e6e77c906613Robert Shih    gFields.cryptoInfoSetPatternID =
68597825a4fd01b8b79ca045ac971d3e6e77c906613Robert Shih        env->GetMethodID(clazz, "setPattern", "(II)V");
68688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
68788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
68888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaExtractor_native_setup(
68907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        JNIEnv *env, jobject thiz) {
69088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaExtractor> extractor = new JMediaExtractor(env, thiz);
69107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    setMediaExtractor(env,thiz, extractor);
69207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber}
69388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
69407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huberstatic void android_media_MediaExtractor_setDataSource(
69507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        JNIEnv *env, jobject thiz,
696d2506a506303ed94fd1991cf986b825b870a67c5Andreas Huber        jobject httpServiceBinderObj,
697d2506a506303ed94fd1991cf986b825b870a67c5Andreas Huber        jstring pathObj,
698d2506a506303ed94fd1991cf986b825b870a67c5Andreas Huber        jobjectArray keysArray,
699d2506a506303ed94fd1991cf986b825b870a67c5Andreas Huber        jobjectArray valuesArray) {
70007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
70107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
70207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    if (extractor == NULL) {
70307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
70407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        return;
70507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    }
70607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
70707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    if (pathObj == NULL) {
70888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
70988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return;
71088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
71188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
71207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    KeyedVector<String8, String8> headers;
71307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    if (!ConvertKeyValueArraysToKeyedVector(
71407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber                env, keysArray, valuesArray, &headers)) {
71507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        return;
71607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    }
71788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
71807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    const char *path = env->GetStringUTFChars(pathObj, NULL);
71907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
72007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    if (path == NULL) {
72188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return;
72288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
72388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
724d2506a506303ed94fd1991cf986b825b870a67c5Andreas Huber    sp<IMediaHTTPService> httpService;
725d2506a506303ed94fd1991cf986b825b870a67c5Andreas Huber    if (httpServiceBinderObj != NULL) {
726d2506a506303ed94fd1991cf986b825b870a67c5Andreas Huber        sp<IBinder> binder = ibinderForJavaObject(env, httpServiceBinderObj);
727d2506a506303ed94fd1991cf986b825b870a67c5Andreas Huber        httpService = interface_cast<IMediaHTTPService>(binder);
728d2506a506303ed94fd1991cf986b825b870a67c5Andreas Huber    }
729d2506a506303ed94fd1991cf986b825b870a67c5Andreas Huber
730d2506a506303ed94fd1991cf986b825b870a67c5Andreas Huber    status_t err = extractor->setDataSource(httpService, path, &headers);
73188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
73207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    env->ReleaseStringUTFChars(pathObj, path);
73307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    path = NULL;
73488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
73588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (err != OK) {
73688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(
73788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber                env,
73888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber                "java/io/IOException",
73988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber                "Failed to instantiate extractor.");
74088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return;
74188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
74207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber}
74388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
74407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huberstatic void android_media_MediaExtractor_setDataSourceFd(
74507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        JNIEnv *env, jobject thiz,
74607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        jobject fileDescObj, jlong offset, jlong length) {
74707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
74807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
74907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    if (extractor == NULL) {
75007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
75107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        return;
75207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    }
75307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
75407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    if (fileDescObj == NULL) {
75507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
75607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        return;
75707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    }
75807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
75907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    int fd = jniGetFDFromFileDescriptor(env, fileDescObj);
76007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
76107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    status_t err = extractor->setDataSource(fd, offset, length);
76207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
76307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    if (err != OK) {
76407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        jniThrowException(
76507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber                env,
76607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber                "java/io/IOException",
76707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber                "Failed to instantiate extractor.");
76807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        return;
76907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    }
77088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
77188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
772c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissenstatic void android_media_MediaExtractor_setDataSourceCallback(
773c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        JNIEnv *env, jobject thiz,
774c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        jobject callbackObj) {
775c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen    sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
776c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen
777c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen    if (extractor == NULL) {
778c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        jniThrowException(env, "java/lang/IllegalStateException", NULL);
779c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        return;
780c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen    }
781c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen
782c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen    if (callbackObj == NULL) {
783c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
784c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        return;
785c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen    }
786c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen
7874eaa2938084353a54dc259466172909329a048ccChris Watkins    sp<DataSource> bridge =
78870d2ba3c06829dd8d7316bea7bd1b8bfbf4b8123Dongwon Kang        CreateDataSourceFromIDataSource(new JMediaDataSource(env, callbackObj));
789c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen    status_t err = extractor->setDataSource(bridge);
790c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen
791c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen    if (err != OK) {
792bc10185fa1669a151568feb72277785d323fc344Chong Zhang        // Clear bridge so that JMediaDataSource::close() is called _before_
793bc10185fa1669a151568feb72277785d323fc344Chong Zhang        // we throw the IOException.
794bc10185fa1669a151568feb72277785d323fc344Chong Zhang        // Otherwise close() gets called when we go out of scope, it calls
795bc10185fa1669a151568feb72277785d323fc344Chong Zhang        // Java with a pending exception and crashes the process.
796bc10185fa1669a151568feb72277785d323fc344Chong Zhang        bridge.clear();
797c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        jniThrowException(
798c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen                env,
799c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen                "java/io/IOException",
800c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen                "Failed to instantiate extractor.");
801c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen        return;
802c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen    }
803c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen}
804c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen
805d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhangstatic void android_media_MediaExtractor_setMediaCas(
806d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang        JNIEnv *env, jobject thiz, jobject casBinderObj) {
807d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang    sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
808d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang
809d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang    if (extractor == NULL) {
810d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang        jniThrowException(env, "java/lang/IllegalStateException", NULL);
811d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang        return;
812d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang    }
813d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang
8142659c2f16cf55d58f5b3817347340ae84f9eaabdChong Zhang    status_t err = extractor->setMediaCas(env, casBinderObj);
815d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang
816d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang    if (err != OK) {
8172659c2f16cf55d58f5b3817347340ae84f9eaabdChong Zhang        extractor.clear();
818d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang        jniThrowException(
819d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang                env,
8202659c2f16cf55d58f5b3817347340ae84f9eaabdChong Zhang                "java/lang/IllegalArgumentException",
821d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang                "Failed to set MediaCas on extractor.");
822d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang    }
823d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang}
824d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang
82574a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huberstatic jlong android_media_MediaExtractor_getCachedDurationUs(
82674a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber        JNIEnv *env, jobject thiz) {
82774a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber    sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
82874a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber
82974a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber    if (extractor == NULL) {
83074a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
83174a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber        return -1ll;
83274a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber    }
83374a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber
83474a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber    int64_t cachedDurationUs;
83574a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber    bool eos;
83674a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber    if (!extractor->getCachedDuration(&cachedDurationUs, &eos)) {
83774a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber        return -1ll;
83874a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber    }
83974a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber
840075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    return (jlong) cachedDurationUs;
84174a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber}
84274a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber
84374a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huberstatic jboolean android_media_MediaExtractor_hasCacheReachedEOS(
84474a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber        JNIEnv *env, jobject thiz) {
84574a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber    sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
84674a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber
84774a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber    if (extractor == NULL) {
84874a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
849075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat        return JNI_TRUE;
85074a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber    }
85174a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber
85274a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber    int64_t cachedDurationUs;
85374a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber    bool eos;
85474a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber    if (!extractor->getCachedDuration(&cachedDurationUs, &eos)) {
855075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat        return JNI_TRUE;
85674a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber    }
85774a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber
858075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    return eos ? JNI_TRUE : JNI_FALSE;
85974a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber}
86074a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber
86188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaExtractor_native_finalize(
86288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        JNIEnv *env, jobject thiz) {
86388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    android_media_MediaExtractor_release(env, thiz);
86488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
86588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
866ba5ce2c0f8c8b7349225d7367a422cf505ff419eRay Essickstatic jobject
867f2d0e40bf01fa133dd6b36f3716005d53fa9776cRay Essickandroid_media_MediaExtractor_native_getMetrics(JNIEnv * env, jobject thiz)
868ba5ce2c0f8c8b7349225d7367a422cf505ff419eRay Essick{
869f2d0e40bf01fa133dd6b36f3716005d53fa9776cRay Essick    ALOGV("android_media_MediaExtractor_native_getMetrics");
870ba5ce2c0f8c8b7349225d7367a422cf505ff419eRay Essick
871ba5ce2c0f8c8b7349225d7367a422cf505ff419eRay Essick    sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
872ba5ce2c0f8c8b7349225d7367a422cf505ff419eRay Essick    if (extractor == NULL ) {
873ba5ce2c0f8c8b7349225d7367a422cf505ff419eRay Essick        jniThrowException(env, "java/lang/IllegalStateException", NULL);
874ba5ce2c0f8c8b7349225d7367a422cf505ff419eRay Essick        return NULL;
875ba5ce2c0f8c8b7349225d7367a422cf505ff419eRay Essick    }
876ba5ce2c0f8c8b7349225d7367a422cf505ff419eRay Essick
877ba5ce2c0f8c8b7349225d7367a422cf505ff419eRay Essick    // get what we have for the metrics from the codec
878ba5ce2c0f8c8b7349225d7367a422cf505ff419eRay Essick    Parcel reply;
879ba5ce2c0f8c8b7349225d7367a422cf505ff419eRay Essick    status_t err = extractor->getMetrics(&reply);
880ba5ce2c0f8c8b7349225d7367a422cf505ff419eRay Essick    if (err != OK) {
881ba5ce2c0f8c8b7349225d7367a422cf505ff419eRay Essick        ALOGE("getMetrics failed");
882ba5ce2c0f8c8b7349225d7367a422cf505ff419eRay Essick        return (jobject) NULL;
883ba5ce2c0f8c8b7349225d7367a422cf505ff419eRay Essick    }
884ba5ce2c0f8c8b7349225d7367a422cf505ff419eRay Essick
885ba5ce2c0f8c8b7349225d7367a422cf505ff419eRay Essick    // build and return the Bundle
886ba5ce2c0f8c8b7349225d7367a422cf505ff419eRay Essick    MediaAnalyticsItem *item = new MediaAnalyticsItem;
887ba5ce2c0f8c8b7349225d7367a422cf505ff419eRay Essick    item->readFromParcel(reply);
888ba5ce2c0f8c8b7349225d7367a422cf505ff419eRay Essick    jobject mybundle = MediaMetricsJNI::writeMetricsToBundle(env, item, NULL);
889ba5ce2c0f8c8b7349225d7367a422cf505ff419eRay Essick
890ba5ce2c0f8c8b7349225d7367a422cf505ff419eRay Essick    // housekeeping
891ba5ce2c0f8c8b7349225d7367a422cf505ff419eRay Essick    delete item;
892ba5ce2c0f8c8b7349225d7367a422cf505ff419eRay Essick    item = NULL;
893ba5ce2c0f8c8b7349225d7367a422cf505ff419eRay Essick
894ba5ce2c0f8c8b7349225d7367a422cf505ff419eRay Essick    return mybundle;
895ba5ce2c0f8c8b7349225d7367a422cf505ff419eRay Essick}
896ba5ce2c0f8c8b7349225d7367a422cf505ff419eRay Essick
897ba5ce2c0f8c8b7349225d7367a422cf505ff419eRay Essick
89876f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gMethods[] = {
89988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    { "release", "()V", (void *)android_media_MediaExtractor_release },
90088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
90160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber    { "getTrackCount", "()I", (void *)android_media_MediaExtractor_getTrackCount },
90288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
903e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen    { "getFileFormatNative", "()Ljava/util/Map;",
904e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen        (void *)android_media_MediaExtractor_getFileFormatNative },
905e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen
90660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber    { "getTrackFormatNative", "(I)Ljava/util/Map;",
90760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        (void *)android_media_MediaExtractor_getTrackFormatNative },
90888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
90988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    { "selectTrack", "(I)V", (void *)android_media_MediaExtractor_selectTrack },
91088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
911f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber    { "unselectTrack", "(I)V",
912f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber        (void *)android_media_MediaExtractor_unselectTrack },
913f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber
914f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber    { "seekTo", "(JI)V", (void *)android_media_MediaExtractor_seekTo },
91588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
91688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    { "advance", "()Z", (void *)android_media_MediaExtractor_advance },
91788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
91888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    { "readSampleData", "(Ljava/nio/ByteBuffer;I)I",
91988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        (void *)android_media_MediaExtractor_readSampleData },
92088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
92188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    { "getSampleTrackIndex", "()I",
92288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        (void *)android_media_MediaExtractor_getSampleTrackIndex },
92388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
92488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    { "getSampleTime", "()J",
92588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        (void *)android_media_MediaExtractor_getSampleTime },
92688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
927d908f38e19b4aaf16cbb9426d4c1dbf728b0ad58Robert Shih    { "getSampleSize", "()J",
928d908f38e19b4aaf16cbb9426d4c1dbf728b0ad58Robert Shih        (void *)android_media_MediaExtractor_getSampleSize },
929d908f38e19b4aaf16cbb9426d4c1dbf728b0ad58Robert Shih
9309b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber    { "getSampleFlags", "()I",
9319b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber        (void *)android_media_MediaExtractor_getSampleFlags },
9329b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber
93391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    { "getSampleCryptoInfo", "(Landroid/media/MediaCodec$CryptoInfo;)Z",
93491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        (void *)android_media_MediaExtractor_getSampleCryptoInfo },
93591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
93688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    { "native_init", "()V", (void *)android_media_MediaExtractor_native_init },
93788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
93807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    { "native_setup", "()V",
93988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber      (void *)android_media_MediaExtractor_native_setup },
94088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
94188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    { "native_finalize", "()V",
94288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber      (void *)android_media_MediaExtractor_native_finalize },
94307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
944d2506a506303ed94fd1991cf986b825b870a67c5Andreas Huber    { "nativeSetDataSource",
945d2506a506303ed94fd1991cf986b825b870a67c5Andreas Huber        "(Landroid/os/IBinder;Ljava/lang/String;[Ljava/lang/String;"
946d2506a506303ed94fd1991cf986b825b870a67c5Andreas Huber        "[Ljava/lang/String;)V",
94707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber      (void *)android_media_MediaExtractor_setDataSource },
94807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
94907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    { "setDataSource", "(Ljava/io/FileDescriptor;JJ)V",
95007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber      (void *)android_media_MediaExtractor_setDataSourceFd },
95174a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber
9524eaa2938084353a54dc259466172909329a048ccChris Watkins    { "setDataSource", "(Landroid/media/MediaDataSource;)V",
953c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen      (void *)android_media_MediaExtractor_setDataSourceCallback },
954c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen
9552659c2f16cf55d58f5b3817347340ae84f9eaabdChong Zhang    { "nativeSetMediaCas", "(Landroid/os/IHwBinder;)V",
956d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang      (void *)android_media_MediaExtractor_setMediaCas },
957d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang
95874a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber    { "getCachedDuration", "()J",
95974a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber      (void *)android_media_MediaExtractor_getCachedDurationUs },
96074a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber
96174a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber    { "hasCacheReachedEndOfStream", "()Z",
96274a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber      (void *)android_media_MediaExtractor_hasCacheReachedEOS },
963ba5ce2c0f8c8b7349225d7367a422cf505ff419eRay Essick
96410353e36018224b86ef2918d1d68107459d445cfRay Essick    {"native_getMetrics",          "()Landroid/os/PersistableBundle;",
965f2d0e40bf01fa133dd6b36f3716005d53fa9776cRay Essick      (void *)android_media_MediaExtractor_native_getMetrics},
96688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber};
96788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
96888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberint register_android_media_MediaExtractor(JNIEnv *env) {
96988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return AndroidRuntime::registerNativeMethods(env,
97088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber                "android/media/MediaExtractor", gMethods, NELEM(gMethods));
97188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
972