MediaCodec如何在Android框架内找到编解码器? [英] How MediaCodec finds the codec inside the framework in Android?

查看:1188
本文介绍了MediaCodec如何在Android框架内找到编解码器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图了解MediaCodec如何用于硬件解码。

I am trying to understanding how MediaCodec is used for hardware decoding.

我在android内部的知识非常有限。

My knowledge in android internal is very limited.

这是我的发现:

有一个xml文件代表android系统中的编解码器详细信息。

There is a xml file which represents the codec details in the android system .

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

这意味着,如果我们使用带媒体编解码器的Java应用程序创建编解码器

Which means, that If we create a codec from the Java Application with Media Codec

MediaCodec codec = MediaCodec.createDecoderByType(type);

应该在xml文件的帮助下找到相应的编码器。

It should be finding out respective coder with the help of xml file.

我在做什么?

我正在尝试弄清楚我们的哪一部分的代码是读取xml并根据给定的类型查找编解码器。

I am trying to figure our which part of the code is reading xml and find the codec based on given 'type'.

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)

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
}

from frameworks / base / media / jni / android_media_MediaCodec.cpp

from 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.

谢谢。

推荐答案

让我们逐步进行流程。


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

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

MediaCodec constructor would create a new ACodec object and store it as mCodec

MediaCodec :: init 被调用,它在内部指示底层 ACodec 通过OMX 组件androidxref.com/4.4.2_r2/xref/frameworks/av/media/libstagefright/MediaCodec.cpp#947> mCodec-> initiateAllocateComponent

When MediaCodec::init is invoked, it internally instructs the underlying ACodec to allocate the OMX component through mCodec->initiateAllocateComponent.

ACodec :: initiateAllocateComponent 将调用 onAllocateComponent

ACodec :: UninitializedState :: onAllocateComponent 将调用 OMXCodec :: findMatchingCodecs 查找编解码器匹配从调用方传递的 MIME 类型。

ACodec::UninitializedState::onAllocateComponent would invoke OMXCodec::findMatchingCodecs to find the codecs matching the MIME type passed from the caller.

OMXCodec ::中: findMatchingCodecs ,可以调用 MediaCodecList 实例作为 MediaCodecList :: getInstance()

In OMXCodec::findMatchingCodecs, there is a call to retrieve an instance of MediaCodecList as MediaCodecList::getInstance().

MediaCodecList :: getInstance 中,检查是否存在现有的 MediaCodecList MediaCodecList 已创建

In MediaCodecList::getInstance, there is a check if there is an existing MediaCodecList or else a new object of MediaCodecList is created.

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

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

parseXMLFile reads the contents and stores the different component names etc into MediaCodecList which can be used for any other codec instance too. The helper function employed for the parsing is startElementHandler . A function of interest could be addMediaCodec.

通过这些步骤, XML 文件内容将转换为列表,任何其他模块都可以使用该列表。 MediaCodecList 也在 Java 层公开,也可以从此处

Through these steps, the XML file contents are translated into a list which can be employed by any other module. MediaCodecList is exposed at Java layer too as can be referred from here.

我跳过了几步,其中 MediaCodec ACodec 使用消息进行实际的通信和调用方法,但是提供的流程应该对底层机制有一个很好的了解。

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.

这篇关于MediaCodec如何在Android框架内找到编解码器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