web-dev-qa-db-fra.com

Emplacements possibles pour les ensembles de paramètres séquence / image pour le flux H.264

Je travaille sur un décodeur H.264 et je me demande où trouver le SPS et le PPS. Ma littérature de référence me dit que ce sont des unités NAL codées dans le flux H.264, mais lorsque je regarde un exemple de fichier MP4 avec IsoViewer, il est indiqué que le SPS et PPS sont dans la boîte avcC.

Comment ça marche exactement? À quoi ressemble-t-il les fichiers .mkv ou autres conteneurs H.264?

Merci d'avance!

72
bananenbär

Tout d’abord, il est important de comprendre qu’il n’existe pas de format de flux binaire élémentaire standard H.264. Le document de spécification contient une annexe, en particulier l'annexe B, qui décrit un format possible, mais il ne s'agit pas d'une exigence réelle. La norme spécifie comment la vidéo est codée en paquets individuels. La façon dont ces paquets sont stockés et transmis est laissée à l'intégrateur.


1. Annexe B

Unités de la couche d'abstraction du réseau

Les paquets sont appelés unités de couche d'abstraction de réseau. Souvent abrégé en NALU (ou parfois juste en NAL), chaque paquet peut être analysé et traité individuellement. Le premier octet de chaque NALU contient le type NALU, en particulier les bits 3 à 7. (le bit 0 est toujours désactivé et les bits 1 à 2 indiquent si une NALU est référencée par une autre NALU).

Il existe 19 types NALU différents définis en deux catégories, VCL et non-VCL:

  • Les paquets VCL ou Video Coding Layer contiennent les informations visuelles réelles.
  • Les non-VCL contiennent des métadonnées qui peuvent ou non être nécessaires pour décoder la vidéo.

Un seul NALU, ou même un VCL NALU, n'est pas la même chose qu'un cadre. Un cadre peut être "découpé" en plusieurs NALU. Tout comme vous pouvez couper une pizza. Une ou plusieurs tranches sont ensuite virtuellement regroupées dans une unité d’accès (AU) contenant une image. Le tranchage a un faible coût de qualité, il est donc peu utilisé.

Vous trouverez ci-dessous un tableau de toutes les NALU définies.

0      Unspecified                                                    non-VCL
1      Coded slice of a non-IDR picture                               VCL
2      Coded slice data partition A                                   VCL
3      Coded slice data partition B                                   VCL
4      Coded slice data partition C                                   VCL
5      Coded slice of an IDR picture                                  VCL
6      Supplemental enhancement information (SEI)                     non-VCL
7      Sequence parameter set                                         non-VCL
8      Picture parameter set                                          non-VCL
9      Access unit delimiter                                          non-VCL
10     End of sequence                                                non-VCL
11     End of stream                                                  non-VCL
12     Filler data                                                    non-VCL
13     Sequence parameter set extension                               non-VCL
14     Prefix NAL unit                                                non-VCL
15     Subset sequence parameter set                                  non-VCL
16     Depth parameter set                                            non-VCL
17..18 Reserved                                                       non-VCL
19     Coded slice of an auxiliary coded picture without partitioning non-VCL
20     Coded slice extension                                          non-VCL
21     Coded slice extension for depth view components                non-VCL
22..23 Reserved                                                       non-VCL
24..31 Unspecified                                                    non-VCL

Il existe quelques types de NALU où il peut être utile d’avoir des connaissances plus tard.

  • Jeu de paramètres de séquence (SPS). Cette NALU non-VCL contient les informations nécessaires à la configuration du décodeur, telles que le profil, le niveau, la résolution et la cadence.
  • Picture Parameter Set (PPS). Semblable au SPS, cette VCL non-VCL contient des informations sur le mode de codage entropique, les groupes de tranches, la prédiction de mouvement et les filtres de déblocage.
  • Rafraîchissement instantané du décodeur (IDR). Cette NALU VCL est une tranche d’image autonome. C'est-à-dire qu'un IDR peut être décodé et affiché sans faire référence à aucun autre SPS et PPS de sauvegarde NALU.
  • délimiteur d'unité d'accès (AUD). Un AUD est un NALU facultatif qui peut être utilisé pour délimiter des images dans un flux élémentaire. Il n'est pas obligatoire (sauf indication contraire du conteneur/protocole, comme TS) et n'est souvent pas inclus pour économiser de l'espace, mais il peut être utile de rechercher le début d'une trame sans avoir à analyser complètement chaque NALU.

