PCR同步在非硬件精确时钟源的情况还是谨慎使用,gstreamer里面采用PCR同步,但是发现好多ffmpeg转的片儿,或者是CP方的片源,pcr打得很粗糙的,老是有跳帧等现象。
音视频同步,有三种方法,视频同步音频,音频同步视频,同步到外部时钟!
第三种,同步到外部时钟也就是PCR同步,和我上面说的那种同步方式,一样!
用的最多的还是,视频同步音频,为什么呢?音频的采样率是固定的,若音频稍有卡顿,都会很明显的听出来,反则视频则不如此,虽然表面上说的是30fps,不一定每一帧的间隔就必须精确到33.33ms,因为人肉眼是观察不出来的,所以视频的帧率可以是动态的,并不是严格标准的!
用视频同步音频,做法很简单!首先,音频线程只管自己独立解码播放。视频线程在显示之前只需要检测视频PTS是否大于音频PTS,若大,则等待音频PTS>=视频PTS,若小,则直接播放,小太多则可以直接丢弃(跳帧)。做法就如此简单!但前提是你编码器一定要打好正确的PTS,若没有则只有自己伪造PTS了!
音视频同步和帧率控制其实是一个东西。我们先不管音视频同步是什么,我们先来看看如何进行帧率控制。明白了帧率控制,音视频同步就有了基础认识。
1、帧率控制
帧率控制的方法有千万种,最2的方法无非是每解码/显示一帧就进行延时,为了方便我们在进行帧率控制的同时能够理解音视频同步,我在此采用PCR同步的方式来进行帧率控制。网上关于PCR同步的原理讲了一大堆,有些很是难懂,一点儿也不通俗,我这里来给大家把晦涩的理论以最通俗的方式表达出来。
拿1280x720@30p的视频源来做理解。30P也就是说每秒钟30帧,也就是每一帧需要1/30*1000ms大概也就是每隔33.33ms就必须显示一帧。

要想知道如何正确的进行解码,就必须先了解编码端是如何工作的!一般编码器会以27MHZ的时钟来进行编码,这些都不重要,重要的就是,编码器一般默认会每隔30ms会发送一次PCR信息,这里的PCR信息就很重要了,他是我们在解码端解码进行帧率控制的时间基点,同时也是我们以后在进行同步校准的校准基点。

说了这么多,那么我就拿个PCR信息来给大家分析分析。PCR信息是33bit组成的一个int64的数据,从解复用器里面出来我们可以得到一个很庞大的数字,看这个我们当然看不太懂!但是如果知道这个数字如何生成的那就好理解多了!

PCR信息说白了就是给视频的时间戳信息,比如一部电影是从  (00:01:23:033)时 : 分 : 秒 : 毫秒 开始,那么这个时间基点生成的PCR信息就是 (((00*60+1)*60+23.033)*90K)%2^33。90K为27M,300分频的结果。刚刚说了PCR会每30ms更新一次,那么PCR每次递增的数值就为0.030*90K=2700,这和PTS的值原理是相同的,这里先提一下,其实这个增量也不重要。我们需要的只是第一个PCR值就OK,但是如果考虑到后期校准,还是要用到以后的PCR值的。这里先不管校准的问题!

说了PCR,还有个值是我们需要的,那就是PTS。其实对于硬解码器来说DTS信息我们根本就不需要管他,我们只需要一帧一帧的把数据送进去,顺便把每一帧的PTS信息送进去,解码器送出来的就是排列好了PTS信息的帧了(ffmpeg)。可以试着把解复用后的每一帧的PTS打印出来,你会发现在解复用后一般是这样排列的9000
3000 6000 18000 12000
15000.......这种是AVC编码的使用的是预测编码决定的,先不管他,你只管这样把每一帧依次送入解码器,解码器解码输出后自然就排列成3000
6000 9000 12000 15000 18000这才是我们需要的PTS!至于什么是PTS,实际上和PCR原理差不多,但是有个关键的地方PTS的增量值可不是默认的30ms了,他是由视频的帧率来决定的!说道重要的地方了哈!根据上面PCR的原理,如果是30p的视频那么每一帧就是1/30这么多的增量,再乘90K=3000。

说透了,我们这里就是利用这个PTS值来进行同步顺便进行帧率控制!
关键的地方来了!
如果视频流现在来了,我们先获取到第一个PCR值为1230000,我们现在马上在解码器端重建一个90K的时钟!这就是关键所在,至于如何重建90K的时钟,说白了就是开一个定时器,定时时间为1/90K(11.11us),每隔11.11us我们就把PCR计数值+1,同时这时候解码器也在工作,试想一下,如果是30P的视频,也就是33.33ms显示一次,那么当过了33.33ms后,PCR的数值加到好多了呢?没错就是33.33ms/11.11us=3000,这个增量不是和PTS的增量一摸一样!这时候你只需要在解码线程里判断当前帧的PTS是不是和这个PCR相等,如果相等就显示,如果PCR大可以丢弃当前帧,也就是说的跳帧,如果PCR小说明解码快了,这个时候就可以等待定时器线程到PCR==PTS。
这样就很巧妙的解决了帧率控制的问题了!同理,音视频同步也可以这样!你可以让音频的PTS去和PCR对比!其实大多数情况下都是以视频同步音频,音频解码不用管它,直接解码播放就OK了,你只需要进行帧率控制就OK了!同时注意随着时间的推移有可能出现延时,那么这个时候就需要重新来获取PCR来更新定时器线程里面的PCR基值了!

