[英]How MediaCodec finds the codec inside the framework in Android?
我試圖了解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
}
我很震驚這個流程。 如果有人指出如何推進它將會有很大幫助。
謝謝。
讓我們一步一步走。
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
,否則創建MediaCodecList
的新對象 。
在MediaCodecList
的構造函數中,調用parseXMLFile
,文件名為/etc/media_codecs.xml
。
parseXMLFile
讀取內容並將不同的組件名稱等存儲到MediaCodecList
, MediaCodecList
也可用於任何其他編解碼器實例。 用於解析的輔助函數是startElementHandler
。 感興趣的功能可以是addMediaCodec
。
通過這些步驟, XML
文件內容被轉換為可由任何其他模塊使用的列表。 MediaCodecList
也在Java層公開,可以從這里引用。
我已經跳過了一些跳,其中MediaCodec
和ACodec
使用消息來實際通信和調用方法,但所提供的流程應該對底層機制有一個很好的了解。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.