/* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_NDEBUG 0 #define LOG_TAG "NdkMediaExtractor" #include "NdkMediaExtractor.h" #include "NdkMediaFormatPriv.h" #include #include #include #include #include #include #include #include #include #include using namespace android; static int translate_error(status_t err) { if (err == OK) { return OK; } ALOGE("sf error code: %d", err); return -1000; } struct AMediaExtractor { sp mImpl; }; extern "C" { AMediaExtractor* AMediaExtractor_new() { ALOGV("ctor"); AMediaExtractor *mData = new AMediaExtractor(); mData->mImpl = new NuMediaExtractor(); return mData; } int AMediaExtractor_delete(AMediaExtractor *mData) { ALOGV("dtor"); delete mData; return OK; } int AMediaExtractor_setDataSourceFd(AMediaExtractor *mData, int fd, off64_t offset, off64_t length) { ALOGV("setDataSource(%d, %lld, %lld)", fd, offset, length); mData->mImpl->setDataSource(fd, offset, length); return 0; } int AMediaExtractor_setDataSource(AMediaExtractor *mData, const char *location) { ALOGV("setDataSource(%s)", location); // TODO: add header support JNIEnv *env = AndroidRuntime::getJNIEnv(); jobject service = NULL; if (env == NULL) { ALOGE("setDataSource(path) must be called from Java thread"); env->ExceptionClear(); return -1; } jclass mediahttpclass = env->FindClass("android/media/MediaHTTPService"); if (mediahttpclass == NULL) { ALOGE("can't find MediaHttpService"); env->ExceptionClear(); return -1; } jmethodID mediaHttpCreateMethod = env->GetStaticMethodID(mediahttpclass, "createHttpServiceBinderIfNecessary", "(Ljava/lang/String;)Landroid/os/IBinder;"); if (mediaHttpCreateMethod == NULL) { ALOGE("can't find method"); env->ExceptionClear(); return -1; } jstring jloc = env->NewStringUTF(location); service = env->CallStaticObjectMethod(mediahttpclass, mediaHttpCreateMethod, jloc); env->DeleteLocalRef(jloc); sp httpService; if (service != NULL) { sp binder = ibinderForJavaObject(env, service); httpService = interface_cast(binder); } mData->mImpl->setDataSource(httpService, location, NULL); env->ExceptionClear(); return 0; } int AMediaExtractor_getTrackCount(AMediaExtractor *mData) { return mData->mImpl->countTracks(); } AMediaFormat* AMediaExtractor_getTrackFormat(AMediaExtractor *mData, size_t idx) { sp format; mData->mImpl->getTrackFormat(idx, &format); return AMediaFormat_fromMsg(&format); } int AMediaExtractor_selectTrack(AMediaExtractor *mData, size_t idx) { ALOGV("selectTrack(%z)", idx); return translate_error(mData->mImpl->selectTrack(idx)); } int AMediaExtractor_unselectTrack(AMediaExtractor *mData, size_t idx) { ALOGV("unselectTrack(%z)", idx); return translate_error(mData->mImpl->unselectTrack(idx)); } bool AMediaExtractor_advance(AMediaExtractor *mData) { //ALOGV("advance"); return mData->mImpl->advance(); } int AMediaExtractor_readSampleData(AMediaExtractor *mData, uint8_t *buffer, size_t capacity) { //ALOGV("readSampleData"); sp tmp = new ABuffer(buffer, capacity); if (mData->mImpl->readSampleData(tmp) == OK) { return tmp->size(); } return -1; } int AMediaExtractor_getSampleFlags(AMediaExtractor *mData) { int sampleFlags = 0; sp meta; status_t err = mData->mImpl->getSampleMeta(&meta); if (err != OK) { return -1; } int32_t val; if (meta->findInt32(kKeyIsSyncFrame, &val) && val != 0) { sampleFlags |= NuMediaExtractor::SAMPLE_FLAG_SYNC; } uint32_t type; const void *data; size_t size; if (meta->findData(kKeyEncryptedSizes, &type, &data, &size)) { sampleFlags |= NuMediaExtractor::SAMPLE_FLAG_ENCRYPTED; } return sampleFlags; } int AMediaExtractor_getSampleTrackIndex(AMediaExtractor *mData) { size_t idx; if (mData->mImpl->getSampleTrackIndex(&idx) != OK) { return -1; } return idx; } int64_t AMediaExtractor_getSampletime(AMediaExtractor *mData) { int64_t time; if (mData->mImpl->getSampleTime(&time) != OK) { return -1; } return time; } } // extern "C"