最近由於公司在做數字電視,播放器和模組由供應商打包一起賣,驅動調通了,可是播放器要硬體解碼,和平台差異,原廠又沒有相關文檔,就自己試著看了一個系統的播放器流程,順便整理了一下,也方便以後查詢,希望對播放器硬解碼的開發能起到點作用。由於對視頻也不瞭解,所以難免有不少錯誤,歡迎高手指導。
1: 由檔案或者裝置來建立一個dataSource(DataSource) (其中可以是檔案描述符fd, uri ,http)
2: 通過dataSource來建立一個MediaExtractor(即視頻的分流器paser)執行個體
3: 由 MediaExtractor執行個體來建立兩個MediaSource(視頻要包含兩個, 一個為視頻mVideoTrack, 一個為音頻 mAudioTrack), 其中就重要的是read函數用於解碼器獲得原始視頻數 據 進行解碼
4: 建立一個OMXClient執行個體並串連(具體調用其connect()方法,並檢查是否成功返回)
5: 建立相應的解碼器執行個體 例如:
mOmxSource = OMXCodec::Create(
mClient.interface(), mAudioTrack->getFormat(),
false, // createEncoder
mAudioTrack);
mVideoSource = OMXCodec::Create(
mClient.interface(), mVideoTrack->getFormat(),
false, // createEncoder
mVideoTrack,
NULL, flags,
mNativeWindow);
mAudioTrack mVideoTrack 即為兩個MediaSource執行個體 分別代表原始的資料來源
注意這兩個都返回了一個MediaSource的執行個體(mOmxSource and mVideoSource),這兩個是用於使用者獲得解碼後的音視頻資料並進行播放使用的
mNativeWindow(ANativeWindow) 為上層Surface的下層體現,即上層要用於顯示的Surface
建立 ANativeWindow 的方法:
1: 從JAVA層會通過JNI傳遞一個JSurface的對象到JNI, 而JNI可以通過這個對象來擷取IGraphicBufferProducer, 方法為:
sp surface;
sp gbp;
if (jSurface) {
surface = android_view_Surface_getSurface(env, jSurface);
if (surface != NULL) {
gbp = surface->getIGraphicBufferProducer();
}
}
最終得到 一個 IGraphicBufferProducer 的 執行個體 gbp
2: 上層提供一個 sp &bufferProducer 的一個引用並可以用來建立ANativeWindow mNativeWindow = new Surface(bufferProducer) //些處參考AwesomePlayer.cpp
6: 調用5返回來的兩個MediaSource執行個體的read方法(主要是用於擷取一個MediaBuffer的執行個體 mVideoBuffer)來擷取解碼後的資料(即在MediaBuffer中)並進行相應處理(即進行播放)
7: 通過ANativeWindow來顯示映像
status_t err = mNativeWindow->queueBuffer(mNativeWindow.get(), mVideoBuffer->graphicBuffer().get(), -1);
sp metaData = mVideoBuffer->meta_data();
metaData->setInt32(kKeyRendered, 1); //主要設定一個渲染標記,說明已經顯示 (猜得)