当前位置: 首页 > news >正文

FFmpeg报错:Connection to tcp://XXX?timeout=XXX failed: Connection timed out

一、现象

通过FFmpeg(FFmpeg的版本是5.0.3)拉摄像机的rtsp流获取音视频数据,执行命令:

./ffmpeg -timeout 3000000 -i "rtsp://172.16.17.156/stream/video5"

报错:Connection to tcp://XXX?timeout=XXX failed: Connection timed out。

二、Wireshark抓包分析

执行FFmpeg命令的本机ip为192.168.16.13,摄像机的ip为172.16.17.156。通过Wireshark抓包可以发现,执行上述命令时,TCP三次握手失败,出现“TCP Retransmission”:

这意味着TCP重传了。图中的“TCP Retransmission”是重传标记,No2到No6的包是重传包,也就是TCP客户端(执行FFmpeg命令的本机)的SYN发出去之后没有收到摄像机的syn ack,TCP客户端持续发syn,重传5次之后就停止了。所以这可能就意味着摄像机掉线/本机访问摄像机不正常/防火墙iptables规则存在问题,我们得要进行一下网络检查。

三、FFmpeg源码分析

调试FFmpeg源码,可以看到

“Connection to tcp://XXX?timeout=XXX failed: Connection timed out”这个错误

是由源文件libavformat/network.c中的函数ff_connect_parallel 中的

av_log(h, AV_LOG_ERROR, "Connection to %s failed: %s\n",h->filename, errbuf);

这一行打印出来的,此时变量last_err的值为-110。

整个程序的调用堆栈为:avformat_open_input

->  if ((ret = s->iformat->read_header(s)) < 0)      [实际执行rtsp_read_header]

-> ret = ff_rtsp_connect(s);

->  if ((ret = ffurl_open_whitelist(&rt->rtsp_hd, tcpname, AVIO_FLAG_READ_WRITE,

&s->interrupt_callback, NULL, s->protocol_whitelist, s->protocol_blacklist, NULL)) < 0)

-> ret = ffurl_connect(*puc, options);

-> uc->prot->url_open(uc, uc->filename, uc->flags);      [实际执行tcp_open]

-> ret = ff_connect_parallel(ai, s->open_timeout / 1000, 3, h, &fd, customize_fd, s);
 

-> av_log(h, AV_LOG_ERROR, "Connection to %s failed: %s\n", h->filename, errbuf);

所以为什么会执行av_log(h, AV_LOG_ERROR, "Connection to %s failed: %s\n", h->filename, errbuf)这条语句呢,是因为last_err的值为-110。而last_err是在执行了函数ff_poll_interrupt后才变为-110的。

我们 看一下函数ff_poll_interrupt 的源码:

static int ff_poll_interrupt(struct pollfd *p, nfds_t nfds, int timeout,AVIOInterruptCB *cb)
{int runs = timeout / POLLING_TIME;int ret = 0;do {if (ff_check_interrupt(cb))return AVERROR_EXIT;ret = poll(p, nfds, POLLING_TIME);if (ret != 0) {if (ret < 0)ret = ff_neterrno();if (ret == AVERROR(EINTR))continue;break;}} while (timeout <= 0 || runs-- > 0);if (!ret)return AVERROR(ETIMEDOUT);return ret;
}

可以看出来,FFmpeg拉流时会执行poll函数(没错,就是跟I/O复用select、epoll 并列的poll函数),当poll函数返回0时,代表没有任何socket描述符准备好读、写,或出错,此时poll超时,超时时间是POLLING_TIME(默认100)毫秒,然后该逻辑执行timeout / POLLING_TIME次后,函数ff_poll_interrupt会返回AVERROR(ETIMEDOUT),也就是返回-110。

四、总结

FFmpeg拉流时会执行poll函数,poll函数超时时会返回0,然后FFmpeg的ff_poll_interrupt函数会返回-110,然后打印错误:Connection to tcp://XXX?timeout=XXX failed: Connection timed out

http://www.lryc.cn/news/151227.html

相关文章:

  • iOS开发Swift-7-得分,问题序号,约束对象,提示框,类方法与静态方法-趣味问答App
  • AUTOSAR规范与ECU软件开发(实践篇)7.10MCAL模块配置方法及常用接口函数介绍之Base与Resource的配置
  • Android11编译第二弹:USB连接MTP模式+USB调试+USB信任
  • Unity ShaderGraph教程——基础shader
  • 第 3 章 栈和队列(单链队列)
  • 【DFS】1254. 统计封闭岛屿的数目
  • C#--sugarClient使用之ColumnName
  • 深度学习-4-二维目标检测-YOLOv5源码测试与训练
  • 找不到msvcp140.dll的解决方法【msvcp140.dll修复工具下载】
  • 内网隧道代理技术(二十)之 CS使用HTTP代理上线不出网机器
  • 安卓 tcp 客户端
  • flutter plugins插件【三】【Flutter Intl】
  • 简单了解ICMP协议
  • MVCC究竟是什么?
  • Kafka知识点总结
  • K8s最基本概念
  • vulnhub渗透测试靶场练习2
  • 在R中安装TensorFlow、TensorFlow_Probability、numpy(R与Python系列第二篇)
  • 十大管理——项目成本管理
  • Java BIO、NIO、AIO学习总结
  • sql各种注入案例
  • 系统学习Linux-ELK日志收集系统
  • IDEA2023隐藏.idea和.iml文件
  • 【深入浅出C#】章节 9: C#高级主题:反射和动态编程
  • Gorm简单了解
  • 第一百三十三回 StreamProvier
  • java 多个list取交集
  • 文件上传与下载
  • SpringBoot 整合 RabbitMQ
  • 气象科普丨气象站的分类与应用