• 音视频技术 即时通讯SDK


    视频流中的DTSPTS究竟是什么
        DTS(解码时间戳)和PTS(显示时间戳)各自是解码器进行解码和显示帧时相对于SCR(系统參考)的时间戳。SCR能够理解为解码器应该開始从磁盘读取数据时的时间。
        mpeg(当前很多其它的是使用H.264视频技术。如AnyChat SDK)
    文件里的每个包都有一个SCR时间戳而且这个时间戳就是读取这个数据包时的系统时间。

    通常情况下,解码器会在它開始读取mpeg流时启动系统时钟(系统时钟的初始值是第一个数据包的SCR值,通常为0但也能够不从0開始)。
        DTS 
    时间戳决定了解码器在SCR时间等于DTS时间时进行解码,PTS时间戳也是类似的。通常,DTS/PTS时间戳指示的是晚于音视频包中的SCR的一个时 间。

    比如,假设一个视频数据包的SCR100ms(意味着此包是播放100ms以后从磁盘中读取的),那么DTS/PTS值就差点儿相同是200 /280ms。表明当SCR200ms时这个视频数据应该被解码并在80ms以后被显示出来(视频数据在一个buffer中一直保存到開始解码)下 溢通常发生在设置的视频数据流相关mux率太高。
          假设mux率是1000000bits/sec(意味着解码器要以1000000bits/sec的速率 读取文件),但是视频速率是2000000bits/sec(意味着须要以2000000bits/sec的速率显示视频数据),从磁盘中读取视频数据时 速度不够快以至于1秒钟内不可以读取足够的视频数据。这样的情况下DTS/PTS时间戳就会指示视频在从硬盘中读出来之前进行解码或显示(DTS/PTS时间戳就要比包括它们的数据包中的SCR时间要早了)。


            
    现在依靠解码器。这基本已经不是什么问题了(虽然MPEG文件由于应该没有下溢而并不全然符合MPEG标准)。一些解码器(非常多著名的基于PC的播放器)尽可能快的读取文件以便显示视频。能够的话直接忽略SCR
           
    注意在你提供的列表中,平均的视频流速率为~3Mbps3000000bits/sec)可是它的峰值达到了14Mbps(相当大,DVD限制在 9.8Mbps内)。这意味着mux率须要调整足够大以处理14Mbps的部分。 bbMPEG计算出来的mux率有时候太低而导致下溢。
    你计划让视频流速率这么高么?这已经超过了DVD的说明了,并且非常可能在大多数独立播放当中都不能播放。

    假设你不是这么计划。我会从1添加mquant的值并且在视频设置中将最大码流设置为9Mbps以保持一个小一点的码流。
         
    假设你确实想让视频码率那么高,你须要增大mux率。从提供的列表能够得出bbMPEG使用14706800bits/sec或者1838350bytes /secmux率(总数据速率为:1838350bytes/sec14706800bits/sec)行)。你在强制mux率字段设置的值应该是以
    bytes/sec
    为单位并被50整除。

    所以我会从367671838350/50)開始,一直添加直到不会再出现下溢错误为止。
    音视频同步原理[ffmpeg]
    ffmpeg
    对视频文件进行解码的大致流程:
    1. 
    注冊全部容器格式和CODEC: av_register_all()
    2. 
    打开文件: av_open_input_file()
    3. 
    从文件里提取流信息: av_find_stream_info()
    4. 
    穷举全部的流。查找当中种类为CODEC_TYPE_VIDEO
    5. 
    查找相应的码器: avcodec_find_decoder()
    6. 
    打开编解码器: avcodec_open()
    7. 
    为解码帧分配内存: avcodec_alloc_frame()
    8. 
    不停地从码流中提取中帧数据: av_read_frame()
    9. 
    推断帧的类型,对于视频帧调用: avcodec_decode_video(
    10. 
    解码完后。释放解码器: avcodec_close()
    11. 
    关闭输入文件:av_close_input_file()
    output_example.c 
    AV同步的代码例如以下(我的代码有些改动),这个实现相当简单,只是挺说明问题。


    音视频同步-时间戳 
    媒体内容在播放时,最令人头痛的就是音视频不同步。从技术上来说,解决音视频同步问题的最佳方案就是时间戳:首先选择一个參考时钟(要求參考时钟上的时间是线性递增的)。生成数据流时根据參考时钟上的时间给每一个数据块都打上时间戳(一般包含開始时间和结束时间);在播放时,读取数据块上的时间戳,同一时候參考当前參考时钟上的时间来安排播放(假设数据块的開始时间大于当前參考时钟上的时间。则不急于播放该数据块。直到參考时钟达到数据块的開始时间;假设数据块的開始时间小于当前參考时钟上的时间,则尽快播放这块数据或者索性将这块数据丢弃,以使播放进度追上參考时钟)。

            
    可见,避免音视频不同步现象有两个关键——一是在生成数据流时要打上正确的时间戳。假设数据块上打的时间戳本身就有问题。那么播放时再怎么调整也于事无补。假如。视频流内容是从0s開始的。假设10s时有人開始说话,要求配上音频流,那么音频流的起始时间应该是10s。假设时间戳从0s或其他时间開始打,则这个混合的音视频流在时间同步上本身就出了问题。打时间戳时。视频流和音频流都是參考參考时钟的时间。而数据流之间不会发生參考关系。也就是说,视频流和音频流是通过一个中立的第三方(也就是參考时钟)来实现同步的。

    第二个关键的地方,就是在播放时基于时间戳对数据流的控制,也就是对数据块早到或晚到採取不同的处理方法。图2.8中,參考时钟时间在0-10s内播放视频流内容过程中。即使收到了音频流数据块也不能马上播放它,而必须等到參考时钟的时间达到10s之后才干够,否则就会引起音视频不同步问题。


            
    基于时间戳的播放过程中,只对早到的或晚到的数据块进行等待或高速处理,有时候是不够的。

    假设想要更加主动而且有效地调节播放性能,须要引入一个反馈机制,也就是要将当前数据流速度太快或太慢的状态反馈给,让源去放慢或加快数据流的速度。

    熟悉DirectShow的读者一定知道,DirectShow中的质量控制(Quality Control)就是这么一个反馈机制。DirectShow对于音视频同步的解决方式是相当出色的。

    WMF SDK在播放时仅仅负责将ASF数据流读出并解码,而并不负责音视频内容的终于呈现。所以它也缺少这种一个反馈机制。

  • 相关阅读:
    初学:利用mybatis-generator自动生成代码
    数组求和forEach方法
    Node.js热部署代码,实现修改代码后自动重启服务方便实时调试
    nodejs中文乱码问题
    简单说一下SS的原理
    Spring Cloud Eureka 3 (Eureka client注册服务提供者)
    Spring Cloud Eureka 2 (Eureka Server搭建服务注册中心)
    Spring Cloud Eureka 1(eureka简介)
    eclipse中创建多模块maven web项目
    eclipse中创建maven web项目
  • 原文地址:https://www.cnblogs.com/gavanwanggw/p/6724181.html
Copyright © 2020-2023  润新知