“输出流中的非单调 DTS”每 13 小时 14 分钟一次

Gni*_*try 2 ffmpeg h.264 video-recording

我对 zeranoe 的最新 ffmpeg 有问题。\n每 13h14m ffmpeg 就会停止录制。

\n\n
ffmpeg started on 2017-09-28 at 10:36:49\nReport written to "ffmpeg-20170928-103649.log"\nCommand line:\n"D:\\\\ffmpeg\\\\ffmpeg.exe" -report\nffmpeg version N-87353-g183fd30 Copyright (c) 2000-2017 the FFmpeg developers\n  built with gcc 7.2.0 (GCC)\n  configuration: --disable-static --enable-shared --enable-gpl --enable-version3 --enable-cuda --enable-cuvid --enable-d3d11va --enable-dxva2 --enable-libmfx --enable-nvenc --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libfreetype --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenh264 --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib\n  libavutil      55. 76.100 / 55. 76.100\n  libavcodec     57.106.101 / 57.106.101\n  libavformat    57. 82.101 / 57. 82.101\n  libavdevice    57.  8.101 / 57.  8.101\n  libavfilter     6.105.100 /  6.105.100\n  libswscale      4.  7.103 /  4.  7.103\n  libswresample   2.  8.100 /  2.  8.100\n  libpostproc    54.  6.100 / 54.  6.100\nSplitting the commandline.\nReading option \'-report\' ... matched as option \'report\' (generate a report) with argument \'1\'.\nFinished splitting the commandline.\nParsing a group of options: global .\nApplying option report (generate a report) with argument 1.\nSuccessfully parsed a group of options.\nHyper fast Audio and Video encoder\n
Run Code Online (Sandbox Code Playgroud)\n\n

我用 3 个摄像头录制视频流。

\n\n

流 1:

\n\n
Input #0, rtp, from \'rtp://225.1.1.1:1024\':\n  Duration: N/A, start: 60424.501000, bitrate: N/A\n  Program 1\n    Stream #0:0: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(progressiv\ne), 1920x1080 [SAR 1:1 DAR 16:9], 50 fps, 50 tbr, 90k tbn, 100 tbc\n    Stream #0:1(eng): Audio: aac (LC) ([15][0][0][0] / 0x000F), 48000 Hz, mono,\nfltp, 164 kb/s\n
Run Code Online (Sandbox Code Playgroud)\n\n

流 2,3:

\n\n
Input #0, rtsp, from \'rtsp://192.168.3.36:554/stream1\':\n  Metadata:\n    title           : Session streamed by "Pelco Streaming Server"\n    comment         : stream1\n  Duration: N/A, start: 0.219167, bitrate: N/A\n    Stream #0:0: Video: h264 (Baseline), yuv420p(progressive), 640x480, 25 fps,\n25 tbr, 90k tbn, 50 tbc\n
Run Code Online (Sandbox Code Playgroud)\n\n

我使用单独的 ffmpeg 实例每 1 分钟分段记录一次,例如:

\n\n
ffmpeg -i "rtsp://192.168.3.36:554/stream1" -vcodec copy -an -f segment -strftime 1 -segment_time 60 "novus-%Y-%m-%d_%H-%M-%S.ts"\n
Run Code Online (Sandbox Code Playgroud)\n\n

每 13 小时 14 分钟(从录制开始),每个 ffmpeg 都会停止录制,并显示“输出流 0:0 中的非单调 DTS”等消息。当我启动每个 ffmpeg 实例时并不重要:如果我在实例 \xe2\x84\x962 1 分钟后启动实例 \xe2\x84\x961,它将在 \xe2\x84\x961 之后 1 分钟内停止录制因此。我在两台 PC 上尝试过:Windows Server 2012 x64 和 Windows 10 x64。

