École Polytechnique de Montréal Département de Génie Informatique INF8500 Automne 2012 Laboratoire #2, Partie 1 Transformation des couleurs dans le MJPEG 1. Objectif L objectif de ce laboratoire est de se familiariser avec une approche de conception de type plateforme (e.g. modélisation, partitionnement, raffinement) en utilisant un environnement graphique SpaceStudio qui permet la spécification, l exploration architecturale, la simulation et le monitoring d un système à travers différents niveaux d abstraction. La partie 1 de ce laboratoire vise à se familiariser avec le fonctionnement interne d un décodeur Motion JPEG (MJPEG) et d être capable d identifier les grandes étapes de traitement de ce dernier en s attardant davantage à la conversion de couleur. 2. Mise en contexte du MJPEG Le standard MJPEG consiste à appliquer le standard JPEG à la partie vidéo d une archive audiovisuelle. En effet, ce précepte propose de traiter une vidéo comme s il s agissait d une suite d image JPEG. Ceci implique que chacune des trames qui composent un fichier MJPEG est individuellement encodée, et ce, sans aucune compression inter trame. Un des systèmes qui découle de cette norme est le décodeur MJPEG. Celui ci consiste en plusieurs opérations et son flot de données lors d un traitement de décodage est représenté à la figure 1 : Figure 1 : Décodeur MJPEG
Les flèches indiquent les communications nécessaires entre ces modules lors d une exécution en parallèle. La tâche TG agit comme un extracteur. Elle lit un fichier MJPEG en mémoire et l injecte dans le décodeur. La deuxième tâche, DEMUX, interprète les marqueurs contenus dans le fichier MJPEG et envoie l information pertinente aux autres modules. L opération VLD (Variable Length Decoding) est une tâche qui applique l algorithme de Huffman. Ensuite, le module IQZZ sert à remettre les éléments d un bloc en ordre (un bloc est une région de l image 8x8 pixels) et à appliquer une quantification sur chaque élément de ce même bloc. La prochaine étape, IDCT, est l application d une transformée inverse en cosinus discrète. Ceci est une transformation similaire à la transformée inverse de Fourrier discrète. Finalement, la dernière tâche, LIBU, réorganise les blocs en une image par ligne et par colonne. Les données brutes qui constituent les images transitent du VLD vers l IQZZ vers IDCT pour finalement aboutir dans le LIBU dans le format YCbCr. Une transformation est appliquée sur ces données dans chacun des 4 modules. Pour en savoir davantage sur les différentes étapes voir http://fr.wikipedia.org/wiki/jpeg. Également, d autres références se trouvent à la dernière page. 3. Travail à effectuer Vous devrez implémenter le module LIBU. Cette tâche consiste à réordonner les blocs de données en provenance du module IDCT pour que l image animée puisse être affichée par le contrôleur VGA. Voici quelques caractéristiques à propos du module LIBU qui vous permettrons de mener à bien cet exercice : 1. Les blocs de données qui arrivent de l IDCT sont appelés macrobloc. Ils représentent un bloc de 8X8 pixels. 2. L ordre d arrivée des macroblocs est le suivant : luminance (Y), chrominance bleue (Cb) et chrominance rouge (Cr). On parle donc ici de 3 macroblocs un à la suite de l autre. Pour chaque lecture, c est un macrobloc entier qui est lu : soit une matrice de 8X8 octets 3. Selon l encodage JPEG, le nombre de macroblocs de luminance peut varier. Il peut être soit de 1, 2 ou 4. On peut calculer cette valeur en multipliant le Horizontal sampling factor (Hi) et le Vertical sampling factor (Vi). Les seules valeurs que peuvent prendre le Hi et le Vi du Y sont 1 ou 2. Il existe aussi un Hi et un Vi pour les macroblocs Cb et Cr mais ceux ci (sauf exception) sont toujours à 1. Pour ce TP on suppose donc qu ils sont toujours à 1. 4. En combinant les valeurs des macroblocs, on peut en extraire la couleur des pixels sous format YCbCr (un triplet Y Cb Cr, pour un total de 3 octets). La combinaison de données s effectue selon le Hi et Vi du Y. L exemple suivant montre comment on combine un Y qui a un Hi Vi de 2 2 avec les Cb Cr : les valeurs Cb Cr sont utilisées 2 fois à l horizontale et 2 fois à la verticale (voir les motifs de couleur). Autrement dit, on combine les valeurs 1, 2, 9 et 10 du Y(1) avec la valeur 1 du Cb et la valeur 1 du Cr ou encore, les valeurs 1, 2, 9 et 10 du Y(2) avec la valeur 4 du Cb et la valeur 4 du Cr.
Voici un tableau qui récapitule les quatre cas possibles : Cas Y (Hi) Y (Vi) Cb et Cr (Hi) Cb et Cr (Vi) Nb macroblocs Nb pixels 1 1 1 1 1 3 8X8 2 2 1 1 1 4 16X8 3 1 2 1 1 4 8X16 4 2 2 1 1 6 16X16 Dans le cadre de ce travail pratique, nous allons vous demander de coder uniquement le cas #4 soit pour un Y ayant un Hi Vi de 2 2. Voici un tableau qui vous indique comment on combine les données afin de déterminer la couleur finale des pixels : Table 1 : Y(1) Table 3 : Y(3) Table 5 : Cb Table 2 : Y(2) Table 4 : Y(4) Table 6 : Cr
Dans le cas illustré précédemment, on a un ratio de 4 valeurs de luminance Y pour 1 valeur de chrominance bleu et rouge (Cb et Cr). Donc avec 4 valeurs Y, 1 valeur de Cb et 1 valeur Cr, on peut décoder 4 pixels de couleur YCbCr. 5. Le contrôleur VGA ne supporte que le format de couleur RGBA. Il faudra donc convertir le format YCbCr avant d envoyer les données finales au contrôleur VGA. Vous pouvez utiliser les formules suivantes pour effectuer la conversion : R = (((y << 10) + 1436 * (cr 128)) >> 10) G = (((y << 10) 352 * (cb 128) 732 * (cr 128)) >> 10) B = (((y << 10) + 1815 * (cb 128)) >> 10) A = 255 6. Pour recréer l image finale, les pixels doivent être agencés selon le Hi Vi du codec : soit uniquement 2 2 pour ce travail. On parle donc ici de quatre blocs de pixel 8X8 qui en formeront un de 16X16 au final. En te basant sur les valeurs d Y(x), voici à quoi ressemblerait l agencement : Table 7 : Disposition de blocs Y pour recréer l'image finale Y(1) Y(2) Y(1) Y(2) Y(1) Y(2) Y(3) Y(4) Y(3) Y(4) Y(3) Y(4) Y(1) Y(2) Y(1) Y(2) Y(1) Y(2) Y(3) Y(4) Y(3) Y(4) Y(3) Y(4) 7. Le contrôleur VGA affiche le résultat dans une fenêtre à dimension fixe. Ses dimensions sont définies dans le fichier ApplicationDefinitions.h sous les variables WIDTH_VGA et HEIGHT_VGA. Supposez que les fichiers vidéo vont toujours être de cette taille ou de taille plus petite. 8. On peut transmettre la valeur d un pixel au contrôleur VGA avec la fonction suivante : DeviceWrite(VGA_CONTROLLER_ID, offset, &outputpixel, 1). VGA_CONTROLLER_ID est l identificateur du module auquel on veut envoyer de l information, offset est l adresse à laquelle on veut écrire de l information sur le module de destination, outpoutpixel est la valeur d un pixel RGBA (un octet par couleur pour un total de 4) et le 1 signifie que l on veut transmettre 1 fois 4 octets de donnée. 9. L adresse du premier pixel dans le contrôleur VGA est 0, celle du deuxième 4 et ainsi de suite. Donc, suivant cette logique et le point précédent, le premier pixel de la deuxième ligne sera à l adresse 4 * WIDTH_VGA. Notes : Avec les caractéristiques énumérées ci dessus, à vous maintenant de parcourir le code du démultiplexeur (DEMUX) et à identifier les informations à transmettre au LIBU. Il y en a tout au plus 5 à
transmettre. Faites attention que l ordre d envoi des informations soit le même que l ordre de réception dans le LIBU. Pour ce TP, vous devez uniquement vous référer au code du DEMUX et du LIBU, la compréhension du code des autres modules est facultative. Référence : http://www.cs.cf.ac.uk/dave/multimedia/node248.html http://www.blackice.com/help/tools/document%20imaging%20sdk%20webhelp/webhelp/what_is_j PEG.htm http://en.wikibooks.org/wiki/jpeg_ _Idea_and_Practice/The_header_part http://en.wikibooks.org/wiki/jpeg_ _Idea_and_Practice/Appendix_1:_Summary_of_the_header_segments http://en.wikipedia.org/wiki/chroma_subsampling#4:1:1