Мне нужно обнаружить I-Frame MPEG4 в пакете RTP. Я знаю, как удалить заголовок RTP и получить в нем кадр MPEG4, но я не могу понять, как идентифицировать I-Frame.
Есть ли у него конкретная подпись/заголовок?
Мне нужно обнаружить I-Frame MPEG4 в пакете RTP. Я знаю, как удалить заголовок RTP и получить в нем кадр MPEG4, но я не могу понять, как идентифицировать I-Frame.
Есть ли у него конкретная подпись/заголовок?
Итак, я понял это для потока h264.
Как определить I-Frame:
Я не могу понять, для потока MPEG4-ES... любые предложения?
РЕДАКТИРОВАТЬ: H264 IDR
Этот работает для моего потока h264 (fmtp:96 packetization-mode=1; profile-level-id=420029;
). Вы просто передаете массив байтов, который представляет фрагмент h264, полученный через RTP. Если вы хотите передать весь RTP, просто скорректируйте значение RTPHeaderBytes
, чтобы пропустить заголовок RTP. Я всегда получаю I-Frame, потому что это единственный фрейм, который может быть фрагментирован, см. здесь. Я использую этот (упрощенный) код на моем сервере, и он работает как шарм!!!! Если I-Frame (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]
EDIT 2: MPEG-4 I-VOP
Я забыл обновить этот... Thanx to Che и документ ISO IEC 14496-2, мне это удалось! Че был обрядом, но не очень точным в его ответе... так вот, как кратко найти I, P и B кадров (I-VOP, P-VOP, B-VOP):
000001B6
(hex). Это то же самое для всех кадров MPEG4 (I, P, B)Далее следует много больше информации, которую я не буду описывать здесь (см. документ IEC), но мы только (как сказал che) нуждаемся в более высоких 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-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-Frame фрагментирован. Никакие другие кадры (P и B) не могут быть фрагментированы, поэтому, если в SDP
есть packetization-mode=1
, то это означает, что I-Frames фрагментированы, и поэтому, если вы читаете 0x7C
в качестве первого байта, то это I-Frame. Подробнее здесь: http://www.rfc-editor.org/rfc/rfc3984.txt.
Это сработало для меня:
- Выясните "тип полезной нагрузки", например: Тип полезной нагрузки: DynamicRTP-Type-96 (96)
- Сообщите wirehark, какой поток H264: File- > preferences- > protocols- > H264. Введите 96 в качестве типа полезной нагрузки.
- Фильтр по slice_type: "h264.slice_type eq 7"
Для H264:
Примеры:
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
...
0x000001b6: vop_start_code (ключевой кадр, если следующие два бита равны нулю) это правильный способ для MPEG-4