Я использую ffmpeg для чтения потока RTSP h264 с IP-камеры Cisco 3050 и перекодирования его на диск как h264 (есть причины, по которым я не просто использую -codec:copy
).
Версия ffmpeg выглядит следующим образом:
ffmpeg version 3.2.6 Copyright (c) 2000-2017 the FFmpeg developers
built with gcc 6.3.0 (Alpine 6.3.0)
Я также пробовал использовать ffmpeg 2.8.14-0ubuntu0.16.04.1 и последнюю версию ffmpeg, созданную из исходного кода (я использовал this commit), и вижу то же поведение, что и ниже.
Я запускаю команду:
ffmpeg -rtsp_transport udp -i 'rtsp://<user>:<pw>@<ip>:554/StreamingSetting?version=1.0&action=getRTSPStream&ChannelID=1&ChannelName=Channel1' -r 10 -c:v h264 -crf 23 -x264-params keyint=60:min-keyint=60 -an -f ssegment -segment_time 60 -strftime 1 /output/%Y%m%d_%H%M%S.ts -abort_on empty_output
Я получаю множество ошибок с довольно постоянной скоростью, по крайней мере, одна в секунду. Вот пример:
[rtsp @ 0x7f268c5e9220] max delay reached. need to consume packet
[rtsp @ 0x7f268c5e9220] RTP: missed 40 packets
[h264 @ 0x55b1e115d400] left block unavailable for requested intra mode
[h264 @ 0x55b1e115d400] error while decoding MB 0 12, bytestream 114567
[h264 @ 0x55b1e115d400] concealing 3889 DC, 3889 AC, 3889 MV errors in I frame
Наиболее распространенным является «ошибка при декодировании MB x x, bytestream x». Это соответствует серьезному повреждению видеофайла при воспроизведении.
Я вижу много ссылок на это сообщение об ошибке в stackoverflow и в других местах, но мне еще предстоит найти удовлетворительное объяснение или обходной путь. Это происходит из этой строки , которая, по-видимому, соответствует отсутствующим данным в конце потока. «левый блок недоступен» происходит от здесь и также выглядит как отсутствующие данные.
Другие предложили вместо этого использовать -rtsp_transport tcp
( 1 , 2 , 3 ), что в моем случае просто дает немного другое сочетание ошибок, и повреждение видео:
[h264 @ 0x557923191b00] left block unavailable for requested intra4x4 mode -1
[h264 @ 0x557923191b00] error while decoding MB 0 28, bytestream 31068
[h264 @ 0x557923191b00] concealing 2609 DC, 2609 AC, 2609 MV errors in I frame
[rtsp @ 0x7f88e817b220] CSeq 5 expected, 0 received.
Используя Wireshark, я подтвердил, что как в режиме UDP, так и в режиме TCP все пакеты передаются с камеры на ПК (последовательные порядковые номера RTP без каких-либо пропусков), что заставляет меня думать, что данные теряются после их поступления в FFmpeg.
Я также вижу похожее поведение при выполнении той же команды с камерой Panasonic WV-SFV110, но с менее частыми ошибками в целом. Переключение с UDP на TCP на камере Panasonic уменьшает, но не полностью устраняет ошибки / повреждения.
Я также попробовал аналогичную команду с VLC и получил похожие ошибки (cvlc rtsp://<user>:<pw>@<ip>/MediaInput/h264 :sout='#transcode{vcodec=h264}:std{access=file, mux=ts, dst="output.ts"}
) - предположительно, код не сильно расходился с тех пор, как libav разветвился от ffmpeg.
Камера подключена непосредственно к порту PoE на ПК, поэтому перегрузка сети не может быть проблемой. Учитывая, что на ПК достаточно процессора для кодирования живого потока, мне кажется, что проблема с ffmpeg в том, что он все еще сбрасывает данные из потока TCP.
Качественно, есть несколько факторов, которые, кажется, усугубляют проблему:
- Более высокое разрешение видео
- Более высокая загрузка системы на машине, на которой запущен ffmpeg (например, перекодирование в файл с низким разрешением .avi приводит к меньшему количеству ошибок, чем при перекодировании в h264 VBR; использование
-codec:copy
устраняет все ошибки, кроме пары, при запуске ffmpeg)
- Большее движение в поле зрения камеры
Что означает ошибка? И что я могу с этим поделать?