MediaPlayer中建立AudioTrack的過程
使用MediaPlayer播放音視頻時,會建立AudioTrack對象用於播放音頻資料。下面就來看看MediaPlayer建立AudioTrack的過程:
1.建立AudioTrack對象
MediaPlayer類中並沒有直接建立AudioTrack,而是把建立AudioTrack對象的操作放在了MediaPlayerService類的內部類AudioOutput中
具體代碼是在 MediaPlayerService::AudioOutput::open函數中,通過建立(new)一個AudioTrack對象,賦給AudioOutput類的成員變數mTrack來實現的。
mTrack是AudioTrack類型的指標變數。
另外,AudioOutput類不但是MediaPlayerService的內部類,還是繼承自MediaPlayerBase::AudioSink的衍生類別。
既然知道了AudioTrack對象是在AudioOutput::open函數中建立的,那麼接下來我們就看看AudioOutput類對象是在哪裡建立的,以及AudioOutput::open是在什麼時候被調用的。
2.建立AudioOutput類對象
在MediaPlayerService::Client::setDataSource函數中,當使用AudioFlinger進行軟體混音時會建立AudioOutput類對象mAudioOutput。
然後調用播放器的setAudioSink函數,把mAudioOutput對象賦值給相應播放器的AudioSink對象。
假設播放的是本地音視頻,在GB、ICS中預設的播放器架構是StagefrightPlayer,對應的播放器對象是AwesomePlayer。
最後調用AwesomePlayer::setAudioSink函數,把mAudioOutput賦給AwesomePlayer類的MediaPlayerBase::AudioSink類型的mAudioSink成員變數。
AwesomePlayer類的成員變數mAudioSink又作為建立AudioPlayer類對象的建構函式參數,傳遞給AudioPlayer類成員變數mAudioSink,它也是MediaPlayerBase::AudioSink類型的變數。
這樣就把MediaPlayerService中建立的AudioOutput類對象,最終傳遞給了AudioPlayer的成員mAudioSink,以待播放時使用。
3.調用AudioOutput::open函數
由於建立AudioTrack對象是在AudioOutput::open函數中進行的,所以清楚什麼時候調用AudioOutput::open函數就很重要。
根據2中我們已經知道了AudioOutput對象已經賦給了AudioPlayer的成員mAudioSink,所以只要知道調用mAudioSink的open函數,也就知道了調用AudioOutput::open函數的處理。
尋找AudioPlayer類可知,調用mAudioSink的open函數是在AudioPlayer::start函數中進行的。
在AudioPlayer::start函數中,當mAudioSink對象不為空白(NULL)時,就調用了mAudioSink的open函數。並且設定了參數預設檔案格式為AudioSystem::PCM_16_BIT,預設audio sink緩衝區個數為DEFAULT_AUDIOSINK_BUFFERCOUNT,值為4。然後調用mAudioSink的start函數,即MediaPlayerService::AudioOutput::start函數進行音頻資料輸出。MediaPlayerService::AudioOutput::start函數中又調用了AudioTrack的start函數。
當mAudioSink對象為空白(NULL)時,則直接建立AudioTrack對象,然後調用AudioTrack對象的start函數。目前為止,還沒有遇到過直接建立AudioTrack對象的處理,因為mAudioSink對象不為空白。
AudioPlayer::start函數是在使用者調用MediaPlayer的start函數後一步步被執行到的。
以上就是筆者對MediaPlayer中建立AudioTrack的過程的理解,如有不對的地方,還請多多指教,謝謝。Ameyume