Я должен обнаружить I-кадр MPEG4 в пакете RTP. Я знаю, как удалить заголовок RTP и получить кадр MPEG4 в нем, но я не могу выяснить, как определить I-кадр.
Это имеет определенную подпись/заголовок?
Хорошо, я выяснил это для потока h264.
Как обнаружить 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) вкратце:
000001B6
(hex). Это то же самое для всех кадров MPEG4 (I,P,B)Далее следует гораздо больше информации, которую я здесь описывать не буду (см. 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. :)
Насколько мне известно, фрагменты потока 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 (они тоже похожи на ключевые кадры)Боюсь, что для уверенности вам понадобится разобрать поток :-/
. На самом деле, вы правильно указали поток h264, если значение NAL (первый байт) равно 0x7C
, это означает, что I-кадр фрагментирован. Никакие другие кадры (P и B) не могут быть фрагментированы, поэтому, если есть packetization-mode = 1
в SDP
, то это означает, что I-кадры фрагментированы, и, следовательно, если вы читаете 0x7C
как первый байт, тогда это I-кадр. Подробнее читайте здесь: http://www.rfc-editor.org/rfc/rfc3984.txt .