ffmpeg 读取RTSP流 av_read_frame 阻塞 卡死 的问题

ffmpeg拉取RTSP流 正常操作不会有问题 但是如果途中,

把RTSP的流断了, 发现 会卡死 在avformat_find_stream_info函数中,

把这个函数注释掉的话就会卡死在av_read_frame中 ,大概需要30m才会返回 

网上搜了下 无论是 设置超时方法 还是  回调函数都不管用,不知道为什么。

经过测试实际的断流有两种情况:

1.是RTSP服务断了 ,这种情况 open_input 那里会返回失败,比较好处理

2.是RTSP服务没断,但是没有视频流了 这种情况会导致open_input成功,但是会导致程序一直卡死在av_read_frame函数里面  具体网上可以搜 FFMpeg源码里面就这么写了,

大体上有两种方法 设置超时处理 第一种是 通过av_dict_set函数设置timeout超时时间,但是我这么试了没有效果,所以只能是第二种方法,设置callback  经过测试 这种callback机制可以实现

具体原因下面FFmpeg代码这么写的 

 
static inline int retry_transfer_wrapper(URLContext *h, uint8_t *buf,
int size, int size_min,
int (*transfer_func)(URLContext *h,
uint8_t *buf,
int size))
{
int ret, len;
int fast_retries = 5;
int64_t wait_since = 0;
len = 0;
while (len < size_min) {
if ( ff_check_interrupt(&h->interrupt_callback))
return AVERROR_EXIT;
ret = transfer_func(h, buf + len, size - len);
if (ret == AVERROR(EINTR))
continue;
if (h->flags & AVIO_FLAG_NONBLOCK)
return ret;
if (ret == AVERROR(EAGAIN)) {
ret = 0;
if (fast_retries) {
fast_retries--;
} else {
if (h->rw_timeout) {
if (!wait_since)
wait_since = av_gettime_relative();
else if ( av_gettime_relative() > wait_since + h->rw_timeout)
return AVERROR(EIO);
}
av_usleep( 1000);
}
} else if (ret == AVERROR_EOF)
return (len > 0) ? len : AVERROR_EOF;
else if (ret < 0)
return ret;
if (ret) {
fast_retries = FFMAX(fast_retries, 2);
wait_since = 0;
}
len += ret;
}
return len;
}
 

可以看到这个while循环里面有一个判断有没有callback 如果没有callback 就会一直卡在这个循环里直到读到了数据,经过实际测试,如果没有callback 视频流断了 之后又重新打开的话,大概需要30-50S左右 av_read_frame会返回失败。可以看下ff_check_interrupt函数

 
int ff_check_interrupt(AVIOInterruptCB *cb)
{
if (cb & & cb- >callback)
return cb- >callback(cb- >opaque);
return 0;
}
 

直接返回callback的,只要是非0 就会跳出这个循环。

可以通过av_time 获取时间,然后在callback里面判断超时时间  比如3s 超过3s之后  callback返回非0 就可以 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值