Хорошо, так что я понял это для потока 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) вкратце:
- VOP (плоскость видеообъекта - кадр) начинается с кода
000001B6
(hex). Это одинаково для всех кадров MPEG4 (I, P, B)
Далее следует много дополнительной информации, которую я не собираюсь здесь описывать (см. Документ 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. :)