Обнаружить MPEG4 / H264 I-Frame (IDR) в потоке RTP - PullRequest
25 голосов
/ 24 декабря 2009

Мне нужно обнаружить I-кадр MPEG4 в пакете RTP. Я знаю, как удалить заголовок RTP и получить в нем кадр MPEG4, но не могу понять, как идентифицировать I-кадр.

Имеет ли он конкретную подпись / заголовок?

Ответы [ 6 ]

31 голосов
/ 28 декабря 2009

Хорошо, так что я понял это для потока h264.

Как определить I-Frame:

  • удалить заголовок RTP
  • проверить значение первого байта в полезной нагрузке h264
  • если значение равно 124 (0x7C), это I-кадр

Я не могу понять это для потока MPEG4-ES ... какие-нибудь предложения?

РЕДАКТИРОВАТЬ: H264 IDR

Это работает для моего потока h264 (fmtp:96 packetization-mode=1; profile-level-id=420029;). Вы просто передаете байтовый массив, который представляет фрагмент h264, полученный через RTP. Если вы хотите передать весь RTP, просто исправьте значение RTPHeaderBytes, чтобы пропустить заголовок RTP. Я всегда получаю I-кадр, потому что это единственный кадр, который можно фрагментировать, см. здесь . Я использую этот (упрощенный) кусок кода на моем сервере, и он работает как шарм !!!! Если I-кадр (IDR) не фрагментирован, fragment_type будет равен 5, поэтому этот код будет возвращать true для фрагментированных и не фрагментированных IDR.

public static bool isH264iFrame(byte[] paket)
    {
        int RTPHeaderBytes = 0;

        int fragment_type = paket[RTPHeaderBytes + 0] & 0x1F;
        int nal_type = paket[RTPHeaderBytes + 1] & 0x1F;
        int start_bit = paket[RTPHeaderBytes + 1] & 0x80;

        if (((fragment_type == 28 || fragment_type == 29) && nal_type == 5 && start_bit == 128) || fragment_type == 5)
        {
            return true;
        }

        return false;
   }

Вот таблица типов единиц NAL:

 Type Name
    0 [unspecified]
    1 Coded slice
    2 Data Partition A
    3 Data Partition B
    4 Data Partition C
    5 IDR (Instantaneous Decoding Refresh) Picture
    6 SEI (Supplemental Enhancement Information)
    7 SPS (Sequence Parameter Set)
    8 PPS (Picture Parameter Set)
    9 Access Unit Delimiter
   10 EoS (End of Sequence)
   11 EoS (End of Stream)
   12 Filter Data
13-23 [extended]
24-31 [unspecified] 

РЕДАКТИРОВАТЬ 2: MPEG4 I-VOP

Я забыл обновить это ... Спасибо Че и документу ISO IEC 14496-2 , мне удалось это решить! Че был обряд, но не такой точный в своем ответе ... так вот, как найти I, P и B кадры (I-VOP, P-VOP, B-VOP) вкратце:

  1. VOP (плоскость видеообъекта - кадр) начинается с кода 000001B6 (hex). Это одинаково для всех кадров MPEG4 (I, P, B)
  2. Далее следует много дополнительной информации, которую я не собираюсь здесь описывать (см. Документ IEC), но нам нужны только (как сказал че) старшие 2 бита из следующего байта (следующие два бита после байт со значением B6). Эти 2 бита сообщают вам VOP_CODING_TYPE, смотрите таблицу:

    VOP_CODING_TYPE (binary)  Coding method
                          00  intra-coded (I)
                          01  predictive-coded (P)
                          10  bidirectionally-predictive-coded (B)
                          11  sprite (S)
    

Итак, чтобы найти I-кадр, найдите пакет, начинающийся с четырех байтов 000001B6 и имеющий старшие два бита следующего байта 00. Это позволит найти I кадр в потоке MPEG4 с простым типом видеообъекта (не обязательно для простого простого).

