ffmpeg 解析媒体流时间戳回绕

一 拿flv/rtmp为例,时间戳用4字节表示,最大范围约是42亿。

 

二 遇到问题,在rtmp推流过程中,有些服务器会在推流断开之后,hold住连接一段时间。

这样一来就会存在续时间戳的问题,有的服务器没有管时间戳,直接透传的。这样一来就会有个问题,

rtmp传输的时候,传输的是相对时间戳,回退的时间戳会被计算成负值。当然也有服务器通过发送绝对时间戳来避开这个问题。

 

在实际项目中,遇到这样的问题,使用公司自研的rtmp服务器,偶尔会出现时间戳超过了32bit表示的最大范围,这就奇怪了。

跟了一下ffmpeg的代码发现,ffmpeg有时间戳回绕判断逻辑,

static int64_t wrap_timestamp(const AVStream *st, int64_t timestamp)

{

if (st->internal->pts_wrap_behavior != AV_PTS_WRAP_IGNORE && st->pts_wrap_bits < 64 &&

st->internal->pts_wrap_reference != AV_NOPTS_VALUE && timestamp != AV_NOPTS_VALUE) {

if (st->internal->pts_wrap_behavior == AV_PTS_WRAP_ADD_OFFSET &&

timestamp < st->internal->pts_wrap_reference) // 当前时间戳小于reference时间戳。

return timestamp + (1ULL << st->pts_wrap_bits);

else if (st->internal->pts_wrap_behavior == AV_PTS_WRAP_SUB_OFFSET &&

timestamp >= st->internal->pts_wrap_reference)

return timestamp - (1ULL << st->pts_wrap_bits);

}

return timestamp;

}

这个reference时间戳是什么呢? 

// reference time stamp should be 60 s before first time stamp

pts_wrap_reference = ref - av_rescale(60, st->time_base.den, st->time_base.num);

是首帧时间戳 - 60s。  这样一来,如果推流的时候,时间戳不是从0开始的,就容易出现这种情况。假设第一次推流时间戳从100s开始,断开后马上重推,

时间戳从0开始,这样就满足条件了。 ffmpeg就会认为是时间戳超过32bit 能表示的最大范围,回绕了。

于是在计算的时间戳的时候就会加上32bit能表示的最大值。

 

因此: 流媒体服务器如果想hold住连接,建议还是做时间戳续上的逻辑,要不然容易引来很多问题。 要不就推流断开的时候,直接把源销毁,重新推流的时候,再重新创建就能避免上述问题。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值