Android - ics - stagefright框架数据流向分析- xww810319的专栏

2025/6/22 19:30:22

这个 drainInputBuffers函数从输入端口的buffers中取出之前分配好的BufferInfo,然后交给drainInputBuffer (info)函数来处理,函数实现如下:

bool OMXCodec::drainInputBuffer(BufferInfo *info) {

//comment by Alan, this buffer has only codec config informations

status_t err = mOMX->emptyBuffer( mNode, info->mBuffer, 0, size,

OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_CODECCONFIG, 0);

for (;;) {

?....

MediaBuffer *srcBuffer; ?...

err = mSource->read(&srcBuffer); ?...

memcpy((uint8_t *)info->mData + offset,

(const uint8_t *)srcBuffer->data() + srcBuffer->range_offset(), srcBuffer->range_length()); ?.....

err = mOMX->emptyBuffer(

mNode, info->mBuffer, 0, offset, flags, timestampUs); ?.... }

这个函数比较复杂,主要的关键代码如上,在这个函数中,首先会把一些和编解码组件相关的specific data送给omx框架来调

用一次emptybuffer,然后会进入一个for(;;)循环,在这个for循环内,会通过mSource->read(&srcBuffer)网

srcBuffer中填充一些原始的流数据(从XXXExtractor解析出来未解码的数据),这里mSource就是前面XXXExtractor在

文件解析的过程中new 的XXXSource这里假定是MPEG4Source。函数的大致实现如下:

status_t MPEG4Source::read(MediaBuffer **out, const ReadOptions *options) { ?...

err = mGroup->acquire_buffer(&mBuffer);

if (usesDRM) {

num_bytes_read =

mDataSource->readAt(offset, (uint8_t*)mBuffer->data(), size); } else {

num_bytes_read = mDataSource->readAt(offset, mSrcBuffer, size); }

?...

*out = mBuffer; mBuffer = NULL; return OK; }

这个函数的实现很复杂,在read的时候不但考虑了seek的问题,而且还涉及到了不少多媒体容器格式方面的一些问题。但是关于

数据流向的函数就是两个,首先acquire_buffer,这个acquire_buffer和前面的add_buffer对应,在MPEG4Source::

start中会被调用到。获得一个mBuffer后就可以通过mDataSource->readAt来往这个buffer上填充数据了。这里的

mDataSource实际上可以对应到一个FileSource或者来之网络的CacheSource。mBuffer数据填充完后赋值给调用函数的

srcBuffer,这样就相当于给 drainInputBuffer(BufferInfo *info)中的info填充了数据,然后回到

drainInputBuffer函数,接着emptyBuffer。实际上这里的BufferInfo *info的数据填充过程还有一些细节需要弄清楚,

BufferInfo的结构体各个字段的意义还有待进一步弄明白。

到了mOMX->emptyBuffer()基本就进入OMX框架了,无非是OMX那一套消息机制,之前已经说过,这里就不在赘述了。

如果还有不清楚的话,其在openMax文档的时候我画的一张时序图。还有一点需要明确,在emptyBuffer的时候会将App Data

copyToOMX,将来之Appcation的数据copy到OMX框架中,而在OMXNodeInstance::onMessage FILL_BUFFER_DONE

的时候,会将数据从OMX框架中copy到Appcation空间,即copyFromOMX。Appcation<-- data --->OMX

来看看其中一个函数的实现,

void CopyToOMX(const OMX_BUFFERHEADERTYPE *header) { if (!mIsBackup) { return; }

memcpy(header->pBuffer + header->nOffset,

(const OMX_U8 *)mMem->pointer() + header->nOffset, header->nFilledLen); }

注意以下,mMem这个成员变量具体指什么,我们看看emptyBuffer这个函数的实现:

status_t OMXNodeInstance::emptyBuffer( OMX::buffer_id buffer,

OMX_U32 rangeOffset, OMX_U32 rangeLength, OMX_U32 flags, OMX_TICKS timestamp) { Mutex::Autolock autoLock(mLock);

OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer; header->nFilledLen = rangeLength; header->nOffset = rangeOffset; header->nFlags = flags;

header->nTimeStamp = timestamp;

BufferMeta *buffer_meta =

static_cast(header->pAppPrivate); buffer_meta->CopyToOMX(header);

OMX_ERRORTYPE err = OMX_EmptyThisBuffer(mHandle, header);

return StatusFromOMXError(err); }

去看一下BufferMeta的构造函数就可以发现,上面mMem实际上指的是head->pAppPrivate。

那么具体的解码过程什么时候开始呢?

在OMX框架中所有的软解部分,最终都会通过OMX的消息机制走到SimpleSoftOMXComponent::

onMessageReceived,函数的实现如下:

void SimpleSoftOMXComponent::onMessageReceived(const sp&msg) {

Mutex::Autolock autoLock(mLock);

switch (msg->what()) { case kWhatSendCommand: {

int32_t cmd, param;

CHECK(msg->findInt32(\

CHECK(msg->findInt32(\

onSendCommand((OMX_COMMANDTYPE)cmd, (OMX_U32)param); break; }

case kWhatEmptyThisBuffer: case kWhatFillThisBuffer: {

OMX_BUFFERHEADERTYPE *header;

CHECK(msg->findPointer(\

CHECK(mState == OMX_StateExecuting && mTargetState == mState);

bool found = false;

for (size_t i = 0; i < mPorts.size(); ++i) {

PortInfo *port = &mPorts.editItemAt(i);

for (size_t j = 0; j < port->mBuffers.size(); ++j) { BufferInfo *buffer = &port->mBuffers.editItemAt(j);

if (buffer->mHeader == header) { CHECK(!buffer->mOwnedByUs);

buffer->mOwnedByUs = true;

CHECK((msg->what() == kWhatEmptyThisBuffer && port->mDef.eDir == OMX_DirInput)

|| (port->mDef.eDir == OMX_DirOutput));

port->mQueue.push_back(buffer); onQueueFilled(i);

found = true; break;

} } }

CHECK(found); break; }


Android - ics - stagefright框架数据流向分析- xww81.doc 将本文的Word文档下载到电脑
搜索更多关于: Android - ics - stagefright框架数 的文档
相关推荐
相关阅读
× 快捷下载通道(下载后可以自由复制和排版)

开通会员免费下载

开通会员后百万份文档资料免费自由复制和下载,是您最优的选择,赶快来试试吧!

单篇下载:10元 点击下载

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信:fanwen365 QQ:370150219