Codes de départ NALU

Un NALU ne contient pas sa taille. Par conséquent, il suffit de concaténer les NALU pour créer un flux, car vous ne saurez pas où l’on s’arrête et où commence le suivant.

La spécification de l’Annexe B résout ce problème en exigeant que les ‘Codes de démarrage’ précèdent chaque NALU. Un code de départ est 2 ou 3 0x00 octets suivis d'un 0x01 octet. par exemple. 0x000001 ou 0x00000001.

La variation de 4 octets est utile pour la transmission sur une connexion série car il est trivial d'aligner le flux d'octets en recherchant 31 bits nuls suivis d'un. Si le bit suivant est 0 (car chaque NALU commence par un bit 0), c'est le début d'une NALU. La variation de 4 octets n'est généralement utilisée que pour signaler des points d'accès aléatoires dans le flux, tels qu'un SPS PPS AUD et IDR Where) car la variation de 3 octets est utilisée partout pour économiser de l'espace.

Octets de prévention d'émulation

Les codes de démarrage fonctionnent parce que les séquences à quatre octets 0x000000, 0x000001, 0x000002 et 0x000003 sont illégaux dans une NALU non RBSP. Ainsi, lors de la création d'une NALU, on prend soin d'échapper à ces valeurs qui pourraient autrement être confondues avec un code de départ. Ceci est accompli en insérant un octet ‘Prévention de l’émulation’ 0x03, pour que 0x000001 devient 0x00000301.

Lors du décodage, il est important de rechercher et d'ignorer les octets de prévention d'émulation. Étant donné que les octets de prévention d'émulation peuvent se trouver presque n'importe où dans une NALU, il est souvent plus pratique dans la documentation de supposer qu'ils ont déjà été supprimés. Une représentation sans octet de prévention d'émulation est appelée charge utile de séquence d'octet brut (RBSP).

Exemple

Regardons un exemple complet.

