原帖地址:http://blog.csdn.net/coroutines/article/details/7472743

VLC版本2.0.1

最近研究IP-STB音视频同步问题,发现方案自带的自动STC在网络延时过大时,不能成功同步音视频。在参考了VLC的串流播放机制后,以为适当缓冲可以解决此问题,可惜最终结果是稍有缓解,并不能从根本上解决。但这种缓冲时间的计算,对于基于网络这种音视频数据的注入有一定的参考意义。

1、最初的线索:

使用 -vvv 参数 启动VLC时,提示:

命令行启动vlc: ./vlc.exe -vvv

[0xb73005f0] main input debug: Buffering 0%
[0xb73005f0] main input debug: Buffering 3%
[0xb73005f0] main input debug: Buffering 6%
[0xb73005f0] main input debug: Buffering 9%
[0xb73005f0] main input debug: Buffering 12%
[0xb73005f0] main input debug: Buffering 15%
[0xb73005f0] main input debug: Buffering 18%
[0xb73005f0] main input debug: Buffering 21%
[0xb73005f0] main input debug: Buffering 24%
[0xb73005f0] main input debug: Buffering 27%

可以查找到这个缓冲过程的打印是从src/input/es_out.c:658行输出的。函数EsOutDecodersStopBuffering的作用是判断当前缓冲流的长度i_stream_duration是否达到预置的i_buffering_duation长度,是则停止缓冲,否则返回等待。

接下来是查i_stream_duration和i_buffering_duation如何计算。

2、i_stream_duration的计算:

在EsOutDecodersStopBuffering中,i_stream_duration是通过input_clock_GetState来获取。而input_clock_GetState是取一个类型为input_clock_t对象的俩个clock_point_t对象成员last和ref的i_stream的差值作为已缓冲数据的长度。

继续查找i_stream值的计算,可以发现i_stream只有在clock_point_Create中进行的设置,而last和ref对象的i_stream值是在input_clock_Update中做了更新,而用于更新i_stream的数据由i_ck_stream传入。input_clock_Update函数的调用位于es_out.c:2324行,该段代码用于设置input_clock_t对象的pcr值,上层传入的命令是ES_OUT_SET_GROUP_PCR,传入此命令的函数只有一个ts.c:2173行的PCRHandle。

查PCRHandle的代码可知,pcr的计算是直接从ts包中获取adaption字段的pcr数据,按照90kHz的时钟转换为秒,并乘以1000000换算成微秒,传递给input_clock_Update,到此完成了i_stream_duration的计算。

3、i_buffering_duration的计算:

在EsOutDecodersStopBuffering中,i_buffering_duration是一个es_out_sys_t对象的i_pts_delay属性再加上另外几个参数来确定。这里我只研究了i_pts_delay的获取,在我的测试中,其余几个值均为0。

es_out_sys_t对象是EsOutDecodersStopBuffering的es_out_t型参数out传入的,回溯代码的调用过程,EsOutDecodersStopBuffering <-EsOutControlLocked <-EsOutControl <-es_out_vaControl <-es_out_control <-CmdExecuteControl,在这里out换成了另一个es_out_t型参数p_out,继续回溯,CmdExecutedControl <-ControlLocked < -Control <-es_out_vaControl <-es_out_Control <-PCRHandle,这里的p_out是demux_t型参数p_demux的成员,PCRHandle <-GatherPES <-Demux <-demux_Demux <-MainLoopDemux,这里的p_demux是input_thread_t型对象p_input成员,再回溯,MainLoopDemux <-MainLoop <-Run,p_input在input.c:550行通过Init函数初始化。

再读Init部分代码,可以发现在input.c:1258行InitSourceInit函数后,i_pts_delay的值发生变化,往下深入,会发现在input.c:2644行,有一个ACCESS_GET_PTS_DELAY操作,最终对应到我的测试中是udp.c:173行,VLC获取了一个叫做:network-caching参数的值,这个值配置的是1000,我猜测应该是ms,返回时又乘以了1000,转换为微秒,准备与i_stream_duration值进行比较。

总结:

这次测试只做了基于udp的组播播放,其它协议可能还有许多细节与udp不同,等到遇到时再进行分析。

读了许久的TS协议,在实际应用中才发现许多东西跟想像的都不同,脱离实际的空想终究是不能成事的。

VLC这个基于PCR的缓冲长度的机制对于我解决不同步的问题,虽没有大的帮助,但应用到播放不同码率的网络串流方面,我想会有一些作用。假设我们开固定大小的缓冲,由于数据传输效率上的问题,经常会遇到解码器缓冲区上溢或下溢的问题,但如果我采用基于时间的缓冲,应该会有一定的改善,只是不知这种分析实时PCR值的方法是否引入了又一个瓶颈。

