使用vlc推流rtsp,同时本地播放和客户端播放rtsp,延时控制

用vlc推送rtsp流的同时,在本地播放流,怎么控制本地播放的流延时和发送rtsp流的延时?
接受的 怎么控制播放的延时?
总结下使用vlc进行发送rtsp流,和vlc播放rtsp流,中间导致时间延迟的原因和可调整策略。
由于数据走网络的缘故,从服务端发送到客户端,数据需要被服务端切片打包,又在客户端接受组包,为了保证接受端的流程播放,vlc在发送数据端,和接受网络数据端,都提供了 延时缓冲的控制接口。
现使用vlc发送rtsp流,发流的同时对该流数据进行本地播放,查看数据流在各个环节存在的延时
服务端代码:

ibvlc_instance_t*vlc; 
libvlc_media_player_t *media_player;
libvlc_media_t *media;
vlc = libvlc_new(0, NULL); 
if(vlc == NULL)
{
  printf("wang errolibvlc_new \n");
  return -1;
}
media_player =libvlc_media_player_new(vlc);
media =libvlc_media_new_path(vlc,"test.mp4");
libvlc_media_add_option(media,":sout=#duplicate{dst=rtp{sdp=rtsp://:10086/canok,caching=500},dst=display{delay=1500}}");

libvlc_media_player_set_media(media_player,media);
libvlc_media_player_play(media_player);

数据的流向和对应的延时:

在这里插入图片描述

上面命令的解析::sout=#duplicate{dst=rtp{sdp=rtsp://:10086/stream,caching=500},dst=display{delay=1500}}

数据源输出到duplicate模块, 分成两份:(参数用逗号隔开,具体模块支持那些参数,在对应源码里面一般都有一个数组ppsz_sout_options)
dst=rtp{sdp=rtsp://:10086/stream,caching=500}
dst=display{delay=1500}

rtp发送模块,两个参数:rtsp://:10086/stream 和 caching=500
caching = 500 即延时 500 ms ,500毫秒。对于图中的delay A
diplay显示模块,一个参数,delay=500,延时 500ms. 途中delay D

接收客户端代码:

 libvlc_instance_t *vlc; libvlc_media_player_t *media_player; libvlc_media_t *media; 
const char * const vlc_args[] = { "--network-caching=1000", };

vlc =  libvlc_new(sizeof(vlc_args)/sizeof(vlc_args[0]), vlc_args);
if(vlc == NULL)
{
   printf("wang errolibvlc_new \n");
   return -1;
}
media_player =libvlc_media_player_new(vlc);
media = libvlc_media_new_location(vlc,"rtsp://192.168.43.233:8989/stream");
libvlc_media_player_set_media(media_player,media);
libvlc_media_player_play(media_player);

上面的 network-caching, vlc启动的时候会根据此选项,在input线程中调用 DEMUX_GET_PTS_DELAY获取delay,由于加载的时live555模块,在live555.cpp的控制中走DEMUX_GET_PTS_DELAY获取到系统设置的变量“network-caching”的值。即图中的delayB

总的来看,期望 delayA+delayB+delayC = delayD而DelayC, 而delayC,受具体网络环境和协议解析的影响,其他几个部分,都是可以配置指定的

上面几个delay配置的具体作用代码:

  • DelayB

上图 ,输入端的延时,DelayB:
file-caching network-caching 等即是配置输入端的延时缓冲,
是vlc的一个“全局变量”,如果输入是网络,则起作用的是network-caching,如果输入是文件,则其作用的是network-caching. 作用机制,input.c输入线程调用demux_Control( in->p_demux, DEMUX_GET_PTS_DELAY, &in->i_pts_delay ); 从demux模块获取delay, 还有一个STREAM_GET_PTS_DELAY,估计是废弃了, 因为播放速率即播放延时的控制,从demux出来就是已经经过速度处理的流数据了,使用live555获取rtsp数据流时,就是liv555.cpp文件中的 DEMUX_GET_PTS_DELAY 从 network-caching 变量中读取。
而这个延时发挥作用的地方在, input.c 中会设置 es_out的 “时钟源” clock, 这样es_out所有的流,音频和视频,都会delay. 即上图的delayB
如果是仅仅对一个流进行delay,
es_out对它的输出 decoder.c decoder的创建者进行设置 p_owner->i_ts_delay , decoder线程解码出帧后需要根据这个 i_ts_delay进行等待和时间戳的修正。 这个decoder的delay,只是对单一的流进行差异化delay,容易误导。

  • DelayA
    则是数据解复用出来后, 给到 rtp发送之前,把所有数据 的时间戳进行了 + delay
  • DelayD 同A一样

这几个Delay, 看上去就是 将时间戳加了一个值,他的具体作用是如何呢?既然是延时,肯定有一个地方在 wait:
vlc中用到的时间精度,微秒,百万分之一秒。
vlc中用到的系统时间,mdate(), linux(包括android)系统上这个 mdate获取的是系统启动,到当前的运行时间(这个时间不会因为你用户校对了一下系统的时间点而变化,除非你重启。)

简单测试了下,在demux 输出模块,decoder输出模块,vout显示模块加上mdate的调试信息,可以看出,这个delay是在 vout模块实际作用的。也就是在解码都已经解完了,放在输出缓冲队列里面因为延时,没有立即显示。 如果使用:
libvlc_media_add_option(media, “:sout=#display{delay=7000}”)
则数据会堆积在 最后的display 显示缓冲区。
如果是 file-caching network-caching,则数据会在input中堆积

在这里插入图片描述

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值