0x0000 | 00 00 00 01 67 64 00 0A AC 72 84 44 26 84 00 00
0x0010 | 03 00 04 00 00 03 00 CA 3C 48 96 11 80 00 00 00
0x0020 | 01 68 E8 43 8F 13 21 30 00 00 01 65 88 81 00 05
0x0030 | 4E 7F 87 DF 61 A5 8B 95 EE A4 E9 38 B7 6A 30 6A
0x0040 | 71 B9 55 60 0B 76 2E B5 0E E4 80 59 27 B8 67 A9
0x0050 | 63 37 5E 82 20 55 FB E4 6A E9 37 35 72 E2 22 91
0x0060 | 9E 4D FF 60 86 CE 7E 42 B7 95 CE 2A E1 26 BE 87
0x0070 | 73 84 26 BA 16 36 F4 E6 9F 17 DA D8 64 75 54 B1
0x0080 | F3 45 0C 0B 3C 74 B3 9D BC EB 53 73 87 C3 0E 62
0x0090 | 47 48 62 CA 59 EB 86 3F 3A FA 86 B5 BF A8 6D 06
0x00A0 | 16 50 82 C4 CE 62 9E 4E E6 4C C7 30 3E DE A1 0B
0x00B0 | D8 83 0B B6 B8 28 BC A9 EB 77 43 FC 7A 17 94 85
0x00C0 | 21 CA 37 6B 30 95 B5 46 77 30 60 B7 12 D6 8C C5
0x00D0 | 54 85 29 D8 69 A9 6F 12 4E 71 DF E3 E2 B1 6B 6B
0x00E0 | BF 9F FB 2E 57 30 A9 69 76 C4 46 A2 DF FA 91 D9
0x00F0 | 50 74 55 1D 49 04 5A 1C D6 86 68 7C B6 61 48 6C
0x0100 | 96 E6 12 4C 27 AD BA C7 51 99 8E D0 F0 ED 8E F6
0x0110 | 65 79 79 A6 12 A1 95 DB C8 AE E3 B6 35 E6 8D BC
0x0120 | 48 A3 7F AF 4A 28 8A 53 E2 7E 68 08 9F 67 77 98
0x0130 | 52 DB 50 84 D6 5E 25 E1 4A 99 58 34 C7 11 D6 43
0x0140 | FF C4 FD 9A 44 16 D1 B2 FB 02 DB A1 89 69 34 C2
0x0150 | 32 55 98 F9 9B B2 31 3F 49 59 0C 06 8C DB A5 B2
0x0160 | 9D 7E 12 2F D0 87 94 44 E4 0A 76 EF 99 2D 91 18
0x0170 | 39 50 3B 29 3B F5 2C 97 73 48 91 83 B0 A6 F3 4B
0x0180 | 70 2F 1C 8F 3B 78 23 C6 AA 86 46 43 1D D7 2A 23
0x0190 | 5E 2C D9 48 0A F5 F5 2C D1 FB 3F F0 4B 78 37 E9
0x01A0 | 45 DD 72 CF 80 35 C3 95 07 F3 D9 06 E5 4A 58 76
0x01B0 | 03 6C 81 20 62 45 65 44 73 BC FE C1 9F 31 E5 DB
0x01C0 | 89 5C 6B 79 D8 68 90 D7 26 A8 A1 88 86 81 DC 9A
0x01D0 | 4F 40 A5 23 C7 DE BE 6F 76 AB 79 16 51 21 67 83
0x01E0 | 2E F3 D6 27 1A 42 C2 94 D1 5D 6C DB 4A 7A E2 CB
0x01F0 | 0B B0 68 0B BE 19 59 00 50 FC C0 BD 9D F5 F5 F8
0x0200 | A8 17 19 D6 B3 E9 74 BA 50 E5 2C 45 7B F9 93 EA
0x0210 | 5A F9 A9 30 B1 6F 5B 36 24 1E 8D 55 57 F4 CC 67
0x0220 | B2 65 6A A9 36 26 D0 06 B8 E2 E3 73 8B D1 C0 1C
0x0230 | 52 15 CA B5 AC 60 3E 36 42 F1 2C BD 99 77 AB A8
0x0240 | A9 A4 8E 9C 8B 84 DE 73 F0 91 29 97 AE DB AF D6
0x0250 | F8 5E 9B 86 B3 B3 03 B3 AC 75 6F A6 11 69 2F 3D
0x0260 | 3A CE FA 53 86 60 95 6C BB C5 4E F3

Ceci est une AU complète contenant 3 NALU. Comme vous pouvez le constater, nous commençons par un code de début suivi d'un SPS (le SPS commence par 67). Dans le SPS, vous verrez deux octets de prévention d'émulation. Sans ces octets, la séquence illégale 0x000000 se produirait à ces positions. Ensuite, vous verrez un code de départ suivi d'un PPS (PPS commence par 68) et d'un code de départ final suivi d'une tranche IDR. Il s'agit d'un flux H.264 complet. Si vous les tapez valeurs dans un éditeur hexadécimal et enregistrez le fichier avec un .264 _ extension, vous pourrez le convertir en cette image:

Lena

L'Annexe B est couramment utilisée dans les formats en direct et en continu tels que les flux de transport, les émissions en direct et les DVD. Dans ces formats, il est courant de répéter le SPS et PPS régulièrement, précédant généralement chaque IDR, créant ainsi un point d'accès aléatoire pour le décodeur. Cela permet de rejoindre un flux déjà en cours.


