rtsp流媒體buffer填充的處理過程

來源:互聯網
上載者:User

NuPlayer流媒體播放器中從網路上取得的rtp包在解碼和顯示時所用buffer的填充和清空的機制,與stagefright架構播放本地視頻時的處理流程類似。

都是通過回呼函數fillbuffer及emptybuffer來實現的。

NuPlayer中的ACodec與Stagefright中的OMXCodec的作用相似。

以下是rtsp流媒體中填充待解碼的buffer,以及把解碼後的buffer送給顯示並清空的處理過程:

1.ACodec::UninitializedState::onSetup

調用status_t err = omx->allocateNode(componentName.c_str(), observer, &node);

2.OMX::allocateNode

status_t OMX::allocateNode(        const char *name, const sp<IOMXObserver> &observer, node_id *node) {    Mutex::Autolock autoLock(mLock);    *node = 0;    OMXNodeInstance *instance = new OMXNodeInstance(this, observer); // OMXNodeInstance是在OMX類中建立的    OMX_COMPONENTTYPE *handle;    OMX_ERRORTYPE err = mMaster->makeComponentInstance(            name, &OMXNodeInstance::kCallbacks, // 註冊了kCallbacks回呼函數,            instance, &handle);

3.OMXNodeInstance::kCallbacks

// staticOMX_CALLBACKTYPE OMXNodeInstance::kCallbacks = {    &OnEvent, &OnEmptyBufferDone, &OnFillBufferDone // 回呼函數OnEmptyBufferDone,OnFillBufferDone};

4.OMXNodeInstance::OnEmptyBufferDone // 資料解碼完,可以取走資料用於顯示了,然後清空buffer

調用instance->owner()->OnEmptyBufferDone(instance->nodeID(), pBuffer)  // owner()返回的是OMX指標對象mOwner
處理過程如下:
(1)在OMX::OnEmptyBufferDone中發送omx_message::EMPTY_BUFFER_DONE訊息,並設定瞭解碼後的buffer
(2)首先ACodec.cpp檔案中的CodecObserver結構體的onMessage方法接收到omx_message::EMPTY_BUFFER_DONE訊息。
(3)然後ACodec::BaseState::onOMXMessage再接收到omx_message::EMPTY_BUFFER_DONE訊息,調用onOMXEmptyBufferDone繼續處理。
(4)在ACodec::BaseState::onOMXEmptyBufferDone 函數中,PortMode為的值為RESUBMIT_BUFFERS,則調用postFillThisBuffer函數
(5)在ACodec::BaseState::postFillThisBuffer 函數中,發送了kWhatInputBufferFilled訊息,設定"what"參數為ACodec::kWhatFillThisBuffer
(6)接收到kWhatInputBufferFilled訊息後,調用onInputBufferFilled 函數
(7)在ACodec::BaseState::onInputBufferFilled 函數中
   1)PortMode為的值為RESUBMIT_BUFFERS,並且buffer != info->mData,則執行記憶體拷貝,把解碼後的資料從buffer->data()拷貝到info->mData->data()中
   memcpy(info->mData->data(), buffer->data(), buffer->size());
   2)然後調用mCodec->mOMX->emptyBuffer函數,最終調用的是OMXNodeInstance::emptyBuffer 函數
   3)再調用getMoreInputDataIfPossible函數,取得下一個解碼完的資料。但在執行到eligible == NULL時,執行了返回動作,沒有調用postFillThisBuffer(eligible)函數繼續處理。

5.OMXNodeInstance::OnFillBufferDone // 資料已經準備好,可以送給解碼器解碼
調用instance->owner()->OnFillBufferDone(instance->nodeID(), pBuffer)

---------------------------------------------------------------------------------

在OMX::allocateNode函數中,建立了CallbackDispatcher對象,即
在CallbackDispatcher建構函式中建立了CallbackDispatcherThread對象,並調用了run函數,在run中會調用Thread::_threadLoop,又調用threadLoop
->
bool OMX::CallbackDispatcherThread::threadLoop() {
    return mDispatcher->loop();
}
->
OMX::CallbackDispatcher::loop()
->
OMX::CallbackDispatcher::dispatch
->
OMXNodeInstance::onMessage
 mObserver->onMessage(msg);// IOMXObserver是建構函式OMXNodeInstance中傳遞過來的,即OMX::allocateNode中傳遞的參數observer,
// 而OMX::allocateNode又是在ACodec::UninitializedState::onSetup函數中被調用的,即observer的類型是CodecObserver。
CodecObserver繼承自BnOMXObserver類,而BnOMXObserver又是IOMXObserver的子類。
所以,OMX::CallbackDispatcher::dispatch中執行mOwner->onMessage(msg),
最終是調用的CodecObserver的onMessage方法,在CodecObserver的onMessage方法中發送ACodec::kWhatOMXMessage訊息。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.