stagefright框架(六)-Audio Playback的流程 到目前為止,我們都只著重在 video 處理的部分,對於 audio 卻隻字未提。這篇文章將會開始 audio 處理的流程。 Stagefright 中關於 audio 的部分是交由 AudioPlayer 來處理,它是在 AwesomePlayer::play_l 中被建立的。 (1) 當上層應用程式要求播放影音時, AudioPlayer 同時被建立出來,並且被啟動 status_t AwesomePlayer: : play_l( ) { . . . mAudioPlayer = new AudioPlayer( mAudioSink, . . . ) ; mAudioPlayer- > start( . . . ) ; . . . } (2) AudioPlayer 在啟動的過程中會先去讀取第一筆解碼後的資料,並且開啟 audio output status_t AudioPlayer: : start( . . . ) { mSource- > read ( & mFirstBuffer) ; if ( mAudioSink. get( ) ! = NULL ) { mAudioSink- > open ( . . . , & AudioPlayer: : AudioSinkCallback, . . . ) ; mAudioSink- > start( ) ; } else { mAudioTrack = new AudioTrack( . . . , & AudioPlayer: : AudioCallback, . . . ) ; mAudioTrack- > start( ) ; } } 從 AudioPlayer::start 的程式碼來看, AudioPlayer 似乎並沒有將 mFirstBuffer 傳給 audio output 。 (3) 開啟 audio output 的同時, AudioPlayer 會將 callback 函式設給它,之後每當 callback 函式被呼叫, AudioPlayer 便去 audio decoder 讀取解碼後的資料 size_t AudioPlayer: : AudioSinkCallback( audioSink, buffer, size, . . . ) { return fillBuffer( buffer, size) ; } void AudioPlayer: : AudioCallback( . . . , info) { buffer = info; fillBuffer( buffer- > raw, buffer- > size) ; } size_t AudioPlayer: : fillBuffer( data, size) { mSource- > read ( & mInputBuffer, . . . ) ; memcpy ( data, mInputBuffer- > data( ) , . . . ) ; } 解碼後 audio 資料的讀取就是由 callback 函式所驅動,但是 callback 函式又是怎麼由 audio output 去驅動的,目前從程式碼上還看不出來。另外一方面,從上面的程式片段可以看出, fillBuffer 將資料 (mInputBuffer) 複製到 data 之後, audio output 應該會去取用 data 。 (5) 至於 audio decoder 的工作流程則和 video decoder 相同,可參閱《 Stagefright (4) - Video Buffer 傳輸流程 》