ffmpeg RTSP ошибка при декодировании МБ - PullRequest
0 голосов
/ 27 апреля 2018

Я использую 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)
  • Большее движение в поле зрения камеры

Что означает ошибка? И что я могу с этим поделать?

Ответы [ 2 ]

0 голосов
/ 01 мая 2018

Звучит так, будто потеря пакетов - это проблема. Более высокое разрешение видео и большее движение увеличивают битрейт кодированного видеопотока, что увеличивает потери пакетов. В зависимости от того, какой пакет потерян, вы увидите различные ошибки в процессе декодирования, как вы указали в своем посте.

Более высокая загрузка системы при запуске ffmpeg также указывает, что ваша сетевая карта может сбрасывать пакеты, например, когда ffmpeg занимает слишком много времени, чтобы прочитать их, пока он занят перекодировкой видео.

Первый вопрос: какова ваша топология сети? Потоковая передача через общедоступный Интернет намного сложнее, чем потоковая передача по локальной сети. Какие коммутаторы / маршрутизаторы находятся в сети?

Следующий вопрос, на каком битрейте вещает ваша камера? Попробуйте уменьшить это и проверьте результаты. Будьте систематичны в своем подходе, т.е.

  • сначала не транскодировать.
  • просто получите видео.
  • записать его в файл.
  • Проверка потери пакетов / видео артефактов.
  • начать с более низких битрейтов, например 100 кбит / с и увеличьте его, если нет очевидных потерь

Следующее, что я хотел бы сделать, это увеличить размер приемных буферов. Хотя я не очень знаком с ffmpeg, похоже, вы можете установить его с помощью recv_buffer_size, как указано здесь . Затем вам нужно разработать достаточно большой размер в зависимости от конфигурации вашей камеры, например, для хранения. пара (5?) секунд видеоданных. Проверьте, меньше ли артефактов при увеличении размера буфера приемника или более длительных периодов без артефактов.

Конечно, если ваш процессор слишком медленный для перекодирования видео в режиме реального времени, рано или поздно вам не хватит места, в этом случае вам, возможно, придется перекодировать с более низким разрешением / битрейтом или использовать менее интенсивный кодировщик настройки и т. д. или запустить транскодирование на более быстрой машине.

Также обратите внимание, что настройка размера буфера приемника не компенсирует потерю пакетов, происходящую в общедоступном Интернете, поэтому приведенное выше поможет предположить, что вы используете потоковую передачу в локальной сети, которая поддерживает битрейт камеры. Если вы превысите пропускную способность сети, вы можете ожидать потерю пакетов. В этом случае может помочь потоковая передача по TCP (по крайней мере, до тех пор, пока буфер приемника не будет переполнен).

Вы можете попробовать еще кое-что, если вышеперечисленное не поможет или полностью не решит проблему:

  • Перехватывать входящий трафик с помощью wireshark или tcpdump. Посмотрите на следы. Фильтруйте трассировку, используя «RTSP». Вы должны быть в состоянии видеть трафик RTP, где последовательные пакеты RTP имеют увеличивающиеся порядковые номера, например 20, 21, 22, 23 и т. Д. Если вы видите пропущенные порядковые номера, значит, у вас потеря пакетов и попытка потоковой передачи по TCP. Повторите трассировку при потоковой передаче по TCP. Также не забывайте увеличивать размер буфера приемника также при потоковой передаче по TCP.

Итак, у вас есть конвейерная архитектура, и вам нужно определить, где в конвейере происходит потеря:

camera -> network -> receiver buffer (OS) -> application (ffmpeg)

0 голосов
/ 01 мая 2018

Глядя на первоначальное сообщение об ошибке:

[rtsp @ 0x7f268c5e9220] max delay reached. need to consume packet
[rtsp @ 0x7f268c5e9220] RTP: missed 40 packets

Полагаю, вы теряете UDP-пакеты. Остальные сообщения об ошибках H.264 вызваны получением неполного потока битов. Теперь ключ состоит в том, чтобы изолировать проблему. Ваша сеть отбрасывает пакеты? Или ваш сервер слишком медленный или перегружен при получении UDP (RTP).

Сначала я бы проверил размер буфера UDP вашей ОС. https://access.redhat.com/documentation/en-US/JBoss_Enterprise_Web_Platform/5/html/Administration_And_Configuration_Guide/jgroups-perf-udpbuffer.html

Если увеличение размера буфера UDP не помогает - используйте ffmpeg с -codec:copy, чтобы снизить нагрузку на процессор. Вы все еще получаете ошибки? Поскольку вы хотите перекодировать, рассмотрите возможность использования Intel Quicksync -vcodec h264_qsv или другого аппаратного кодера, снижающего нагрузку на ваш процессор.

Вопрос не столько в том, достаточно ли у ПК процессора . Но подробнее об идентификации горлышка бутылки в конвейере обработки. Ваш кодер H.264 (x264) может переподписать ваш ЦП, чтобы вы могли получить кратковременные пиковые нагрузки, которые приводят к отбрасыванию пакетов. Попробуйте ограничить количество потоков для x264 и / или понизьте качество до «быстро» или «быстрее».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...