修复 ffmpeg 随时间推移而产生的延迟

修复 ffmpeg 随时间推移而产生的延迟

我在以下设置中运行 ffmpeg/ffserver:

10.1.2.2 从视频采集卡(16 通道)捕获并将它们作为 mpeg1video 流式传输到 ffserver

10.1.1.1/10.1.2.1(两个 NIC)托管 ffserver 和一些将 mpeg1video 流转换为 webm 流的进程以及 zoneminder(从原始 ffmpeg 流中获取数据)。10.1.2.2 和 10.1.2.1 通过千兆交叉电缆连接。/tmp 目录通过 tmpfs 安装为 128MB RAM。

mpeg1video 流总是比 webm 流延迟约 0.1-0.2 秒,这对我来说是完全可以接受的(但我提到它是因为了解这一点可能对故障排除有用)。

重新启动时,所有流都会延迟 3-5 秒(我想减少这个延迟 - 我可以直接从视频设备实时观看任何单个流,因此除了复合延迟之外,可能是我获取的格式错误)。当整夜运行时,流仍然以 mpeg1video 和 webm 格式显示为“实时”(流畅运动),但明显延迟了 4-5 小时(事实很明显,当我今天早上进来时,灯似乎熄灭了,这让我感到惊讶,我一直看着屏幕,直到那天早上人们开始进来 4-5 小时后灯才亮起[但不是全部同时亮起,它们似乎也彼此不同步])。

这些是我正在使用的流程:

在 10.1.2.2 上:

ffmpeg -f video4linux2 -standard ntsc -i /dev/video0 http://10.1.2.1:8090/0.ffm

在 10.1.2.1/10.1.1.15 上:

ffserver -f /etc/ffserver.conf
ffmpeg -f mpegvideo -i http://localhost:8090/0.mpg -vcodec libvpx http://localhost:8090/0_webm.ffm

10.1.2.1/10.1.1.15 上的 /etc/ffserver.conf 摘录如下:

Port 8090
MaxHTTPConnections 2000
MAXClients 100
MaxBandwidth 1000000
CustomLog /var/log/ffserver
NoDaemon

<Feed 0.ffm>
File /tmp/0.ffm
FileMaxSize 1M
ACL allow 10.1.2.2
</Feed>

<Feed 0_webm.ffm>
File /tmp/0_webm.ffm
FileMaxSize 1M
ACL allow localhost
</Feed>

<Stream 0.mpg>
Feed 0.ffm
Format mpeg1video
NoAudio
VideoFrameRate 29.97
VideoBitRate 512K
VideoSize 320x240
VideoBufferSize 40
VideoGopSize 12
#VideoIntraOnly
</Stream>

<Stream 0.webm>
Feed 0_webm.ffm
Format webm
NoAudio
VideoCodec libvpx
VideoSize 320x240
VideoFrameRate 29.97
AVOptionVideo flags +global_header
AVOptionVideo cpu-used 0
AVOptionVideo quality good
PreRoll 0
StartSendOnKey
VideoGopSize 12
VideoBitRate 256
</Stream>

现在,1MB 是远的太小,无法容纳 4-5 小时的 29.97 FPS 和 320x240 分辨率的 yuv420p 颜色流媒体视频 - 所以我的问题是,这里发生了什么,我该如何解决?对我来说,这似乎是 10.1.2.2 上的初始 ffmpeg 过程中发生的事情,但我不知道是什么,ffmpeg 是否使用它自己的一些缓冲区,或者是否有一个命令我可以用来强制它在从视频卡中提取时丢弃任何多余的帧 - 即尽快拍摄快照并从单个图像缓冲区发送到 ffserver,以确保发送的内容始终是实时的?

我的目标是将实时流输入到 zoneminder 中,并为 16 个频道(0-15)中的每一个频道输出 webm 格式的实时流 - 所以我愿意接受任何解决方案,但更喜欢基于 ffmpeg/ffserver 的解决方案,因为它们似乎是 Linux 中完成此类任务的黄金标准。

最初的 3-5 秒延迟和 4-5 小时延迟也可能是不同的问题。当我通过“sudo reboot”关闭 10.1.2.2 时,来自 10.1.1.15 的各个 mpg/webm 流需要 3-5 秒才能切断,因此似乎 ffserver 中发生了一些缓冲,而不仅仅是中继流。

编辑:尝试将所有源 FileMaxSize 减少到 30K,但所有流中仍然存在 3-5 秒的延迟。无论 10.1.2.2 上有 16 个还是只有 1 个 ffmpeg 进程,都存在相同的延迟。

日志输出:

服务器:

sudo ffserver -f /etc/ffserver.conf -d

