"Немонотонный DTS в выходном потоке" каждые 13 часов 14 минут

У меня проблема с последней версией ffmpeg от zeranoe. Каждые 13 часов 14 минут 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

Потоки 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

Я записываю каждый из них с сегментацией каждую 1 минуту, используя отдельные экземпляры ffmpeg, такие как:

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 прекращает запись с сообщениями типа "Немонотонный DTS в выходном потоке 0:0". И не имеет значения, когда я запускал каждый экземпляр ffmpeg: если я запустил экземпляр №2 через 1 минуту после этого экземпляра №1, он остановит запись через 1 минуту после №1 соответственно. Я попробовал это на двух ПК: 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 Мб, в архиве): https://drive.google.com/file/d/0B1LIS8G55R7-OGY4QkdkQ0J1cVE/view?usp=sharing Я не могу записывать видео бесконечно. Каждые 13 часов у меня нарушается запись. Я пытался записать с "copytb 1", "genpts", но это не помогает. Я не думаю, что это проблема сети, потому что я пытался записать один и тот же поток rtsp двумя экземплярами ffmpeg с временным сдвигом запуска: они зависли отдельно в отдельное время. Кто-нибудь знает как это решить? Я могу предоставить вам другую необходимую вам информацию об этом.

Обновление: если я подожду 13 часов после появления ошибки, запись начнется снова.

2 ответа

С некоторыми IP-камерами мы также узнали об этой проблеме и нашли решение:

-correct_ts_overflow 0

Объяснение: Это связано с несколькими проблемами в FFMPEG. Во-первых, временные метки генерируются из демультиплексора RTP. Когда для камеры имеется более одного потока, временные метки генерируются, используя время RTCP ntp и временные метки RTP вместе для правильной синхронизации потока. Однако только для одного потока кумулятивная временная метка генерируется из временной метки RTP. Проблема заключается в том, что некоторые камеры сообщают начальную временную метку в SDP, которая больше, чем первая временная метка пакета RTP, которая используется в качестве базовой временной метки. Это, в свою очередь, создает отрицательную метку времени, переданную в ff_read_frame. Другая проблема состоит в том, что RTSP/RTP устанавливает свои биты переноса метки времени как 32 бита. Проблема состоит в том, что временные метки в случае одного потока на самом деле являются 64-битными временными метками, поскольку временные метки - это не абсолютные метки времени, а скорее кумулятивные метки времени. Эта временная метка не будет переноситься до битов 63 для положительных временных меток.

Однако мы обнаружили, что внутри вызова ff_read_frame есть некоторая логика для работы с переносом PTS/DTS, используемым для поиска в ситуациях переворачивания. Поскольку первая временная метка в этом случае отрицательна И биты переноса установлены на 32 бита, код переноса устанавливается неправильно. Таким образом, с камерами, которые запускаются с отрицательной отметкой времени, код переноса вычитает UINT32MAX из отметки времени, когда он становится значением, превышающим некоторое индексированное значение (я полагаю, что примерно за 60 секунд видео до UINT32MAX). Затем генерируется новая отрицательная временная метка из ff_read_frame. Поскольку ffmpeg.c затем обнаруживает это как немонотонную временную метку, новая временная метка вывода всего на один тик больше, чем старая, которая испортила весь выходной поток. Затем требуется еще один UINT32MAX для меток времени из демплексора RTP для восстановления, или примерно 13 часов.

Это выглядит как 32-разрядное целое число без знака. Максимальное значение для 32-разрядного целого числа без знака составляет 4294967295, что близко к вашим временным меткам.

Теперь вопрос: это ffmpeg или ваш источник RTP? Вы должны изолировать проблему. Используйте пример кода live555 и запишите свой поток без ffmpeg и зарегистрируйте временные метки.

Если я сделаю неверное предположение - я бы сказал, что это, вероятно, ваш сетевой источник с ошибочной реализацией RTP (RTCP).

Другие вопросы по тегам