OMXCodec创建完边解码组件之后, 需要对每一个port口进行buffer的分配.主要流程如下
需要对OMXCodec中buffer的管理说一下:
struct BufferInfo {
IOMX::buffer_id mBuffer; //BufferInfo的唯一标示
BufferStatus mStatus; //OWNED_BY_US OWNED_BY_COMPONENT
sp<IMemory> mMem; //当数据需要备份时,将mData的数据备份到这里
size_t mSize; //每一块buffer的size
void *mData; //指向component操作的buffer上
MediaBuffer *mMediaBuffer; //播放器最后操作的buffer,包含mData的引用
};
Vector<BufferInfo> mPortBuffers[2]; //管理input/output port的buffer。
PortStatus mPortStatus[2]; //ENABLED, DISABLED
List<size_t> mFilledBuffers; //指向mPortBuffers
//[kPortIndexOutput]中填满数据的那些
//BufferInfo
Condition mBufferFilled; //同步的信号量
OMX Component中获得allocateBuffer后, 根据以下struct管理buffer
typedef struct OMX_BUFFERHEADERTYPE
{
OMX_U32 nSize; //结构体的大小
OMX_U8* pBuffer; //指向最终操作buffer的内存块
OMX_U32 nAllocLen; //分配多少bytes的内存大小,由真正的编解码组件初始化
OMX_U32 nFilledLen; //真正在buffer中写入了多少的bytes
OMX_U32 nOffset; //从buffer中读取的偏移量
OMX_TICKS nTimeStamp; //时间戳
OMX_U32 nOutputPortIndex; //正在使用buffer的output port口
OMX_U32 nInputPortIndex; //正在使用buffer的input port口
} OMX_BUFFERHEADERTYPE;
struct BufferInfo {
OMX_BUFFERHEADERTYPE *mHeader; //Component根据header来确定操作哪一块buffer
bool mOwnedByUs;
};
struct PortInfo {
OMX_PARAM_PORTDEFINITIONTYPE mDef; //component 中port的参数
Vector<BufferInfo> mBuffers;
List<BufferInfo *> mQueue; //需要处理的数据
};
所以OMXCodec中的BufferInfo.mData就是指向了OMX_BUFFERHEADERTYPE.pBuffer,
也就是MediaBuffer中也是直接指向了这块内存.
所以OMXCodec直接向这块MediaBuffer指向的内存写入压缩数据, OMX Component直接从Input port口的pBuffer读取压缩数据, 进行解码. 然后将解码之后的PCM/YUV 数据直接写到Output port口的pBuffer中, 然后通过回调通知OMXCodec从Output port口的MediaBuffer中读取PCM/YUV数据.
具体流程如下: