15a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber/* 25a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber * Copyright 2012, The Android Open Source Project 35a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber * 45a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 55a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber * you may not use this file except in compliance with the License. 65a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber * You may obtain a copy of the License at 75a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber * 85a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 95a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber * 105a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber * Unless required by applicable law or agreed to in writing, software 115a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 125a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber * See the License for the specific language governing permissions and 145a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber * limitations under the License. 155a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber */ 165a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber 175a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber//#define LOG_NDEBUG 0 185a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber#define LOG_TAG "MediaCodec-JNI" 195a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber#include <utils/Log.h> 205a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber 215a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber#include <media/stagefright/foundation/ADebug.h> 22b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar#include <media/stagefright/foundation/AMessage.h> 235a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber#include <media/stagefright/MediaCodecList.h> 24cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar#include <media/IMediaCodecList.h> 25cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar#include <media/MediaCodecInfo.h> 265a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber 275a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber#include "android_runtime/AndroidRuntime.h" 285a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber#include "jni.h" 295a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber#include "JNIHelp.h" 30b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar#include "android_media_Utils.h" 315a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber 325a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huberusing namespace android; 335a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber 34cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnarstatic sp<IMediaCodecList> getCodecList(JNIEnv *env) { 35cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar sp<IMediaCodecList> mcl = MediaCodecList::getInstance(); 36cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar if (mcl == NULL) { 37cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar // This should never happen unless something is really wrong 38cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar jniThrowException( 39cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar env, "java/lang/RuntimeException", "cannot get MediaCodecList"); 40cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar } 41cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar return mcl; 42cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar} 43cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar 4460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huberstatic jint android_media_MediaCodecList_getCodecCount( 455a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber JNIEnv *env, jobject thiz) { 46cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar sp<IMediaCodecList> mcl = getCodecList(env); 47cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar if (mcl == NULL) { 48cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar // Runtime exception already pending. 49cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar return 0; 50cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar } 51cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar return mcl->countCodecs(); 525a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber} 535a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber 545a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huberstatic jstring android_media_MediaCodecList_getCodecName( 555a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber JNIEnv *env, jobject thiz, jint index) { 56cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar sp<IMediaCodecList> mcl = getCodecList(env); 57cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar if (mcl == NULL) { 58cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar // Runtime exception already pending. 59cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar return NULL; 60cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar } 615a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber 62cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar const sp<MediaCodecInfo> &info = mcl->getCodecInfo(index); 63cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar if (info == NULL) { 645a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 655a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber return NULL; 665a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber } 675a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber 68cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar const char *name = info->getCodecName(); 695a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber return env->NewStringUTF(name); 705a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber} 715a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber 7293077a2902a74256b7eb4795e1ef92bbc5c50f10Martin Storsjostatic jint android_media_MediaCodecList_findCodecByName( 7393077a2902a74256b7eb4795e1ef92bbc5c50f10Martin Storsjo JNIEnv *env, jobject thiz, jstring name) { 7493077a2902a74256b7eb4795e1ef92bbc5c50f10Martin Storsjo if (name == NULL) { 7593077a2902a74256b7eb4795e1ef92bbc5c50f10Martin Storsjo jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 7693077a2902a74256b7eb4795e1ef92bbc5c50f10Martin Storsjo return -ENOENT; 7793077a2902a74256b7eb4795e1ef92bbc5c50f10Martin Storsjo } 7893077a2902a74256b7eb4795e1ef92bbc5c50f10Martin Storsjo 7993077a2902a74256b7eb4795e1ef92bbc5c50f10Martin Storsjo const char *nameStr = env->GetStringUTFChars(name, NULL); 8093077a2902a74256b7eb4795e1ef92bbc5c50f10Martin Storsjo if (nameStr == NULL) { 8193077a2902a74256b7eb4795e1ef92bbc5c50f10Martin Storsjo // Out of memory exception already pending. 8293077a2902a74256b7eb4795e1ef92bbc5c50f10Martin Storsjo return -ENOENT; 8393077a2902a74256b7eb4795e1ef92bbc5c50f10Martin Storsjo } 8493077a2902a74256b7eb4795e1ef92bbc5c50f10Martin Storsjo 85cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar sp<IMediaCodecList> mcl = getCodecList(env); 86cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar if (mcl == NULL) { 87cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar // Runtime exception already pending. 88018b70f5de79e614fff3297c617e2416dbf34d77Lajos Molnar env->ReleaseStringUTFChars(name, nameStr); 89cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar return -ENOENT; 90cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar } 91cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar 92cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar jint ret = mcl->findCodecByName(nameStr); 9393077a2902a74256b7eb4795e1ef92bbc5c50f10Martin Storsjo env->ReleaseStringUTFChars(name, nameStr); 9493077a2902a74256b7eb4795e1ef92bbc5c50f10Martin Storsjo return ret; 9593077a2902a74256b7eb4795e1ef92bbc5c50f10Martin Storsjo} 9693077a2902a74256b7eb4795e1ef92bbc5c50f10Martin Storsjo 975a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huberstatic jboolean android_media_MediaCodecList_isEncoder( 985a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber JNIEnv *env, jobject thiz, jint index) { 99cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar sp<IMediaCodecList> mcl = getCodecList(env); 100cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar if (mcl == NULL) { 101cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar // Runtime exception already pending. 102cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar return false; 103cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar } 104cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar 105cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar const sp<MediaCodecInfo> &info = mcl->getCodecInfo(index); 106cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar if (info == NULL) { 107cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 108cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar return false; 109cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar } 110cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar 111cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar return info->isEncoder(); 1125a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber} 1135a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber 1145a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huberstatic jarray android_media_MediaCodecList_getSupportedTypes( 1155a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber JNIEnv *env, jobject thiz, jint index) { 116cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar sp<IMediaCodecList> mcl = getCodecList(env); 117cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar if (mcl == NULL) { 118cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar // Runtime exception already pending. 119cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar return NULL; 120cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar } 1215a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber 122cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar const sp<MediaCodecInfo> &info = mcl->getCodecInfo(index); 123cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar if (info == NULL) { 1245a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 1255a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber return NULL; 1265a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber } 1275a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber 128cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar Vector<AString> types; 129cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar info->getSupportedMimes(&types); 130cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar 1315a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber jclass clazz = env->FindClass("java/lang/String"); 1325a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber CHECK(clazz != NULL); 1335a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber 1345a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber jobjectArray array = env->NewObjectArray(types.size(), clazz, NULL); 1355a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber 1365a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber for (size_t i = 0; i < types.size(); ++i) { 1375a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber jstring obj = env->NewStringUTF(types.itemAt(i).c_str()); 1385a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber env->SetObjectArrayElement(array, i, obj); 1395a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber env->DeleteLocalRef(obj); 1405a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber obj = NULL; 1415a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber } 1425a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber 1435a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber return array; 1445a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber} 1455a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber 1465a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huberstatic jobject android_media_MediaCodecList_getCodecCapabilities( 1475a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber JNIEnv *env, jobject thiz, jint index, jstring type) { 1485a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber if (type == NULL) { 1495a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 1505a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber return NULL; 1515a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber } 1525a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber 153cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar sp<IMediaCodecList> mcl = getCodecList(env); 154cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar if (mcl == NULL) { 155cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar // Runtime exception already pending. 156cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar return NULL; 157cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar } 158cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar 159cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar const sp<MediaCodecInfo> &info = mcl->getCodecInfo(index); 160cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar if (info == NULL) { 161cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 162cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar return NULL; 163cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar } 164cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar 1655a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber const char *typeStr = env->GetStringUTFChars(type, NULL); 1665a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber if (typeStr == NULL) { 1675a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber // Out of memory exception already pending. 1685a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber return NULL; 1695a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber } 1705a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber 171cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar Vector<MediaCodecInfo::ProfileLevel> profileLevels; 1725a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber Vector<uint32_t> colorFormats; 173b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 174b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar sp<AMessage> defaultFormat = new AMessage(); 175b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar defaultFormat->setString("mime", typeStr); 176b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 177b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar // TODO query default-format also from codec/codec list 178cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar const sp<MediaCodecInfo::Capabilities> &capabilities = 179cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar info->getCapabilitiesFor(typeStr); 180018b70f5de79e614fff3297c617e2416dbf34d77Lajos Molnar env->ReleaseStringUTFChars(type, typeStr); 181018b70f5de79e614fff3297c617e2416dbf34d77Lajos Molnar typeStr = NULL; 182cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar if (capabilities == NULL) { 1835a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 1845a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber return NULL; 1855a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber } 186cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar 187cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar capabilities->getSupportedColorFormats(&colorFormats); 188cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar capabilities->getSupportedProfileLevels(&profileLevels); 189cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar uint32_t flags = capabilities->getFlags(); 190cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar sp<AMessage> details = capabilities->getDetails(); 191cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar bool isEncoder = info->isEncoder(); 1925a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber 193b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar jobject defaultFormatObj = NULL; 194b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar if (ConvertMessageToMap(env, defaultFormat, &defaultFormatObj)) { 195b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return NULL; 196b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 197b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 198b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar jobject infoObj = NULL; 199cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar if (ConvertMessageToMap(env, details, &infoObj)) { 200b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar env->DeleteLocalRef(defaultFormatObj); 201b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return NULL; 202b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 203b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 2045a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber jclass capsClazz = 20560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber env->FindClass("android/media/MediaCodecInfo$CodecCapabilities"); 2065a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber CHECK(capsClazz != NULL); 2075a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber 2085a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber jclass profileLevelClazz = 20960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber env->FindClass("android/media/MediaCodecInfo$CodecProfileLevel"); 2105a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber CHECK(profileLevelClazz != NULL); 2115a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber 2125a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber jobjectArray profileLevelArray = 2135a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber env->NewObjectArray(profileLevels.size(), profileLevelClazz, NULL); 2145a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber 2155a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber jfieldID profileField = 21607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber env->GetFieldID(profileLevelClazz, "profile", "I"); 2175a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber 2185a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber jfieldID levelField = 21907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber env->GetFieldID(profileLevelClazz, "level", "I"); 2205a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber 2215a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber for (size_t i = 0; i < profileLevels.size(); ++i) { 222cd5e3f95bfcc6039aa048b7f3141f265de02d114Lajos Molnar const MediaCodecInfo::ProfileLevel &src = profileLevels.itemAt(i); 2235a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber 2245a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber jobject profileLevelObj = env->AllocObject(profileLevelClazz); 2255a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber 2265a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber env->SetIntField(profileLevelObj, profileField, src.mProfile); 2275a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber env->SetIntField(profileLevelObj, levelField, src.mLevel); 2285a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber 2295a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber env->SetObjectArrayElement(profileLevelArray, i, profileLevelObj); 2305a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber 2315a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber env->DeleteLocalRef(profileLevelObj); 2325a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber profileLevelObj = NULL; 2335a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber } 2345a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber 235b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar jintArray colorFormatsArray = env->NewIntArray(colorFormats.size()); 236b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 237b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar for (size_t i = 0; i < colorFormats.size(); ++i) { 238b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar jint val = colorFormats.itemAt(i); 239b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar env->SetIntArrayRegion(colorFormatsArray, i, 1, &val); 240b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 241b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 242b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar jmethodID capsConstructID = env->GetMethodID(capsClazz, "<init>", 243b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar "([Landroid/media/MediaCodecInfo$CodecProfileLevel;[IZI" 244b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar "Ljava/util/Map;Ljava/util/Map;)V"); 245b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 246b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar jobject caps = env->NewObject(capsClazz, capsConstructID, 247b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar profileLevelArray, colorFormatsArray, isEncoder, flags, 248b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar defaultFormatObj, infoObj); 249b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 250b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar env->DeleteLocalRef(profileLevelArray); 251b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar profileLevelArray = NULL; 252b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 2535a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber env->DeleteLocalRef(colorFormatsArray); 2545a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber colorFormatsArray = NULL; 2555a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber 256b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar env->DeleteLocalRef(defaultFormatObj); 257b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar defaultFormatObj = NULL; 258b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 259b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar env->DeleteLocalRef(infoObj); 260b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar infoObj = NULL; 261b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 2625a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber return caps; 2635a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber} 2645a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber 2655a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huberstatic void android_media_MediaCodecList_native_init(JNIEnv *env) { 2665a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber} 2675a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber 2685a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huberstatic JNINativeMethod gMethods[] = { 269b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar { "native_getCodecCount", "()I", (void *)android_media_MediaCodecList_getCodecCount }, 2705a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber { "getCodecName", "(I)Ljava/lang/String;", 2715a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber (void *)android_media_MediaCodecList_getCodecName }, 2725a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber { "isEncoder", "(I)Z", (void *)android_media_MediaCodecList_isEncoder }, 2735a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber { "getSupportedTypes", "(I)[Ljava/lang/String;", 2745a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber (void *)android_media_MediaCodecList_getSupportedTypes }, 2755a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber 2765a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber { "getCodecCapabilities", 27760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber "(ILjava/lang/String;)Landroid/media/MediaCodecInfo$CodecCapabilities;", 2785a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber (void *)android_media_MediaCodecList_getCodecCapabilities }, 2795a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber 28093077a2902a74256b7eb4795e1ef92bbc5c50f10Martin Storsjo { "findCodecByName", "(Ljava/lang/String;)I", 28193077a2902a74256b7eb4795e1ef92bbc5c50f10Martin Storsjo (void *)android_media_MediaCodecList_findCodecByName }, 28293077a2902a74256b7eb4795e1ef92bbc5c50f10Martin Storsjo 2835a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber { "native_init", "()V", (void *)android_media_MediaCodecList_native_init }, 2845a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber}; 2855a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber 2865a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huberint register_android_media_MediaCodecList(JNIEnv *env) { 2875a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber return AndroidRuntime::registerNativeMethods(env, 2885a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber "android/media/MediaCodecList", gMethods, NELEM(gMethods)); 2895a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber} 2905a04bf395514a9342dd26af519b88f4b3e309eb9Andreas Huber 291