ffserver version git-2013-03-15-cd5f50a Copyright (c) 2000-2013 the FFmpeg developers
  built on Mar 15 2013 14:03:16 with gcc 4.6 (Ubuntu/Linaro 4.6.3-1ubuntu5)
  configuration: --enable-gpl --enable-libass --enable-libfaac --enable-libfdk-aac --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libspeex --enable-librtmp --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-nonfree --enable-version3
  libavutil      52. 19.100 / 52. 19.100
  libavcodec     55.  0.100 / 55.  0.100
  libavformat    55.  0.100 / 55.  0.100
  libavdevice    55.  0.100 / 55.  0.100
  libavfilter     3. 45.104 /  3. 45.104
  libswscale      2.  2.100 /  2.  2.100
  libswresample   0. 17.102 /  0. 17.102
  libpostproc    52.  2.100 / 52.  2.100
Thu Mar 21 14:08:53 2013 FFserver started.
Thu Mar 21 14:08:57 2013 10.1.3.2 - - New connection: GET /15.ffm
Thu Mar 21 14:08:57 2013 10.1.3.2 - - [GET] "/15.ffm HTTP/1.1" 200 4175
Thu Mar 21 14:08:57 2013 10.1.3.2 - - New connection: POST /15.ffm
Thu Mar 21 14:09:03 2013 127.0.0.1 - - New connection: GET /15.mpg
Thu Mar 21 14:09:06 2013 127.0.0.1 - - New connection: GET /15_webm.ffm
Thu Mar 21 14:09:06 2013 127.0.0.1 - - [GET] "/15_webm.ffm HTTP/1.1" 200 4175

sudo ffmpeg -f video4linux2 -standard ntsc -i /dev/video7 http://10.1.3.1:8090/15.ffm

视频设备 --> mpg

ffmpeg version git-2013-03-21-4331484 Copyright (c) 2000-2013 the FFmpeg developers
  built on Mar 20 2013 20:44:06 with gcc 4.6 (Ubuntu/Linaro 4.6.3-1ubuntu5)
  configuration: --enable-gpl --enable-libass --enable-libfaac --enable-libfdk-aac --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libspeex --enable-librtmp --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-nonfree --enable-version3
  libavutil      52. 22.100 / 52. 22.100
  libavcodec     55.  1.100 / 55.  1.100
  libavformat    55.  0.100 / 55.  0.100
  libavdevice    55.  0.100 / 55.  0.100
  libavfilter     3. 48.100 /  3. 48.100
  libswscale      2.  2.100 /  2.  2.100
  libswresample   0. 17.102 /  0. 17.102
  libpostproc    52.  2.100 / 52.  2.100
[video4linux2,v4l2 @ 0xa1d34c0] Estimating duration from bitrate, this may be inaccurate
Input #0, video4linux2,v4l2, from '/dev/video7':
  Duration: N/A, start: 1363889339.048888, bitrate: 27620 kb/s
    Stream #0:0: Video: rawvideo (I420 / 0x30323449), yuv420p, 320x240, 27620 kb/s, 29.97 fps, 29.97 tbr, 1000k tbn, 1000k tbc
Output #0, ffm, to 'http://10.1.3.1:8090/15.ffm':
  Metadata:
    creation_time   : now
    encoder         : Lavf55.0.100
    Stream #0:0: Video: mpeg1video, yuv420p, 320x240, q=2-31, 512 kb/s, 1000k tbn, 29.97 tbc
Stream mapping:
  Stream #0:0 -> #0:0 (rawvideo -> mpeg1video)
Press [q] to stop, [?] for help
frame= 3552 fps= 30 q=5.5 size=    7644kB time=00:01:58.45 bitrate= 528.7kbits/s

ffmpeg -f mpegvideo -i http://localhost:8090/15.mpg -vcodec libvpx http://localhost:8090/15_webm.ffm

mpg--> webm

ffmpeg version git-2013-03-15-cd5f50a Copyright (c) 2000-2013 the FFmpeg developers
  built on Mar 15 2013 14:03:16 with gcc 4.6 (Ubuntu/Linaro 4.6.3-1ubuntu5)
  configuration: --enable-gpl --enable-libass --enable-libfaac --enable-libfdk-aac --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libspeex --enable-librtmp --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-nonfree --enable-version3
  libavutil      52. 19.100 / 52. 19.100
  libavcodec     55.  0.100 / 55.  0.100
  libavformat    55.  0.100 / 55.  0.100
  libavdevice    55.  0.100 / 55.  0.100
  libavfilter     3. 45.104 /  3. 45.104
  libswscale      2.  2.100 /  2.  2.100
  libswresample   0. 17.102 /  0. 17.102
  libpostproc    52.  2.100 / 52.  2.100
[mpeg1video @ 0x3901000] 0x0 is invalid
    Last message repeated 2 times