2. AVCC

L’autre méthode courante de stockage d’un flux H.264 est le format AVCC. Dans ce format, chaque NALU est précédée de sa longueur (au format big endian). Cette méthode est plus facile à analyser, mais vous perdez les fonctionnalités d'alignement d'octet de l'Annexe B. Juste pour compliquer les choses, la longueur peut être codée en utilisant 1, 2 ou 4 octets. Cette valeur est stockée dans un objet d'en-tête. Cet en-tête est souvent appelé "extradata" ou "en-tête de séquence". Son format de base est le suivant:

bits    
8   version ( always 0x01 )
8   avc profile ( sps[0][1] )
8   avc compatibility ( sps[0][2] )
8   avc level ( sps[0][3] )
6   reserved ( all bits on )
2   NALULengthSizeMinusOne
3   reserved ( all bits on )
5   number of SPS NALUs (usually 1)
repeated once per SPS:
  16     SPS size
  variable   SPS NALU data
8   number of PPS NALUs (usually 1)
repeated once per PPS
  16    PPS size
  variable PPS NALU data

En utilisant le même exemple ci-dessus, l'extradata AVCC ressemblera à ceci:

0x0000 | 01 64 00 0A FF E1 00 19 67 64 00 0A AC 72 84 44
0x0010 | 26 84 00 00 03 00 04 00 00 03 00 CA 3C 48 96 11
0x0020 | 80 01 00 07 68 E8 43 8F 13 21 30

Vous remarquerez que SPS et PPS sont maintenant stockés hors bande. En d'autres termes, ils sont distincts des données du flux élémentaire. Le stockage et la transmission de ces données constituent le travail du conteneur de fichiers et sortent du cadre. Notez que, même si nous n’utilisons pas de codes de début, des octets de prévention d’émulation sont toujours insérés.

De plus, il existe une nouvelle variable appelée NALULengthSizeMinusOne. Cette variable nommée qui porte à confusion nous indique le nombre d'octets à utiliser pour stocker la longueur de chaque NALU. Ainsi, si NALULengthSizeMinusOne est défini sur 0, chaque NALU est précédée d’un seul octet indiquant sa longueur. En utilisant un seul octet pour stocker la taille, la taille maximale d’un NALU est de 255 octets. C'est évidemment assez petit. Bien trop petit pour une image clé entière. L'utilisation de 2 octets nous donne 64k par NALU. Cela fonctionnerait dans notre exemple, mais reste une limite assez basse. 3 octets seraient parfaits, mais pour une raison quelconque, ils ne sont pas universellement pris en charge. Par conséquent, 4 octets est de loin le plus commun, et c'est ce que nous avons utilisé ici:

