AwesomePlayer类的seek操作介绍

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;
}

发布了270 篇原创文章 · 获赞 273 · 访问量 377万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览