*由於工作需要,需要利用MediaCodec實現Playback及Transcode等功能,故在學習過程中翻譯了Google官方的MediaCodec API文檔,由於作者水平限制,文中難免有錯誤和不恰當之處,望批評指正。
*轉載請注明出處:http://www.cnblogs.com/roger-yu/
概述
在MediaCodec的生命周期內存在三種狀態:Stopped, Executing or Released,其中
Stopped狀態包含三種子狀態:Uninitialized, Configured and Error
Executing狀態包含三種子狀態:Flushed, Running and End-of-Stream
由於MediaCodec在不同的數據處理模式下狀態間的轉換會有些許差別,故接下來我們分別對同步處理模式及異步處理模式下的狀態轉換做詳細分析
同步模式下的狀態轉換(Synchronous Processing using Buffers)
首先我們先看一下狀態轉換的流程圖,如下:

1. 當通過 MediaCodec.createByCodecName(...) or MediaCodec.createDecoderByType(...) or MediaCodec.createEncoderByType(...)三種方法中的任一種創建一個MediaCodec對象實例后,Codec將會處於 Uninitialized 狀態;
2. 當你調用 MediaCodec.configure(...)方法對Codec進行配置后,Codec將進入 Configured 狀態;
3. 之后可以調用 MediaCodec.start() 方法啟動Codec,Codec會轉入 Executing 狀態,start后Codec立即進入 Flushed 子狀態,此時的Codec擁有所有的input and output buffers,Client無法操作這些buffers;
4. 一旦第一個input buffer 出隊列,也即Client通過調用 MediaCodec.dequeueInputBuffer(...)請求得到了一個有效的input buffer index, Codec立即進入到了 Running 子狀態,在這個狀態下Codec會進行實際的數據處理(解碼、編碼)工作,度過它生命周期的主要階段;
5. 當輸入端入隊列一個帶有 end-of-stream 標記的input buffer時(queueInputBuffer(EOS)),Codec將轉入 End of Stream 子狀態。在此狀態下,Codec不再接受新的input buffer數據,但仍會處理之前入隊列而未處理完的input buffer並產生output buffer,直到end-of-stream 標記到達輸出端,數據處理的過程也隨即終止;
6. 在 Executing狀態下可以調用 MediaCodec.flush()方法使Codec進入 Flushed 子狀態;
7. 在 Executing狀態下可以調用 MediaCodec.stop()方法使Codec進入 子狀態,可以對Codec進行重新配置;Uninitialized
8. 極少數情況下Codec會遇到錯誤進入 Error 狀態,可以調用 MediaCodec.reset() 方法使其再次可用;
9. 當MediaCodec數據處理任務完成時或不再需要MediaCodec時,可使用 MediaCodec.release()方法釋放其資源。
異步模式下的狀態轉換(ASynchronous Processing using Buffers)
首先我們先看一下狀態轉換的流程圖,如下:

異步模式下狀態轉換與同步模式下大同小異,主要有兩點區別:
1. 調用 MediaCodec.start() 方法啟動Codec,Codec會直接轉入 Running 子狀態;
2. 當調用 MediaCodec.flash() 方法進入 Flushed 子狀態后,必須調用 MediaCodec.start() 方法Codec才會進入 Running 子狀態。
其他情況下均與同步模式下相同,就不在此贅述。
微信掃一掃,關注玖零日記,獲取更多相關資訊及源碼 -- 雖無面朝大海,依舊春暖花開