0x0000 | 00 00 02 41 65 88 81 00 05 4E 7F 87 DF 61 A5 8B
0x0010 | 95 EE A4 E9 38 B7 6A 30 6A 71 B9 55 60 0B 76 2E
0x0020 | B5 0E E4 80 59 27 B8 67 A9 63 37 5E 82 20 55 FB
0x0030 | E4 6A E9 37 35 72 E2 22 91 9E 4D FF 60 86 CE 7E
0x0040 | 42 B7 95 CE 2A E1 26 BE 87 73 84 26 BA 16 36 F4
0x0050 | E6 9F 17 DA D8 64 75 54 B1 F3 45 0C 0B 3C 74 B3
0x0060 | 9D BC EB 53 73 87 C3 0E 62 47 48 62 CA 59 EB 86
0x0070 | 3F 3A FA 86 B5 BF A8 6D 06 16 50 82 C4 CE 62 9E
0x0080 | 4E E6 4C C7 30 3E DE A1 0B D8 83 0B B6 B8 28 BC
0x0090 | A9 EB 77 43 FC 7A 17 94 85 21 CA 37 6B 30 95 B5
0x00A0 | 46 77 30 60 B7 12 D6 8C C5 54 85 29 D8 69 A9 6F
0x00B0 | 12 4E 71 DF E3 E2 B1 6B 6B BF 9F FB 2E 57 30 A9
0x00C0 | 69 76 C4 46 A2 DF FA 91 D9 50 74 55 1D 49 04 5A
0x00D0 | 1C D6 86 68 7C B6 61 48 6C 96 E6 12 4C 27 AD BA
0x00E0 | C7 51 99 8E D0 F0 ED 8E F6 65 79 79 A6 12 A1 95
0x00F0 | DB C8 AE E3 B6 35 E6 8D BC 48 A3 7F AF 4A 28 8A
0x0100 | 53 E2 7E 68 08 9F 67 77 98 52 DB 50 84 D6 5E 25
0x0110 | E1 4A 99 58 34 C7 11 D6 43 FF C4 FD 9A 44 16 D1
0x0120 | B2 FB 02 DB A1 89 69 34 C2 32 55 98 F9 9B B2 31
0x0130 | 3F 49 59 0C 06 8C DB A5 B2 9D 7E 12 2F D0 87 94
0x0140 | 44 E4 0A 76 EF 99 2D 91 18 39 50 3B 29 3B F5 2C
0x0150 | 97 73 48 91 83 B0 A6 F3 4B 70 2F 1C 8F 3B 78 23
0x0160 | C6 AA 86 46 43 1D D7 2A 23 5E 2C D9 48 0A F5 F5
0x0170 | 2C D1 FB 3F F0 4B 78 37 E9 45 DD 72 CF 80 35 C3
0x0180 | 95 07 F3 D9 06 E5 4A 58 76 03 6C 81 20 62 45 65
0x0190 | 44 73 BC FE C1 9F 31 E5 DB 89 5C 6B 79 D8 68 90
0x01A0 | D7 26 A8 A1 88 86 81 DC 9A 4F 40 A5 23 C7 DE BE
0x01B0 | 6F 76 AB 79 16 51 21 67 83 2E F3 D6 27 1A 42 C2
0x01C0 | 94 D1 5D 6C DB 4A 7A E2 CB 0B B0 68 0B BE 19 59
0x01D0 | 00 50 FC C0 BD 9D F5 F5 F8 A8 17 19 D6 B3 E9 74
0x01E0 | BA 50 E5 2C 45 7B F9 93 EA 5A F9 A9 30 B1 6F 5B
0x01F0 | 36 24 1E 8D 55 57 F4 CC 67 B2 65 6A A9 36 26 D0
0x0200 | 06 B8 E2 E3 73 8B D1 C0 1C 52 15 CA B5 AC 60 3E
0x0210 | 36 42 F1 2C BD 99 77 AB A8 A9 A4 8E 9C 8B 84 DE
0x0220 | 73 F0 91 29 97 AE DB AF D6 F8 5E 9B 86 B3 B3 03
0x0230 | B3 AC 75 6F A6 11 69 2F 3D 3A CE FA 53 86 60 95
0x0240 | 6C BB C5 4E F3

Un avantage de ce format est la possibilité de configurer le décodeur au début et de sauter au milieu d’un flux. Il s'agit d'un cas d'utilisation courant dans lequel le support est disponible sur un support à accès aléatoire, tel qu'un disque dur, et est donc utilisé dans des formats de conteneur courants tels que MP4 et MKV.

246
szatmary

J'ai récemment travaillé sur quelque chose comme ça.

Découvrez un inspecteur MP4. Comme vous pouvez le voir sur cette image, un MP4 comporte de nombreuses zones qui doivent être analysées pour trouver les données dont vous avez besoin.

enter image description here

Ici, j'ai étiqueté les parties de la boîte avcc

enter image description here

Je viens tout juste d'écrire un blog à plusieurs posts sur mon utilisation de h264. Je pense que c'est trop long pour poster ici http://cagneymoreau.com/stream-video-Android/

3
cagney