Android Media Framework(二)OpenMAX 类型阅读与分析

必读:Android Media Framework - 开篇

OMX IL Spec将API划分为Control API、Data API、Extension API,所谓Control API指的是IL Client用于控制组件的接口,包含调用OMX Core和OMX Component要用的接口与相关结构体,这一篇我们将重点阅读与Control API相关的宏、结构体与枚举。

1、OMX IL目录结构

OMX IL API由一组头文件定义,包含以下内容:

  • OMX_Types.h:OMX使用的数据类型;
  • OMX_Core.h:OMX Core API以及相关结构体类型;
  • OMX_Component.h:OMX Component API以及相关结构体类型;
  • OMX_Audio.h:audio domain(域)相关的结构体,domain表示范围的意思,这里表示audio范围内的,后续将audio domain简称为audio;
  • OMX_IVCommon.h:audio、image和video公用的结构体;
  • OMX_Video.h:video相关的结构体;
  • OMX_Image.h:image相关的结构体;
  • OMX_Other.h:其他域用到的结构体;
  • OMX_Index.h:所有OMX定义的数据结构的索引,上面所说的所有结构体都有一个索引与之相对应;

在Android中,OMX IL API放在 frameworks/native/headers/media_plugin/media/openmax 目录下,进入目录可以看到包含所有上述提到的文件,除此之外还多了几个Ext结尾的文件,比如OMX_AudioExt.hOMX_VideoExt.h,与之相对应的要添加索引文件OMX_IndexExt.h,Ext表示扩展,意为这是Android在OMX IL基础上扩展的内容。

2、OMX_Types.h

OMX IL使用的基本数据类型存放在OMX_Types.h中,里面有一些宏定义,枚举和结构体,这里我们挑一些比较常见的来阅读。

OMX IL API在函数声明中使用宏参数功能进行描述:

  • OMX_IN:指定参数是一个输入参数,由调用者设定,由函数体读取;
  • OMX_OUT:指定参数是一个输出参数,参数值由函数体设定并回传给调用者,函数返回时调用者可以从参数中读到新的值,属于引用传递;
  • OMX_INOUT:指定函数调用者可以设置的参数类型为输入/输出参数,函数体可以读到参数值,也可以将

还有另外一个宏OMX_ALL,用于选择相同类型下的所有内容,在端口选择中会用到这个宏,表示选择所有端口。

接下来是一组typedef定义的数据类型:

typedef unsigned char       OMX_U8;
typedef signed char         OMX_S8;
typedef unsigned short      OMX_U16;
typedef signed short        OMX_S16;
typedef uint32_t            OMX_U32;
typedef int32_t             OMX_S32;
typedef unsigned long long  OMX_U64;
typedef signed long long    OMX_S64;

typedef void*               OMX_PTR;
typedef char*               OMX_STRING;
typedef unsigned char*      OMX_BYTE;

typedef OMX_PTR             OMX_HANDLETYPE;

上篇文章中提到组件句柄,它使用的类型是OMX_HANDLETYPE,在这我们可以知道组件句柄就是一个void*指针。

最后是一些枚举类型:

typedef enum OMX_DIRTYPE
{
    OMX_DirInput,              /**< Port is an input port */
    OMX_DirOutput,             /**< Port is an output port */
    OMX_DirMax = 0x7FFFFFFF
} OMX_DIRTYPE;

Dir是Direction的缩写,表示方向,用于表示端口数据的流向。如果数据向组件流入,端口用OMX_DirInput描述,表示输入端口;相对的如果数据从组件流出,用OMX_DirOutput表示输出端口。

为了跨平台OMX IL用枚举定义了布尔类型:

typedef enum OMX_BOOL {
    OMX_FALSE = 0,
    OMX_TRUE = !OMX_FALSE,
    OMX_BOOL_MAX = 0x7FFFFFFF
} OMX_BOOL;

3、OMX_Core.h

OMX Core API主要用于动态加载卸载组件,调用组件方法,所有调用组件用到的参数枚举、结构体类型,加载卸载函数,组件调用函数都存放在OMX_Core.h。

OMX_COMMANDTYPE包含了OMX IL可能发送给OMX组件的所有命令:

typedef enum OMX_COMMANDTYPE
{
    OMX_CommandStateSet,
    OMX_CommandFlush,
    OMX_CommandPortDisable,
    OMX_CommandPortEnable,
    OMX_CommandMarkBuffer,
    OMX_CommandKhronosExtensions = 0x6F000000,
    OMX_CommandVendorStartUnused = 0x7F000000,
    OMX_CommandMax = 0X7FFFFFFF
} OMX_COMMANDTYPE;

Android中常用的有:

  • OMX_CommandStateSet:用于改变组件的状态;
  • OMX_CommandFlush:刷新组件端口上的缓冲区队列;
  • OMX_CommandPortDisable:禁用组件的一个端口;
  • OMX_CommandPortEnable:启用组件的一个端口;
  • OMX_CommandVendorStartUnused:除了OMX IL定义的这些命令外,厂商也可以自定义命令,命令值从0x7F000001开始;
typedef enum OMX_STATETYPE
{
    OMX_StateInvalid,
    OMX_StateLoaded,
    OMX_StateIdle,
    OMX_StateExecuting,
    OMX_StatePause,
    OMX_StateWaitForResources,
    OMX_StateVendorStartUnused = 0x7F000000,
    OMX_StateMax = 0X7FFFFFFF
} OMX_STATETYPE;

OMX_STATETYPE定义了OMX组件的状态类型,Android中只用到了前四个:

  • OMX_StateInvalid:组件已损坏或遇到无法恢复的错误进入到该状态;
  • OMX_StateLoaded:组件加载/创建完成,但是资源还未分配,资源指的是端口中的buffer;
  • OMX_StateIdle:组件拥有所有的资源,但尚未传输任何缓冲区或开始处理数据;
  • OMX_StateExecuting:组件正在传输缓冲区并正在处理数据;

由于Android用到的状态只有四种,所以我把组件状态转换图做了简化:

image

图中的四个红色的状态并不是OMX IL的标准内容,所以在头文件中是找不到的,但是它们在spec中有所描述。组件做状态切换时可能要处理一些事务,事务处理完成后才能完成状态切换,红色状态描述的是处理事务的中间过程。

  • OMX_StateLoadedToIdle:当IL Client请求让组件从OMX_StateLoaded状态进入OMX_StateIdle状态时,组件在完成状态转换前需要获取到所有的资源(buffers),等待获取资源的过程用OMX_StateLoadedToIdle来描述。

组件连接IL Client的端口,端口中的buffer可由IL Client分配,通过调用OMX_UseBuffer将buffer传递给组件,也可由IL Client调用OMX_AllocateBuffer方法让组件来分配。

image

以上图为例,IL Client调用OMX_UseBuffer将buffer传递给OMX组件,OMX组件in port共享IL Client的buffer,in port获取到需要的资源;OMX组件out port由自己分配buffer,IL Client调用OMX_AllocateBuffer让组件分配出所要用的buffer,out port获取到需要的资源;当所有端口buffer获取完成,OMX组件即可进入Idle状态。

如果端口用于隧道模式,supplier port中的buffer可由自己分配,也可以复用其他buffer,简单来说我们并不在意供应端口的buffer是怎么来的;供应端口组件调用OMX_UseBuffer把buffer传递给非供应端口。

关注公众号《青山渺渺》阅读全文:
Android Media Framework(二)OpenMAX 类型阅读与分析

image

posted @ 2024-06-06 23:46  青山渺渺  阅读(20)  评论(0编辑  收藏  举报