Android4.2.2下Stagefright下OMX编解码器组件的控制流

本文均属自己阅读源代码的点滴总结。转账请注明出处谢谢。

欢迎和大家交流。

qq:1037701636 email:[email protected]

Android源代码版本号Version:4.2.2; 硬件平台 全志A31

之所以单独把这块内容提炼出来,在于其具备的一定的层次性,结构上具备统一性,API函数的设计须要实现OMX架构独有的接口。

1. 在上一博文Android4.2.2下Stagefright多媒体架构中的A31的OMX插件和Codec组件中我们提到。通过Binder架构,在MPS的线程上创建完一个实际的编解码器节点后,获取到了一个node:node_id。例如以下所看到的将会依据相关的节点信息,创建一个MPS側的OMXCodec结构体,作为相似本地的一个编解码器。

.....
    sp<OMXCodec> codec = new OMXCodec(
                    omx, node, quirks, flags,
                    createEncoder, mime, componentName,
                    source, nativeWindow);//创建一个本地OMXCodec解码器。node成为兴许的操作的关键IOMX::node_id
//omx为Master
            observer->setCodec(codec);//将解码器交给observer

            err = codec->configureCodec(meta);//依据数据源配置本地的这个解码器
........

在configureCodec对这个解码器的配置中。我们能够看到一些对之前分配的解码器节点的控制操作。

我们以它当中的一个函数调用为例,进行控制流的层层分析:

 setVideoOutputFormat(mMIME, meta);//设置视频输出格式
mOMX->getParameter(mNode, OMX_IndexParamPortDefinition, &def, sizeof(def))

这里看到mOMX是在创建AwesomePlayer时获取的一个匿名的BpOMX对象。

终于的实如今MediaPlayerService中的中的OMX对象来实现getParameter。

2.OMX对象下的操作。

status_t OMX::getParameter(
        node_id node, OMX_INDEXTYPE index,
        void *params, size_t size) {
    return findInstance(node)->getParameter(
            index, params, size);
}

findInstance(node)这里就是依据这个node_id来获取之前注冊的一个OMXNodeInstance对象实例:

OMXNodeInstance *OMX::findInstance(node_id node) {
    Mutex::Autolock autoLock(mLock);

    ssize_t index = mNodeIDToInstance.indexOfKey(node);

    return index < 0 ? NULL : mNodeIDToInstance.valueAt(index);
}

终于就变成了例如以下的调用:

status_t OMXNodeInstance::setParameter(
        OMX_INDEXTYPE index, const void *params, size_t size) {
    Mutex::Autolock autoLock(mLock);

    OMX_ERRORTYPE err = OMX_SetParameter(
            mHandle, index, const_cast<void *>(params));

    return StatusFromOMXError(err);
}

3.OMX_XXX的实现

#define OMX_GetParameter(                                           hComponent,                                                 nParamIndex,                                                ComponentParameterStructure)                            ((OMX_COMPONENTTYPE*)hComponent)->GetParameter(                 hComponent,                                                 nParamIndex,                                                ComponentParameterStructure)    /* Macro End */

OMX_SetParameter等宏函数是OMX_CORE的核心所在。也是原来OpenOMx里的OMX IL层的体现。来看mHandle的类型,作为一个OMXNodeInstance对象的成员变量。他维护着之前makeComponentInstance返回的一个对底层编解码组件库的句柄。这里看上去就是一个OMX节点实例,一个句柄可操作最下层的解码组件。能够看到handle转为OMX_COMPONENTTYPE类型。

里看看其的结构体类型:

