Обнаружьте I-кадр MPEG4/H264 (IDR) в потоке RTP

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

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

25
задан Cœur 27 December 2018 в 05:19
поделиться

3 ответа

Хорошо, я выяснил это для потока h264.

Как обнаружить I-Frame:

  • remove RTP header
  • check the value of the first byte in h264 pay load
  • if the value is 124 (0x7C) it is a I-Frame

I can't figure it out for the MPEG4-ES stream. ... есть предложения?

EDIT: H264 IDR

Это работает для моего потока h264 (fmtp:96 packetization-mode=1; profile-level-id=420029;). Просто передается массив байт, представляющий фрагмент h264, полученный через RTP. Если вы хотите передать весь RTP, просто исправьте значение RTPHeaderBytes, чтобы пропустить заголовок RTP. Я всегда получаю I-Frame, так как это единственный кадр, который может быть фрагментирован, смотрите здесь. Я использую этот (упрощенный) фрагмент кода на своем сервере, и он работает как charm!!!!. Если бы I-Frame (IDR) не был фрагментирован, то тип_фрагмента был бы 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] 

EDIT 2: MPEG4 I-VOP

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

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

    VOP_CODING_TYPE (двоичный) Метод кодирования
     00 внутрикодовый (I)
     01 прогностический код (P)
     10 двунаправленный прогнозный код (B)
     11 спрайт (S)
    

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

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

32
ответ дан 28 November 2019 в 21:01
поделиться

Насколько мне известно, фрагменты потока 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 (они тоже похожи на ключевые кадры)
  • что-то другое (вероятно, не ключевой кадр)

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

.
7
ответ дан 28 November 2019 в 21:01
поделиться

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

6
ответ дан 28 November 2019 в 21:01
поделиться