使用ffmpeg发送udp-cbr内容会造成内存问题



我很难在一个UDP输出(MPTS(中复用几个UDP输入(来自文件的SPTS(。当我使用以下命令时

ffmpeg -thread_queue_size 2048 -i "udp://233.0.0.1:4005?fifo_size=1000000&buffer_size=10000000" -thread_queue_size 2048 -i "udp://233.0.0.1:4000?fifo_size=1000000&buffer_size=10000000" -thread_queue_size 2048 -i "udp://233.0.0.1:4001?fifo_size=1000000&buffer_size=10000000" -thread_queue_size 2048 -i "udp://233.0.0.1:4002?fifo_size=1000000&buffer_size=10000000" -thread_queue_size 2048 -i "udp://233.0.0.1:4003?fifo_size=1000000&buffer_size=10000000" -thread_queue_size 2048 -i "udp://233.0.0.1:4004?fifo_size=1000000&buffer_size=10000000" -map 0 -map 1 -map 2 -map 3 -map 4 -map 5 -program title=Program0:st=0:st=1 -program title=Program1:st=2:st=3 -program title=Program2:st=4:st=5 -program title=Program3:st=6:st=7 -program title=Program4:st=8:st=9 -program title=Program5:st=10:st=11 -c copy -metadata service_provider=FILE -f mpegts -muxrate 40000000 -flush_packets 0 "udp://239.2.2.2:2222?overrun_nonfatal=1&fifo_size=1000000&buffer_size=10000000&pkt_size=1316&ttl=1"

我可以(用VLC(播放MPTS内容很多小时,没有任何问题。

当我添加比特率参数以使UDP输出流为CBR 时

"udp://239.2.2.2:2222?overrun_nonfatal=1&fifo_size=1000000&buffer_size=10000000&pkt_size=1316&ttl=1&bitrate=40000000"

而不是

"udp://239.2.2.2:2222?overrun_nonfatal=1&fifo_size=1000000&buffer_size=10000000&pkt_size=1316&ttl=1"

a听到许多音频剪辑,然后从VLC我看到:

主警告:定时错误(漂移:-89659 us(:停止重新采样
主警告:播放太早(-89367(:向下采样
main警告:播放方式太早(-126525(:静音播放
main-debug:插入6073个零
主要警告:播放过早(47858(:向下取样
main警告:定时失败(漂移:-997495 us(:终止重新采样
main警告:播放太早(-96807(:下采样
主警告:播放方式太早(-134672(:静音播放
主要调试:插入6464个零

并且在一段随机时间(几分钟(后,ffmpeg由于以下错误而停止工作:

av_interleaved_write_frame((:无法分配内存

如何使用CBR UDP比特率
我厌倦了更改buffer_size和fifo_size的参数,但没有成功
我增加了操作系统UDP缓冲区以提高性能,但也存在同样的内存问题

我遇到了完全相同的内存错误,我不知道为什么。但我找到了一个对我有效的变通方法。

我所做的不是将输出直接用于udp流,而是首先将其发送到管道。然后使用ffmpeg从管道中读取并通过udp多播地址将其发送到。

创建命名管道:

mkfifo pipename.ts

从ffmpeg命令中删除ffmpeg输出:

"udp://239.2.2.2:2222?overrun_nonfatal=1&fifo_size=1000000&buffer_size=10000000&pkt_size=1316&ttl=1&bitrate=40000000" 

并使用以下输出:

pipe:1 > pipename.ts

所以第一个命令看起来是这样的:

ffmpeg -thread_queue_size 2048 -i "udp://233.0.0.1:4005?fifo_size=1000000&buffer_size=10000000" -thread_queue_size 2048 -i "udp://233.0.0.1:4000?fifo_size=1000000&buffer_size=10000000" -thread_queue_size 2048 -i "udp://233.0.0.1:4001?fifo_size=1000000&buffer_size=10000000" -thread_queue_size 2048 -i "udp://233.0.0.1:4002?fifo_size=1000000&buffer_size=10000000" -thread_queue_size 2048 -i "udp://233.0.0.1:4003?fifo_size=1000000&buffer_size=10000000" -thread_queue_size 2048 -i "udp://233.0.0.1:4004?fifo_size=1000000&buffer_size=10000000" -map 0 -map 1 -map 2 -map 3 -map 4 -map 5 -program title=Program0:st=0:st=1 -program title=Program1:st=2:st=3 -program title=Program2:st=4:st=5 -program title=Program3:st=6:st=7 -program title=Program4:st=8:st=9 -program title=Program5:st=10:st=11 -c copy -metadata service_provider=FILE -f mpegts -muxrate 40000000 -flush_packets 0 pipe:1 > pipename.ts

然后运行另一个ffmpeg进程从管道中读取并输出到UDP:

ffmpeg -re -i pipename.ts -c copy -f mpegts "udp://239.2.2.2:2222?overrun_nonfatal=1&fifo_size=1000000&buffer_size=10000000&pkt_size=1316&ttl=1&bitrate=40000000"

我无法解释为什么这样做有效。

我在Centos 6.7(ffmpeg版本N-90991-g0736f32(上遇到了同样的问题。无意中,我在另一台服务器上用Ubuntu 18.04.2(内核4.15.0-128-generic(和ffmpeg版本3.4.8-ubuntu0.2(从apt-get安装(尝试了这个。现在看起来很稳定。

最新更新