typedef struct OMX_COMPONENTTYPE
{
    OMX_U32 nSize;

    OMX_VERSIONTYPE nVersion;

    OMX_COMPONENTNAMETYPE eCompName;

    OMX_PTR pComponentPrivate;

    OMX_ERRORTYPE (*GetParameter)(
            OMX_IN  OMX_HANDLETYPE hComponent,
            OMX_IN  OMX_INDEXTYPE nIndex,
            OMX_IN  OMX_PTR ComponentParameterStructure);...............

这个handle的获取是在之前创建解码器节点时完毕的,通过须要创建的解码器的name,通过OMX插件库,再进入到libOmxCore.so(OMX IL固有结构)调用OMX_GetHandle来获取相应组件name下的平台解码库libOmxVdec.so。或者libOmxVenc.so等。

这个handle通过下面完毕初始化:

void* aw_omx_create_component_wrapper(OMX_PTR obj_ptr)
{
    aw_omx_component *pThis        = (aw_omx_component *)obj_ptr;//omx_vdec对象
    OMX_COMPONENTTYPE* component   = &(pThis->m_cmp);//对m_cmp进行初始化
    memset(&pThis->m_cmp,0,sizeof(OMX_COMPONENTTYPE));

    component->nSize               = sizeof(OMX_COMPONENTTYPE);
    component->nVersion.nVersion   = OMX_SPEC_VERSION;
    component->pApplicationPrivate = 0;
    component->pComponentPrivate   = obj_ptr;//保存着omx_vdec这个对象

    component->AllocateBuffer      = &aw_omx_component_allocate_buffer;
    component->FreeBuffer          = &aw_omx_component_free_buffer;
    component->GetParameter        = &aw_omx_component_get_parameter;
    component->SetParameter        = &aw_omx_component_set_parameter;
    component->SendCommand         = &aw_omx_component_send_command;
    component->FillThisBuffer      = &aw_omx_component_fill_this_buffer;
    component->EmptyThisBuffer     = &aw_omx_component_empty_this_buffer;
    component->GetState            = &aw_omx_component_get_state;
    component->GetComponentVersion = &aw_omx_component_get_version;
    component->GetConfig           = &aw_omx_component_get_config;
    component->SetConfig           = &aw_omx_component_set_config;
    component->GetExtensionIndex   = &aw_omx_component_get_extension_index;
    component->ComponentTunnelRequest = &aw_omx_component_tunnel_request;
    component->UseBuffer           = &aw_omx_component_use_buffer;
    component->SetCallbacks        = &aw_omx_component_set_callbacks;
    component->UseEGLImage         = &aw_omx_component_use_EGL_image;
    component->ComponentRoleEnum   = &aw_omx_component_role_enum;
    component->ComponentDeInit     = &aw_omx_component_deinit;
    return (void *)component;
}

通过以上的赋值操作,我们关注这个component->pComponentPrivate   = obj_ptr,他是将硬件平台的解码器实例维护到handle结构体中。由于终于的操作肯定都要回到最底层的解码器控制。

这也就是OMX IL的架构给予了开发人员的方便性和规划化。通过这个我们就能够总结出须要下面几个文件来衔接更底层的编解码器:

xxx_omx_core.c和omx_core_cmp.c两个源文件来完毕。前者提供向上的接口用于创建编解码器实例。后者提供比如上述的xxx_omx_component_api接口的实现,而实际事实上现是调用的是编解码的相关API来处理:

OMX_ERRORTYPE aw_omx_component_get_parameter(OMX_IN OMX_HANDLETYPE     hComp,
                                             OMX_IN OMX_INDEXTYPE paramIndex,
                                             OMX_INOUT OMX_PTR     paramData)
{
	OMX_ERRORTYPE eRet = OMX_ErrorBadParameter;
	aw_omx_component *pThis = (hComp)? (aw_omx_component *)(((OMX_COMPONENTTYPE *)hComp)->pComponentPrivate):NULL;
	DEBUG_PRINT("OMXCORE: aw_omx_component_get_parameter %x, %x , %d\n",(unsigned)hComp,(unsigned)paramData,paramIndex);

	if(pThis)
	{
		eRet = pThis->get_parameter(hComp,paramIndex,paramData);
	}

	return eRet;
}

这里的pThis技术当前最底层的解码器组件的控制入口。即所谓的aw_omx_component的派生类对象。

这样也就是说明了我们自己要构建的编解码须要实aw_omx_component的相关接口函数,能够看到这里我们最底层的解码器组件就是对这些函数的实现,加快了自己定义一个新的组件类型,下面是几个接口的定义和实现:

OMX_ERRORTYPE  omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp, OMX_IN OMX_INDEXTYPE paramIndex,  OMX_IN OMX_PTR paramData)
OMX_ERRORTYPE  omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp,
                                       OMX_IN OMX_INDEXTYPE  paramIndex,
                                       OMX_INOUT OMX_PTR     paramData)

到这里我们基本走通了从OMXCodec到对最底层的编解码器组件的控制,层次分明。接口规范带给我们的是高速开发,我们须要做的核心是在自己的编解码器组件中实现相关的业务,而这和自身的硬件平台具有紧密性。

4.总结新建一个属于stagefright下OMX的编解码组件须要做的事情

我们所要做的核心工作就在libOmxCore.so和libOmxVdec.so这两个库文件的设计。

但都须要符合OMX的协议就可以。


分析了那么多的控制流,也已经有了所谓的OMXCodec,那么兴许主要内容将是数据流的处理。

时间: 2024-10-09 02:34:20

Android4.2.2下Stagefright下OMX编解码器组件的控制流的相关文章

