简体   繁体   English

MediaCodec如何在Android框架内找到编解码器?

[英]How MediaCodec finds the codec inside the framework in Android?

I am trying to understanding how MediaCodec is used for hardware decoding. 我试图了解MediaCodec如何用于硬件解码。

My knowledge in android internal is very limited. 我在android内部的知识非常有限。

Here is my findings: 以下是我的发现:

There is a xml file which represents the codec details in the android system . 有一个xml文件,代表android系统中的编解码器细节。

 device/ti/omap3evm/media_codecs.xml for an example. 

Which means, that If we create a codec from the Java Application with Media Codec 这意味着,如果我们使用Media Codec从Java Application创建编解码器

MediaCodec codec = MediaCodec.createDecoderByType(type);

It should be finding out respective coder with the help of xml file. 应该在xml文件的帮助下找出各自的编码器。

What am I doing? 我在做什么?

I am trying to figure our which part of the code is reading xml and find the codec based on given 'type'. 我试图找出代码的哪一部分正在读取xml并根据给定的'type'找到编解码器。

1) Application Layer : 1)应用层:

   MediaCodec codec = MediaCodec.createDecoderByType(type);

2) MediaCodec.java -> [ frameworks/base/media/java/android/media/MediaCodec.java ] 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) 3)

private MediaCodec(
        String name, boolean nameIsType, boolean encoder) {
    native_setup(name, nameIsType, encoder);    --> JNI Call.
}

4) JNI Implementation -> [ frameworks/base/media/jni/android_media_MediaCodec.cpp ] 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
}

from frameworks/base/media/jni/android_media_MediaCodec.cpp 来自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
    }

I am struck with this flow. 我很震惊这个流程。 If someone points out how to take it forward would help a lot. 如果有人指出如何推进它将会有很大帮助。

thanks. 谢谢。

Let's take the flow step by step. 让我们一步一步走。

  1. MediaCodec::CreateByType will create a new MediaCodec object MediaCodec::CreateByType将创建一个新的MediaCodec对象

  2. MediaCodec constructor would create a new ACodec object and store it as mCodec MediaCodec构造函数将创建一个新的ACodec对象并将其存储为mCodec

  3. When MediaCodec::init is invoked, it internally instructs the underlying ACodec to allocate the OMX component through mCodec->initiateAllocateComponent . 当调用MediaCodec::init ,它在内部指示底层ACodec通过mCodec->initiateAllocateComponent分配OMX组件。

  4. ACodec::initiateAllocateComponent would invoke onAllocateComponent ACodec::initiateAllocateComponent将调用onAllocateComponent

  5. ACodec::UninitializedState::onAllocateComponent would invoke OMXCodec::findMatchingCodecs to find the codecs matching the MIME type passed from the caller. ACodec::UninitializedState::onAllocateComponent将调用OMXCodec::findMatchingCodecs来查找与从调用者传递的MIME类型匹配的编解码器。

  6. In OMXCodec::findMatchingCodecs , there is a call to retrieve an instance of MediaCodecList as MediaCodecList::getInstance() . OMXCodec::findMatchingCodecs ,有一个调用将MediaCodecList的实例检索为MediaCodecList::getInstance()

  7. In MediaCodecList::getInstance , there is a check if there is an existing MediaCodecList or else a new object of MediaCodecList is created . MediaCodecList::getInstance ,检查是否存在现有MediaCodecList ,否则创建MediaCodecList的新对象

  8. In the constructor of MediaCodecList , there is a call to parseXMLFile with the file name as /etc/media_codecs.xml . MediaCodecList的构造函数中,调用parseXMLFile ,文件名为/etc/media_codecs.xml

  9. parseXMLFile reads the contents and stores the different component names etc into MediaCodecList which can be used for any other codec instance too. parseXMLFile读取内容并将不同的组件名称等存储到MediaCodecListMediaCodecList也可用于任何其他编解码器实例。 The helper function employed for the parsing is startElementHandler . 用于解析的辅助函数是startElementHandler A function of interest could be addMediaCodec . 感兴趣的功能可以是addMediaCodec

Through these steps, the XML file contents are translated into a list which can be employed by any other module. 通过这些步骤, XML文件内容被转换为可由任何其他模块使用的列表。 MediaCodecList is exposed at Java layer too as can be referred from here . MediaCodecList也在Java层公开,可以从这里引用。

I have skipped a few hops wherein MediaCodec and ACodec employ messages to actually communicate and invoke methods, but the flow presented should give a good idea about the underlying mechanism. 我已经跳过了一些跳,其中MediaCodecACodec使用消息来实际通信和调用方法,但所提供的流程应该对底层机制有一个很好的了解。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM