У меня есть исходный поток H.264 из IP-камеры, упакованной в RTP-кадры. Я хочу получить сырые данные H.264 в файл, чтобы преобразовать его с помощью ffmpeg
.
Поэтому, когда я хочу записать данные в свой файл H.264, я обнаружил, что он должен выглядеть следующим образом:
00 00 01 [SPS]
00 00 01 [PPS]
00 00 01 [NALByte]
[PAYLOAD RTP Frame 1] // Payload always without the first 2 Bytes -> NAL
[PAYLOAD RTP Frame 2]
[... until PAYLOAD Frame with Mark Bit received] // From here its a new Video Frame
00 00 01 [NAL BYTE]
[PAYLOAD RTP Frame 1]
....
Итак, я получаю SPS
и PPS
из Session Description Protocol
из моего предыдущего сообщения RTSP
. Кроме того, камера отправляет SPS
и PPS
в два отдельных сообщения перед началом видеопотока.
Итак, я фиксирую сообщения в следующем порядке:
1. Preceding RTSP Communication here ( including SDP with SPS and PPS )
2. RTP Frame with Payload: 67 42 80 28 DA 01 40 16 C4 // This is the SPS
3. RTP Frame with Payload: 68 CE 3C 80 // This is the PPS
4. RTP Frame with Payload: ... // Video Data
Затем появляются некоторые фреймы с полезной нагрузкой и в какой-то момент RTP Frame с Marker Bit = 1
. Это означает (если я правильно понял), что у меня есть полный видеокадр. Afer это я снова пишу последовательность префикса (00 00 01
) и NAL
из полезной нагрузки и продолжаю с той же процедурой.
Теперь моя камера отправляет меня после каждых 8 полных видеофрагментов SPS
и PPS
снова. (Опять же в двух кадрах RTP, как показано в примере выше). Я знаю, что особенно PPS
может меняться между потоками, но это не проблема.
Теперь мои вопросы:
1. Нужно ли писать SPS/PPS каждый 8-й видеоканал?
Если мои SPS
и my PPS
не меняются, должно быть достаточно, чтобы они были написаны в самом начале моего файла и ничего больше?
2. Как отличить SPS/PPS от нормальных кадров RTP?
В моем С++-коде, который анализирует переданные данные, мне нужно сделать разницу между RTP-кадрами с нормальной полезной нагрузкой и теми, у которых есть SPS/PPS
. Как я могу их отличить? Ладно, кадры SPS/PPS
обычно меньше, но это не призыв к сохранению, на который можно положиться. Потому что, если я их игнорирую, мне нужно знать, какие данные я могу выбросить, или если мне нужно их написать, мне нужно поставить префикс 00 00 01
перед ними.? Или это фиксированное правило, что они происходят каждый 8-й видеоканал?