关于音视频同步 ffplay的同步方式解析

今天有时间继续研究ffplay了,之前把重点放在编码解码上了,今天看了一下ffplay的音视频同步的代码,也是看了一个人的博客,但是这个对初学者可能还是有点看不懂,在这里就只对一个方法做解析,这个方法了解就知道音视频同步的原理了。

//一下代码是我从另一个人的博客拷贝过来的,因为需要弄懂的就在这个方法里面,所以直接上他的代码了,不然还要去

static double compute_target_delay(double delay, VideoState *is)

{

    double sync_threshold,diff;

 

    /* update delay to followmaster synchronisation source */

    /*如果主同步方式不是以视频为主,默认是以audio为主进行同步*/

    if(get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {

        /* if video is slave,we try to correct big delays by

           duplicating ordeleting a frame */

 

        /*get_clock(&is->vidclk)获取到的实际上是:从处理最后一帧开始到现在的时间加上最后一帧的pts,具体参考set_clock_at get_clock的代码

        get_clock(&is->vidclk) ==is->vidclk.pts, av_gettime_relative() / 1000000.0 -is->vidclk.last_updated  +is->vidclk.pts*/

        /*driff实际上就是已经播放的最近一个视频帧和音频帧pts的差值+ 两方系统的一个差值,用公式表达如下:

        pre_video_pts: 最近的一个视频帧的pts

        video_system_time_diff: 记录最近一个视频pts 到现在的时间,即av_gettime_relative()/ 1000000.0 - is->vidclk.last_updated

        pre_audio_pts: 音频已经播放到的时间点,即已经播放的数据所代表的时间,通过已经播放的samples可以计算出已经播放的时间,在sdl_audio_callback中被设置

        audio_system_time_diff: video_system_time_diff

        //我要说的就是这个了,直接看下面的图,如果之前没看过这个博客的先看

       //他的博客。

         最终视频和音频的diff可以用下面的公式表示:

        diff = (pre_video_pts-pre_audio_pts) +(video_system_time_diff -  audio_system_time_diff)


       关于音视频同步 ffplay的同步方式解析_第1张图片

        如果diff<0, 则说明视频播放太慢了,如果diff>0,

        则说明视频播放太快,此时需要通过计算delay来调整视频的播放速度如果

        diffAV_SYNC_THRESHOLD_MAX 则不用调整delay?*/

 

        diff =get_clock(&is->vidclk) - get_master_clock(is);

 

        /* skip or repeatframe. We take into account the

           delay to computethe threshold. I still don't know

           if it is the bestguess */

       sync_threshold=FFMAX(AV_SYNC_THRESHOLD_MIN,FFMIN(AV_SYNC_THRESHOLD_MAX,delay));

        if (!isnan(diff)&& fabs(diff) < is->max_frame_duration) {

            if (diff <=-sync_threshold)

                delay =FFMAX(0, delay + diff);

            else if (diff >= sync_threshold&& delay > AV_SYNC_FRAMEDUP_THRESHOLD)

                delay = delay+ diff;

            else if (diff>= sync_threshold)

                delay = 2 *delay;

        }

    }

    av_dlog(NULL, "video:delay=%0.3f A-V=%f\n",

            delay, -diff);

    return delay;

}

 

 


你可能感兴趣的:(关于音视频同步 ffplay的同步方式解析)