av_read_frame 返回-5错误解决

问题描述

在使用ffmpeg做一个播放器的时候,拉取https流,av_read_frame 读包的时候总是偶尔出现返回-5的情况,-5其实是EIO错误,AVERROR(EIO) 返回为5。

#define EIO             5

这个问题给我造成了很大的麻烦,所以这里记录一下排查的过程以及解决方法,希望能帮忙遇到相同场景的同学。

原因调查

目前使用ffmpeg自带log日志,进行回调写入日志发现,返回-5的时候日志输出为下面,啥用没有

Error in the pull function.

猜测原因

猜测原因验证
由于资源文件损坏使用VLC拉流同样可以成功,排除
由于网络抖动使用工具设置丢包率50%,未能必现,排除
代码流程播放本地文件,发现未能出现该场景,排除
解码耗时打印拉流和解码时间,只有几十微秒,排除

因为我的拉流以及解码是放在同一个线程里的,之前在网上寻找帮助看过有人说是因为解码耗时导致线程占用CPU高,需要放在不同线程,但是我只拉MP3,也就是只有音频解码,同时打印了时间,发现整个下来才几十微秒,所以没有尝试编解码放两个线程的方案。

但是验证问题已经进行不下去了,所以笔者只能尝试是否能绕过该问题

目前尝试绕过该问题,解决方案:

解决方案效果
出现问题时再次拉流会一直出现EIO错误,没有效果
出现问题时,定位后面一秒播放无作用,同时av_log 输出invalid new backstep -1
出现问题时,释放资源再拉流可以再次重新拉流,但是有几率会再次出现EIO错误,同时,重置资源会造成耗时
尝试将解码缓存加大可以降低出错频率,不能根治

|版本声明:山河君,未经博主允许,禁止转载


解决方案:

后面阅读ffmpeg官方文档,发现有一个文档专门介绍协议的:文档连接
里面有对于http协议属性设置,遂增加了以下几个属性

		AVDictionary *format_opts = NULL;
		av_dict_set(&format_opts, "stimeout", std::to_string(1 * 1000000).c_str(), 0); //设置链接超时时间(us)
		av_dict_set_int(&format_opts, "multiple_requests", 1, 0);
		av_dict_set_int(&format_opts, "read_ahead_limit", INT_MAX, 0);

        //Open
        if (avformat_open_input(&pFormatCtx_, UTF8ToGBK(strFileNameUTF8).c_str(), NULL, &format_opts) != 0) 

stimeout:连接超时时间
multiple_requests:Use persistent connections if set to 1, default is 0. //设置为1为长连接
read_ahead_limit:Amount in bytes that may be read ahead when seeking isn’t supported. Range is -1 to INT_MAX. -1 for unlimited. Default is 65536. //预读限制 默认值为 65536

后没有发生错误

原因分析:

根据测试,应该是multiple_requests该属性导致了读包返回-5

因为使用的是http协议,http分为长连接和短连接,如果不设置属性,默认为短连接
而长连接和短连接的区别在于:

短连接定义:

Client方与server每进行一次报文收发交易时才进行通讯连接,交易完毕后立即断开连接。此方式常用于一点对多点通讯。

短连接的操作步骤是:建立连接——数据传输——关闭连接…建立连接——数据传输——关闭连接

长连接定义:

client方与server方先建立连接,连接建立后不断开,然后再进行报文发送和接收。这种方式下由于通讯连接一直存在。此种方式常用于P2P点对点的通信。

长连接的操作步骤是:建立连接——数据传输…(保持连接)…数据传输——关闭连接

个人觉得可能是每次连接拉取一个包后,就会断开连接,然后再进行连接导致该问题的出现。

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值