Android4.2.2下Stagefright多媒体架构中的A31的OMX插件和Codec组件

本文均属自己阅读源码的点滴总结,转账请注明出处谢谢. 欢迎和大家交流.qq:1037701636 email: [email protected] 在前面的博文中提到,AwesomePlayer::onPrepareAsyncEvent()开始进行Codec解码器组件的获取以及创建,这里和大家分享. 1.以解码器实例作为切入点 status_t AwesomePlayer::initVideoDecoder(uint32_t flags) { ATRACE_CALL(); ...... ALOG

Android4.2.2的Stagefright中编解码器数据流的维护

本文均属自己阅读源码的点滴总结,转账请注明出处谢谢. 欢迎和大家交流.qq:1037701636 email:[email protected] Android源码版本Version:4.2.2; 硬件平台 全志A31 前沿: 在前面的博文中,基本提到的是stagefright相关的控制流,具体分析了android架构中的MediaExtractor.AwesomePlayer.StagefrightPlayer.OMXCodec等的创建,底层OMXNodinstance实例的创建.分析了OMX

Tomcat下conf下server.xml的文件配置信息

Tomcat下conf下server.xml的文件配置信息,基本上不用做任何修改就可以使用,修改的地方就是host区域的一些配置,此文件设置端口为80. 注意:Tomcat配置文件中(即server.xml文件)不能出现中文,否则服务是无法启动的. [xhtml] view plaincopy <!-- Server中的port监听关闭tomcat的请求,shutdown指定向端口发送的命令串--> <Server port="8005" shutdown="

最近遇到一个很纠结的问题:jquery.autocomplete在IE6下被下拉框遮挡 。

最近遇到一个很纠结的问题:jquery.autocomplete在IE6下被下拉框遮挡 . 如图: 网上找到原因,例如:http://www.360doc.com/content/10/1126/16/2197500_72641076.shtml 但是,我们的问题是我们用了jquery.autocomplete这个控件,这些方法对于我们就不行了. 废话多了,直接解决方法: 第一步:打开jquery.autocomplete.min.js(或者直接jquery.autocomplete.js),找

使用position:relative制作下边框下的小三角

在制作tab选项卡的时候,有时会有下边框,且下边框下另一个头向下的小三角,这全然能够用css来实现,而不必使用背景图片. 由于使用背景图片时会有一个问题,选项卡内容字数不同.导致使用背景图片时无法控制它始终在中间显示. <ul class="technical_list"> <li class="active-tab">入门指南<div class="triangle"></div></li&

Linux下ffmpeg的各种编解码器的安装

首先要安装各种解码器 1.lame lame-3.99.5.tar.gz Url:http://sourceforge.net/project/showfiles.php?group_id=290&package_id=309 安装方法如下: 1 tar -zxvf lame-3.99.5.tar.gz 2 cd lame-3.99.5 3 ./configure --enable-shared 4 make 5 make install 2.libogg libogg-1.3.1.tar.gz

关于linux系统下iptables下的管理的8种命令

虽然iptables在Unix系统中不是服务,但是为了方便平时的管理也就对iptables写了chkconfig的启动脚本(chkconfig的启动脚本可以参看http://jim123.blog.51cto.com/4763600/1845648),定义在/etc/init.d/即rc.d/init.d目录下,但是iptables和正常的service服务又多了几种命令 Usage: /etc/init.d/iptables {start|stop|reload|restart|condres

Win7下的内置FTP组件的设置详解

在局域网中共享文件,FTP是比较方便的方案之一.Win7内部集成了FTP,只是设置起来颇费一番功夫.着文以记之. 一.安装FTP组件 由于Win7默认没有安装FTP组件.故FTP的设置第一步就是安装FTP组件 点击:控制面板—>程序和功能—>打开或关闭Windows功能.勾选“FTP服务器”及“FTP服务”“FTP扩展性”,点击“确定”,安装FTP组件.如下图所示 二.添加FTP站点 点击:控制面板—>管理工具.选中“Internet信息服务(IIS)管理器”,如图 双击“Interne

CentOS下WDCP下的MYSQL开启远程连接

1.首先要在防火墙开启3306端口访问 2.然后做如下操作 如何开启MySQL的远程帐号-1)首先以 root 帐户登陆 MySQL 在 Windows 主机中点击开始菜单,运行,输入"cmd",进入控制台,然后cd 进入MySQL 的 bin 目录下,然后输入下面的命令. > MySQL -uroot -p123456                 (123456 为 root 用户的密码.) 如何开启MySQL的远程帐号-2)创建远程登陆用户并授权  > grant