Skip to content

Commit 5a04bf3

Browse files
committed
New API to query available codecs and their capabilities.
Change-Id: I448ba443a96d8fee2bc9179750d57362ed31d9d9
1 parent 0424716 commit 5a04bf3

File tree

4 files changed

+248
-0
lines changed

4 files changed

+248
-0
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright (C) 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+
package android.media;
18+
19+
/**
20+
* MediaCodecList class can be used to enumerate available codecs,
21+
* find a codec supporting a given format and query the capabilities
22+
* of a given codec.
23+
* @hide
24+
*/
25+
final public class MediaCodecList {
26+
public static native final int countCodecs();
27+
public static native final String getCodecName(int index);
28+
public static native final boolean isEncoder(int index);
29+
public static native final String[] getSupportedTypes(int index);
30+
31+
public static final class CodecProfileLevel {
32+
public int mProfile;
33+
public int mLevel;
34+
};
35+
36+
public static final class CodecCapabilities {
37+
public CodecProfileLevel[] mProfileLevels;
38+
public int[] mColorFormats;
39+
};
40+
public static native final CodecCapabilities getCodecCapabilities(
41+
int index, String type);
42+
43+
private static native final void native_init();
44+
45+
private MediaCodecList() {}
46+
47+
static {
48+
System.loadLibrary("media_jni");
49+
native_init();
50+
}
51+
}

media/jni/Android.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ include $(CLEAR_VARS)
33

