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

时间:2014-04-04 08:08:18

标签: android android-internet stagefright openmax opencore

我试图了解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
    }

我很震惊这个流程。如果有人指出如何推进它将会有很大帮助。

感谢。

1 个答案:

答案 0 :(得分:12)

让我们一步一步走。

  1. MediaCodec::CreateByType将创建一个新的MediaCodec对象

  2. MediaCodec构造函数会创建一个新的ACodec对象并将其存储为mCodec

  3. 调用MediaCodec::init时,它会在内部指示基础ACodec通过mCodec->initiateAllocateComponent分配OMX组件。

  4. ACodec::initiateAllocateComponent会调用onAllocateComponent

  5. ACodec::UninitializedState::onAllocateComponent会调用OMXCodec::findMatchingCodecs来查找与来自调用方传递的MIME类型匹配的编解码器。

  6. OMXCodec::findMatchingCodecs中,有一个调用将MediaCodecList的实例检索为MediaCodecList::getInstance()

  7. MediaCodecList::getInstance中,检查是否存在MediaCodecLista new object of MediaCodecList is created

  8. MediaCodecList的构造函数中,调用parseXMLFile,文件名为/etc/media_codecs.xml

  9. parseXMLFile读取内容并将不同的组件名称等存储到MediaCodecList中,这也可以用于任何其他编解码器实例。用于解析的辅助函数是startElementHandler。感兴趣的功能可以是addMediaCodec

  10. 通过这些步骤,XML文件内容被转换为可供任何其他模块使用的列表。 MediaCodecList也会在 Java 层公开,可以从here引用。

    我跳过了一些跳,其中MediaCodecACodec使用消息来实际通信并调用方法,但所提供的流程应该对基本机制有一个很好的了解。