Как фрагментировать пакеты H264 в RTP, совместимом с RFC3984

У меня есть потоковое базовое видео FFMPEG h264, которое я должен инкапсулировать в RTP и отправить на SIP-телефоны для их декодирования. Я использую Linphone с плагином h264 для Windows и Mirial для декодирования. Однако иногда я получаю огромный размер кадра (3Kb ~ 9Kb) от FFMPEG, который явно не помещается в MTU.

Если я отправлю эти кадры «как есть» и доверюсь функции IP-фрагментации, некоторые телефоны смогут воспроизвести их достаточно хорошо, а другие захлебнутся и не смогут декодировать поток. Я думаю, это связано с тем, что поток не совместим с RFC 3984, в котором указано, что пакеты, которые не соответствуют MTU, должны быть разделены на разные NALU и помечать конец кадра функцией Mark RTP.

Как мне узнать, где я могу «вырезать» кадр I или P? Я заметил, что фрагментированные пакеты h264 (без метки Mark) иногда заканчиваются на 0xF8, но не могут получить шаблон, а в RFC 3984, описывающем, как отправлять эти пакеты по RTP, не указано, как это сделать.

ОБНОВЛЕНИЕ: Кто-нибудь знает, как сообщить библиотеке X264, как генерировать NALU максимального размера? таким образом я должен быть в состоянии избежать этой проблемы. Всем спасибо


person Pierluigi Cifani    schedule 01.04.2011    source источник


Ответы (2)


Как автор RFC 3984bis (будет RFC 6184), он подробно описывает, как преобразовывать NAL H.264 в пакеты RFC 3984. Существует 3 режима: 0 (одиночный NAL), 1 (позволяет фрагментировать и комбинировать NAL) и 2 (позволяет фрагментировать, комбинировать и чередовать порядок передачи, чтобы изменить, среди прочего, влияние пакетной потери на поток. ). См. режим пакетирования SDP. Требуется только режим 0.

Режим 0 (Single-NAL) требует, чтобы вы либо использовали фрагментацию UDP (не рекомендуется), либо сказали кодировщику не генерировать NAL, превышающие MTU-X. Вы должны сообщить об этом кодировщику.

Режим 1 позволяет фрагментировать. См. RFC, чтобы узнать, как настроить пакет FU-A. Информация о фрагментации находится на передней панели. Вы также можете использовать STAP для объединения небольших NAL, таких как пакеты SPS и PPS, отправленные до IDR (обычно). Для каждого пакета требуются обычные заголовки RTP с увеличенными порядковыми номерами (но с той же отметкой времени).

Отметка на последнем RTP-пакете фрейма (не фрагмента или NAL) ожидается, но рассчитывать на нее не стоит.

person jesup    schedule 07.04.2011
comment
@jesusp Спасибо за ваш ответ! однако я использую X264 в качестве уровня кодировщика, и я не знаю, как сообщить кодировщику генерировать NALU размером не более 1500 байт. Поиск в Google привел меня сюда: ссылка. Однако, похоже, он не был объединен с библиотекой. Кто-нибудь знает способ сделать это с помощью X264? В противном случае мне придется реализовать режим пакетирования = 1. Всем спасибо - person Pierluigi Cifani; 11.04.2011
comment
@jesup Можете ли вы объяснить, почему фрагментация UDP плохая? Насколько я понимаю, фрагментация UDP (или, лучше, фрагментация IP) должна приводить к меньшему сетевому трафику, поскольку вам не нужно кодировать заголовок RTP (соответственно UDP) для каждого пакета (так что вы получаете от 12 до 20 байт на пакет) . - person xryl669; 05.06.2015
comment
Об этом много сказано... Некоторые маршрутизаторы вообще не поддерживают фрагментацию. Различные ОС и другие промежуточные блоки могут нуждаться в повторной сборке фрагментированного пакета, и все они имеют ограничения на размер повторно собранного пакета — обычно намного меньше максимального размера UDP в 65535 байт (часто около 4 КБ). Стандартного максимального размера нет. фрагментация делает вас более уязвимым к потере пакетов (хотя, если данные непригодны для использования в отдельных пакетах, это может не сильно помочь). Возможно, к этому следует вернуться, но отсутствие полезного типоразмера — большая проблема. - person jesup; 11.06.2015

Я считаю, что в x264 для управления размером можно использовать int i_slice_max_size в x264_param_t. Посмотрите в x264.h. Я не могу вспомнить, где я это читал, но в сообщении говорилось, что этот элемент структуры можно использовать для управления размером NAL, но я сам не пробовал.

интервал i_slice_max_size; /* Максимальный размер слайса в байтах; включает предполагаемые служебные данные NAL. */

РЕДАКТИРОВАТЬ: я нашел источник

http://mailman.videolan.org/pipermail/x264-devel/2011-February/008263.html

person ianhobo    schedule 25.04.2011
comment
Спасибо! Я займусь этим сегодня днем, но я уже проверил, и применить эти изменения не будет проблемой. Спасибо большое за вашу помощь! - person Pierluigi Cifani; 26.04.2011