44
LOCAL_SRC_FILES:= \
55
android_media_MediaCodec.cpp \
6+
android_media_MediaCodecList.cpp \
67
android_media_MediaExtractor.cpp \
78
android_media_MediaPlayer.cpp \
89
android_media_MediaRecorder.cpp \
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
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+
28+
using namespace android;
29+
30+
static jint android_media_MediaCodecList_countCodecs(
31+
JNIEnv *env, jobject thiz) {
32+
return MediaCodecList::getInstance()->countCodecs();
33+
}
34+
35+
static 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+
47+
static jboolean android_media_MediaCodecList_isEncoder(
48+
JNIEnv *env, jobject thiz, jint index) {
49+
return MediaCodecList::getInstance()->isEncoder(index);
50+
}
51+
52+
static jarray android_media_MediaCodecList_getSupportedTypes(
53+
JNIEnv *env, jobject thiz, jint index) {
54+
Vector<AString> types;
55+
status_t err =
56+
MediaCodecList::getInstance()->getSupportedTypes(index, &types);
57+
58+
if (err != OK) {
59+
jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
60+
return NULL;
61+
}
62+
63+
jclass clazz = env->FindClass("java/lang/String");
64+
CHECK(clazz != NULL);
65+
66+
jobjectArray array = env->NewObjectArray(types.size(), clazz, NULL);
67+
68+
for (size_t i = 0; i < types.size(); ++i) {
69+
jstring obj = env->NewStringUTF(types.itemAt(i).c_str());
70+
env->SetObjectArrayElement(array, i, obj);
71+
env->DeleteLocalRef(obj);
72+
obj = NULL;
73+
}
74+
75+
return array;
76+
}
77+
78+
static jobject android_media_MediaCodecList_getCodecCapabilities(
79+
JNIEnv *env, jobject thiz, jint index, jstring type) {
80+
if (type == NULL) {
81+
jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
82+
return NULL;
83+
}
84+
85+
const char *typeStr = env->GetStringUTFChars(type, NULL);
86+
87+
if (typeStr == NULL) {
88+
// Out of memory exception already pending.
89+
return NULL;
90+
}
91+
92+
Vector<MediaCodecList::ProfileLevel> profileLevels;
93+
Vector<uint32_t> colorFormats;
94+
95+
status_t err =
96+
MediaCodecList::getInstance()->getCodecCapabilities(
97+
index, typeStr, &profileLevels, &colorFormats);
98+
99+
env->ReleaseStringUTFChars(type, typeStr);
100+
typeStr = NULL;
101+
102+
if (err != OK) {
103+
jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
104+
return NULL;
105+
}
106+
107+
jclass capsClazz =
108+
env->FindClass("android/media/MediaCodecList$CodecCapabilities");
109+
CHECK(capsClazz != NULL);
110+
111+
jobject caps = env->AllocObject(capsClazz);
112+
113+
jclass profileLevelClazz =
114+
env->FindClass("android/media/MediaCodecList$CodecProfileLevel");
115+
CHECK(profileLevelClazz != NULL);
116+
117+
jobjectArray profileLevelArray =
118+
env->NewObjectArray(profileLevels.size(), profileLevelClazz, NULL);
119+
120+
jfieldID profileField =
121+
env->GetFieldID(profileLevelClazz, "mProfile", "I");
122+
123+
jfieldID levelField =
124+
env->GetFieldID(profileLevelClazz, "mLevel", "I");
125+
126+
for (size_t i = 0; i < profileLevels.size(); ++i) {
127+
const MediaCodecList::ProfileLevel &src = profileLevels.itemAt(i);
128+
129+
jobject profileLevelObj = env->AllocObject(profileLevelClazz);
130+
131+
env->SetIntField(profileLevelObj, profileField, src.mProfile);
132+
env->SetIntField(profileLevelObj, levelField, src.mLevel);
133+
134+
env->SetObjectArrayElement(profileLevelArray, i, profileLevelObj);
135+
136+
env->DeleteLocalRef(profileLevelObj);
137+
profileLevelObj = NULL;
138+
}
139+
140+
jfieldID profileLevelsField = env->GetFieldID(
141+
capsClazz,
142+
"mProfileLevels",
143+
"[Landroid/media/MediaCodecList$CodecProfileLevel;");
144+
145+
env->SetObjectField(caps, profileLevelsField, profileLevelArray);
146+
147+
env->DeleteLocalRef(profileLevelArray);
148+
profileLevelArray = NULL;
149+
150+
jintArray colorFormatsArray = env->NewIntArray(colorFormats.size());
151+
152+
for (size_t i = 0; i < colorFormats.size(); ++i) {
153+
jint val = colorFormats.itemAt(i);
154+
env->SetIntArrayRegion(colorFormatsArray, i, 1, &val);
155+
}
156+
157+
jfieldID colorFormatsField = env->GetFieldID(
158+
capsClazz, "mColorFormats", "[I");
159+
160+
env->SetObjectField(caps, colorFormatsField, colorFormatsArray);
161+
162+
env->DeleteLocalRef(colorFormatsArray);
163+
colorFormatsArray = NULL;
164+
165+
return caps;
166+
}
167+
168+
static void android_media_MediaCodecList_native_init(JNIEnv *env) {
169+
}
170+
171+
static JNINativeMethod gMethods[] = {
172+
{ "countCodecs", "()I", (void *)android_media_MediaCodecList_countCodecs },
173+
{ "getCodecName", "(I)Ljava/lang/String;",
174+
(void *)android_media_MediaCodecList_getCodecName },
175+
{ "isEncoder", "(I)Z", (void *)android_media_MediaCodecList_isEncoder },
176+
{ "getSupportedTypes", "(I)[Ljava/lang/String;",
177+
(void *)android_media_MediaCodecList_getSupportedTypes },
178+
179+
{ "getCodecCapabilities",
180+
"(ILjava/lang/String;)Landroid/media/MediaCodecList$CodecCapabilities;",
181+
(void *)android_media_MediaCodecList_getCodecCapabilities },
182+
183+
{ "native_init", "()V", (void *)android_media_MediaCodecList_native_init },
184+
};
185+
186+
int register_android_media_MediaCodecList(JNIEnv *env) {
187+
return AndroidRuntime::registerNativeMethods(env,
188+
"android/media/MediaCodecList", gMethods, NELEM(gMethods));
189+
}
190+

media/jni/android_media_MediaPlayer.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -881,6 +881,7 @@ static int register_android_media_MediaPlayer(JNIEnv *env)
881881

882882
extern int register_android_media_MediaCodec(JNIEnv *env);
883883
extern int register_android_media_MediaExtractor(JNIEnv *env);
884+
extern int register_android_media_MediaCodecList(JNIEnv *env);
884885
extern int register_android_media_MediaMetadataRetriever(JNIEnv *env);
885886
extern int register_android_media_MediaRecorder(JNIEnv *env);
886887
extern int register_android_media_MediaScanner(JNIEnv *env);
@@ -962,6 +963,11 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved)
962963
goto bail;
963964
}
964965

966+
if (register_android_media_MediaCodecList(env) < 0) {
967+
ALOGE("ERROR: MediaCodec native registration failed");
968+
goto bail;
969+
}
970+
965971
/* success -- return valid version number */
966972
result = JNI_VERSION_1_4;
967973

0 commit comments

Comments
 (0)