Для любых других проблем, вы можете проверить предоставленный документ ( ISO IEC 14496-2 ), есть все, что вы хотите знать о MPEG4. :)

7 голосов
/ 03 января 2010

Насколько я знаю, фрагменты потока MPEG4-ES в полезной нагрузке RTP обычно начинаются со стартового кода MPEG4, который может быть одним из следующих:

  • 0x000001b0: visual_object_sequence_start_code (вероятно, ключевой кадр)
  • 0x000001b6: vop_start_code (ключевой кадр, если следующие два бита равны нулю)
  • 0x000001b3: group_of_vop_start_code, который содержит три байта, а затем, надеюсь, vop_start_code, который может принадлежать или не принадлежать ключевому кадру (см. Выше)
  • 0x00000120: код video_object_layer_start_code (возможно, ключевой кадр)
  • 0x00000100 - 0x0000011f: video_object_start_code (они также выглядят как ключевые кадры)
  • что-то еще (вероятно, не ключевой кадр)

Боюсь, вам понадобится разобрать поток, чтобы убедиться: - /

6 голосов
/ 15 мая 2010

На самом деле, вы были правы для потока h264, если значение NAL (первый байт) равно 0x7C, это означает, что I-кадр фрагментирован. Никакие другие кадры (P и B) не могут быть фрагментированы, поэтому, если в SDP есть packetization-mode=1, то это означает, что I-кадры фрагментированы, и, следовательно, если вы читаете 0x7C как первый байт, то это I-Frame. Подробнее читайте здесь: http://www.rfc -editor.org / rfc / rfc3984.txt .

1 голос
/ 05 ноября 2013

Это сработало для меня:
- Определить «тип полезной нагрузки», например: Тип полезной нагрузки: DynamicRTP-Type-96 (96)
- Скажите wireshark, какой поток является H264: Файл-> Настройки-> Протоколы-> H264. Введите 96 в качестве типа полезной нагрузки.
- Фильтр по типу фрагмента: "h264.slice_type eq 7"

0 голосов
/ 23 октября 2016

Для H264:

  1. Удалить заголовок RTP.
  2. Если тип NAL фрагмента (в первом байте) имеет SPS (7) или PPS (8), пометьте кадр как IFrame (многие камеры не используют SPS и PPS (включая Axis)).
  3. Если тип NAL фрагмента равен # 28 FU A (блок фрагментации A), проверьте заголовок FU (следующий байт), если IDR типа NAL (5) (IDR (изображение мгновенного обновления декодирования)), является IFrame.

Примеры:

nal_ref_idc: 3, nal type: 7 (0x07) descripcion: 7 (SPS)<br>
00000000  24 00 00 2B 80 60 22 ED 96 57 3E 68 57 F3 22 B5  $..+.`"í.W>hWó"µ<br>
00000010  67 64 00 1E AD 84 01 0C 20 08 61 00 43 08 02 18  gd..­... .a.C...

00000020  40 10 C2 00 84 2B 50 5A 09 34 DC 04 04 04 08  @.Â..+PZ.4Ü....<br>
nal_ref_idc: 3, nal type: 8 (0x08) descripcion: 8 (PPS)<br>
00000000  24 00 00 10 80 60 22 EE 96 57 3E 68 57 F3 22 B5  $....`"î.W>hWó"µ
00000010  68 EE 3C B0  hî<°

FU_A (fragmentation unit A) 
nal_ref_idc: 3, nal type: 5 (0x05) descripcion: 5 (IDR (Instantaneous Decoding Refresh) Picture)
00000000  24 00 05 96 80 60 22 F1 96 57 3E 68 57 F3 22 B5  $....`"ñ.W>hWó"µ
00000010  7C 05 A0 AA 2F 81 92 AB CA FE 9E 34 D8 06 AD 74  |. ª/..«Êþ.4Ø.­t
...
0 голосов
/ 13 января 2012

0x000001b6: vop_start_code (ключевой кадр, если следующие два бита равны нулю) это правильный путь для MPEG-4

...