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

摘要:
例如,以下内容将在MPS侧创建一个OMXCodec结构,作为基于相关节点信息sp的类似本地编解码器创建本地OMXCodec解码器。最后,实现MediaPlayerService中的OMX对象以实现getParameter。将mHandle的类型视为OMXNodeInstance对象的成员变量。他维护makeComponentInstance返回的底层编解码器组件库的句柄。

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

欢迎和大家交流。

qq:1037701636 email:gzzaigcn2012@gmail.com

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
",(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的协议就可以。

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

Android4.2.2下Stagefright下OMX编解码器组件的控制流第2张
分析了那么多的控制流,也已经有了所谓的OMXCodec,那么兴许主要内容将是数据流的处理。



 


 



 


 

免责声明:文章转载自《Android4.2.2下Stagefright下OMX编解码器组件的控制流》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇IOC容器的初始化如何让程序启动时以管理员身份运行下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

基于图像的三维物体重建:在深度学习时代的最新技术和趋势之人脸重建和场景分析

作者:Longway 来源:公众号@3D视觉工坊 链接: 基于图像的三维物体重建:在深度学习时代的最新技术和趋势之人脸重建和场景分析 1.三维人脸重建 基于精细密集图像的人脸三维重建是计算机视觉和计算机图形学中一个长期存在的问题,其目标是恢复人脸的形状、姿态、表情、皮肤反射率和更精细的表面细节。最近,这个问题被描述为一个回归问题,并用卷积神经网络来解决...

《【GraphTER】通过逐点变换实现无监督图神经网络共变特征学习》

【GraphTER】通过逐点变换实现无监督图神经网络共变特征学习 齐国君 MAPLE(maple-lab.net)实验室 已关注 王晋东不在家 等21 人赞同了该文章 GraphTER: Unsupervised Learning of Graph Transformation Equivariant Representations...

机器学习(ML)十二之编码解码器、束搜索与注意力机制

编码器—解码器(seq2seq) 在自然语言处理的很多应用中,输入和输出都可以是不定长序列。以机器翻译为例,输入可以是一段不定长的英语文本序列,输出可以是一段不定长的法语文本序列,例如 英语输入:“They”、“are”、“watching”、“.” 法语输出:“Ils”、“regardent”、“.” 当输入和输出都是不定长序列时,我们可以使用编码器—解...

神经机器翻译(NMT)相关资料整理

作者:zhbzz2007 出处:http://www.cnblogs.com/zhbzz2007 欢迎转载,也请保留这段声明。谢谢! 1 简介 自2013年提出了神经机器翻译系统之后,神经机器翻译系统取得了很大的进展。最近几年相关的论文,开源系统也是层出不穷。本文主要梳理了神经机器翻译入门、进阶所需要阅读的资料和论文,并提供了相关链接以及简单的介绍,以及总...

MPEG2-TS音视频同步原理(PCR dts pts)

一、引言MPEG2系统用于视音频同步以及系统时钟恢复的时间标签分别在ES,PES和TS这3个层次中。在TS 层, TS头信息包含了节目时钟参考PCR(Program Clock Reference),用于恢复出与编码端一致的系统时序时钟STC(System Time Clock)。 在PES层, 在PES头信息里包含有表示时间戳PTS(Presentati...

当Transformer遇见U-Net!

前言 留给Transformer + U-Net 组合命名的缩写不多了... 之前盘点了目前已公开的5篇MICCAI 2021上的Transformer+医学图像分割的工作,详见:Transformer一脚踹进医学图像分割!看5篇MICCAI 2021有感 没想到大家这么喜欢这篇文章,收藏量高的可怕... 那么本文将盘点Tranformer + U-Net...