锐英源软件
第一信赖

精通

英语

开源

擅长

开发

培训

胸怀四海 

第一信赖

当前位置:锐英源 / 开源技术 / C++开源技术 / VLC接收网络串流缓冲时间的计算
服务方向
软件开发技术服务
软件开发
办公财务MIS
股票
设备监控
网页信息采集及控制
多媒体
软件开发培训
Java 安卓移动开发
Java Web开发
网站前端开发
VC++
C++游戏开发培训
C#软件
C语言(Linux)
ASP.NET网站开发(C#)
C#软件+ASP.NET网站
SOCKET网络通信开发
COMOLE和ActiveX开发
C++(Linux)
汇编和破解
驱动开发
SkinMagicVC++换肤
流媒体开发
MicroStation二次开发
软件开发在线教育
计算机英语翻译
联系方式
固话:0371-63888850
手机:138-0381-0136
Q Q:396806883

VLC接收网络串流缓冲时间的计算

VLC版本2.0.1

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

1、最初的线索:

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

[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值的方法是否引入了又一个瓶颈。

友情链接
版权所有 Copyright(c)2004-2021 锐英源软件
公司注册号:410105000449586 豫ICP备08007559号 最佳分辨率 1024*768
地址:郑州大学北校区院(文化路97号院)内