這篇文章將介紹Stagefright中是如何和OMX video decoder傳遞buffer。
(1) OMXCodec會在一開始的時候透過read函式來傳送未解碼的data給decoder,並且要求decoder將解碼後的data傳回來
- status_t OMXCodec::read(...)
- {
- if (mInitialBufferSubmit)
- {
- mInitialBufferSubmit = false;
-
- drainInputBuffers(); <----- OMX_EmptyThisBuffer
- fillOutputBuffers(); <----- OMX_FillThisBuffer
- }
-
- ...
- }
-
- void OMXCodec::drainInputBuffers()
- {
- Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
-
- for (i = 0; i < buffers->size(); ++i)
- {
- drainInputBuffer(&buffers->editItemAt(i));
- }
- }
-
- void OMXCodec::drainInputBuffer(BufferInfo *info)
- {
- mOMX->emptyBuffer(...);
- }
-
- void OMXCodec::fillOutputBuffers()
- {
- Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
-
- for (i = 0; i < buffers->size(); ++i)
- {
- fillOutputBuffer(&buffers->editItemAt(i));
- }
- }
-
- void OMXCodec::fillOutputBuffer(BufferInfo *info)
- {
- mOMX->fillBuffer(...);
- }
(2) Decoder從input port讀取資料後,開始進行解碼,並且回傳EmptyBufferDone通知OMXCodec
- void OMXCodec::on_message(const omx_message &msg)
- {
- switch (msg.type)
- {
- case omx_message::EMPTY_BUFFER_DONE:
- {
- IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer;
- drainInputBuffer(&buffers->editItemAt(i));
- }
- }
- }
OMXCodec收到EMPTY_BUFFER_DONE之後,繼續傳送下一個未解碼的資料給decoder。
(3) Decoder將解碼完的資料送到output port,並回傳FillBufferDone通知OMXCodec
- void OMXCodec::on_message(const omx_message &msg)
- {
- switch (msg.type)
- {
- case omx_message::FILL_BUFFER_DONE:
- {
- IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer;
- fillOutputBuffer(info);
-
- mFilledBuffers.push_back(i);
- mBufferFilled.signal();
- }
- }
- }
OMXCodec收到FILL_BUFFER_DONE之後,將解碼後的資料放入mFilledBuffers,發出mBufferFilled信號,並且要求decoder繼續送出資料。
(4) read函式在後段等待mBufferFilled信號。當mFilledBuffers被填入資料後,read函式將其指定給buffer指標,並回傳給AwesomePlayer
- status_t OMXCodec::read(MediaBuffer **buffer, ...)
- {
- ...
-
- while (mFilledBuffers.empty())
- {
- mBufferFilled.wait(mLock);
- }
-
- BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index);
- info->mMediaBuffer->add_ref();
- *buffer = info->mMediaBuffer;
- }
(zhaixishan) |