VLC接收网络串流缓冲时间的计算 (转)的更多相关文章

  1. 两个VLC实现播放串流测试

    实现原理: 一个VLC打开视频文件发布串流(格式HTTP.RTP.RTSP等),另一个VLC打开串流播放 发布串流步骤: 1.菜单“媒体”->“流”,先添加视频文件.选择“串流”,如下图: 2. ...

  2. 两个VLC实现播放串流测试 (转)

    实现原理: 一个VLC打开视频文件发布串流(格式HTTP.RTP.RTSP等),另一个VLC打开串流播放 发布串流步骤: 1.菜单“媒体”->“流”,先添加视频文件.选择“串流”,如下图: 2. ...

  3. 【嵌入式开发】树莓派+官方摄像头模块+VLC串流实时输出网络视频流

    sudo apt-get update sudo apt-get install vlc sudo raspivid -o - -t 0 -w 640 -h 360 -fps 25|cvlc -vvv ...

  4. Windows 11实现直播,VLC超简单实现捕获、串流、播放

    上一篇文章说了搭建Nginx的rtmp服务.实现直播功能 期间发现一个更便捷的工具 VLC media play,官方下载:https://www.videolan.org 1.傻瓜式安装,略过 2. ...

  5. 使用VLC创建组播流

    vlc既是一个播放器,又可以成为一个流媒体服务器.最近需要做udp组播播放相关的东西,需要先在本地搭建一个udp组播服务器,因为机器上本来就装有vlc,所以就用它了. 第一步: 点击媒体->流 ...

  6. 使用VLC推送TS流(纯图版)

    在没有编码器的情况下,可以使用VLC进行推送TS+UDP流 操作步骤如下: 一.UDP方式: 媒体-->流 选用要播放的文件,可以选择多个来播放,选择串流播放 这里直接点击下一步 需要选择在本地 ...

  7. ffmpeg利用libav库把yuv视频流转换为TS串流

    今天到月末了,才发我这个月的第一篇文章,因为这个月前三周一直在看ffmpeg的libavcodec和libavformat两个库源码.实验室要做一个“小传大”的软件,就是android手机或平板电脑的 ...

  8. 调用Live555接收RTSP直播流,转换为Http Live Streaming(iOS直播)协议

    Live555接收RTSP直播流,转换Http Live Streaming(iOS直播)协议 RTSP协议也是广泛使用的直播/点播流媒体协议,之前实现过一个通过live555接收RTSP协议,然后转 ...

  9. -1-4 java io java流 常用流 分类 File类 文件 字节流 字符流 缓冲流 内存操作流 合并序列流

      File类 •文件和目录路径名的抽象表示形式 构造方法 •public File(String pathname) •public File(String parent,Stringchild) ...

随机推荐

  1. 数据库使用B+树原理

    转载:http://zhuanlan.51cto.com/art/201808/582078.htm https://www.cnblogs.com/vincently/p/4526560.html( ...

  2. 硬盘安装CentOS 6.0(超级详细图文教程)

    硬盘安装CentOS 6.0(超级详细图文教程) 来源:   引言: 电脑系统是Windows XP,电脑没有光驱.手头没有U盘.没有移动硬盘.电脑主板不支持U盘启动,在这种情况下想安装CentOS ...

  3. 关于C#引用dll动态链接库文件的注释问题

    1.dll动态库文件项目生成属性中要勾选"XML文档文件" 注意:1).要选中项目,查看项目属性,选中解决方案是找不到的.2).XML文件的名字不要修改. 2.添加引用时XML文件 ...

  4. ssh远程操作服务器

    登录方式 ssh account@192.168.xxx.xxx 输入密码 远程上传下载文件 上传: scp filepath acount@192.168.xxx.xxx:path filepath ...

  5. PHP连接不上MySQL解决方案总结

    1. 获取当前 mysql.default_socket.mysqli.default_socket.pdo_mysql.default_socket 配置信息 建立一个 PHP 文件, 显示 php ...

  6. 【项目经验】macpro上安装office办公软件并破解

    链接: https://pan.baidu.com/s/1i5hyKO9 密码: 7zjf 如果本机原有office,先卸载 双击pkg文件安装office for Mac 2016 安装完不要做打开 ...

  7. goaccess nginx日志分析工具简单使用

    goaccess 是一个比较方便的支持实时的日志分析工具,比较方便,同时安装&&配置简单 安装 centos yum yum install -y goaccess 运行 我的ngin ...

  8. CentOS7 RPM安装 rabbitmqDownloads on Bintray

    下载 0依赖Erlang RPM for RabbitMQ包(https://github.com/rabbitmq/erlang-rpm) https://dl.bintray.com/rabbit ...

  9. LOJ 6485 LJJ 学二项式定理——单位根反演

    题目:https://loj.ac/problem/6485 \( \sum\limits_{k=0}^{3}\sum\limits_{i=0}^{n}C_{n}^{i}s^{i}a_{k}[4|(i ...

  10. 阿里云OSS linux使用备忘录

    ossutil config example: accessKeyId = "AccessKeyId"; accessKeySecret = "AccessKeySecr ...