Introduction to seek operations of the awesomeplayer class
1. There are only two places where the audio seek is executed (maudioplayer-> seekto), one is in the seekaudioifnecessary_l function, and the other is in the finishseekifnecessary function.
2. The seekaudioifnecessary_l function is executed in two places, one in the seekto_l function and the other in the play_l function.
(1) In the seekto_l function, seekaudioifnecessary_l is executed unconditionally.
(2) In the play_l function, the seekaudioifnecessary_l function is executed only when deferredaudioseek is true.
The deferredaudioseek variable is assigned true only when the creation object maudioplayer is executed. Therefore, the variable is executed only once when the playback starts. It is played first, paused, and then played again.
3. The finishseekifnecessary function is executed in onvideoevent function in three places.
The finishseekifnecessary function parameter is the video time, so this function is related to the video. The function is defined:
void AwesomePlayer::finishSeekIfNecessary(int64_t videoTimeUs)
(1) The first step is to call the finishseekifnecessary (-1) operation when mvideobuffer is null and an error is returned when the READ function of mvideosource is executed to read the video buffer.
If the parameter is set to-1, the audio seek is sent to the actual seek location. The Code is as follows:
// If we don't have a video time, seek audio to the originally // requested seek time instead. if (mRTSPController == NULL) { mAudioPlayer->seekTo(videoTimeUs < 0 ? mSeekTimeUs : videoTimeUs); mAudioPlayer->resume(); }
(2) The second step is to get the Video timestamp from mvideobuffer, and then place the audio seek to the vidoe timestamp, which should be done in order to keep the audio and video synchronized.
The Code is as follows:
int64_t timeUs; CHECK(mVideoBuffer->meta_data()->findInt64(kKeyTime, &timeUs)); { Mutex::Autolock autoLock(mMiscStateLock); mVideoTimeUs = timeUs; } bool wasSeeking = mSeeking; finishSeekIfNecessary(timeUs);
(3) The third part is called when the video render fails to be initialized.
Similar to the first call in (1), the audio seek is directed to the actual seek location.
The Code is as follows:
if (mVideoRendererIsPreview || mVideoRenderer == NULL || mNewSurfaceIsSet) { mVideoRendererIsPreview = false; mNewSurfaceIsSet = false; status_t err = initRenderer_l(); if (err != OK) { finishSeekIfNecessary(-1); mFlags |= VIDEO_AT_EOS; LOGV("video stream ended err1:%d !",err); postStreamDoneEvent_l(err); return; } }
4. (1) Before audioplayer executes the actual seek operation, the following operations are performed to notify meidaplayer seek to complete.
Mobserver-> postaudioseekcomplete ();
At this time, the data is read from seek to the time point, that is, seek is complete.
Here, mobserver is a member variable of the audioplayer class and its type is awesomeplayer.
Call the awesomeplayer: oncheckaudiostatus () function to notify the mediaplayer audio seek to complete and play the completed message.
(2) When data reading from the source fails, the postaudioeos function of awesomeplayer is called. This function also calls the awesomeplayer: oncheckaudiostatus () function through postevent, it is used to notify mediaplayer that the audio seek is complete and the playback completion message is complete.
if (err != OK) { if (mObserver && !mReachedEOS) { mObserver->postAudioEOS(); } mReachedEOS = true; mFinalStatus = err; break;}