android_media_MediaCodecList.cpp revision 80c4437ebfe3e679267a64e4c9d7bdd585b7afce
1/* 2 * Copyright 2012, 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 "MediaCodec-JNI" 19#include <utils/Log.h> 20 21#include <media/stagefright/foundation/ADebug.h> 22#include <media/stagefright/MediaCodecList.h> 23 24#include "android_runtime/AndroidRuntime.h" 25#include "jni.h" 26#include "JNIHelp.h" 27 28using namespace android; 29 30static jint android_media_MediaCodecList_getCodecCount( 31 JNIEnv *env, jobject thiz) { 32 return MediaCodecList::getInstance()->countCodecs(); 33} 34 35static jstring android_media_MediaCodecList_getCodecName( 36 JNIEnv *env, jobject thiz, jint index) { 37 const char *name = MediaCodecList::getInstance()->getCodecName(index); 38 39 if (name == NULL) { 40 jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 41 return NULL; 42 } 43 44 return env->NewStringUTF(name); 45} 46 47static jint android_media_MediaCodecList_findCodecByName( 48 JNIEnv *env, jobject thiz, jstring name) { 49 if (name == NULL) { 50 jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 51 return -ENOENT; 52 } 53 54 const char *nameStr = env->GetStringUTFChars(name, NULL); 55 56 if (nameStr == NULL) { 57 // Out of memory exception already pending. 58 return -ENOENT; 59 } 60 61 jint ret = MediaCodecList::getInstance()->findCodecByName(nameStr); 62 env->ReleaseStringUTFChars(name, nameStr); 63 return ret; 64} 65 66static jboolean android_media_MediaCodecList_isEncoder( 67 JNIEnv *env, jobject thiz, jint index) { 68 return MediaCodecList::getInstance()->isEncoder(index); 69} 70 71static jarray android_media_MediaCodecList_getSupportedTypes( 72 JNIEnv *env, jobject thiz, jint index) { 73 Vector<AString> types; 74 status_t err = 75 MediaCodecList::getInstance()->getSupportedTypes(index, &types); 76 77 if (err != OK) { 78 jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 79 return NULL; 80 } 81 82 jclass clazz = env->FindClass("java/lang/String"); 83 CHECK(clazz != NULL); 84 85 jobjectArray array = env->NewObjectArray(types.size(), clazz, NULL); 86 87 for (size_t i = 0; i < types.size(); ++i) { 88 jstring obj = env->NewStringUTF(types.itemAt(i).c_str()); 89 env->SetObjectArrayElement(array, i, obj); 90 env->DeleteLocalRef(obj); 91 obj = NULL; 92 } 93 94 return array; 95} 96 97static jobject android_media_MediaCodecList_getCodecCapabilities( 98 JNIEnv *env, jobject thiz, jint index, jstring type) { 99 if (type == NULL) { 100 jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 101 return NULL; 102 } 103 104 const char *typeStr = env->GetStringUTFChars(type, NULL); 105 106 if (typeStr == NULL) { 107 // Out of memory exception already pending. 108 return NULL; 109 } 110 111 Vector<MediaCodecList::ProfileLevel> profileLevels; 112 Vector<uint32_t> colorFormats; 113 uint32_t flags; 114 115 status_t err = 116 MediaCodecList::getInstance()->getCodecCapabilities( 117 index, typeStr, &profileLevels, &colorFormats, &flags); 118 119 env->ReleaseStringUTFChars(type, typeStr); 120 typeStr = NULL; 121 122 if (err != OK) { 123 jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 124 return NULL; 125 } 126 127 jclass capsClazz = 128 env->FindClass("android/media/MediaCodecInfo$CodecCapabilities"); 129 CHECK(capsClazz != NULL); 130 131 jfieldID flagsField = 132 env->GetFieldID(capsClazz, "flags", "I"); 133 134 jobject caps = env->AllocObject(capsClazz); 135 136 jclass profileLevelClazz = 137 env->FindClass("android/media/MediaCodecInfo$CodecProfileLevel"); 138 CHECK(profileLevelClazz != NULL); 139 140 jobjectArray profileLevelArray = 141 env->NewObjectArray(profileLevels.size(), profileLevelClazz, NULL); 142 143 jfieldID profileField = 144 env->GetFieldID(profileLevelClazz, "profile", "I"); 145 146 jfieldID levelField = 147 env->GetFieldID(profileLevelClazz, "level", "I"); 148 149 for (size_t i = 0; i < profileLevels.size(); ++i) { 150 const MediaCodecList::ProfileLevel &src = profileLevels.itemAt(i); 151 152 jobject profileLevelObj = env->AllocObject(profileLevelClazz); 153 154 env->SetIntField(profileLevelObj, profileField, src.mProfile); 155 env->SetIntField(profileLevelObj, levelField, src.mLevel); 156 157 env->SetObjectArrayElement(profileLevelArray, i, profileLevelObj); 158 159 env->DeleteLocalRef(profileLevelObj); 160 profileLevelObj = NULL; 161 } 162 163 jfieldID profileLevelsField = env->GetFieldID( 164 capsClazz, 165 "profileLevels", 166 "[Landroid/media/MediaCodecInfo$CodecProfileLevel;"); 167 168 env->SetObjectField(caps, profileLevelsField, profileLevelArray); 169 170 env->SetIntField(caps, flagsField, flags); 171 172 env->DeleteLocalRef(profileLevelArray); 173 profileLevelArray = NULL; 174 175 jintArray colorFormatsArray = env->NewIntArray(colorFormats.size()); 176 177 for (size_t i = 0; i < colorFormats.size(); ++i) { 178 jint val = colorFormats.itemAt(i); 179 env->SetIntArrayRegion(colorFormatsArray, i, 1, &val); 180 } 181 182 jfieldID colorFormatsField = env->GetFieldID( 183 capsClazz, "colorFormats", "[I"); 184 185 env->SetObjectField(caps, colorFormatsField, colorFormatsArray); 186 187 env->DeleteLocalRef(colorFormatsArray); 188 colorFormatsArray = NULL; 189 190 return caps; 191} 192 193static void android_media_MediaCodecList_native_init(JNIEnv *env) { 194} 195 196static JNINativeMethod gMethods[] = { 197 { "getCodecCount", "()I", (void *)android_media_MediaCodecList_getCodecCount }, 198 { "getCodecName", "(I)Ljava/lang/String;", 199 (void *)android_media_MediaCodecList_getCodecName }, 200 { "isEncoder", "(I)Z", (void *)android_media_MediaCodecList_isEncoder }, 201 { "getSupportedTypes", "(I)[Ljava/lang/String;", 202 (void *)android_media_MediaCodecList_getSupportedTypes }, 203 204 { "getCodecCapabilities", 205 "(ILjava/lang/String;)Landroid/media/MediaCodecInfo$CodecCapabilities;", 206 (void *)android_media_MediaCodecList_getCodecCapabilities }, 207 208 { "findCodecByName", "(Ljava/lang/String;)I", 209 (void *)android_media_MediaCodecList_findCodecByName }, 210 211 { "native_init", "()V", (void *)android_media_MediaCodecList_native_init }, 212}; 213 214int register_android_media_MediaCodecList(JNIEnv *env) { 215 return AndroidRuntime::registerNativeMethods(env, 216 "android/media/MediaCodecList", gMethods, NELEM(gMethods)); 217} 218 219