我试图了解MediaCodec如何用于硬件解码。
我在android内部的知识非常有限。
以下是我的发现:
有一个xml文件代表android系统中的编解码器详细信息。
device/ti/omap3evm/media_codecs.xml for an example.
这意味着,如果我们使用Media Codec从Java Application创建编解码器
MediaCodec codec = MediaCodec.createDecoderByType(type);
应该在xml文件的帮助下找出各自的编码器。
我在做什么?
我试图找出代码的哪一部分正在读取xml并根据给定的'type'找到编解码器。
1)应用层:
MediaCodec codec = MediaCodec.createDecoderByType(type);
2)MediaCodec.java - > [ frameworks / base / media / java / android / media / MediaCodec.java ]
public static MediaCodec createDecoderByType(String type) {
return new MediaCodec(type, true /* nameIsType */, false /* encoder */);
}
3)
private MediaCodec(
String name, boolean nameIsType, boolean encoder) {
native_setup(name, nameIsType, encoder); --> JNI Call.
}
4) JNI实施 - > [ frameworks / base / media / jni / android_media_MediaCodec.cpp ]
static void android_media_MediaCodec_native_setup (..) {
.......
const char *tmp = env->GetStringUTFChars(name, NULL);
sp<JMediaCodec> codec = new JMediaCodec(env, thiz, tmp, nameIsType, encoder); ---> Here
}
来自frameworks / base / media / jni / android_media_MediaCodec.cpp
JMediaCodec::JMediaCodec( ..) {
....
mCodec = MediaCodec::CreateByType(mLooper, name, encoder); //Call goes to libstagefright
.... }
sp<MediaCodec> MediaCodec::CreateByType(
const sp<ALooper> &looper, const char *mime, bool encoder) {
sp<MediaCodec> codec = new MediaCodec(looper);
if (codec->init(mime, true /* nameIsType */, encoder) != OK) { --> HERE.
return NULL;
}
return codec;
}
status_t MediaCodec::init(const char *name, bool nameIsType, bool encoder) {
// MediaCodec
}
我很震惊这个流程。如果有人指出如何推进它将会有很大帮助。
感谢。
答案 0 :(得分:12)
让我们一步一步走。
MediaCodec::CreateByType
将创建一个新的MediaCodec
对象
MediaCodec
构造函数会创建一个新的ACodec
对象并将其存储为mCodec
调用MediaCodec::init
时,它会在内部指示基础ACodec
通过mCodec->initiateAllocateComponent
分配OMX
组件。
ACodec::initiateAllocateComponent
会调用onAllocateComponent
ACodec::UninitializedState::onAllocateComponent
会调用OMXCodec::findMatchingCodecs
来查找与来自调用方传递的MIME
类型匹配的编解码器。
在OMXCodec::findMatchingCodecs
中,有一个调用将MediaCodecList
的实例检索为MediaCodecList::getInstance()
。
在MediaCodecList::getInstance
中,检查是否存在MediaCodecList
或a new object of MediaCodecList
is created。
在MediaCodecList
的构造函数中,调用parseXMLFile
,文件名为/etc/media_codecs.xml
。
parseXMLFile
读取内容并将不同的组件名称等存储到MediaCodecList
中,这也可以用于任何其他编解码器实例。用于解析的辅助函数是startElementHandler
。感兴趣的功能可以是addMediaCodec
。
通过这些步骤,XML
文件内容被转换为可供任何其他模块使用的列表。 MediaCodecList
也会在 Java 层公开,可以从here引用。
我跳过了一些跳,其中MediaCodec
和ACodec
使用消息来实际通信并调用方法,但所提供的流程应该对基本机制有一个很好的了解。