191 lines
5.9 KiB
C++
191 lines
5.9 KiB
C++
/*
|
|
* 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_getCodecCount(
|
|
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/MediaCodecInfo$CodecCapabilities");
|
|
CHECK(capsClazz != NULL);
|
|
|
|
jobject caps = env->AllocObject(capsClazz);
|
|
|
|
jclass profileLevelClazz =
|
|
env->FindClass("android/media/MediaCodecInfo$CodecProfileLevel");
|
|
CHECK(profileLevelClazz != NULL);
|
|
|
|
jobjectArray profileLevelArray =
|
|
env->NewObjectArray(profileLevels.size(), profileLevelClazz, NULL);
|
|
|
|
jfieldID profileField =
|
|
env->GetFieldID(profileLevelClazz, "profile", "I");
|
|
|
|
jfieldID levelField =
|
|
env->GetFieldID(profileLevelClazz, "level", "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,
|
|
"profileLevels",
|
|
"[Landroid/media/MediaCodecInfo$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, "colorFormats", "[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[] = {
|
|
{ "getCodecCount", "()I", (void *)android_media_MediaCodecList_getCodecCount },
|
|
{ "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/MediaCodecInfo$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));
|
|
}
|
|
|