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