AwesomePlayer类的seek操作介绍

来源:互联网 发布:mac safari添加收藏 编辑:程序博客网 时间:2024/05/22 17:40
AwesomePlayer类的seek操作介绍

1.执行音频seek的地方(mAudioPlayer->seekTo)只有两处,一处是在seekAudioIfNecessary_l函数中,另外一处是在finishSeekIfNecessary函数中。

2.执行seekAudioIfNecessary_l函数的地方有两处,一处是在seekTo_l函数中,另外一处是在play_l函数中。
(1)在seekTo_l函数中,seekAudioIfNecessary_l是无条件执行的。
(2)在play_l函数中,只有当deferredAudioSeek为true时,才执行seekAudioIfNecessary_l函数。
而deferredAudioSeek变量只有在执行创建对象mAudioPlayer时才会被赋值为true,所以只会在开始播放时执行一次,当先播放,暂停然后再播放时不会执行。

3.执行finishSeekIfNecessary函数的地方有三处,都是在onVideoEvent函数中被执行的。
finishSeekIfNecessary函数的参数是视频的时间,所以此函数是与视频有关的。函数定义为:
void AwesomePlayer::finishSeekIfNecessary(int64_t videoTimeUs) 
(1)第一处是在mVideoBuffer为NULL,执行mVideoSource的read函数读取视频buffer返回错误时,调用了finishSeekIfNecessary(-1)操作
参数设置为-1,则把音频seek到实际seek的位置,代码如下:
        // 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)第二处是在从mVideoBuffer中取得video的时间戳,然后把音频seek到vidoe的时间戳的位置,应该是为了保持音视频同步才这样处理。
代码如下:
    int64_t timeUs;    CHECK(mVideoBuffer->meta_data()->findInt64(kKeyTime, &timeUs));    {        Mutex::Autolock autoLock(mMiscStateLock);        mVideoTimeUs = timeUs;    }    bool wasSeeking = mSeeking;    finishSeekIfNecessary(timeUs);
(3)第三处是在初始化视频的render失败时调用的。
与(1)中第一次调用类似,此时把音频seek到实际seek的位置。
代码如下:
    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)AudioPlayer执行实际的seek操作之前,执行了以下操作,通知MeidaPlayer seek完成。
mObserver->postAudioSeekComplete();

此时读取数据时,就从seek到的时间点开始读取数据,即seek完成了。

其中mObserver是AudioPlayer的类成员变量,类型为AwesomePlayer。

通过调用AwesomePlayer::onCheckAudioStatus()函数,用于通知MediaPlayer音频seek完成,播放完成消息。

(2)当从source中读取数据失败时,调用了AwesomePlayer的postAudioEOS函数,此函数也会通过postEvent,调用AwesomePlayer::onCheckAudioStatus()函数,用于通知MediaPlayer音频seek完成,播放完成消息。

if (err != OK) {    if (mObserver && !mReachedEOS) {        mObserver->postAudioEOS();    }    mReachedEOS = true;    mFinalStatus = err;    break;}

原创粉丝点击