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

news/2024/7/7 20:53:07

一、现象

通过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://lihuaxi.xjx100.cn/news/1509759.html

相关文章

微信小程序通过npm引入tdesign包进行构建的时候报错

问题 在通过npm 引入 tdesign时&#xff1a;https://tdesign.tencent.com/miniprogram/getting-started 通过微信小程序IDE进行npm构建的时候出现&#xff1a;无法构建&#xff0c;应该怎么办&#xff1f; 解决方法&#xff1a; 1 输入&#xff1a; npm init -y命令 2 重新点…

音频——硬件拓扑

文章目录 硬件拓扑I2S 数据通路五线模式四线模式两线 TX两线 RX 典型应用硬件连接数据流 硬件拓扑 控制路径&#xff1a;UART/I2C/SPI数据路径&#xff1a;I2S 简略图如下 I2S 数据通路 五线模式 四线模式 两线 TX 两线 RX 典型应用 硬件连接 控制信号&#xff1a;SPI 用…

说说HTTP 和 HTTPS 有什么区别?

分析&回答 http协议 超文本传输协议&#xff0c;是互联网上应用最多的协议&#xff0c;基于TCP/IP通讯协议来传递信息&#xff0c;用于从WWW服务器传输超文本到本地浏览器的传输协议。 https协议 我们可以将其看作是以安全为目标的http协议。在http协议的基础上增加了S…

kafka 3.5 kafka服务端接收生产者发送的数据源码

一、服务端接收生产者数据的方法二、遍历需要保存数据的topic分区&#xff0c;分别执行保存数据操作到topic分区Leader三、在数据写入分区Leader之前&#xff0c;先获一些锁1、首先获得leaderIsrUpdateLock的读锁&#xff0c;得到Leader日志读取权限&#xff0c;做一些验证2、在…

JS中的new操作符

文章目录 JS中的new操作符一、什么是new&#xff1f;二、new经历了什么过程&#xff1f;三、new的过程分析四、总结 JS中的new操作符 参考&#xff1a;https://www.cnblogs.com/buildnewhomeland/p/12797537.html 一、什么是new&#xff1f; 在JS中&#xff0c;new的作用是通过…

HttpClient默认重试机制

分析&回答 只有发生IOExecetion时才会发生重试InterruptedIOException、UnknownHostException、ConnectException、SSLException&#xff0c;发生这4中异常不重试get方法可以重试3次&#xff0c;post方法在socket对应的输出流没有被write并flush成功时可以重试3次。读/写超…

一不留神就掉坑

乘除顺序问题 在据卡特兰数[1]公式,解决leetcode-96 不同的二叉搜索树[2]时,遇到一个非常诡异的问题, package mainimport "fmt"func main() { for i : 0; i < 40; i { fmt.Printf("第%d个卡特兰数为:%d\n", i, numTrees(i)) }}func numTrees(n int) i…

Springboot - 1.什么是springboot

&#x1f440;Spring的核心模块 Spring Framework是一个功能强大的开源框架&#xff0c;用于构建Java企业级应用程序。它提供了多个核心模块&#xff0c;每个模块都提供不同的功能&#xff0c;用于解决应用程序开发中的各种问题。以下是Spring Framework的核心模块的全面解析&…