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

时间:2017-10-10 13:02:37

标签: ffmpeg h.264 video-recording

我遇到了来自zeranoe的最新ffmpeg的问题。 每隔13h14m ffmpeg停止录音。

ffmpeg started on 2017-09-28 at 10:36:49
Report written to "ffmpeg-20170928-103649.log"
Command line:
"D:\\ffmpeg\\ffmpeg.exe" -report
ffmpeg version N-87353-g183fd30 Copyright (c) 2000-2017 the FFmpeg developers
  built with gcc 7.2.0 (GCC)
  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
  libavutil      55. 76.100 / 55. 76.100
  libavcodec     57.106.101 / 57.106.101
  libavformat    57. 82.101 / 57. 82.101
  libavdevice    57.  8.101 / 57.  8.101
  libavfilter     6.105.100 /  6.105.100
  libswscale      4.  7.103 /  4.  7.103
  libswresample   2.  8.100 /  2.  8.100
  libpostproc    54.  6.100 / 54.  6.100
Splitting the commandline.
Reading option '-report' ... matched as option 'report' (generate a report) with argument '1'.
Finished splitting the commandline.
Parsing a group of options: global .
Applying option report (generate a report) with argument 1.
Successfully parsed a group of options.
Hyper fast Audio and Video encoder

我录制了3台摄像机的视频流。

第1流:

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

Streams 2,3:

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

我使用分离的ffmpeg实例(例如:

)每隔1分钟使用分段记录每个分段
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"

每13小时14分钟(从录制开始)每个ffmpeg停止录制,如“输出流0:0中的非单调DTS”。并且当我开始每个ffmpeg时都没关系:如果我在1分钟之后开始实例№2那个实例№1,它将在№1之后的1分钟内停止录制。我在两台PC上试过它:Windows Server 2012 x64和Windows 10 x64。

...
[NULL @ 000000000034a900] SEI type 5 size 408 truncated at 160
[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
[NULL @ 000000000034a900] SEI type 5 size 408 truncated at 160
[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
[NULL @ 000000000034a900] SEI type 5 size 408 truncated at 160
[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
[NULL @ 000000000034a900] SEI type 5 size 336 truncated at 160
[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.
[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
[NULL @ 000000000034a900] SEI type 5 size 408 truncated at 160
[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.
[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
[NULL @ 000000000034a900] SEI type 5 size 408 truncated at 160
[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.
[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
frame=1190370 fps= 25 q=-1.0 size=N/A time=13:14:21.50 bitrate=N/A speed=   1x    
[NULL @ 000000000034a900] SEI type 5 size 408 truncated at 160
[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.
...

这个问题的完整调试日志在这里(25 Mb,压缩): https://drive.google.com/file/d/0B1LIS8G55R7-OGY4QkdkQ0J1cVE/view?usp=sharing 我无法无限录制视频。我每13个小时就打破了录音。我试着用“copytb 1”,“genpts”进行录音,但它没有帮助。我不认为这是网络问题,因为我试图通过两个ffmpeg实例记录相同的rtsp流,并且时间偏移为start:它们在不同的时间单独停留。 有谁知道如何解决它?我可以为您提供有关此的所需信息。

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

2 个答案:

答案 0 :(得分:1)

这看起来像32位无符号整数溢出。 32位无符号整数的最大值为4294967295,接近您的时间戳。

现在问题是:它是ffmpeg还是你的RTP源? 你必须孤立这个问题。使用live555的示例代码并在没有ffmpeg的情况下记录您的流并记录时间戳。

如果我猜测 - 我会说它可能是你的网络资源,它有一个错误的RTP(RTCP)实现。

答案 1 :(得分:1)

使用某些IP摄像头,我们也会意识到这个问题,并找到了解决方法:

-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秒的视频)。然后,这将从ff_read_frame生成新的负时间戳。由于ffmpeg.c然后将其检测为非单调时间戳,因此新的输出时间戳只比旧的输出时间戳大一个。然后它需要另一个UINT32MAX来从RTP分路器的时间戳恢复,或大约13个小时。