1.音訊seekTo最終是在AudioPlayer類中實現的,AudioPlayer::seekTo函數
status_t AudioPlayer::seekTo(int64_t time_us) { Mutex::Autolock autoLock(mLock); mSeeking = true;// 設定seek標誌為true mReachedEOS = false;// 可以seek,說明還未到檔案末尾,則結束標識設定為false mSeekTimeUs = time_us;// seek到的時間點 if (mAudioSink != NULL) { // mAudioSink優先,mAudioSink內部會create AudioTrack並註冊callback mAudioSink->flush(); } else { mAudioTrack->flush(); } return OK;}
2. buffer的填充是在AudioPlayer::AudioSinkCallback函數中調用AudioPlayer::fillBuffer來填充的,而fillBuffer又是通過調用mSource->read(&mInputBuffer, &options);來實現的,read會調用音訊類型對應MediaSource的實作類別來實現讀取seekto位置的資料,例如MP3音頻,如果是軟解的話,就會調用MP3Source::read方法,讀取seekto位置的資料填充buffer。
seek到的位置被設定到MediaSource::ReadOptions對象options中,通過以下方法設定。
options.setSeekTo(mSeekTimeUs);
而options又作為mSource->read的參數,被傳遞到MP3Source::read函數中,賦值給MP3Source的成員變數mCurrentTimeUs。當讀完一幀資料後,mCurrentTimeUs的值就增加了一幀的時間長度。計算方法如下:
mCurrentTimeUs += frame_size * 8000ll / bitrate;
3.AudioSinkCallback函數是在AudioPlayer::start函數中註冊的。
if (mAudioSink.get() != NULL) { status_t err = mAudioSink->open( mSampleRate, numChannels, AudioSystem::PCM_16_BIT, DEFAULT_AUDIOSINK_BUFFERCOUNT, &AudioPlayer::AudioSinkCallback, this);
4.在fillBuffer函數中,當INFO_FORMAT_CHANGED時,又重新註冊了AudioSinkCallback函數。
status_t err = mAudioSink->open( mSampleRate, numChannels, AudioSystem::PCM_16_BIT, DEFAULT_AUDIOSINK_BUFFERCOUNT, &AudioPlayer::AudioSinkCallback, this);
以上是對音頻seekTo的分析。