Как записать поток RTP/H264 в файл

Я не смог найти решение для моего предыдущего вопроса, поэтому решил попробовать шаг за шагом.

Теперь я хочу сохранить поток RTP/H264 в качестве файла.

Что я нашел до сих пор:

(во-первых, мой RTP/H264 - FU-A, который является формой)

| RTP HEADER 12bytes long | FU INDICATOR 1byte | FU HEADER 1byte | FU payload |

Как я понял документ RFC 6184, я запускаю NAL с пакетом, который имеет "1" в первом бите заголовка FU и добавляет следующие пакеты, которые устанавливают "0" в первом бите, до последнего пакета, который имеет '1' во втором бите заголовка FU.

Я думаю, что как получить полный NAL до пакетирования FU-A, а также то, что я нашел, мне нужно поставить "начальные бит" (0x00000001) в начале каждого полного NAL.

Но пока не повезло. Ниже приведена часть журнала

 ========= the new NAL is as 1400
 [0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]7C/1111100 [5]85/10000101 [6]B8/10111000 [7]40/1000000 ...
 ========= adding the next NAL as 1400
 [0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]7C/1111100 [5]85/10000101 [6]B8/10111000 [7]40/1000000 ...
 ========= adding the next NAL as 1400
 [0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]7C/1111100 [5]85/10000101 [6]B8/10111000 [7]40/1000000 ...
 ========= adding the next NAL as 716
 [0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]7C/1111100 [5]85/10000101 [6]B8/10111000 [7]40/1000000 ...
 ========= a NAL is summed up as 4866
 ========= the new NAL is as 1400
 [0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]5C/1011100 [5]81/10000001 [6]E2/11100010 [7]20/100000 ...
 ========= adding the next NAL as 1400
 [0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]5C/1011100 [5]81/10000001 [6]E2/11100010 [7]20/100000 ...
 ========= adding the next NAL as 1400
 [0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]5C/1011100 [5]81/10000001 [6]E2/11100010 [7]20/100000 ...
 ========= adding the next NAL as 1400
 [0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]5C/1011100 [5]81/10000001 [6]E2/11100010 [7]20/100000 ...
 ========= adding the next NAL as 1400
 [0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]5C/1011100 [5]81/10000001 [6]E2/11100010 [7]20/100000 ...
 ========= adding the next NAL as 139
 [0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]5C/1011100 [5]81/10000001 [6]E2/11100010 [7]20/100000 ...
 ========= a NAL is summed up as 7061
 ========= the new NAL is as 1377
 [0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]41/1000001 [5]E4/11100100 [6]40/1000000 [7]1A/11010 ...
 ========= a NAL is summed up as 1369
 ========= the new NAL is as 1400
 [0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]5C/1011100 [5]81/10000001 [6]E6/11100110 [7]60/1100000 ...
 ========= adding the next NAL as 94
 [0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]5C/1011100 [5]81/10000001 [6]E6/11100110 [7]60/1100000 ...
 ========= a NAL is summed up as 1472
 ========= the new NAL is as 447
 [0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]41/1000001 [5]E8/11101000 [6]80/10000000 [7]16/10110 ...
 ========= a NAL is summed up as 439
 ========= the new NAL is as 1400
 [0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]5C/1011100 [5]81/10000001 [6]EA/11101010 [7]A0/10100000  ...
 ========= adding the next NAL as 1174
 [0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]5C/1011100 [5]81/10000001 [6]EA/11101010 [7]A0/10100000 ...
 ========= a NAL is summed up as 2552
 ========= the new NAL is as 1400
 [0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]5C/1011100 [5]81/10000001 [6]EC/11101100 [7]C0/11000000 ...
 ========= adding the next NAL as 1364
 [0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]5C/1011100 [5]81/10000001 [6]EC/11101100 [7]C0/11000000 ...
 ========= a NAL is summed up as 2742
 ========= the new NAL is as 1400
 ...

мой вопрос:

  • если я могу получить полные NAL из фрагментированных пакетов FU-A, как я могу сделать его как файл, который может запускаться VLC или другим игроком?

  • Я все еще смущен, если мне нужно сохранить индикатор FU и заголовок FU или нет. Кто-то сказал, что мне нужно взять их только для самого первого пакета (начиная с "1" в заголовке FU)

Любые советы будут действительно оценены.

Спасибо.

Ответ 1

Блоки FU, STAP и MTAP NAL специфичны только для пакетирования RTP, поскольку они предназначены для облегчения сетевого транспорта. Другими словами, не рассчитывайте на правильность их разбора. В конечном счете вам нужно собрать сборки NAL, как в случае пакетов FU, или разбить их на несколько блоков NAL в случае STAP/MTAP.

Как только у вас есть блок NAL (и это включает в себя PPS, SPS, SEI, разделы разделов и все другие типы в диапазоне 1-23), вы можете записать на диск вместе с начальными кодами 0001 H.264, приложение B.

Размещение в потоке B.2 приложения B.2.2 в контейнер, такой как MPEG-4, может выполняться с помощью различных инструментов командной строки (я уверен, что ffmpeg может это сделать).

Ответ 2

  • Один из вариантов - мультиплексировать данные в формат файла, такой как mp4 или avi, чтобы иметь возможность проигрывать его с VLC. AFAIR avi плохо подходит для H.264 (не могу вспомнить причину от руки). Существуют бесплатные библиотеки, такие как libmp4, или если вы работаете в Windows с помощью DirectShow, Geraint mp4mux.

    Другой вариант - использовать ffmpeg для преобразования файла .264 в mp4

    ffmpeg -i test.264 test.mp4

    Это предполагает, что файл .264 содержит блоки NAL, разделенные стартовыми кодами.

  • Из RFC6184

    Полезная нагрузка FU состоит из фрагментов полезной нагрузки фрагментированного NAL, так что, если единичные единицы фрагментации последовательных FU последовательно конкатенируются, полезная нагрузка фрагментированного NAL блок может быть восстановлен. Октет типа блока NAL фрагментированного Блок NAL не включается как таковой в полезную нагрузку единицы фрагментации, а скорее информация о октете типа блока NAL фрагментированная единица NAL передается в F и NRI-полях FU индикатор октета блока фрагментации и в поле типа заголовок FU. Полезная нагрузка FU МОЖЕТ иметь любое количество октетов и МАЙ пусто.

    Вам нужно будет восстановить исходный блок NAL, прежде чем записывать его в файл .264, если вы возьмете второй подход, указанный в 1.