J'ai besoin de détecter le cadre I MPEG4 dans le paquet RTP. Je sais comment supprimer l'en-tête RTP et y insérer le cadre MPEG4, mais je ne peux pas comprendre comment identifier le cadre en I.
At-il une signature/un en-tête spécifique?
Ok, donc je l'ai trouvé pour le flux h264.
Comment détecter I-Frame:
Je ne peux pas le comprendre pour le flux MPEG4-ES ... des suggestions?
EDIT: H264 IDR
Cela fonctionne pour mon flux h264 (fmtp:96 packetization-mode=1; profile-level-id=420029;
). Vous venez de passer un tableau d'octets qui représente le fragment h264 reçu via RTP. Si vous voulez passer le RTP entier, corrigez simplement la valeur RTPHeaderBytes
pour ignorer l'en-tête RTP. J'obtiens toujours l'I-Frame, car c'est le seul cadre qui peut être fragmenté , voir ici . J'utilise ce morceau de code (simplifié) sur mon serveur, et cela fonctionne comme un charme !!!! Si l'I-Frame (IDR) n'est pas fragmenté, le fragment_type
serait 5, donc ce code retournerait true
pour les IDR fragmentés et non fragmentés.
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;
}
Voici le tableau des types d'unités 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
J'ai oublié de mettre à jour ceci ... Merci à Che et ISO IEC 14496-2 document, j'ai réussi à résoudre ça! Che était rite, mais pas si précis dans sa réponse ... alors voici comment trouver les trames I, P et B (I-VOP, P-VOP, B-VOP) en bref:
000001B6
(hex). C'est la même chose pour toutes les trames MPEG4 (I, P, B)Suit beaucoup plus d'informations, que je ne vais pas décrire ici (voir le document IEC), mais nous avons seulement (comme l'a dit che) besoin des 2 bits supérieurs de l'octet suivant (les deux suivants bits après l'octet avec la valeur B6
). Ces 2 bits vous indiquent le VOP_CODING_TYPE, voir le tableau:
VOP_CODING_TYPE (binary) Coding method
00 intra-coded (I)
01 predictive-coded (P)
10 bidirectionally-predictive-coded (B)
11 Sprite (S)
Donc, pour trouver I-Frame, trouvez le paquet commençant par quatre octets 000001B6
et ayant les deux bits supérieurs de l'octet suivant 00
. Cela trouvera une image dans le flux MPEG4 avec un type d'objet vidéo simple (pas sûr pour les simples avancés).
Pour tout autre problème, vous pouvez vérifier le document fourni ( ISO IEC 14496-2 ), il y a tout ce que vous voulez savoir sur MPEG4. :)
Pour autant que je sache, les fragments de flux MPEG4-ES dans RTP commence généralement par le code de démarrage MPEG4, qui peut être l'un des suivants:
0x000001b0
: visual_object_sequence_start_code (probablement une image clé)0x000001b6
: vop_start_code (image clé, si les deux bits suivants sont nuls)0x000001b3
: group_of_vop_start_code, qui contient trois octets puis, espérons-le, un vop_start_code qui peut ou non appartenir à une image clé (voir ci-dessus)0x00000120
: video_object_layer_start_code (probablement une image clé)0x00000100
-0x0000011f
: video_object_start_code (ceux-ci ressemblent également à des images clés)J'ai peur que vous ayez besoin d'analyser le flux pour être sûr: - /
En fait, vous aviez raison pour le flux h264, si la valeur NAL (premier octet) est 0x7C
cela signifie que l'I-Frame est fragmenté. Aucune autre trame (P et B) ne peut être fragmentée, donc s'il y a packetization-mode=1
dans SDP
, cela signifie que les I-Frames sont fragmentés, et donc si vous lisez 0x7C
comme premier octet, puis c'est I-Frame. En savoir plus ici: http://www.rfc-editor.org/rfc/rfc3984.txt .
Cela a fonctionné pour moi:
- Déterminez le "type de charge utile", par exemple: Type de charge utile: DynamicRTP-Type-96 (96)
- Indiquez à Wireshark quel flux est H264: Fichier-> préférences-> protocoles-> H264. Entrez 96 comme type de charge utile.
- Filtre sur slice_type: "h264.slice_type eq 7"
0x000001b6: vop_start_code (image clé, si les deux bits suivants sont nuls) c'est la bonne façon pour MPEG-4
Pour H264:
Exemples:
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
...