10c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen/*
20c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen * Copyright (C) 2014 The Android Open Source Project
30c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen *
40c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen * Licensed under the Apache License, Version 2.0 (the "License");
50c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen * you may not use this file except in compliance with the License.
60c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen * You may obtain a copy of the License at
70c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen *
80c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen *      http://www.apache.org/licenses/LICENSE-2.0
90c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen *
100c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen * Unless required by applicable law or agreed to in writing, software
110c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen * distributed under the License is distributed on an "AS IS" BASIS,
120c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen * See the License for the specific language governing permissions and
140c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen * limitations under the License.
150c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen */
160c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
17c7a11b2208aa8f1e6a39eb70a136fbc0dafd3260Marco Nelissen//#define LOG_NDEBUG 0
180c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen#define LOG_TAG "NdkMediaExtractor"
190c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
200c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
217e8d4ba5887affda749978d787b898bf31fda729Colin Cross#include <media/NdkMediaError.h>
227e8d4ba5887affda749978d787b898bf31fda729Colin Cross#include <media/NdkMediaExtractor.h>
230df451b305aa6095384741c713759a37e3f3f171Robert Shih#include "NdkMediaDataSourcePriv.h"
240c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen#include "NdkMediaFormatPriv.h"
250c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
260c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
27214c833fcde68833691cc54d2a4cd995d7eb0e16Aurimas Liutikas#include <inttypes.h>
280c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen#include <utils/Log.h>
290c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen#include <utils/StrongPointer.h>
30050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen#include <media/hardware/CryptoAPI.h>
310c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen#include <media/stagefright/foundation/ABuffer.h>
320c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen#include <media/stagefright/foundation/AMessage.h>
330c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen#include <media/stagefright/MetaData.h>
340c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen#include <media/stagefright/NuMediaExtractor.h>
350c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen#include <media/IMediaHTTPService.h>
360c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen#include <android_runtime/AndroidRuntime.h>
370c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen#include <android_util_Binder.h>
380c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
390c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen#include <jni.h>
400c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
410c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissenusing namespace android;
420c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
43e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenstatic media_status_t translate_error(status_t err) {
440c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    if (err == OK) {
45e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_OK;
46d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih    } else if (err == ERROR_END_OF_STREAM) {
47d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih        return AMEDIA_ERROR_END_OF_STREAM;
48d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih    } else if (err == ERROR_IO) {
49d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih        return AMEDIA_ERROR_IO;
500c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    }
51d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih
520c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    ALOGE("sf error code: %d", err);
53e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    return AMEDIA_ERROR_UNKNOWN;
540c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
550c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
560c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissenstruct AMediaExtractor {
570c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    sp<NuMediaExtractor> mImpl;
58050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    sp<ABuffer> mPsshBuf;
590c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen};
600c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
610c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissenextern "C" {
620c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
633425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
640c3be875376adaee8d8e8dd917c64926e1513b29Marco NelissenAMediaExtractor* AMediaExtractor_new() {
650c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    ALOGV("ctor");
660c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    AMediaExtractor *mData = new AMediaExtractor();
670c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    mData->mImpl = new NuMediaExtractor();
680c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    return mData;
690c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
700c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
713425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
72e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaExtractor_delete(AMediaExtractor *mData) {
730c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    ALOGV("dtor");
740c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    delete mData;
75e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    return AMEDIA_OK;
760c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
770c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
783425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
79b187de1ada34a9023c05d020a4592686ba761278Glenn Kastenmedia_status_t AMediaExtractor_setDataSourceFd(AMediaExtractor *mData, int fd, off64_t offset,
80b187de1ada34a9023c05d020a4592686ba761278Glenn Kasten        off64_t length) {
81214c833fcde68833691cc54d2a4cd995d7eb0e16Aurimas Liutikas    ALOGV("setDataSource(%d, %" PRId64 ", %" PRId64 ")", fd, offset, length);
82e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    return translate_error(mData->mImpl->setDataSource(fd, offset, length));
830c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
840c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
853425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
86e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaExtractor_setDataSource(AMediaExtractor *mData, const char *location) {
870c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    ALOGV("setDataSource(%s)", location);
880c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    // TODO: add header support
890c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
900c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    JNIEnv *env = AndroidRuntime::getJNIEnv();
910c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    jobject service = NULL;
920c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    if (env == NULL) {
930c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        ALOGE("setDataSource(path) must be called from Java thread");
94e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_UNSUPPORTED;
950c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    }
960c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
970c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    jclass mediahttpclass = env->FindClass("android/media/MediaHTTPService");
980c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    if (mediahttpclass == NULL) {
990c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        ALOGE("can't find MediaHttpService");
1000c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        env->ExceptionClear();
101e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_UNSUPPORTED;
1020c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    }
1030c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
1040c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    jmethodID mediaHttpCreateMethod = env->GetStaticMethodID(mediahttpclass,
1050c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen            "createHttpServiceBinderIfNecessary", "(Ljava/lang/String;)Landroid/os/IBinder;");
1060c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    if (mediaHttpCreateMethod == NULL) {
1070c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        ALOGE("can't find method");
1080c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        env->ExceptionClear();
109e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_UNSUPPORTED;
1100c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    }
1110c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
1120c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    jstring jloc = env->NewStringUTF(location);
1130c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
1140c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    service = env->CallStaticObjectMethod(mediahttpclass, mediaHttpCreateMethod, jloc);
1150c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    env->DeleteLocalRef(jloc);
1160c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
1170c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    sp<IMediaHTTPService> httpService;
1180c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    if (service != NULL) {
1190c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        sp<IBinder> binder = ibinderForJavaObject(env, service);
1200c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        httpService = interface_cast<IMediaHTTPService>(binder);
1210c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    }
1220c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
123e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    status_t err = mData->mImpl->setDataSource(httpService, location, NULL);
1240c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    env->ExceptionClear();
125e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    return translate_error(err);
1260c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
1270c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
1283425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
1290df451b305aa6095384741c713759a37e3f3f171Robert Shihmedia_status_t AMediaExtractor_setDataSourceCustom(AMediaExtractor* mData, AMediaDataSource *src) {
1300df451b305aa6095384741c713759a37e3f3f171Robert Shih    return translate_error(mData->mImpl->setDataSource(new NdkDataSource(src)));
1310df451b305aa6095384741c713759a37e3f3f171Robert Shih}
1320df451b305aa6095384741c713759a37e3f3f171Robert Shih
1330df451b305aa6095384741c713759a37e3f3f171Robert ShihEXPORT
13430e3c7d2f0c08ee6e1f5a466732faa341868b597Robert ShihAMediaFormat* AMediaExtractor_getFileFormat(AMediaExtractor *mData) {
13530e3c7d2f0c08ee6e1f5a466732faa341868b597Robert Shih    sp<AMessage> format;
13630e3c7d2f0c08ee6e1f5a466732faa341868b597Robert Shih    mData->mImpl->getFileFormat(&format);
13730e3c7d2f0c08ee6e1f5a466732faa341868b597Robert Shih    return AMediaFormat_fromMsg(&format);
13830e3c7d2f0c08ee6e1f5a466732faa341868b597Robert Shih}
13930e3c7d2f0c08ee6e1f5a466732faa341868b597Robert Shih
14030e3c7d2f0c08ee6e1f5a466732faa341868b597Robert ShihEXPORT
141e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissensize_t AMediaExtractor_getTrackCount(AMediaExtractor *mData) {
1420c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    return mData->mImpl->countTracks();
1430c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
1440c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
1453425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
1460c3be875376adaee8d8e8dd917c64926e1513b29Marco NelissenAMediaFormat* AMediaExtractor_getTrackFormat(AMediaExtractor *mData, size_t idx) {
1470c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    sp<AMessage> format;
1480c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    mData->mImpl->getTrackFormat(idx, &format);
1490c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    return AMediaFormat_fromMsg(&format);
1500c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
1510c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
1523425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
153e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaExtractor_selectTrack(AMediaExtractor *mData, size_t idx) {
15498f28cde0d5d682956b5e6b119823e7e8d40415bMark Salyzyn    ALOGV("selectTrack(%zu)", idx);
1550c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    return translate_error(mData->mImpl->selectTrack(idx));
1560c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
1570c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
1583425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
159e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaExtractor_unselectTrack(AMediaExtractor *mData, size_t idx) {
16098f28cde0d5d682956b5e6b119823e7e8d40415bMark Salyzyn    ALOGV("unselectTrack(%zu)", idx);
1610c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    return translate_error(mData->mImpl->unselectTrack(idx));
1620c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
1630c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
1643425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
1650c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissenbool AMediaExtractor_advance(AMediaExtractor *mData) {
1660c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    //ALOGV("advance");
16770452261b0ed8e47676641ee5cc546dc5f8333baRobert Shih    status_t err = mData->mImpl->advance();
16870452261b0ed8e47676641ee5cc546dc5f8333baRobert Shih    if (err == ERROR_END_OF_STREAM) {
16970452261b0ed8e47676641ee5cc546dc5f8333baRobert Shih        return false;
17070452261b0ed8e47676641ee5cc546dc5f8333baRobert Shih    } else if (err != OK) {
17170452261b0ed8e47676641ee5cc546dc5f8333baRobert Shih        ALOGE("sf error code: %d", err);
17270452261b0ed8e47676641ee5cc546dc5f8333baRobert Shih        return false;
17370452261b0ed8e47676641ee5cc546dc5f8333baRobert Shih    }
17470452261b0ed8e47676641ee5cc546dc5f8333baRobert Shih    return true;
1750c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
1760c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
1773425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
17879e2b622702fb148ccff12d6f38643466555c4ebMarco Nelissenmedia_status_t AMediaExtractor_seekTo(AMediaExtractor *ex, int64_t seekPosUs, SeekMode mode) {
17979e2b622702fb148ccff12d6f38643466555c4ebMarco Nelissen    android::MediaSource::ReadOptions::SeekMode sfmode;
18079e2b622702fb148ccff12d6f38643466555c4ebMarco Nelissen    if (mode == AMEDIAEXTRACTOR_SEEK_PREVIOUS_SYNC) {
18179e2b622702fb148ccff12d6f38643466555c4ebMarco Nelissen        sfmode = android::MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC;
18279e2b622702fb148ccff12d6f38643466555c4ebMarco Nelissen    } else if (mode == AMEDIAEXTRACTOR_SEEK_CLOSEST_SYNC) {
18379e2b622702fb148ccff12d6f38643466555c4ebMarco Nelissen        sfmode = android::MediaSource::ReadOptions::SEEK_CLOSEST_SYNC;
18479e2b622702fb148ccff12d6f38643466555c4ebMarco Nelissen    } else {
18579e2b622702fb148ccff12d6f38643466555c4ebMarco Nelissen        sfmode = android::MediaSource::ReadOptions::SEEK_NEXT_SYNC;
18679e2b622702fb148ccff12d6f38643466555c4ebMarco Nelissen    }
18779e2b622702fb148ccff12d6f38643466555c4ebMarco Nelissen
18879e2b622702fb148ccff12d6f38643466555c4ebMarco Nelissen    return translate_error(ex->mImpl->seekTo(seekPosUs, sfmode));
18979e2b622702fb148ccff12d6f38643466555c4ebMarco Nelissen}
19079e2b622702fb148ccff12d6f38643466555c4ebMarco Nelissen
19179e2b622702fb148ccff12d6f38643466555c4ebMarco NelissenEXPORT
192e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenssize_t AMediaExtractor_readSampleData(AMediaExtractor *mData, uint8_t *buffer, size_t capacity) {
1930c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    //ALOGV("readSampleData");
1940c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    sp<ABuffer> tmp = new ABuffer(buffer, capacity);
1950c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    if (mData->mImpl->readSampleData(tmp) == OK) {
1960c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        return tmp->size();
1970c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    }
1980c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    return -1;
1990c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
2000c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
2013425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
20230e3c7d2f0c08ee6e1f5a466732faa341868b597Robert Shihssize_t AMediaExtractor_getSampleSize(AMediaExtractor *mData) {
20330e3c7d2f0c08ee6e1f5a466732faa341868b597Robert Shih    size_t sampleSize;
20430e3c7d2f0c08ee6e1f5a466732faa341868b597Robert Shih    status_t err = mData->mImpl->getSampleSize(&sampleSize);
20530e3c7d2f0c08ee6e1f5a466732faa341868b597Robert Shih    if (err != OK) {
20630e3c7d2f0c08ee6e1f5a466732faa341868b597Robert Shih        return -1;
20730e3c7d2f0c08ee6e1f5a466732faa341868b597Robert Shih    }
20830e3c7d2f0c08ee6e1f5a466732faa341868b597Robert Shih    return sampleSize;
20930e3c7d2f0c08ee6e1f5a466732faa341868b597Robert Shih}
21030e3c7d2f0c08ee6e1f5a466732faa341868b597Robert Shih
21130e3c7d2f0c08ee6e1f5a466732faa341868b597Robert ShihEXPORT
212e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenuint32_t AMediaExtractor_getSampleFlags(AMediaExtractor *mData) {
2130c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    int sampleFlags = 0;
2140c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    sp<MetaData> meta;
2150c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    status_t err = mData->mImpl->getSampleMeta(&meta);
2160c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    if (err != OK) {
2170c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        return -1;
2180c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    }
2190c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    int32_t val;
2200c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    if (meta->findInt32(kKeyIsSyncFrame, &val) && val != 0) {
221e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        sampleFlags |= AMEDIAEXTRACTOR_SAMPLE_FLAG_SYNC;
2220c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    }
2230c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
2240c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    uint32_t type;
2250c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    const void *data;
2260c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    size_t size;
2270c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    if (meta->findData(kKeyEncryptedSizes, &type, &data, &size)) {
228e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        sampleFlags |= AMEDIAEXTRACTOR_SAMPLE_FLAG_ENCRYPTED;
2290c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    }
2300c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    return sampleFlags;
2310c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
2320c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
2333425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
2340c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissenint AMediaExtractor_getSampleTrackIndex(AMediaExtractor *mData) {
2350c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    size_t idx;
2360c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    if (mData->mImpl->getSampleTrackIndex(&idx) != OK) {
2370c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        return -1;
2380c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    }
2390c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    return idx;
2400c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
2410c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
2423425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
243eb4860c305def68c5965474bb43c67c2c9d49bbbMarco Nelissenint64_t AMediaExtractor_getSampleTime(AMediaExtractor *mData) {
2440c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    int64_t time;
2450c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    if (mData->mImpl->getSampleTime(&time) != OK) {
2460c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        return -1;
2470c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    }
2480c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    return time;
2490c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
2500c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
2513425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
252050eb3280d7305b84f723d515be2dc9606dc39d1Marco NelissenPsshInfo* AMediaExtractor_getPsshInfo(AMediaExtractor *ex) {
253050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
254050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    if (ex->mPsshBuf != NULL) {
255050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        return (PsshInfo*) ex->mPsshBuf->data();
256050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    }
257050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
258050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    sp<AMessage> format;
259050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    ex->mImpl->getFileFormat(&format);
260050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    sp<ABuffer> buffer;
261050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    if(!format->findBuffer("pssh", &buffer)) {
262050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        return NULL;
263050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    }
264050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
265050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    // the format of the buffer is 1 or more of:
266050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    //    {
267050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    //        16 byte uuid
268050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    //        4 byte data length N
269050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    //        N bytes of data
270050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    //    }
271050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
272050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    // Determine the number of entries in the source data.
273050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    // Since we got the data from stagefright, we trust it is valid and properly formatted.
274050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    const uint8_t* data = buffer->data();
275050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    size_t len = buffer->size();
276050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    size_t numentries = 0;
277050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    while (len > 0) {
278050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        numentries++;
279050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
280346bb516cc55944fbdf683a928b7e99fac2f7eb6Marco Nelissen        if (len < 16) {
281346bb516cc55944fbdf683a928b7e99fac2f7eb6Marco Nelissen            ALOGE("invalid PSSH data");
282346bb516cc55944fbdf683a928b7e99fac2f7eb6Marco Nelissen            return NULL;
283346bb516cc55944fbdf683a928b7e99fac2f7eb6Marco Nelissen        }
284050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        // skip uuid
285050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        data += 16;
286050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        len -= 16;
287050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
288050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        // get data length
289346bb516cc55944fbdf683a928b7e99fac2f7eb6Marco Nelissen        if (len < 4) {
290346bb516cc55944fbdf683a928b7e99fac2f7eb6Marco Nelissen            ALOGE("invalid PSSH data");
291346bb516cc55944fbdf683a928b7e99fac2f7eb6Marco Nelissen            return NULL;
292346bb516cc55944fbdf683a928b7e99fac2f7eb6Marco Nelissen        }
293050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        uint32_t datalen = *((uint32_t*)data);
294050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        data += 4;
295050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        len -= 4;
296050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
297346bb516cc55944fbdf683a928b7e99fac2f7eb6Marco Nelissen        if (len < datalen) {
298346bb516cc55944fbdf683a928b7e99fac2f7eb6Marco Nelissen            ALOGE("invalid PSSH data");
299346bb516cc55944fbdf683a928b7e99fac2f7eb6Marco Nelissen            return NULL;
300346bb516cc55944fbdf683a928b7e99fac2f7eb6Marco Nelissen        }
301050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        // skip the data
302050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        data += datalen;
303050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        len -= datalen;
304050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    }
305050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
30658344bc9165a9465a63acc874f3e71251a0d7f50Marco Nelissen    // there are <numentries> in the source buffer, we need
30758344bc9165a9465a63acc874f3e71251a0d7f50Marco Nelissen    // (source buffer size) - (sizeof(uint32_t) * numentries) + sizeof(size_t)
30858344bc9165a9465a63acc874f3e71251a0d7f50Marco Nelissen    //  + ((sizeof(void*) + sizeof(size_t)) * numentries) bytes for the PsshInfo structure
30958344bc9165a9465a63acc874f3e71251a0d7f50Marco Nelissen    // Or in other words, the data lengths in the source structure are replaced by size_t
31058344bc9165a9465a63acc874f3e71251a0d7f50Marco Nelissen    // (which may be the same size or larger, for 64 bit), and in addition there is an
31158344bc9165a9465a63acc874f3e71251a0d7f50Marco Nelissen    // extra pointer for each entry, and an extra size_t for the entire PsshInfo.
31258344bc9165a9465a63acc874f3e71251a0d7f50Marco Nelissen    size_t newsize = buffer->size() - (sizeof(uint32_t) * numentries) + sizeof(size_t)
31358344bc9165a9465a63acc874f3e71251a0d7f50Marco Nelissen            + ((sizeof(void*) + sizeof(size_t)) * numentries);
314346bb516cc55944fbdf683a928b7e99fac2f7eb6Marco Nelissen    if (newsize <= buffer->size()) {
315346bb516cc55944fbdf683a928b7e99fac2f7eb6Marco Nelissen        ALOGE("invalid PSSH data");
316346bb516cc55944fbdf683a928b7e99fac2f7eb6Marco Nelissen        return NULL;
317346bb516cc55944fbdf683a928b7e99fac2f7eb6Marco Nelissen    }
318050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    ex->mPsshBuf = new ABuffer(newsize);
319050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    ex->mPsshBuf->setRange(0, newsize);
320050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
321050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    // copy data
322050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    const uint8_t* src = buffer->data();
323050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    uint8_t* dst = ex->mPsshBuf->data();
32458344bc9165a9465a63acc874f3e71251a0d7f50Marco Nelissen    uint8_t* dstdata = dst + sizeof(size_t) + numentries * sizeof(PsshEntry);
32558344bc9165a9465a63acc874f3e71251a0d7f50Marco Nelissen    *((size_t*)dst) = numentries;
32658344bc9165a9465a63acc874f3e71251a0d7f50Marco Nelissen    dst += sizeof(size_t);
327050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    for (size_t i = 0; i < numentries; i++) {
328050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        // copy uuid
329050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        memcpy(dst, src, 16);
330050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        src += 16;
331050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        dst += 16;
332050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
333050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        // get/copy data length
334050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        uint32_t datalen = *((uint32_t*)src);
33558344bc9165a9465a63acc874f3e71251a0d7f50Marco Nelissen        *((size_t*)dst) = datalen;
33658344bc9165a9465a63acc874f3e71251a0d7f50Marco Nelissen        src += sizeof(uint32_t);
33758344bc9165a9465a63acc874f3e71251a0d7f50Marco Nelissen        dst += sizeof(size_t);
338050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
339050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        // the next entry in the destination is a pointer to the actual data, which we store
340050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        // after the array of PsshEntry
34158344bc9165a9465a63acc874f3e71251a0d7f50Marco Nelissen        *((void**)dst) = dstdata;
34258344bc9165a9465a63acc874f3e71251a0d7f50Marco Nelissen        dst += sizeof(void*);
343050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
344050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        // copy the actual data
345050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        memcpy(dstdata, src, datalen);
346050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        dstdata += datalen;
347050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        src += datalen;
348050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    }
349050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
350050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    return (PsshInfo*) ex->mPsshBuf->data();
351050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen}
352050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
3533425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
354050eb3280d7305b84f723d515be2dc9606dc39d1Marco NelissenAMediaCodecCryptoInfo *AMediaExtractor_getSampleCryptoInfo(AMediaExtractor *ex) {
355050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    sp<MetaData> meta;
356050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    if(ex->mImpl->getSampleMeta(&meta) != 0) {
357050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        return NULL;
358050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    }
359050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
360050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    uint32_t type;
361050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    const void *crypteddata;
362050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    size_t cryptedsize;
363050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    if (!meta->findData(kKeyEncryptedSizes, &type, &crypteddata, &cryptedsize)) {
364050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        return NULL;
365050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    }
366050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    size_t numSubSamples = cryptedsize / sizeof(size_t);
367050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
368050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    const void *cleardata;
369050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    size_t clearsize;
370050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    if (meta->findData(kKeyPlainSizes, &type, &cleardata, &clearsize)) {
371050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        if (clearsize != cryptedsize) {
372050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen            // The two must be of the same length.
373050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen            return NULL;
374050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        }
375050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    }
376050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
377050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    const void *key;
378050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    size_t keysize;
379b2fb3c9787e4cc372e87b71eb55bfe008b2693ccEdwin Wong    if (meta->findData(kKeyCryptoKey, &type, &key, &keysize)) {
380050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        if (keysize != 16) {
381b2fb3c9787e4cc372e87b71eb55bfe008b2693ccEdwin Wong            // Keys must be 16 bytes in length.
382050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen            return NULL;
383050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        }
384050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    }
385050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
386050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    const void *iv;
387050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    size_t ivsize;
388050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    if (meta->findData(kKeyCryptoIV, &type, &iv, &ivsize)) {
389050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        if (ivsize != 16) {
390050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen            // IVs must be 16 bytes in length.
391050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen            return NULL;
392050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        }
393050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    }
394050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
395050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    int32_t mode;
396050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    if (!meta->findInt32(kKeyCryptoMode, &mode)) {
397050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        mode = CryptoPlugin::kMode_AES_CTR;
398050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    }
399050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
400050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    return AMediaCodecCryptoInfo_new(
401050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen            numSubSamples,
402050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen            (uint8_t*) key,
403050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen            (uint8_t*) iv,
40479e2b622702fb148ccff12d6f38643466555c4ebMarco Nelissen            (cryptoinfo_mode_t) mode,
405050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen            (size_t*) cleardata,
406050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen            (size_t*) crypteddata);
407050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen}
408050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
40930e3c7d2f0c08ee6e1f5a466732faa341868b597Robert ShihEXPORT
41030e3c7d2f0c08ee6e1f5a466732faa341868b597Robert Shihint64_t AMediaExtractor_getCachedDuration(AMediaExtractor *ex) {
41130e3c7d2f0c08ee6e1f5a466732faa341868b597Robert Shih    bool eos;
41230e3c7d2f0c08ee6e1f5a466732faa341868b597Robert Shih    int64_t durationUs;
41330e3c7d2f0c08ee6e1f5a466732faa341868b597Robert Shih    if (ex->mImpl->getCachedDuration(&durationUs, &eos)) {
41430e3c7d2f0c08ee6e1f5a466732faa341868b597Robert Shih        return durationUs;
41530e3c7d2f0c08ee6e1f5a466732faa341868b597Robert Shih    }
41630e3c7d2f0c08ee6e1f5a466732faa341868b597Robert Shih    return -1;
41730e3c7d2f0c08ee6e1f5a466732faa341868b597Robert Shih}
4180c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
419d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert ShihEXPORT
420d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shihmedia_status_t AMediaExtractor_getSampleFormat(AMediaExtractor *ex, AMediaFormat *fmt) {
421d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih    if (fmt == NULL) {
422d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih        return AMEDIA_ERROR_INVALID_PARAMETER;
423d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih    }
424d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih
425d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih    sp<MetaData> sampleMeta;
426d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih    status_t err = ex->mImpl->getSampleMeta(&sampleMeta);
427d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih    if (err != OK) {
428d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih        return translate_error(err);
429d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih    }
430d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih
431d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih    sp<AMessage> meta;
432d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih    AMediaFormat_getFormat(fmt, &meta);
433d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih    meta->clear();
434d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih
435d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih    int32_t layerId;
436d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih    if (sampleMeta->findInt32(kKeyTemporalLayerId, &layerId)) {
437d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih        meta->setInt32(AMEDIAFORMAT_KEY_TEMPORAL_LAYER_ID, layerId);
438d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih    }
439d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih
440d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih    size_t trackIndex;
441d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih    err = ex->mImpl->getSampleTrackIndex(&trackIndex);
442d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih    if (err == OK) {
443d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih        meta->setInt32(AMEDIAFORMAT_KEY_TRACK_INDEX, trackIndex);
444d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih        sp<AMessage> trackFormat;
445d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih        AString mime;
446d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih        err = ex->mImpl->getTrackFormat(trackIndex, &trackFormat);
447d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih        if (err == OK
448d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih                && trackFormat != NULL
449d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih                && trackFormat->findString(AMEDIAFORMAT_KEY_MIME, &mime)) {
450d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih            meta->setString(AMEDIAFORMAT_KEY_MIME, mime);
451d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih        }
452d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih    }
453d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih
454d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih    int64_t durationUs;
455d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih    if (sampleMeta->findInt64(kKeyDuration, &durationUs)) {
456d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih        meta->setInt64(AMEDIAFORMAT_KEY_DURATION, durationUs);
457d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih    }
458d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih
459d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih    uint32_t dataType; // unused
460d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih    const void *seiData;
461d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih    size_t seiLength;
462d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih    if (sampleMeta->findData(kKeySEI, &dataType, &seiData, &seiLength)) {
463d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih        sp<ABuffer> sei = ABuffer::CreateAsCopy(seiData, seiLength);;
464d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih        meta->setBuffer(AMEDIAFORMAT_KEY_SEI, sei);
465d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih    }
466d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih
467d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih    const void *mpegUserDataPointer;
468d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih    size_t mpegUserDataLength;
469d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih    if (sampleMeta->findData(
470d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih            kKeyMpegUserData, &dataType, &mpegUserDataPointer, &mpegUserDataLength)) {
471d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih        sp<ABuffer> mpegUserData = ABuffer::CreateAsCopy(mpegUserDataPointer, mpegUserDataLength);
472d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih        meta->setBuffer(AMEDIAFORMAT_KEY_MPEG_USER_DATA, mpegUserData);
473d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih    }
474d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih
475d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih    return AMEDIA_OK;
476d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih}
477d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih
47808eb908098436ce8cc1faf0f009ced1a8fa32c9aRobert ShihEXPORT
47908eb908098436ce8cc1faf0f009ced1a8fa32c9aRobert Shihmedia_status_t AMediaExtractor_disconnect(AMediaExtractor * ex) {
48008eb908098436ce8cc1faf0f009ced1a8fa32c9aRobert Shih    ex->mImpl->disconnect();
48108eb908098436ce8cc1faf0f009ced1a8fa32c9aRobert Shih    return AMEDIA_OK;
48208eb908098436ce8cc1faf0f009ced1a8fa32c9aRobert Shih}
48308eb908098436ce8cc1faf0f009ced1a8fa32c9aRobert Shih
4840c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen} // extern "C"
4850c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
486