diff options
author | Andreas Huber <andih@google.com> | 2012-03-29 16:41:38 -0700 |
---|---|---|
committer | Andreas Huber <andih@google.com> | 2012-04-02 15:43:42 -0700 |
commit | 5a04bf395514a9342dd26af519b88f4b3e309eb9 (patch) | |
tree | d54a10176d38444301522d412d48f5e916375380 /media/jni | |
parent | 0424716328a7d0f7bb794d24f7481a76be08d379 (diff) | |
download | frameworks_base-5a04bf395514a9342dd26af519b88f4b3e309eb9.zip frameworks_base-5a04bf395514a9342dd26af519b88f4b3e309eb9.tar.gz frameworks_base-5a04bf395514a9342dd26af519b88f4b3e309eb9.tar.bz2 |
New API to query available codecs and their capabilities.
Change-Id: I448ba443a96d8fee2bc9179750d57362ed31d9d9
Diffstat (limited to 'media/jni')
-rw-r--r-- | media/jni/Android.mk | 1 | ||||
-rw-r--r-- | media/jni/android_media_MediaCodecList.cpp | 190 | ||||
-rw-r--r-- | media/jni/android_media_MediaPlayer.cpp | 6 |
3 files changed, 197 insertions, 0 deletions
diff --git a/media/jni/Android.mk b/media/jni/Android.mk index fcc3b13..dd1e505 100644 --- a/media/jni/Android.mk +++ b/media/jni/Android.mk @@ -3,6 +3,7 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ android_media_MediaCodec.cpp \ + android_media_MediaCodecList.cpp \ android_media_MediaExtractor.cpp \ android_media_MediaPlayer.cpp \ android_media_MediaRecorder.cpp \ diff --git a/media/jni/android_media_MediaCodecList.cpp b/media/jni/android_media_MediaCodecList.cpp new file mode 100644 index 0000000..2b8f91e --- /dev/null +++ b/media/jni/android_media_MediaCodecList.cpp @@ -0,0 +1,190 @@ +/* + * Copyright 2012, 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 "MediaCodec-JNI" +#include <utils/Log.h> + +#include <media/stagefright/foundation/ADebug.h> +#include <media/stagefright/MediaCodecList.h> + +#include "android_runtime/AndroidRuntime.h" +#include "jni.h" +#include "JNIHelp.h" + +using namespace android; + +static jint android_media_MediaCodecList_countCodecs( + JNIEnv *env, jobject thiz) { + return MediaCodecList::getInstance()->countCodecs(); +} + +static jstring android_media_MediaCodecList_getCodecName( + JNIEnv *env, jobject thiz, jint index) { + const char *name = MediaCodecList::getInstance()->getCodecName(index); + + if (name == NULL) { + jniThrowException(env, "java/lang/IllegalArgumentException", NULL); + return NULL; + } + + return env->NewStringUTF(name); +} + +static jboolean android_media_MediaCodecList_isEncoder( + JNIEnv *env, jobject thiz, jint index) { + return MediaCodecList::getInstance()->isEncoder(index); +} + +static jarray android_media_MediaCodecList_getSupportedTypes( + JNIEnv *env, jobject thiz, jint index) { + Vector<AString> types; + status_t err = + MediaCodecList::getInstance()->getSupportedTypes(index, &types); + + if (err != OK) { + jniThrowException(env, "java/lang/IllegalArgumentException", NULL); + return NULL; + } + + jclass clazz = env->FindClass("java/lang/String"); + CHECK(clazz != NULL); + + jobjectArray array = env->NewObjectArray(types.size(), clazz, NULL); + + for (size_t i = 0; i < types.size(); ++i) { + jstring obj = env->NewStringUTF(types.itemAt(i).c_str()); + env->SetObjectArrayElement(array, i, obj); + env->DeleteLocalRef(obj); + obj = NULL; + } + + return array; +} + +static jobject android_media_MediaCodecList_getCodecCapabilities( + JNIEnv *env, jobject thiz, jint index, jstring type) { + if (type == NULL) { + jniThrowException(env, "java/lang/IllegalArgumentException", NULL); + return NULL; + } + + const char *typeStr = env->GetStringUTFChars(type, NULL); + + if (typeStr == NULL) { + // Out of memory exception already pending. + return NULL; + } + + Vector<MediaCodecList::ProfileLevel> profileLevels; + Vector<uint32_t> colorFormats; + + status_t err = + MediaCodecList::getInstance()->getCodecCapabilities( + index, typeStr, &profileLevels, &colorFormats); + + env->ReleaseStringUTFChars(type, typeStr); + typeStr = NULL; + + if (err != OK) { + jniThrowException(env, "java/lang/IllegalArgumentException", NULL); + return NULL; + } + + jclass capsClazz = + env->FindClass("android/media/MediaCodecList$CodecCapabilities"); + CHECK(capsClazz != NULL); + + jobject caps = env->AllocObject(capsClazz); + + jclass profileLevelClazz = + env->FindClass("android/media/MediaCodecList$CodecProfileLevel"); + CHECK(profileLevelClazz != NULL); + + jobjectArray profileLevelArray = + env->NewObjectArray(profileLevels.size(), profileLevelClazz, NULL); + + jfieldID profileField = + env->GetFieldID(profileLevelClazz, "mProfile", "I"); + + jfieldID levelField = + env->GetFieldID(profileLevelClazz, "mLevel", "I"); + + for (size_t i = 0; i < profileLevels.size(); ++i) { + const MediaCodecList::ProfileLevel &src = profileLevels.itemAt(i); + + jobject profileLevelObj = env->AllocObject(profileLevelClazz); + + env->SetIntField(profileLevelObj, profileField, src.mProfile); + env->SetIntField(profileLevelObj, levelField, src.mLevel); + + env->SetObjectArrayElement(profileLevelArray, i, profileLevelObj); + + env->DeleteLocalRef(profileLevelObj); + profileLevelObj = NULL; + } + + jfieldID profileLevelsField = env->GetFieldID( + capsClazz, + "mProfileLevels", + "[Landroid/media/MediaCodecList$CodecProfileLevel;"); + + env->SetObjectField(caps, profileLevelsField, profileLevelArray); + + env->DeleteLocalRef(profileLevelArray); + profileLevelArray = NULL; + + jintArray colorFormatsArray = env->NewIntArray(colorFormats.size()); + + for (size_t i = 0; i < colorFormats.size(); ++i) { + jint val = colorFormats.itemAt(i); + env->SetIntArrayRegion(colorFormatsArray, i, 1, &val); + } + + jfieldID colorFormatsField = env->GetFieldID( + capsClazz, "mColorFormats", "[I"); + + env->SetObjectField(caps, colorFormatsField, colorFormatsArray); + + env->DeleteLocalRef(colorFormatsArray); + colorFormatsArray = NULL; + + return caps; +} + +static void android_media_MediaCodecList_native_init(JNIEnv *env) { +} + +static JNINativeMethod gMethods[] = { + { "countCodecs", "()I", (void *)android_media_MediaCodecList_countCodecs }, + { "getCodecName", "(I)Ljava/lang/String;", + (void *)android_media_MediaCodecList_getCodecName }, + { "isEncoder", "(I)Z", (void *)android_media_MediaCodecList_isEncoder }, + { "getSupportedTypes", "(I)[Ljava/lang/String;", + (void *)android_media_MediaCodecList_getSupportedTypes }, + + { "getCodecCapabilities", + "(ILjava/lang/String;)Landroid/media/MediaCodecList$CodecCapabilities;", + (void *)android_media_MediaCodecList_getCodecCapabilities }, + + { "native_init", "()V", (void *)android_media_MediaCodecList_native_init }, +}; + +int register_android_media_MediaCodecList(JNIEnv *env) { + return AndroidRuntime::registerNativeMethods(env, + "android/media/MediaCodecList", gMethods, NELEM(gMethods)); +} + diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp index 745e253..3074bb1 100644 --- a/media/jni/android_media_MediaPlayer.cpp +++ b/media/jni/android_media_MediaPlayer.cpp @@ -881,6 +881,7 @@ static int register_android_media_MediaPlayer(JNIEnv *env) extern int register_android_media_MediaCodec(JNIEnv *env); extern int register_android_media_MediaExtractor(JNIEnv *env); +extern int register_android_media_MediaCodecList(JNIEnv *env); extern int register_android_media_MediaMetadataRetriever(JNIEnv *env); extern int register_android_media_MediaRecorder(JNIEnv *env); extern int register_android_media_MediaScanner(JNIEnv *env); @@ -962,6 +963,11 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) goto bail; } + if (register_android_media_MediaCodecList(env) < 0) { + ALOGE("ERROR: MediaCodec native registration failed"); + goto bail; + } + /* success -- return valid version number */ result = JNI_VERSION_1_4; |