[mpegvideo @ 0x38f4f80] max_analyze_duration 5000000 reached at 5011633 microseconds
[mpegvideo @ 0x38f4f80] Estimating duration from bitrate, this may be inaccurate
Input #0, mpegvideo, from 'http://localhost:8090/15.mpg':
  Duration: N/A, bitrate: 1024 kb/s
    Stream #0:0: Video: mpeg1video, yuv420p, 320x240 [SAR 1:1 DAR 4:3], 1024 kb/s, 29.92 fps, 29.97 tbr, 1200k tbn, 29.97 tbc
[libvpx @ 0x39046a0] v1.2.0
Output #0, ffm, to 'http://localhost:8090/15_webm.ffm':
  Metadata:
    creation_time   : now
    encoder         : Lavf55.0.100
    Stream #0:0: Video: vp8, yuv420p, 320x240 [SAR 1:1 DAR 4:3], q=1-31, 128 kb/s, 1000k tbn, 29.97 tbc
Stream mapping:
  Stream #0:0 -> #0:0 (mpeg1video -> libvpx)
Press [q] to stop, [?] for help
frame= 4845 fps= 31 q=0.0 size=    4192kB time=00:02:41.66 bitrate= 212.4kbits/s dup=4 drop=0

每个请求添加更多输出:

$v4l
No command 'v4l' found, did you mean:
 Command 'vl' from package 'atfs' (universe)
 Command 'dv4l' from package 'dv4l' (universe)
v4l: command not found

$v4l2
No command 'v4l2' found, did you mean:
 Command 'qv4l2' from package 'qv4l2' (universe)
v4l2: command not found

$ sudo ffprobe -show_streams -show_format -f video4linux2 /dev/video0
ffprobe version git-2013-03-16-c9a51c2 Copyright (c) 2007-2013 the FFmpeg developers
  built on Mar 16 2013 18:48:40 with gcc 4.6 (Ubuntu/Linaro 4.6.3-1ubuntu5)
  configuration: --enable-gpl --enable-libass --enable-libfaac --enable-libfdk-aac --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libspeex --enable-librtmp --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-nonfree --enable-version3
  libavutil      52. 19.100 / 52. 19.100
  libavcodec     55.  0.100 / 55.  0.100
  libavformat    55.  0.100 / 55.  0.100
  libavdevice    55.  0.100 / 55.  0.100
  libavfilter     3. 47.100 /  3. 47.100
  libswscale      2.  2.100 /  2.  2.100
  libswresample   0. 17.102 /  0. 17.102
  libpostproc    52.  2.100 / 52.  2.100
[video4linux2,v4l2 @ 0xb0a0540] Estimating duration from bitrate, this may be inaccurate
Input #0, video4linux2,v4l2, from '/dev/video0':
  Duration: N/A, start: 1364261173.317100, bitrate: 27620 kb/s
    Stream #0:0: Video: rawvideo (I420 / 0x30323449), yuv420p, 320x240, 27620 kb/s, 29.97 fps, 29.97 tbr, 1000k tbn, 1000k tbc
[STREAM]
index=0
codec_name=rawvideo
codec_long_name=raw video
profile=unknown
codec_type=video
codec_time_base=1/1000000
codec_tag_string=I420
codec_tag=0x30323449
width=320
height=240
has_b_frames=0
sample_aspect_ratio=0:1
display_aspect_ratio=0:1
pix_fmt=yuv420p
level=-99
timecode=N/A
id=N/A
r_frame_rate=30000/1001
avg_frame_rate=30000/1001
time_base=1/1000000
start_pts=1364261173317100
start_time=1364261173.317100
duration_ts=N/A
duration=N/A
bit_rate=27620379
nb_frames=N/A
nb_read_frames=N/A
nb_read_packets=N/A
DISPOSITION:default=0
DISPOSITION:dub=0
DISPOSITION:original=0
DISPOSITION:comment=0
DISPOSITION:lyrics=0
DISPOSITION:karaoke=0
DISPOSITION:forced=0
DISPOSITION:hearing_impaired=0
DISPOSITION:visual_impaired=0
DISPOSITION:clean_effects=0
DISPOSITION:attached_pic=0
[/STREAM]
[FORMAT]
filename=/dev/video0
nb_streams=1
format_name=video4linux2,v4l2
format_long_name=Video4Linux2 device grab
start_time=1364261173.317100
duration=N/A
size=N/A
bit_rate=27620379
[/FORMAT]

视频采集卡bt878a 8通道按照制造商的说明,在包含卡的两台机器上,使用带有 /etc/modprobe.d/bttv.conf 设置的 bttv 驱动程序,如下所示:

options i2c-algo-bit_test=1
options bttv gbuffers=16 card=102,102,102,102,102,102,102,102 radio=0,0,0,0,0,0,0,0 tuner=4,4,4,4,4,4,4,4 chroma_agc=1 combfilter=2 full_luma_range=1 coring=1 autoload=0

在本地机器上使用:

ffplay -f video4linux2 -standard ntsc -i /dev/video0

实时工作,并且无论运行多长时间都不会产生延迟。

相关内容