Как фрагментировать пакеты 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 (пакеты без метки) иногда заканчиваются в 0xF8, но не могут получить шаблон, а в RFC 3984, который описывает, как отправлять эти пакеты по RTP, не указывается, как это сделать.
ОБНОВЛЕНИЕ: Кто-нибудь знает, как сказать библиотеке X264, как генерировать NALU максимального размера? таким образом я смогу избежать этой проблемы. Спасибо всем
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) ожидается, но вы не должны на это рассчитывать.
В x264 я считаю, что int i_slice_max_size в x264_param_t может использоваться для управления размером. Взгляните на x264.h. Я не могу вспомнить, где я это читал, но в посте говорилось, что этот член структуры может использоваться для контроля размера NAL, но я сам не пробовал.
int i_slice_max_size; / * Максимальный размер на срез в байтах; включает в себя расчетные накладные расходы NAL. */
РЕДАКТИРОВАТЬ: я нашел источник
http://mailman.videolan.org/pipermail/x264-devel/2011-February/008263.html