通俗的解释下音视频同步里pcr作用的更多相关文章

  1. FFmpeg简易播放器的实现-音视频同步

    本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10284653.html 基于FFmpeg和SDL实现的简易视频播放器,主要分为读取视频文 ...

  2. ffmpeg 2.3版本号, 关于ffplay音视频同步的分析

    近期学习播放器的一些东西.所以接触了ffmpeg,看源代码的过程中.就想了解一下ffplay是怎么处理音视频同步的,之前仅仅大概知道通过pts来进行同步,但对于怎样实现却不甚了解,所以想借助这个机会, ...

  3. ffplay的音视频同步分析

    以前工作中参与了一些音视频程序的开发,不过使用的都是芯片公司的SDK,没有研究到更深入一层,比如说音视频同步是怎么回事.只好自己抽点时间出来分析开源代码了,做音视频编解码的人都知道ffmpeg,他在各 ...

  4. (转)ffplay的音视频同步分析之视频同步到音频

          以前工作中参与了一些音视频程序的开发,不过使用的都是芯片公司的SDK,没有研究到更深入一层,比如说音视频同步是怎么回事.只好自己抽点时间出来分析开源代码了,做音视频编解码的人都知道ffmp ...

  5. WebRTC 音视频同步原理与实现

    所有的基于网络传输的音视频采集播放系统都会存在音视频同步的问题,作为现代互联网实时音视频通信系统的代表,WebRTC 也不例外.本文将对音视频同步的原理以及 WebRTC 的实现做深入分析. 时间戳 ...

  6. Android 音视频同步机制

    一.概述 音视频同步(avsync),是影响多媒体应用体验质量的一个重要因素.而我们在看到音视频同步的时候,最先想到的就是对齐两者的pts,但是实际使用中的各类播放器,其音视频同步机制都比这些复杂的多 ...

  7. Android 音视频同步(A/V Sync)

    1.  音视频同步原理 1)时间戳 音视频同步主要用于在音视频流的播放过程中,让同一时刻录制的声音和图像在播放的时候尽可能的在同一个时间输出. 解决音视频同步问题的最佳方案就是时间戳:首先选择一个参考 ...

  8. ffplay(2.0.1)中的音视频同步

    最近在看ffmpeg相关的一些东西,以及一些播放器相关资料和代码. 然后对于ffmpeg-2.0.1版本下的ffplay进行了大概的代码阅读,其中这里把里面的音视频同步,按个人的理解,暂时在这里作个笔 ...

  9. libstagefright 音视频同步方案

    1:音视频数据都有一个list,用于存放解码后的数据:    List mFilledBuffers; 2:解码后的音视频数据不断的往list中存放,不做音视频同步方面的时间上控制    mFille ...

随机推荐

  1. static静态变量-投票案例

    public class Voter { String name; //名字 private static int count; //投票数 public Voter() {} public Vote ...

  2. Visual Studio Debug和Release的区别及obj的作用

    一.Debug和Release的区别      1.Debug:调试版本,包含调试信息,所以容量比Release大很多,并且不进行任何优化(优化会使调试复杂化,因为源代码和生成的指令间关系会更复杂), ...

  3. js封装的一行半显示省略号。(字数自由控制)

    $(function() { //控制一行半隐藏 (function ($) { $.fn.displayPart = function (opts) { $(this).each(function ...

  4. barrier and Fence

    barrier 管理的是commandbuffer里面 command之间 fence管理的是queue之间 queue和cpu之间的顺序 通过flag比如等待所有面片画完 ------------- ...

  5. ES6里关于数字的拓展

    一.指数运算符 ES6引入的唯一一个JS语法变化是求幂运算符,它是一种将指数应用于基数的数学运算.JS已有的Math.pow()方法可以执行求幂运算,但它也是为数不多的需要通过方法而不是正式的运算符来 ...

  6. 搭建Git本地服务器(转)

    http://www.cnblogs.com/trying/archive/2012/06/28/2863758.html 当前任务,学习中... 公司小范围用法:  服务器上做的: 在服务器上建立一 ...

  7. 【AS3 Coder】任务五:Flash 2D游戏的第二春(中)

    在上一节中,我们介绍了如何构建我们小小的90度角RPG游戏的背景,在这一节中我将为列位带来重头戏部分,隆重介绍我们的主角及NPC登场,噔噔噔噔……掌声在哪里?! 额,没听到掌声,罢了,直接开场吧. 本 ...

  8. Spark Streaming与Storm的对比及使用场景

    Spark Streaming与Storm都可以做实时计算,那么在做技术选型的时候到底应该选择哪个呢?通过下图可以从计算模型.计算延迟.吞吐量.事物.容错性.动态并行度等方方面进行对比. 对比点    ...

  9. zabbix监控php-fpm

    1.启用php-fpm的状态功能 [root@web01 ~]# vim /etc/php-fpm.d/www.conf 121 pm.status_path = /php_status [root@ ...

  10. Solidworks 如何快速完全定义草图

    工具-尺寸标注-完全定义草图