Les données ont une représentation, elles ne sont pas simplement posées comme cela dans la partie Value. Elles doivent suivre certaines règles.
Chaque règle est comme un modèle (dans le sens "template") : il existe plusieurs modèles, certains sont très simples et d'autres plus complexes.
Plus imagé, voyez cela comme les petits casiers qu'on place dans les tiroirs pour ranger notre bordel :
Et bien, la structure de Value sera identique selon le petit casier-modèle utilisé :)
Tout d'abord, il faut savoir que les modèles sont classés dans deux grandes familles :
Pour le premier, il n'en existe qu'un seul modèle, lui-même, le Data Item. Pour le second, il existe 3 modèles :
Nous avons donc quatre modèles pour le "rangement" des données :
Le 1er modèle (Data Item) est le simple, ce sont les données brutes qui sont placées directement dans la partie Value sans aucun traitement.
Pour les autres modèles de la famille Data Groups, les données sont rangées dans des petites cases et il faudra suivre le modèle pour comprendre comment ils ont été placés.
Revenons plus en détails sur chaque type de données en commençant par le plus simple : Data Items
Peu de chose à dire, il suffit de lire les données brutes directement. C'est un peu l'équivalent avec ce casier :
C'est le type le plus simple: il suffit de lire le Length pour déterminer la taille totale de Value et de récupérer les données brutes.
Ces données peuvent être une frame JPEG2000 non-chiffrée (vous verrez les entêtes du J2C dès les premiers octets de Value), les pistes sonores au format WAV non-chiffrées ou bien d'autres encores.
Dès que vous voyez ce type de KLV, il n'y aura aucun traitement particulier à effectuer hormis extraire la donnée et - suivant le format - le traiter par son codec habituel. Par exemple, pour du JPEG2000, vous avez la librairie libre OpenJPEG ou la librairie propriétaire Kakadu pour ne citer que les plus connus.
Key aura donc son Category Designator à 0x01
(Data Items - Dictionary)
Les données structurées sont des données rangées en respectant certaines règles. Certaines règles permettent aux données d'être très libres - dans leurs emplacements, leurs tailles - et d'autres plus restrictives qui imposent des emplacements stricts ou la présence obligatoire de certaines données.
Nos équivalents casiers seraient ceux-là :
Voici les trois modèles normalisés pour les données structurées :
Local Sets : Ils ont un champ pour une petite clef (item.key) appelé Local Tag, un champ pour la taille des données (item.length) et un champ pour les données en eux-même (item.value) : oui, ce sont des KLV à l'intérieur de KLV, je les appelle des bébés KLV :
Defined-Length Pack : Ce sont des données fixes avec une taille précise. Elles n'ont ni item.key ni item.length - seulement les item.value placées l'une à la suite de l'autre :
Variable-Length Pack : Les données variables - sans item.key - avec seulement item.length et item.value :
Voila les trois modèles pour les données structurées.
Key aura donc son Category Designator à 0x02
(Data Groups - Sets/Packs)
Voyons en détail chaque modèle des données structurées.
Category Designator | 0x02 (Data Groups - Sets/Packs) |
---|---|
Registry Designator | 0x53 (Local Sets) 1 |
Exemple de KLV | Preface, Identification, Content Storage, Material Package, Timeline Track, Sequence, Index Table Segment |
Ce modèle est appelé Local Sets.
Le Local Sets stocke une multitude de petit KLV - que je surnomme des bébés KLV - de leurs vrais noms Items.
Chaque item respecte les règles des KLV que nous avons déjà vu mais avec quelques modifications :
Leurs clefs (item.key) sont nommées Local Tags et sont encodés sur 2 octets (16 bits)
Les tailles (item.length) sont encodées sur 2 octets (16 bits)
Les données (item.value) ... sont les données brutes.
Quelques règles sur ces items :
Si vous voulez en savoir plus sur le principe des Local Tags
Category Designator | 0x02 (Data Groups - Sets/Packs) |
---|---|
Registry Designator | 0x04 (Variable-Length Pack) 2 |
Exemple de KLV | Encrypted Essence |
Ce type reprend toutes les caractéristiques de Local Sets mais sans les clefs. Tous les items seront définis dans un certain ordre et suivant des critères définis dans la norme.
Dans Variable-Length Pack, vous aurez donc un Length puis un Value, ainsi de suite.
Normalement, vous ne pourrez définir précisement où se trouve tel ou tels items sans avoir lu le premier item.length qui permettra de déterminer la première item.value, qui déterminera ainsi le second item.length et ainsi de suite.
Notez que c'est la théorie parfaite. Il arrive que pour certains types de KLV, les normes définissent directement la taille des item.length et des item.value (ce qui rend inutile les item.length...).
Category Designator | 0x02 (Data Groups - Sets/Packs) |
---|---|
Registry Designator | 0x05 (Defined-Length Pack) |
Exemple | Partition Pack (Body, Footer, Header), Primer Pack, Random Index Pack |
Ce type de KLV est très simple : les items ont chacun un emplacement et une taille fixe. Il est donc assez simple d'aller chercher une donnée en particulier à un emplacement particulier.
A contrario, il est impossible de déroger à une valeur. Si elle est inutile, elle devra être complétée avec du vide pour respecter la structure. On se retrouve donc parfois avec une suite de zéros inutiles.
Ce type de KLV est parfois appelé Fixed-Length Pack dans certaines documentations SMPTE.
Surprise !
Ce n'est pas un terme officiel, c'est le surnom que j'ai donné à ce type de données structurées :-)
Ce sont des structures de données particulières : elles respectent soit une partie des Local Sets, soit des Variable-Length Pack soit des Fixed-Length Pack ... mais pas tout à fait : Certaines débutent avec des Local Tags mais ommettent la partie Length et passent directement à la Data avec une taille fixe; et d'autres ont juste les Lengths sans les Local Tags et les données ont une taille variable et d'autres encore ont des Lengths qu'ils n'utilisent pas ou bien respectent une partie du Variable-Length Pack mais d'un coup ajoute un bloc de Fixed-Length Pack (ou inversement).
Je mettrais par exemple, le KLV Encrypted Essence Container dans cette section, même si au niveau de la norme, cela n'est pas exact : il est considéré comme un Variable-Length Pack. J'expliquerai pourquoi dans les différentes parties des KLV respectifs (un exemple avec Encrypted Essence Container).
Voici un tableau récapitulatif des différents modèles pour la Value d'un KLV :
Data Items | - | Données brutes | item.value | ||
---|---|---|---|---|---|
Data Groups | Local Sets | KLV | item.key + item.length + item.value | ||
Variable-Length Pack | Données à tailles variables | item.length + item.value | |||
Fixed-Length Pack | Données à tailles fixées | item.value |
Voyons maintenant les différents types de KLV
Dans un MXF, nous avons plusieurs Local Set avec des valeurs de Registry Designator comme 0x03
, 0x13
et 0x53
, mais nous n'utiliserons que 0x53
. Voir KLV: Key: L'identifiant de type pour plus d'informations ↩
Variable entre 1 octet et 4 octets mais pour notre cas, c'est un BER. Cela est déterminé par la valeur du Registry Designator. ↩