\n\n
...\n[NULL @ 000000000034a900] SEI type 5 size 408 truncated at 160\n[segment @ 000000000034e780] stream:0 start_pts_time:47640.5 pts:4289549528 pts_time:47661.7 dts:4289549528 dts_time:47661.7 -> pts:4289549528 pts_time:47661.7 dts:4289549528 dts_time:47661.7\n[NULL @ 000000000034a900] SEI type 5 size 408 truncated at 160\n[segment @ 000000000034e780] stream:0 start_pts_time:47640.5 pts:4289553131 pts_time:47661.7 dts:4289553131 dts_time:47661.7 -> pts:4289553131 pts_time:47661.7 dts:4289553131 dts_time:47661.7\n[NULL @ 000000000034a900] SEI type 5 size 408 truncated at 160\n[segment @ 000000000034e780] stream:0 start_pts_time:47640.5 pts:4289556734 pts_time:47661.7 dts:4289556734 dts_time:47661.7 -> pts:4289556734 pts_time:47661.7 dts:4289556734 dts_time:47661.7\n[NULL @ 000000000034a900] SEI type 5 size 336 truncated at 160\n[segment @ 000000000034e780] Non-monotonous DTS in output stream 0:0; previous: 4289535114, current: -5428580; changing to 4289535115. This may result in incorrect timestamps in the output file.\n[segment @ 000000000034e780] stream:0 start_pts_time:47640.5 pts:4289556735 pts_time:47661.7 dts:4289556735 dts_time:47661.7 -> pts:4289556735 pts_time:47661.7 dts:4289556735 dts_time:47661.7\n[NULL @ 000000000034a900] SEI type 5 size 408 truncated at 160\n[segment @ 000000000034e780] Non-monotonous DTS in output stream 0:0; previous: 4289535115, current: -5424977; changing to 4289535116. This may result in incorrect timestamps in the output file.\n[segment @ 000000000034e780] stream:0 start_pts_time:47640.5 pts:4289556736 pts_time:47661.7 dts:4289556736 dts_time:47661.7 -> pts:4289556736 pts_time:47661.7 dts:4289556736 dts_time:47661.7\n[NULL @ 000000000034a900] SEI type 5 size 408 truncated at 160\n[segment @ 000000000034e780] Non-monotonous DTS in output stream 0:0; previous: 4289535116, current: -5421374; changing to 4289535117. This may result in incorrect timestamps in the output file.\n[segment @ 000000000034e780] stream:0 start_pts_time:47640.5 pts:4289556737 pts_time:47661.7 dts:4289556737 dts_time:47661.7 -> pts:4289556737 pts_time:47661.7 dts:4289556737 dts_time:47661.7\nframe=1190370 fps= 25 q=-1.0 size=N/A time=13:14:21.50 bitrate=N/A speed=   1x    \n[NULL @ 000000000034a900] SEI type 5 size 408 truncated at 160\n[segment @ 000000000034e780] Non-monotonous DTS in output stream 0:0; previous: 4289535117, current: -5417772; changing to 4289535118. This may result in incorrect timestamps in the output file.\n...\n
Run Code Online (Sandbox Code Playgroud)\n\n

有关此问题的完整调试日志位于此处(25 Mb,压缩):\n\xe2\x80\x8b https://drive.google.com/file/d/0B1LIS8G55R7-OGY4QkdkQ0J1cVE/view?usp=sharing \n我可以不无限录制视频。每13个小时我就会打破记录。我尝试用“copytb 1”、“genpts”进行记录,但没有帮助。我不认为这是网络问题,因为我尝试通过两个 ffmpeg 实例以开始时移的方式记录相同的 rtsp 流:它们在不同的时间分别卡住。\n有人知道如何解决它吗?我可以为您提供您需要的其他信息。

\n\n

更新:如果我在错误出现后等待 13 小时,录制会再次开始。

\n

小智 5

对于某些网络摄像机,我们也意识到了这个问题,并找到了解决方案:

- Correct_ts_overflow 0

解释:它源于 FFMPEG 中的几个问题。首先,时间戳是由 RTP 解复用器生成的。当摄像机有多个流时,将使用 RTCP ntp 时间和 RTP 时间戳一起生成时间戳,以实现正确的流计时。然而,仅对于一个流,累积时间戳是从 RTP 时间戳生成的。问题在于,某些摄像机在 SDP 中报告的起始时间戳大于用作基本时间戳的第一个 RTP 数据包时间戳。这反过来又创建了一个传递给 ff_read_frame 的负时间戳。另一个问题是 RTSP/RTP 将其时间戳包装位设置为 32 位。问题在于,单个流的时间戳实际上是一个 int 64 位时间戳,因为时间戳不是绝对时间戳,而是累积时间戳。对于正时间戳,该时间戳直到第 63 位才会回绕。

然而我们发现,在对 ff_read_frame 的调用内部有一些逻辑来处理用于在翻转情况下查找的 PTS/DTS 包装。由于本例中的第一个时间戳为负并且包装位设置为 32 位,因此包装代码设置不正确。因此,对于以负时间戳开头的摄像机,当 UINT32MAX 的值大于某个索引值时(我相信在 UINT32MAX 之前大约有 60 秒的视频),换行代码会从时间戳中减去 UINT32MAX。然后,这会从 ff_read_frame 中生成一个新的负时间戳。由于 ffmpeg.c 随后将其检测为非单调时间戳,因此新的输出时间戳仅比旧的时间戳大一个刻度,从而弄乱了整个输出流。然后,需要另一个 UINT32MAX 来获取来自 RTP 解复用器的时间戳,即大约 13 小时。