NdkMediaExtractor.cpp revision 0c3be875376adaee8d8e8dd917c64926e1513b29
1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#define LOG_NDEBUG 0 18#define LOG_TAG "NdkMediaExtractor" 19 20 21#include "NdkMediaExtractor.h" 22#include "NdkMediaFormatPriv.h" 23 24 25#include <utils/Log.h> 26#include <utils/StrongPointer.h> 27#include <media/stagefright/foundation/ABuffer.h> 28#include <media/stagefright/foundation/AMessage.h> 29#include <media/stagefright/MetaData.h> 30#include <media/stagefright/NuMediaExtractor.h> 31#include <media/IMediaHTTPService.h> 32#include <android_runtime/AndroidRuntime.h> 33#include <android_util_Binder.h> 34 35#include <jni.h> 36 37using namespace android; 38 39static int translate_error(status_t err) { 40 if (err == OK) { 41 return OK; 42 } 43 ALOGE("sf error code: %d", err); 44 return -1000; 45} 46 47struct AMediaExtractor { 48 sp<NuMediaExtractor> mImpl; 49 50}; 51 52extern "C" { 53 54AMediaExtractor* AMediaExtractor_new() { 55 ALOGV("ctor"); 56 AMediaExtractor *mData = new AMediaExtractor(); 57 mData->mImpl = new NuMediaExtractor(); 58 return mData; 59} 60 61int AMediaExtractor_delete(AMediaExtractor *mData) { 62 ALOGV("dtor"); 63 delete mData; 64 return OK; 65} 66 67int AMediaExtractor_setDataSourceFd(AMediaExtractor *mData, int fd, off64_t offset, off64_t length) { 68 ALOGV("setDataSource(%d, %lld, %lld)", fd, offset, length); 69 mData->mImpl->setDataSource(fd, offset, length); 70 return 0; 71} 72 73int AMediaExtractor_setDataSource(AMediaExtractor *mData, const char *location) { 74 ALOGV("setDataSource(%s)", location); 75 // TODO: add header support 76 77 JNIEnv *env = AndroidRuntime::getJNIEnv(); 78 jobject service = NULL; 79 if (env == NULL) { 80 ALOGE("setDataSource(path) must be called from Java thread"); 81 env->ExceptionClear(); 82 return -1; 83 } 84 85 jclass mediahttpclass = env->FindClass("android/media/MediaHTTPService"); 86 if (mediahttpclass == NULL) { 87 ALOGE("can't find MediaHttpService"); 88 env->ExceptionClear(); 89 return -1; 90 } 91 92 jmethodID mediaHttpCreateMethod = env->GetStaticMethodID(mediahttpclass, 93 "createHttpServiceBinderIfNecessary", "(Ljava/lang/String;)Landroid/os/IBinder;"); 94 if (mediaHttpCreateMethod == NULL) { 95 ALOGE("can't find method"); 96 env->ExceptionClear(); 97 return -1; 98 } 99 100 jstring jloc = env->NewStringUTF(location); 101 102 service = env->CallStaticObjectMethod(mediahttpclass, mediaHttpCreateMethod, jloc); 103 env->DeleteLocalRef(jloc); 104 105 sp<IMediaHTTPService> httpService; 106 if (service != NULL) { 107 sp<IBinder> binder = ibinderForJavaObject(env, service); 108 httpService = interface_cast<IMediaHTTPService>(binder); 109 } 110 111 mData->mImpl->setDataSource(httpService, location, NULL); 112 env->ExceptionClear(); 113 return 0; 114} 115 116int AMediaExtractor_getTrackCount(AMediaExtractor *mData) { 117 return mData->mImpl->countTracks(); 118} 119 120AMediaFormat* AMediaExtractor_getTrackFormat(AMediaExtractor *mData, size_t idx) { 121 sp<AMessage> format; 122 mData->mImpl->getTrackFormat(idx, &format); 123 return AMediaFormat_fromMsg(&format); 124} 125 126int AMediaExtractor_selectTrack(AMediaExtractor *mData, size_t idx) { 127 ALOGV("selectTrack(%z)", idx); 128 return translate_error(mData->mImpl->selectTrack(idx)); 129} 130 131int AMediaExtractor_unselectTrack(AMediaExtractor *mData, size_t idx) { 132 ALOGV("unselectTrack(%z)", idx); 133 return translate_error(mData->mImpl->unselectTrack(idx)); 134} 135 136bool AMediaExtractor_advance(AMediaExtractor *mData) { 137 //ALOGV("advance"); 138 return mData->mImpl->advance(); 139} 140 141int AMediaExtractor_readSampleData(AMediaExtractor *mData, uint8_t *buffer, size_t capacity) { 142 //ALOGV("readSampleData"); 143 sp<ABuffer> tmp = new ABuffer(buffer, capacity); 144 if (mData->mImpl->readSampleData(tmp) == OK) { 145 return tmp->size(); 146 } 147 return -1; 148} 149 150int AMediaExtractor_getSampleFlags(AMediaExtractor *mData) { 151 int sampleFlags = 0; 152 sp<MetaData> meta; 153 status_t err = mData->mImpl->getSampleMeta(&meta); 154 if (err != OK) { 155 return -1; 156 } 157 int32_t val; 158 if (meta->findInt32(kKeyIsSyncFrame, &val) && val != 0) { 159 sampleFlags |= NuMediaExtractor::SAMPLE_FLAG_SYNC; 160 } 161 162 uint32_t type; 163 const void *data; 164 size_t size; 165 if (meta->findData(kKeyEncryptedSizes, &type, &data, &size)) { 166 sampleFlags |= NuMediaExtractor::SAMPLE_FLAG_ENCRYPTED; 167 } 168 return sampleFlags; 169} 170 171int AMediaExtractor_getSampleTrackIndex(AMediaExtractor *mData) { 172 size_t idx; 173 if (mData->mImpl->getSampleTrackIndex(&idx) != OK) { 174 return -1; 175 } 176 return idx; 177} 178 179int64_t AMediaExtractor_getSampletime(AMediaExtractor *mData) { 180 int64_t time; 181 if (mData->mImpl->getSampleTime(&time) != OK) { 182 return -1; 183 } 184 return time; 185} 186 187 188} // extern "C" 189 190