Mémoire de Multimédia MPEG4 et XviD - Free
Transcript of Mémoire de Multimédia MPEG4 et XviD - Free
Mémoire de MultimédiaMPEG4 et XviD
parEdouard GomezetLionel Dufresne27 juin 2003
Résumé
Ce mémoire présente l’aspect historique d’MPEG dans une première partie. Puis les techniques em-ployées dans la méthode de compression MPEG sont explicités dans une deuxième partie. Enfin dansune dernière partie, nous nous sommes appuyés sur XviD afin d’illustrer par des chiffres et des exemplesles diverses conséquences du codage MPEG.
Table des matières
1 Introduction non technique à MPEG 21.1 Qu’est ce que MPEG ?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.2 Historique des standards MPEG. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.2.1 MPEG1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41.2.2 MPEG2. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41.2.3 MPEG3. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51.2.4 MPEG4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5Applications visées. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.3 Système de licence. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61.4 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2 Techniques employées par MPEG4 Visual Part 82.1 Vue d’ensemble. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92.2 Frame, Macro-block et blocks. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92.3 Espaces de couleur. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .102.4 Types d’images. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .112.5 La prédiction et la compensation de mouvement. . . . . . . . . . . . . . . . . . . . . . 122.6 La Transformée en Cosinus Discrète. . . . . . . . . . . . . . . . . . . . . . . . . . . . 142.7 La quantification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .152.8 Le codage entropique. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .162.9 Contrôle de la qualité du codage. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3 XviD 193.1 Historique du projet. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .203.2 Architecture d’XviD 1.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213.3 Système de Plugin. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .22
3.3.1 Les Plugins de BitRate Control. . . . . . . . . . . . . . . . . . . . . . . . . . 233.3.2 Les Plugins de Traitement d’Image. . . . . . . . . . . . . . . . . . . . . . . . 23
3.4 Mise en application d’XviD. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243.4.1 Comparaison en terme de taille. . . . . . . . . . . . . . . . . . . . . . . . . . . 243.4.2 Comparaison en terme de PSNR. . . . . . . . . . . . . . . . . . . . . . . . . . 253.4.3 Résultats moyens sur la série de test complète. . . . . . . . . . . . . . . . . . . 27
1
3.4.4 Comparaison visuelle. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
4 Conclusion 294.1 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .30
I Annexes 31.1 Code des scripts tests. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .32
.1.1 Tests de taille d’image. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
.1.2 Tests de PSNR. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .34.2 Code d’xvid_encraw . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .37
2
Chapitre 1
Introduction non technique à MPEG
3
Qu’est ce que MPEG ?
1.1 Qu’est ce que MPEG ?
MPEG est l’acronyme de Moving Picture Expert Group, un groupe formé sous les auspices de l’Organi-sation Internationationale de Normalisation (ISO) et de la Commission Internationale d’Electrotechnique(IEC). Il s’agit d’un groupe d’industriels qui se réunit afin d’élaborer des standards dans le domaine descompressions de la vidéo et de l’audio numériques. Ils définissent en particulier des flux binaires com-pressés desquels découlent implicitement des décodeurs. Cependant les algorithmes utilisés afin d’obte-nir ce format de flux binaire compressé est laissé au bon vouloir des implanteurs de la norme.
Voici une liste de quelques membres :
– Canon, Inc.– Curitel Communications, Inc.– France Télécom, société anonyme– Fujitsu Limited– GE Technology Development, Inc.– General Instrument Corporation– Hitachi, Ltd.– KDDI Corporation– Koninklijke Philips Electronics N.V.– Matsushita Electric Industrial Co., Ltd.– Microsoft Corporation– Mitsubishi Electric Corporation– Oki Electric Industry Co.– Samsung Electronics Co., Ltd.– SANYO Electric Co., Ltd.– Sharp Kabushiki Kaisha– Sony Corporation– Telenor Communication II AS– Toshiba Corporation– Victor Company of Japan, Ltd.
Aujourd’hui le grand public utilise quotidiennement des produits (matériel ou logiciel) issus des stan-dards du groupe MPEG. En voyant la liste précédente, on voit mal de toute façon comment il auraitpu être autrement tellement les acteurs participant à MPEG touchent une clientèle sur de très diversmarchés : informatique, téléphonie.... Entre autres standards usuels, on peut citer les plus connus :
– Les formats vidéo MPEG1/2/4.– Les formats audio MPEG1 Layer I,II, III (aka “mp3”).
Le groupe MPEG définit aussi comment tous ces types de flux basiques peuvent être multiplexés pourdonner un flux transmissible comprenant son, vidéo et informations diverses telles que les sous titres,information de chapitrage etc...
4
Historique des standards MPEG
1.2 Historique des standards MPEG
1.2.1 MPEG1
MPEG1 est le premier essai du groupe MPEG afin de définir un format efficace de compression vidéo. Lestandard MPEG1 est un ensemble de 5 publications de l’Organisation Internationale de Normalisations,sous la dénomination ISO/IEC 11172 Part 1 à 5. Les 3 premières publications ont été écrits en 1993,ils définissent les flux binaires vidéo (Part 2), audio (Part 3) ainsi que leur multiplexage pour aboutir àun flux multimédia complet (Part 1). La 4ème publication en 1995, standardise une plate-forme de testsafin de s’assurer de l’inter-opérabilité des matériels et softwares se voulant être compatibles MPEG1.En 1998, l’ISO publie la part 5 du standard, mais il ne s’agit pas d’un texte, c’est en fait un logiciel deréférence publié sous forme de code source. C’est de lui que dérivent tous les logiciels les plus usités parle public.
Le standard MPEG1 est prévu pour un vitesse de flux autour de 1,5MB pour une image n’excedant pasles 352x240. Cela correspond approximativement à une qualité équivalente à du VHS. On pourra noterque le MPEG1 a surtout été utilisé dans les pays d’Asie où il a su s’imposer à travers le format VCD(Vidéo CD) très employés entre autre dans les karaokés.
Cependant MPEG1 a très vite montré ses limites. Dès lors que le matériel a permis de traiter des imagesde taille plus conséquente, MPEG1 n’offrait plus les moyens techniques de garantir une qualité suffisante.
1.2.2 MPEG2
Voyant que le MPEG1 ne saurait satisfaire les besoins de la vidéo numérique (haute définition, hautequalité), le groupe MPEG a entamé une autre collaboration afin d’établir les bases d’un standard capablede supporter des hauts débits ainsi qu’une image de plus haute résolution.
Ce standard a été progressivement publié de 1998 à 2000, un peu à la façon de MPEG1 en publiantdivers écrit traitant chacun d’une partie du standard. Il définit une nouvelle génération de compression“MPEG” qui délivre une qualité supérieure et se montre plus efficace pour les hauts débits et grandesimages. MPEG2 intègre aussi le support de formats d’image professionnels tel que le format YUV422. Ilintroduit aussi de nouveaux concepts de compression tels que les références temporelles bidirectionnelleset le support natif des séquences entrelacées (très utilisées par/pour la télévision). MPEG2 apporte aussiénormément au niveau de la couche transport/multiplexage et en fait un candidat idéal pour des fluxmultimédias complexes avec une intéractivité réduite. Sa fourchette de débit idéal se situe entre 1.5MB/set 15MB/s.
L’un des principaux problèmes lié à la diffusion de MPEG1 est sa totale absence de contrôle de flux.C’est à dire qu’il se contente d’être émit sans se soucier des capacités de l’équipement terminal. LeMPEG2 permet un contrôle de flux en proposant au niveau de son codage différentes couches :– une couche de base avec une qualité restreinte,– une ou plusieurs couches supplémentaires d’améliorations.
5
Historique des standards MPEG
Ceci permet d’avoir plusieurs films vidéos transmis dans les mêmes trames (suite de bits envoyés surle réseau). Quatre modes de codages hiérarchiques sont définis par MPEG2 (temporel, spatial, avecvariation du pas de quantification, avec partitionnement des données prioritaires). Pour chacun d’eux ily a une couche de base et une ou plusieurs couches d’améliorations.
Ses utilisations les plus courantes sont le DVD1 et le DVB2 dans la télévision numérique par satellite.
1.2.3 MPEG3
Cette norme n’a jamais vu le jour, elle était censé couvrir les très hauts débits. Mais MPEG2 se montraitétonnamment performant dans les très hauts débits et MPEG3 fut directement intégré dans MPEG2.
1.2.4 MPEG4
Description
MPEG4 est plus qu’une simple amélioration des générations précédentes, il définit une véritable philo-sophie de la vidéo en dépassant les concepts de codage et de compression. Le MPEG4, en effet, définità la fois une syntaxe du flux vidéo codé et un ensemble d’outils permettant la diffusion de cette vidéosur des réseaux hétérogènes. L’aspect le plus visible du MPEG4 est l’introduction de la notion d’objetsmédias. La scène vidéo est décomposée en objets visuels indépendants, une personne, un meuble, unecarte, ... et en objets audio comme la voix d’une personne, le bruit de moteur d’une voiture, ...
De plus ces objets peuvent être naturels ou synthétiques : ils peuvent provenir d’une caméra ou d’unordinateur. En fait un mixage est fait entre des sources réelles et des sources synthétiques. Ces sources" rapportées " peuvent être aussi bien en 2D, qu’en 3D. En plus de définir des objets, MPEG4 définitune arborescence structurant ces objets en les décomposant en d’autres objets. Une personne pourraêtre décomposée en sa voix, son visage, ses mains, et le reste du corps. La scène vidéo sera donc ainsidécomposée selon une hiérarchie de ces médias objets et selon leur disposition spatiale. MPEG4 permetégalement de les manipuler de différentes façons et ainsi de rendre interactif la scène vidéo transmise.Les objets média pourront être identifiés et recevoir un code qui leur permettra de ne pas être réutilisé àoutrance. On pourra ainsi protéger les droits d’un auteur sur son objet média.
Applications visées
Nous pouvons essayer de dénombrer les utilisations de MPEG4 en les séparant selon leurs spécificités.Ces spécificités ne sont pas liées à la qualité de service, car celle-ci est fonction de l’équipement terminal,mais plutôt de l’utilisation possible du flux vidéo. Ce flux peut être en temps réel et ainsi convenir
1Digital Versatile Disc2Digital Video Broadcasting
6
Système de licence
à la diffusion d’émissions télévisées. Bien sur d’autres applications sont également visées comme lavidéophonie qui requiert, comme le téléphone, des notions de synchronisation et de faibles délais depropagation, la vidéo-conférence et, en général, tout travail effectué à distance en “direct”, comme parexemple un professeur américain qui donne des cours à des élèves français.
Les applications peuvent être interactives, c’est à dire que l’utilisateur peut intervenir dans le flux vidéoen modifiant les propriétés de certains objets médias ou en déclenchant des événements en cascade.
Les applications dans ce cas sont nombreuses et on peut penser à Internet avec de nombreuses opportu-nités de pages web où au lieu de cliquer sur un lien hypertexte, on cliquerait sur un objet dans une vidéopour accéder, par exemple à une page descriptive de l’objet sélectionné. On parle alors d’hypermédia.
En fait, à part pour certains types de transmissions (vers des portables par exemple), beaucoup des appli-cations ciblées par MPEG4 seront interactives. Enfin, les applications peuvent être une simple diffusionde vidéo entre un opérateur distribuant des films et l’abonné, mais aussi une connexion entre deux parti-culiers ou deux sites qui dialoguent entre eux via MPEG4 (vidéophonie, visioconférence,...).
Pour résumer, une application utilisant MPEG4 pourra être :– Interactive (hypermédia) ou non (télévision, transmission vers des portables,...).– En temps réel (transmission depuis une source d’échantillonnage, vidéo conférence, téléphonie mobile
...) ou non (transmission depuis une unité de stockage)– Symétrique (Vidéophonie) ou non (caméra de surveillance, jeux, consultation d’informations).
1.3 Système de licence
Face à la concurrence technologique et commerciale de Microsoft avec son format propriétaire WindowsMedia, le MPEG-4 voyait son avenir s’assombrir. Pour préserver ses parts de marché et - surtout - tenterde poursuivre son déploiement auprès des industriels, le MPEG-LA, organisme chargé de commercialiserla norme de compression vidéo, vient d’annoncer l’unification des licences (depuis le 12 février 2003).Un choix commercial qui devrait simplifier la vie des entreprises.
Jusqu’à présent, lorsqu’un éditeur ou un constructeur souhaitait exploiter les technologies de la normeMPEG-4, il était soumis à une licence particulière en fonction de l’utilisation finale. Ainsi, on ne payaitpas le même prix selon que l’on utilisait le format de compression vidéo sur Internet ou un appareilmobile, un enregistreur ou un support de stockage, à des fins d’utilisation individuelles ou en entreprise.Cette politique de licence catégorisée vient de voler en éclats au profit d’une licence unique pour tous lesusages.
Baptisée MPEG-4 Patent Systems Portfolio License, cette nouvelle licence unique donnera un "accèsjuste, raisonnable et non discriminatoire" à "l’essentiel" des technologies qui constituent la base du for-mat de compression vidéo et détenues par sept sociétés (Apple, ETRI, France Télécom, Philips, Mitsubi-shi, Samsung et Sun). La nouvelle politique du MPEG-LA résulte, selon son communiqué, des observa-tions rapportées par les industriels du secteur. Mais c’est surtout une réponse au récent format WindowsMedia 9 de Microsoft qui, en cassant les prix de ses licences, se présente comme un sérieux concurrent
7
Conclusion
tant commercial que technologique face au MPEG-4 en voie de standardisation dans les faits. Malgréles dissensions qui existent probablement entre les différents pourvoyeurs de la technologie MPEG-4,le MPEG-LA a réussi à s’adapter rapidement à la concurrence et à la demande du marché. Il ne resteplus qu’à convaincre les industriels d’adopter ces technologies qui, rappelons-le, présentent l’avantaged’évoluer en permanence par l’intermédiaire notamment de nouveaux codecs.
1.4 Conclusion
MPEG4 cible la vidéo à très faible débit (VLBV : Very Low Bitrate Video). Pour cela, elle reprend lesfonctionnalités de MPEG2 et élargit son champ d’action. MPEG4 peut ainsi se concevoir comme uneboîte à outils permettant à la fois de décomposer une vidéo en différents types d’objets et de manipulerces objets avec des outils adéquats. En plus de cela, MPEG4 est une norme portable qui lui permettra des’affranchir des contraintes liées aux réseaux. Sa façon de définir des interfaces vers certains outils plutôtque ces outils eux-mêmes la rend très malléable et n’impose pas ainsi à un distributeur de services uneseule façon d’implémenter un décodeur ou un codeur. L’extension de la notion de codage hiérarchiqueintroduite par MPEG2 est aussi une révolution en matière de flexibilité et de réduction de trafic dans lesréseaux. Les apports de la version 2 par rapport à la version 1 sont nombreux mais n’entraînent pas demodification de la structure profonde de MPEG4.
Les outils ajoutés et les améliorations apportées auront plusieurs objectifs :– Accentuer l’efficacité du codage audio et vidéo– Accentuer la portabilité et donc le champ d’action de MPEG4– Augmenter les contrôles d’erreurs et réduire les problèmes de déséquencement– Permettre d’autres types d’utilisation (MPEG-J)– Offrir une norme très moderne et très puissante
8
Chapitre 2
Techniques employées par MPEG4 VisualPart
9
Vue d’ensemble
2.1 Vue d’ensemble
On ne peut aborder chacun des algorithmes mis en jeu dans un codeur MPEG sans avoir une visiond’ensemble préalable. Le schéma qui suit montre une architecture d’un codeur MPEG dans son ensemble.Les différentes étapes qui y sont évoquées seront développées par la suite.
FIG. 2.1 – Codeur MPEG4 typique
2.2 Frame, Macro-block et blocks
Une grande partie des algorithmes employés dans MPEG ne s’appliquent pas aux images complètes carles codeurs ne sauraient alors pas exploiter la cohérence spatiale du signal vidéo. En fait, ces algorithmessont appliqués à des sous parties d’images : les blocs, sous images de 8x8 pixels2 ainsi que les macro-blocs composés de 4 blocs adjacents. La figure suivante montre cette hiérarchie.
10
Espaces de couleur
FIG. 2.2 – Hiérarchie Image/Macro Block/Block
2.3 Espaces de couleur
Un codeur MPEG travaille avec des images dans l’espace de couleur YV12. Il s’agit d’un espace decouleurs composé de 3 plans : 1 plan de luminance en pleine résolution et 2 plans de chrominance dontla résolution est 2 fois inférieure. Cette particularité fait qu’un pixel est en moyenne représenté par 12bit.La figure suivante montre les représentations d’une même image dans l’espace Rouge Vert Bleu (RGB)dans l’espace YV12.
11
Types d’images
Espace RGB Espace YV12
FIG. 2.3 – Les espaces de couleurs RGB et YV12
2.4 Types d’images
Dans MPEG4, il existe 3 types d’images qui diffèrent par la façon dont elles sont encodées.
Intra Frames Ces images sont codées directement telles des images JPEG. On les nommeIntra carelles ne référencent aucune autre image qu’elle même. Ces images sont gourmandes en terme debits, car elles n’exploitent pas du tout la cohérence temporelle des images. Les IFrames peuventservir de référence au codage des autres types d’images.
Predicted Frames Ces images sont codées en effectuant une compensation de mouvement déduite àpartir de l’image de référence précédente. Leur codage est plus efficace car il tire parti des redon-dances temporelles à travers cette compensation de mouvement. Mais leur codage implique aussil’inclusion des informations de mouvements, leur taille dépend donc de plusieurs facteurs : com-plexité de l’image, et “quantité” de mouvement entre l’image codée et l’image de référence. LesPFrames peuvent elles même servir de référence.
Bidirectional Frame Ce dernier type d’image pousse l’idée de prédiction d’image encore plus loin. Latechnique employée ici consiste à coder l’image en référençant 2 images. L’image peut alors êtrecodée selon 3 modes : forward/backward, bidirectional ou direct mode. Ces 3 modes diffèrent dansleur façon de tirer parti des informations de mouvements des images de référence. Le premier tireuniquement parti de l’une des images de référence, le deuxième mode tire parti des 2 images deréférence en pondérant les informations provenant des 2 images, le troisième mode exploite luiaussi les deux images de référence mais cette fois ci en interpolant les informations en fonction dela distance temporelle de l’image codée par rapport à chacune des images de référence. Le dernier
12
La prédiction et la compensation de mouvement
mode ne nécessite plus l’inclusion d’informations de mouvement, c’est ce qui fait son efficacité.Les BFrames ne servent pas de référence. C’est pourquoi il est intéressant de sacrifier des bits surles BFrames afin de les distribuer sur des images de référence qui profitent à plusieurs images.
Notons que le choix du type d’image est du ressort du codeur, et que ce choix peut même être fait auniveau du bloc. Ainsi une PFrame peut contenir des blocs en mode Intra, et une BFrame peut contenirtout type de blocs. Le schéma suivant montre comment les images se référencent mutuellement.
FIG. 2.4 – Les trois types d’image dans MPEG4 et leur référence ment mutuel
2.5 La prédiction et la compensation de mouvement
Les premières étapes dans un codeur MPEG sont la prédiction et la compensation de mouvement :
– La prédiction de mouvement consiste à trouver un vecteur représentant le mouvement de l’image àcoder par rapport à l’image de référence. Tout cela se passe au niveau des macro-blocs ou bien desblocs eux mêmes.
– La compensation de mouvement consiste à soustraire à chaque macro-bloc de l’image à coder, le bloccorrespondant de l’image de référence en modifiant l’origine par le vecteur de déplacement.
Dans l’absolu, l’étape d’estimation de mouvement devrait trouver un champ de vecteur tel qu’après lacompensation de mouvement, l’information à coder soit minimale et la qualité optimale. C’est en fait
13
La prédiction et la compensation de mouvement
ici que tout se joue ; en fonction du choix des opérateurs mathématiques, des optimisations, un codeurMPEG se comportera mieux que son concurrent, ou pas...
Nous allons présenter le plus connu, il s’agit de la “somme des valeurs absolues des différences”, appeléSAD1 en anglais. Voici sa définition :
SAD( ~O,~v) =w∑
x=0
h∑y=0
∣∣f(Ox + x− vx, Oy + y − vy)− f ′(Ox + x,Oy + y)∣∣ (2.1)
où
w eth représentent la taille d’un bloc.~O est l’origine du bloc dans le système de coordonnées de l’image.~v est le vecteur candidat à tester.f(x, y) retourne la valeur du pixel à la position(x, y) de l’image originalef ′(x, y) retourne la valeur du pixel à la position(x, y) de l’image à coder
Alors la prédiction de mouvement (étape notée Motion Estimation dans la figure2.1) consiste à trouver~v tel que SAD( ~O,~v) soit minimale.
La figure suivante montre un champ de vecteur pouvant avoir été déduit par une étape de motion estima-tion.
FIG. 2.5 – Champ vectoriel généré suite à l’étape de motion estimation
1Sum of Absolute Difference
14
La Transformée en Cosinus Discrète
2.6 La Transformée en Cosinus Discrète
Jusqu’à maintenant tout s’est déroulé dans l’espace des couleurs YUV. Mais la représentation des échan-tillons de couleurs dans cet espace rend difficile la compression, car elle attribue à tous les pixels unemême importance. Or l’oeil répond différemment aux stimulis visuels en fonction de leur fréquencespatiale, de leur agencement mutuels...
Donc pour représenter les échantillons de façon efficace, on applique une transformation en cosinusdiscrète qui ressemble quelque peu à une transformée de Fourier. Cette opération mathématique estappliquée à chaque bloc. C’est d’ailleurs à cause de la DCT que les blocs ont été fixés à une taille de 8x8pixels2. Il s’agissait d’un compromis qualité/performance, car la DCT est une opération gourmande enressources2.
Voici la formule mathématique générale :
F (u, v) =2√NM
.c(u).c(v)N−1∑i=0
M−1∑j=0
f(x, y) cos[(2i + 1)uπ
2N
]. cos
[(2j + 1)vπ
2M
](2.2)
où c(i) vaut
{1 pouri 6= 01√2
pouri = 0etN = M = 8
Voici un exemple d’application de cette formule sur un bloc extrait d’une image :
171 161 160 161 164 171 178 181159 151 150 152 159 171 180 182133 128 128 136 151 168 179 183131 151 167 177 181 141 160 172177 180 127 132 142 155 166 173178 178 140 146 156 163 168 173180 179 152 157 165 169 171 173178 179 152 157 165 169 171 173
→
1298 −43 49 16 7 −13 −17 −5−14 −38 −15 −13 2 13 12 936 7 3 11 −5 8 10 −216 29 26 13 −3 −4 −3 −88 19 −9 −13 5 −3 −6 38 −1 −31 −18 8 2 1 9−12 −13 7 7 −2 1 2 −2−15 −9 30 20 −8 0 2 −9
On dit que la DCT “concentre l’énergie dans le coin supérieur gauche” du bloc. En effet, la DCT peutêtre assimilée à une transformation qui permet de passer du domaine spatial au domaine fréquentiel.Or le coin supérieur gauche contient les coefficients de plus faible fréquence (verticale et horizontale) .Comme les images naturelles sont plutôt constitués de gradients (fréquence basses) que de détails (hautesfréquences), on comprend alors pourquoi les coefficients les plus grand en valeur absolue se trouventdans le coin supérieur gauche. La figure suivante montre cela bien mieux que les chiffres de l’exempleprécédent.
2cela est de moins en moins vrai grâce aux avancées considérables de la puissance des CPU et DSP.
15
La quantification
FIG. 2.6 – Énergie des coefficients
2.7 La quantification
La quantification est l’étape qui permet de supprimer l’information jugée inutile par le paramètreq ducodeur.q s’appelle le nombre de quantification. Cette étape va favoriser l’apparition de nombreux zérosdans les blocs, et ceci est d’autant plus vrai queq est grand. On verra comment l’encodeur entropiqueassocié à un parcours en zigzag des blocs tirera parti de ces nombreux zéros. MPEG4 intègre deuxméthodes de quantification des coefficients :
Type H263 coeff(u, v) = sign(F (u, v)). |F (u,v)|− q2
2q(2.3)
Type MPEG2 coeff(u, v) = sign(F (u, v)).16|F (u,v)|//wuv
2q(2.4)
où
// désigne une division entière avec arrondi supérieur pourresultat > 0et arrondi inférieur pourresultat < 0
∀(i, j) 6= (0, 0) wij ∈
8 17 18 19 21 23 25 2717 18 19 21 23 25 27 2820 21 22 23 24 26 28 3021 22 23 24 26 28 30 3222 23 24 26 28 30 32 3523 24 26 28 30 32 35 3825 26 28 30 32 35 38 4127 28 30 32 35 38 41 45
pour une image Intra
∀(i, j) wij ∈
16 17 18 19 20 21 22 2317 18 19 20 21 22 23 2418 19 20 21 22 23 24 2519 20 21 22 23 24 26 2720 21 22 23 25 26 27 2821 22 23 24 26 27 28 3022 23 24 26 27 28 30 3123 24 25 27 28 30 31 33
pour une image Inter
16
Le codage entropique
Notons que le coefficient(0, 0) encore appelé coefficient DC, est traité indépendemment dans le casd’une image Intra :
coeff(0, 0) = dc_scaler.F (0, 0), sa valeur exacte dépend de “q” (2.5)
On remarque que l’étape de quantification risque de “dégrader” plus rapidement les coefficients de hautefréquence (leurs diviseurs sont plus grands). Pour comprendre la raison à cela, il faut prendre en comptele fait que l’oeil humain est moins sensibles aux détail (HF) qu’au global (BF). Ainsi la quantificationtire parti de cette caractéristique psycho-visuelle afin d’éliminer l’information la moins nécessaire à l’oeilpour la compréhension de l’image dans son ensemble.
Voici un exemple :
Bloc après DCT Bloc après quantification type H263 Inter
1298 −43 49 16 7 −13 −17 −5−14 −38 −15 −13 2 13 12 936 7 3 11 −5 8 10 −216 29 26 13 −3 −4 −3 −88 19 −9 −13 5 −3 −6 38 −1 −31 −18 8 2 1 9−12 −13 7 7 −2 1 2 −2−15 −9 30 20 −8 0 2 −9
Quant 4→
162 −5 5 1 0 −1 −1 0−1 −4 −1 −1 0 1 1 04 0 0 1 0 0 1 01 3 3 1 0 0 0 00 2 0 −1 0 0 0 00 0 −3 −2 0 0 0 0−1 −1 0 0 0 0 0 0−1 0 3 2 0 0 0 0
L’étape de quantification est donc responsable de la disparition d’une partie de l’information, c’est pour-quoi les compressions de type MPEG sont qualifiées de “Lossy”, traduit en Français par le terme “avecpertes”. La quantification permet aussi au codeur MPEG de respecter un certains débit, puisque c’est enjouant sur le paramètreq, qu’on est à même de supprimer plus ou moins d’information visuelle, et doncdes bits à coder.
2.8 Le codage entropique
Le parcours en ZigZag permet de parcourir les coefficients du bloc dans un ordre croissant des fréquenceshorizontales et verticales. La matrice qui suit donne la correspondance linéaire entre l’indice linéaire duparcours en zigzag et son équivalent dans le bloc original :
0 1 8 16 9 2 3 1017 24 32 25 18 11 4 512 19 26 33 40 48 41 3427 20 13 6 7 14 21 2835 42 49 56 57 50 43 3629 22 15 23 30 37 44 5158 59 52 45 38 31 39 4653 60 61 54 47 55 62 63
Le parcours en ZigZag du macro-bloc quantifié dans la partie précédente donnerait la séquence de coef-ficient suivante :
162 -5 -1 4 -4 5 1 -1 0 1 0 3 0 -1 0 -1 0 1 3 2 0 -1 0 0 1 0 1 -1 0 1 0 0 -1 -3 -1 -1 0 0 \ 1
-2 1 0 0 0 0 0 0 3 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2
17
Contrôle de la qualité du codage
Le parcours en zigzag va avoir une tendance naturelle à créer des séquences de zéro. Cela est d’autantplus vrai qu’on s’approche des hautes fréquences.
Puis le codeur crée à partir de cette séquence de coefficients une suite de triplés(run, last, level) oùrunindique le nombre de zéros précédant le coefficient actuel,last indique si ce coefficient est le derniercoefficient non nul de la séquence,level représente la valeur du coefficient actuel.
(0,0,162) (0,0,-5) (0,0,-1) (0,0,4) (0,0,-4) (0,0,5) (0,0,1) (0,0,-1) (1,0,1) (1, 0, 3) \ 1
(1,0,3) (0,0,-1) (1,0,-1) (1,0,1) (0,0,3) (0,0,2) (1,0,-1) (2,0,1) (1,0,1) (0,0,-1) \ 2
(1,0,1) (2,0,-1) (0,0,-3) (0,0,-1) (0,0,-1) (2,0,-2) (2,0,1) (6,0,3) (0,1,2) 3
En fonction de ces triplés et de tables décrites dans le standard, le codeur va créer un flux binaire quiminimise le nombre de bits employés pour cette série de triplés. En fait le coefficient DC est traitédifféremment puisqu’il est codé de façon différentielle par rapport à la valeur des coefficients DC desblocs voisins.
Les vecteurs déterminés durant l’étape de Motion Estimation sont quant à eux codés différentiellementpar rapport aux vecteurs de leurs blocs voisins afin de minimiser la place requise pour les coder. Cettetechnique repose sur le principe que le champs de vecteur présente une distribution linéaire.
2.9 Contrôle de la qualité du codage
Le codage MPEG entraîne forcement des pertes de qualité. Cela est principalement dû à l’étape dequantification où bon nombre de coefficients sont ramenés au niveau zéro. Mesurer cette perte permetde s’assurer de la qualité de la vidéo codée. Mais un problème majeur se pose : comment mesurer uneperte de qualité visuelle ? En effet, la simple mesure de la différence entre l’image originale et l’imagecodée n’est pas suffisante car l’oeil réagit différemment pour un même niveau de différence selon quecette différence soit très localisée ou étalée sur l’ensemble de l’image.
Il y a beaucoup de travaux dans ce domaine, mais il y a un opérateur qui même s’il n’est pas le meilleurindicateur, sert de référence pour tous les tests visant à comparer les codeurs MPEG. Il s’agit du piquede rapport signal-bruit (PSNR).
Voici sa définition :
MSE =width∑x=0
height∑y=0
|f(x, y)− f ′(x, y)|width.height
où
{f(x, y) retourne la valeur du pixel à la position(x, y) de l’image originalef ′(x, y) retourne la valeur du pixel à la position(x, y) de l’image codée
}
18
Contrôle de la qualité du codage
PSNR = 10. log10
(2552
MSE
)dB
19
Chapitre 3
XviD
20
Historique du projet
3.1 Historique du projet
XviD est un projet de Logiciel libre qui a pour but d’implémenter le standard MPEG4 Visual Part2.Rappelons brièvement son historique avant de développer son statut actuel dans un deuxième temps.
Replaçons nous dans le contexte de l’an 2000. A cette époque, DivX était déjà connu à travers un co-dec devenu incontournable : DivX 3.11 ;-). Mais ce codec était malheureusement un hack1 du codecMS-MPEG4 publié parMicrosoft et basé sur les premiers travaux du groupe ISO/IEC dont Microsoftétait alors un membre actif. DivX 3.11 ;-) et MS-MPEG4 étaient tous deux incompatibles avec ce quiétait entre temps devenu ISO/IEC MPEG4. On ne sait pas pourquoi, mais Microsoft n’a jamais intentéde procès pour plagia aux auteurs de DivX. Mais conscients de leur position délicate, les développeursde DivX 3.11 ;-) décidèrent de monter une start-up dans le but de financer la création d’un nouveau codecsur des bases légales saines.
Le choix de l’équipe DivX, alors devenuDivXNetwork, se porte sur l’adoption de la norme ISO MPEG4pour leur futur codec. Ce choix n’est pas anodin, il leur permet de tirer parti de leur expérience sur lecodec DivX 3.11 ;-) qui est quand même proche du standard ISO, et surtout ce choix leur permet departir de l’implantation de référence fournie librement et gratuitement par le comité ISO/IEC. Cependantl’équipe de développement est insuffisante pour mener à terme ce développement et DivXNetwork décidealors de mettre en place un projet Open Source nomméOpenDivXet qui à terme servira à lancerDivX4.
La communauté Open Source s’empresse de participer à ce projet qui permettrait alors d’avoir un codecvidéo efficace même sur les systèmes d’exploitation non Microsoft. Malheureusement la gestion du projetOpenDivX s’avère être des plus opaques. Alors que les contributions se font de plus en plus nombreuses,les changements ne sont (presque) jamais intégré à la version disponible au public. Après quelques moisd’un silence et d’un inactivité inquiétante, DivXNetwork annonce DivX4. C’est un véritable choc quisecoue toute la communauté qui avait participé au projet OpenDivX. Certes DivXNetwork n’avait paspromis que DivX4 soit open source, mais DivXNetwork avait délibérément pillé le travail de quelquesdéveloppeurs.
Fort de cette constatation, un jeune étudiant allemand, Michael Militzer, décide de regrouper toutes lescontributions apportées au projet OpenDivX et qui ne furent jamais intégrées. Une fois toutes les piècesréunies, il propose de lancer un nouveau projet qui aurait pour but de faire évoluer OpenDivX sous unelicence propre à DivXNetwork vers un autre codec toujours basé sur ISO MPEG4 mais sous une licenceGNU GPL, ce qui garantirait à jamais l’existence d’un codec MPEG4 Logiciel Libre. Michael est alorsrejoint par quelques développeurs dont Christoph Lampert2, Peter Ross et quelques autres contributeursréguliers3
Restait encore à baptiser le projet... Le nom XviD fut choisi. Il suffit de lire ce nom à l’envers pourdécouvrir pourquoi il a été choisi. Ce nom montre la volonté du projet XviD de faire le contraire de ce queDivX est devenu. XviD serait un projet Libre et transparent, XviD n’aurait pour seul but que le supportdu standard ISO MPEG4 là où DivX se permet des libertés qui le rendent clairement incompatible, et
1Piraterie2Un autre étudiant allemand, depuis lors devenu Docteur Es Mathématiques3dont je (Edouard Gomez) fais fièrement parti :-)
21
Architecture d’XviD 1.0
enfin XviD ne deviendrait pas un projet commercial.
XviD s’est ainsi peu à peu complètement débarrasse du code provenant d’OpenDivX pour devenir unprojet complètement indépendant et totalement libre sous licence GNU GPL. Son succès est principa-lement amoindri par la puissance commerciale de DivX. Mais XviD donne de très bon résultats lors decomparaisonsde codecs vidéo. XviD est apprécié pour sa qualité d’image souvent jugée supérieure à ceque DivX permet d’obtenir.
XviD a même connu une crise majeure lorsque ses auteurs ont découvert qu’un grand nom du matérielvidéo grand public,Sigma Designsavait tenté de voler le code d’XviD en Juin 2002. L’affaire a alorsfait grand bruit car c’était la première fois qu’une tentative de tromperie et de vol était aussi clairementdémontré... Finalement Sigma Designs fut contraint de céder et de publier leur codec vidéo sous lalicence GPL, puisqu’il dérivait d’XviD.
Depuis ce temps, le développement a sagement repris et XviD distribua des versions 0.9.x de leur codecalors devenu très stable. Aujourd’hui l’équipe de développement prépare la distribution de la version 1.0,qui mettra un terme à plus d’un an de développement depuis la dernière version stable officielle. Cettenouvelle version contient une toute nouvelle architecture, et de nombreuses nouvelles fonctionnalités quidevraient aider XviD à mieux coder dans les bas débits.
3.2 Architecture d’XviD 1.0
XviD 1.0 est encore en projet, mais il est d’ores et déjà possible d’obtenir toutes les informations concer-nant son “coeur” : la librairie xvidcore sur laquelle repose tous les softs se basant sur XviD.
Le schéma ci dessous décrit assez précisément l’organisation logique des internes d’XviD. Biensûr pourplus de détails, il suffit de télécharger le code source librement sur lesite via CVS4 en rapatriant labranche de développement “dev-api-4”.
4Concurrent Version System : outil très répandu dans les projets Open Source pour gérer le développement des logiciels parplusieurs développeurs en parallèle
22
Système de Plugin
FIG. 3.1 – Architecture d’XviD 1.0
3.3 Système de Plugin
XviD 1.0 sera la première version d’XviD dont le coeur fonctionnel reposera principalement sur un fra-mework de plugin simple permettant aux applications externes d’intervenir directement dans la chaînede codage de l’image. Le premier gain est un gain en terme de flexibilité. Le deuxième gain se fait direc-tement au niveau du coeur d’XviD, qui gagne en clarté en externalisant certaines de ses fonctionnalitéssous forme de plugin.
On prévoit principalement deux types de plugins :– Les plugins de bit rate control– Les plugins de traitement d’image post ou pre compression.
23
Système de Plugin
3.3.1 Les Plugins de BitRate Control
Un des sous systèmes les plus important d’un codeur MPEG, est le “bit rate controller”, c’est lui qui vadéterminer combien de bits on alloue pour une image donnée. Donc implicitement, il choisit le paramètre“quantizer” qui est à l’origine du principal gain en compression et le principal fautif dans la perte dequalité. Le choix d’une bonne série de quantizer est la clef pour obtenir des vidéos dont la qualité sembleconstante et donc sont plus agréables à regarder.
Trois approches cohabitent dans XviD :
Mode CBR ou codage à bitrate constant. Ce mode ne nécessite qu’une seule passe des données etconvient particulièrement bien aux captures en temps réel à condition de ne pas exiger un bitratetrop petit. Il assure un bitrate presque constant tout au long du codage de la séquence.
CQ Codage à “quantizer” constant. Ce mode ne nécessite lui aussi qu’une seule passe des donnéeset convient don lui aussi aux prises en temps réel. Mais ce mode ci, ne conserve pas un bitrateconstant. Il va avoir tendance à conserver une qualité visuelle quasi constante étant donné que le“quantizer” est directement responsable de la perte de qualité. Si le “quantizer” reste constant,alors la qualité a de fortes chances de l’être aussi. Cependant aucune garantie sur le bitrate ne peutêtre émise.
Two pass ou codage en deux passes. Ce mode nécessite deux passes bien distinctes sur les données. Lapremière passe sert à emmagasiner des statistiques et caractéristiques de la séquence à coder. Laseconde va exploiter ces données recueillies afin d’optimiser la distribution de bits afin de garantirune qualité quasi constante, tout en pouvant préciser un bitrate à respecter sur la totalité de laséquence. Le mode Two Pass, semble donc répondre au seul défaut du mode CQ.
3.3.2 Les Plugins de Traitement d’Image
Un codeur MPEG est en soi un bien piètre manipulateur d’image. Il a une tendance à supprimer lesfréquences élevées (les détails) dès que le quantizer dépasse la valeur de 4, or si on veut atteindre destaux de compression intéressants, ce paramètre quantizer est bien souvent au dessus de ce seuil observé.
Afin de pallier à ce défaut intrinsèque au codage MPEG, l’application de filtres d’image peut s’avérernécessaire dans 2 situations :
– Préparer l’image afin de rendre sa compression moins destructive. Il s’agit souvent d’un filtre qui vafaire disparaître des détails de façon sélective et moins agressive que les algorithmes mis en oeuvredans MPEG.
– Tenter de compenser les défauts du codeur MPEG lors de la décompression afin de rendre à l’imageune qualité plus appréciable. Ces filtres sont appelés filtres de “deblocking” et filtres de “deringing”.En effet, le codage MPEG fait souvent apparaître les blocs de compression (le “blocking”) et lorsquede fort contrastes existent dans l’image, il arrive qu’il fasse baver la couleur de haute luminosité sur lacouleur plus sombre (le “ringing”).
24
Mise en application d’XviD
3.4 Mise en application d’XviD
XviD fournit quelques applications de tests qui permettent déjà de mettre en pratique bon nombre desconcepts développés dans ce mémoire.
La première série de tests va permettre de voir comment le mode 2 passes d’XviD permet de mieuxrespecter dans l’ensemble la courbe naturelle de bitrate de la source vidéo. Les scripts de tests sontdisponibles en annexe, le programme utilisé pour obtenir les informations sur le codage estxvid_encrawdistribué dans XviD.
Les paramètres de test sont les valeurs par défaut du programmexvid_encrawet un bitrate réglé à384kbps (un bitrate adéquat pour faire apparaître les premiers défauts d’un codec MPEG4)
3.4.1 Comparaison en terme de taille
Courbe originale de bitrate Courbes en mode Single Pass et mode Two Passes.
FIG. 3.2 – Séquence Hall Monitor
25
Mise en application d’XviD
Courbe originale de bitrate Courbes en mode Single Pass et mode Two Passes.
FIG. 3.3 – Séquence Hall Monitor
On remarque particulièrement bien sur le deuxième test comment le mode Two pass permet une meilleurepoursuite de la courbe naturelle de bitrate mise à l’échelle. Cependant le contrôle du bitrate n’assure pasforcement une meilleure qualité.
3.4.2 Comparaison en terme de PSNR
La série de tests suivante, permet de comparer le PSNR tout au long de la séquence. Il ne faut pas oublierque le PSNR est certes un indicateur quantitatif, mais il est loin de traduire l’aspect qualitatif de laqualité d’image. En effet il vaut mieux conserver une qualité constante tout au long du film même si elleest médiocre, que d’imposer à l’oeil des sauts de qualité variant du très bon au très mauvais et qui enmoyenne résulterait sur un même PSNR que la qualité médiocre constante.
26
Mise en application d’XviD
Courbe originale de PSNR Courbes en mode Single Pass et mode Two Passes.
FIG. 3.4 – Séquence Hall Monitor
Courbe originale de PSNR Courbes en mode Single Pass et mode Two Passes.
FIG. 3.5 – Séquence Hall Monitor
Ces petites séquences ne sont pas adéquates pour montrer la force de l’approche en Deux passes, cepen-dant le codage d’un DVD complet est de bien meilleure qualité lorsqu’il est compressé en mode 2 passes.En effet, la connaissance de la courbe de bits originale permet d’anticiper et de ne pas braquer le RateController en cas de forte demande de bits pour une scène d’action. Le Bit Rate controller distribuera cemanque de bits sur les scènes suivantes et ainsi la qualité paraîtra constante là où le mode Single Passaurait fait apparaître des défauts de codages dans les scènes d’actions (explosions, combats, mouvementsde caméra désordonné, poursuite).
27
Mise en application d’XviD
3.4.3 Résultats moyens sur la série de test complète
Et voici en vrac quelques chiffres directement tiré de la série de test complète :
Séquence bitrate 1pass bitrate 2pass PSNR 1pass) PSNR 2Pass
Coastguard 430kbps 371kbps 30.76dB 30.15dBContainer 394kbps 379kbps 37.22dB 33.92dBForeman 413kbps 369kbps 34.70dB 33.87Garden 694kbps N/A 24.59dB N/AHall Monitor 394kbps 361kbps 38.22dB 37.64dBMobile 478kbps 593kbps 24.76dB 22.27dBParis 388kbps 383kbps 34.38dB 33.81dB
3.4.4 Comparaison visuelle
Comparons la qualité visuelle des images entre l’originale et la version codée à 384kbps.
Image originale Image codée.
FIG. 3.6 – Séquence Coastguard
28
Mise en application d’XviD
On remarque que les détails de l’herbe en arrière plan ont disparu, et il apparaît certains défauts decodage au niveau des vagues qui précèdent le bateaux. Ces deux types de pertes sont typiques du codageMPEG4. Ils correspondent à l’élimination des hautes fréquences par l’étape de quantification.
Image originale Image codée.
FIG. 3.7 – Séquence Hall Monitor
Cette image met en évidence le même type de pertes que dans l’image précédente. Les poils de la mo-quette ont disparu sur l’image codée et les jeu d’ombre et de lumière au plafond sont plus fou sur laversion codée. On note aussi un assombrissement des placards au fond de l’image. Cet effet est le ré-sultat de la mise à zéro des coefficients constituants le bloc et qui une fois reconstruits, n’apportent plusaucune information à l’image.
29
Chapitre 4
Conclusion
30
Conclusion
4.1 Conclusion
Nous avons abordé dans ce mémoire une bonne partie de ce qui constitue le MPEG4 Visual Part, évi-demment il n’est pas question d’être exhaustif tellement l’implantation d’un codec MPEG4 et complexe.
Néanmoins, les bases mathématiques et algorithmiques exposées dans ce document permettent de mieuxappréhender les technologies se cachant derrière l’acronyme MPEG4. Le fait d’appuyer notre travail surXviD permettra au lecteur d’aller directement puiser l’information au coeur du code s’il en a l’envie.Pour les moins courageux, ce document a, nous l’espérons, contribuer à démystifier le monde de lacompression MPEG.
31
Première partie
Annexes
32
Code des scripts tests
.1 Code des scripts tests
.1.1 Tests de taille d’image
1# / b in / sh2
3# #############################################################################4# DIRS5# #############################################################################6
7XVIDCORE_SRC=" / home / edy /C / x v i d c o r e / x v i d c o r e "8XVID_ENCRAW=" ${XVIDCORE_SRC} / examples / xv id_encraw "9
10RESULT_DIR=" / home / edy /C / x v i d c o r e / r e s u l t s "11
12VIDEO_DIR=" / mnt / v rac / xv id− t e s t / sequences "13VIDEO_FILES="$VIDEO_FILES c o a s t g u a r d−352x288 . yuv "14VIDEO_FILES="$VIDEO_FILES c o n t a i n e r−352x288 . yuv "15VIDEO_FILES="$VIDEO_FILES foreman−352x288 . yuv "16VIDEO_FILES="$VIDEO_FILES garden−352x240 . yuv "17VIDEO_FILES="$VIDEO_FILES h a l l _ m o n i t o r−352x288 . yuv "18VIDEO_FILES="$VIDEO_FILES mobi le−352x288 . yuv "19VIDEO_FILES="$VIDEO_FILES p a r i s−352x288 . yuv "20
21# #############################################################################22# Encoding paramete rs23# #############################################################################24MAX_BFRAMES=" 0 "25BITRATE=" 384000 "26
27f o r VIDEO i n ${VIDEO_FILES } ; do28
29SEQUENCE= ‘echo ${VIDEO } | c u t −d ’− ’ − f 1 ‘30WIDTH= ‘ echo ${VIDEO } | c u t −d ’− ’ − f 2 | c u t −d ’ . ’ − f 1 | c u t −d ’ x ’ − f 1 ‘31HEIGHT= ‘ echo ${VIDEO } | c u t −d ’− ’ − f 2 | c u t −d ’ . ’ − f 1 | c u t −d ’ x ’ − f 2 ‘32
33echo "+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+"34echo " | T e s t i n g ${VIDEO } ( ${WIDTH}x${HEIGHT} ) "35echo "+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+"36echo37
38f o r pass i n 1 2 ; do39
40echo−n " Pass ${ pass } . . . "41
42${XVID_ENCRAW} \43−asm \44− i " ${VIDEO_DIR } / ${VIDEO} " \45−w ${WIDTH } \46−h ${HEIGHT } \47−b i t r a t e ${BITRATE } \48−pass$ { pass } f i r s t p a s s . s t a t s \49−max_bframes ${MAX_BFRAMES} \50−s t a t s \51| awk ’BEGIN{FS = " | " } / t ype = / { p r i n t $2} ’ \52| sed \53−e s / psn r / / g−e s / t ype / / g−e s / quan t / / g−e s / l e n / / g \54−e s / = / / g−e s / , / / g−e s / u / / g−e s / v / / g−e s / y / / g \55> " ${RESULT_DIR } / ${SEQUENCE}−pass$ { pass } . s t a t s "56done57
33
Code des scripts tests
58echo−n " Pass CBR"59
60${XVID_ENCRAW} \61−asm \62− i " ${VIDEO_DIR } / ${VIDEO} " \63−w ${WIDTH } \64−h ${HEIGHT } \65−b i t r a t e ${BITRATE } \66−s i n g l e \67−max_bframes ${MAX_BFRAMES} \68−s t a t s \69| awk ’BEGIN{FS = " | " } / t ype = / { p r i n t $2 } ’ \70| sed71−e s / psn r / / g−e s / t ype / / g−e s / quan t / / g−e s / l e n / / g \72−e s / = / / g−e s / , / / g−e s / u / / g−e s / v / / g−e s / y / / g \73> " ${RESULT_DIR } / ${SEQUENCE}−s i n g l e p a s s . s t a t s "74
75echo76echo " Graphing coded frame s i z e s . . . "77GNUPLOT_SCRIPT=" g n u p l o t . cmd"78PNG_FILE=" ${SEQUENCE}−coded−f r a m e s i z e . png "79TMP_DAT1=" ${RESULT_DIR } / ${SEQUENCE}−pass2 . s t a t s "80TMP_DAT2=" ${RESULT_DIR } / ${SEQUENCE}−s i n g l e p a s s . s t a t s "81
82
83# Genera tes t h e g n u p l o t s c r i p t t o be e x e c u t e d84ca t > $GNUPLOT_SCRIPT < < EOF85s e t te rm png sm a l l c o l o r86s e t o u t p u t "$PNG_FILE"87s e t x l a b e l " Frame "88s e t y l a b e l " S i ze ( b y t e s ) "89s e t t i t l e " S i ze = f ( f rame ) [ ${SEQUENCE} sequence ] "90s e t g r i d91p l o t "$TMP_DAT2" u s i n g 3 t i t l e ’ S i n g l e Pass cod ing ’ w i th l i n e s ,92"$TMP_DAT1" u s i ng 3 t i t l e ’Two Pass cod ing ’ w i th l i n e s93EOF94
95# Run GNU P l o t96g n u p l o t $GNUPLOT_SCRIPT97
98# remove a l l temp f i l e s99rm − f $GNUPLOT_SCRIPT100
101echo " Graphing o r i g i n a l f rame s i z e s . . . "102
103PNG_FILE=" ${SEQUENCE}−o r i g i n a l−f r a m e s i z e . png "104TMP_DAT1=" ${RESULT_DIR } / ${SEQUENCE}−pass1 . s t a t s "105
106
107# Genera tes t h e g n u p l o t s c r i p t t o be e x e c u t e d108ca t > $GNUPLOT_SCRIPT < < EOF109s e t te rm png sm a l l c o l o r110s e t o u t p u t "$PNG_FILE"111s e t x l a b e l " Frame "112s e t y l a b e l " S i ze ( b y t e s ) "113s e t t i t l e " S i ze = f ( f rame ) [ ${SEQUENCE} sequence ] Co ns ta n t Q u a n t i z e r 2 "114s e t g r i d115p l o t "$TMP_DAT1" u s i n g 3 t i t l e ’ " N a t u r a l " f r a m e s i z e s ’ w i th l i n e s116EOF117
118# Run GNU P l o t119g n u p l o t $GNUPLOT_SCRIPT120
34
Code des scripts tests
121# remove a l l temp f i l e s122rm − f $GNUPLOT_SCRIPT123
124echo " Computing s t a t i s t i c s f o r Two pass . . . "125awk ’126BEGIN{127nf rames =0;128a v g s i z e =0;129}130
131{132nf rames ++;133a v g s i z e +=$3 ;134}135
136END{137p r i n t f ( " Average frame s i z e : % . 2 f \ n B i t r a t e : % f \ n " ,138a v g s i z e / nf rames , ( a v g s i z e∗25∗8) / (1000∗ nf rames ) ) ;139} ’ " ${RESULT_DIR } / ${SEQUENCE}−pass2 . s t a t s "140
141echo " Computing s t a t i s t i c s f o r S i n g l e pass . . . "142awk ’143BEGIN{144nf rames =0;145a v g s i z e =0;146}147
148{149nf rames ++;150a v g s i z e +=$3 ;151}152
153END{154p r i n t f ( " Average frame s i z e : % . 2 f \ n B i t r a t e : % f \ n " ,155a v g s i z e / nf rames , ( a v g s i z e∗25∗8) / (1000∗ nf rames ) ) ;156} ’ " ${RESULT_DIR } / ${SEQUENCE}−s i n g l e p a s s . s t a t s "157
158echo159echo160echo161
162done
.1.2 Tests de PSNR
1# / b in / sh2
3# #############################################################################4# DIRS5# #############################################################################6
7XVIDCORE_SRC=" / home / edy /C / x v i d c o r e / x v i d c o r e "8XVID_ENCRAW=" ${XVIDCORE_SRC} / examples / xv id_encraw "9
10RESULT_DIR=" / home / edy /C / x v i d c o r e / r e s u l t s "11
12VIDEO_DIR=" / mnt / v rac / xv id− t e s t / sequences "13VIDEO_FILES="$VIDEO_FILES c o a s t g u a r d−352x288 . yuv "14VIDEO_FILES="$VIDEO_FILES c o n t a i n e r−352x288 . yuv "15VIDEO_FILES="$VIDEO_FILES foreman−352x288 . yuv "
35
Code des scripts tests
16VIDEO_FILES="$VIDEO_FILES garden−352x240 . yuv "17VIDEO_FILES="$VIDEO_FILES h a l l _ m o n i t o r−352x288 . yuv "18VIDEO_FILES="$VIDEO_FILES mobi le−352x288 . yuv "19VIDEO_FILES="$VIDEO_FILES p a r i s−352x288 . yuv "20
21# #############################################################################22# Encoding paramete rs23# #############################################################################24MAX_BFRAMES=" 0 "25BITRATE=" 384000 "26
27f o r VIDEO i n ${VIDEO_FILES } ; do28
29SEQUENCE= ‘echo ${VIDEO } | c u t −d ’− ’ − f 1 ‘30WIDTH= ‘ echo ${VIDEO } | c u t −d ’− ’ − f 2 | c u t −d ’ . ’ − f 1 | c u t −d ’ x ’ − f 1 ‘31HEIGHT= ‘ echo ${VIDEO } | c u t −d ’− ’ − f 2 | c u t −d ’ . ’ − f 1 | c u t −d ’ x ’ − f 2 ‘32
33echo "+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+"34echo " | T e s t i n g ${VIDEO } ( ${WIDTH}x${HEIGHT} ) "35echo "+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+"36echo37
38f o r pass i n 1 2 ; do39
40echo−n " Pass ${ pass } . . . "41
42${XVID_ENCRAW} \43−asm \44− i " ${VIDEO_DIR } / ${VIDEO} " \45−w ${WIDTH } \46−h ${HEIGHT } \47−b i t r a t e ${BITRATE } \48−pass$ { pass } f i r s t p a s s . s t a t s \49−max_bframes ${MAX_BFRAMES} \50−s t a t s \51| awk ’BEGIN{FS = " | " } / t ype = / { p r i n t $2} ’ \52| sed \53−e s / psn r / / g−e s / t ype / / g−e s / quan t / / g−e s / l e n / / g \54−e s / = / / g−e s / , / / g−e s / u / / g−e s / v / / g−e s / y / / g \55> " ${RESULT_DIR } / ${SEQUENCE}−pass$ { pass } . s t a t s "56done57
58echo−n " Pass CBR"59
60${XVID_ENCRAW} \61−asm \62− i " ${VIDEO_DIR } / ${VIDEO} " \63−w ${WIDTH } \64−h ${HEIGHT } \65−b i t r a t e ${BITRATE } \66−s i n g l e \67−max_bframes ${MAX_BFRAMES} \68−s t a t s \69| awk ’BEGIN{FS = " | " } / t ype = / { p r i n t $2 } ’ \70| sed71−e s / psn r / / g−e s / t ype / / g−e s / quan t / / g−e s / l e n / / g \72−e s / = / / g−e s / , / / g−e s / u / / g−e s / v / / g−e s / y / / g \73> " ${RESULT_DIR } / ${SEQUENCE}−s i n g l e p a s s . s t a t s "74
75echo76echo " Graphing coded frame s i z e s . . . "77GNUPLOT_SCRIPT=" g n u p l o t . cmd"78PNG_FILE=" ${SEQUENCE}−coded−f r a m e s i z e . png "
36
Code des scripts tests
79TMP_DAT1=" ${RESULT_DIR } / ${SEQUENCE}−pass2 . s t a t s "80TMP_DAT2=" ${RESULT_DIR } / ${SEQUENCE}−s i n g l e p a s s . s t a t s "81
82
83# Genera tes t h e g n u p l o t s c r i p t t o be e x e c u t e d84ca t > $GNUPLOT_SCRIPT < < EOF85s e t te rm png sm a l l c o l o r86s e t o u t p u t "$PNG_FILE"87s e t x l a b e l " Frame "88s e t y l a b e l " S i ze ( b y t e s ) "89s e t t i t l e " S i ze = f ( f rame ) [ ${SEQUENCE} sequence ] "90s e t g r i d91p l o t "$TMP_DAT2" u s i n g 3 t i t l e ’ S i n g l e Pass cod ing ’ w i th l i n e s ,92"$TMP_DAT1" u s i ng 3 t i t l e ’Two Pass cod ing ’ w i th l i n e s93EOF94
95# Run GNU P l o t96g n u p l o t $GNUPLOT_SCRIPT97
98# remove a l l temp f i l e s99rm − f $GNUPLOT_SCRIPT100
101echo " Graphing o r i g i n a l f rame s i z e s . . . "102
103PNG_FILE=" ${SEQUENCE}−o r i g i n a l−f r a m e s i z e . png "104TMP_DAT1=" ${RESULT_DIR } / ${SEQUENCE}−pass1 . s t a t s "105
106
107# Genera tes t h e g n u p l o t s c r i p t t o be e x e c u t e d108ca t > $GNUPLOT_SCRIPT < < EOF109s e t te rm png sm a l l c o l o r110s e t o u t p u t "$PNG_FILE"111s e t x l a b e l " Frame "112s e t y l a b e l " S i ze ( b y t e s ) "113s e t t i t l e " S i ze = f ( f rame ) [ ${SEQUENCE} sequence ] Co ns ta n t Q u a n t i z e r 2 "114s e t g r i d115p l o t "$TMP_DAT1" u s i n g 3 t i t l e ’ " N a t u r a l " f r a m e s i z e s ’ w i th l i n e s116EOF117
118# Run GNU P l o t119g n u p l o t $GNUPLOT_SCRIPT120
121# remove a l l temp f i l e s122rm − f $GNUPLOT_SCRIPT123
124echo " Computing s t a t i s t i c s f o r Two pass . . . "125awk ’126BEGIN{127nf rames =0;128a v g s i z e =0;129}130
131{132nf rames ++;133a v g s i z e +=$3 ;134}135
136END{137p r i n t f ( " Average frame s i z e : % . 2 f \ n B i t r a t e : % f \ n " ,138a v g s i z e / nf rames , ( a v g s i z e∗25∗8) / (1000∗ nf rames ) ) ;139} ’ " ${RESULT_DIR } / ${SEQUENCE}−pass2 . s t a t s "140
141echo " Computing s t a t i s t i c s f o r S i n g l e pass . . . "
37
Code d’xvid_encraw
142awk ’143BEGIN{144nf rames =0;145a v g s i z e =0;146}147
148{149nf rames ++;150a v g s i z e +=$3 ;151}152
153END{154p r i n t f ( " Average frame s i z e : % . 2 f \ n B i t r a t e : % f \ n " ,155a v g s i z e / nf rames , ( a v g s i z e∗25∗8) / (1000∗ nf rames ) ) ;156} ’ " ${RESULT_DIR } / ${SEQUENCE}−s i n g l e p a s s . s t a t s "157
158echo159echo160echo161
162done
.2 Code d’xvid_encraw
1/∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗2∗3∗ XVID MPEG−4 VIDEO CODEC4∗ − Console based t e s t a p p l i c a t i o n−5∗6∗ Copy r i gh t (C) 2002−2003 C h r i s t o p h Lampert < gruel@web . de>7∗ 2002−2003 Edouard Gomez < ed . gomez@free . f r >8∗ 2003 P e t e r Ross < pross@xvid . org>9∗10∗ Th is program i s f r e e s o f t w a r e ; you can r e d i s t r i b u t e i t and / or mod i fy11∗ i t under t h e te rms o f t h e GNU Genera l P u b l i c L i c e n s e as p u b l i s h e d by12∗ t h e Free So f twa r e Foundat ion ; e i t h e r v e r s i o n 2 o f t h e L icense , or13∗ ( a t your o p t i o n ) any l a t e r v e r s i o n .14∗15∗ Th is program i s d i s t r i b u t e d i n t h e hope t h a t i t w i l l be u s e f u l ,16∗ bu t WITHOUT ANY WARRANTY ; w i t h o u t even t h e i m p l i e d war ran ty o f17∗ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See t h e18∗ GNU Genera l P u b l i c L i c e n s e f o r more d e t a i l s .19∗20∗ You shou ld have r e c e i v e d a copy o f t h e GNU Genera l P u b l i c L i c e n s e21∗ a long w i th t h i s program ; i f not , w r i t e t o t h e Free So f t wa re22∗ Foundat ion , Inc . , 5 9 Temple Place , S u i t e 3 3 0 , Boston , MA 02111−1307 USA23∗24∗ $Id : xv id_encraw . c , v 1 . 1 1 . 2 . 2 8 2 0 0 3 / 0 6 / 2 5 2 3 : 2 3 : 2 1 edgomez Exp $25∗26∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗ /27
28/∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗29∗ A p p l i c a t i o n n o t e s :30∗31∗ A sequence o f raw YUV I420 p i c s or YUV I420 PGM f i l e fo rma t i s encoded32∗ The speed i s measured and f rames ’ PSNR are t a k e n from core .33∗34∗ The program i s p l a i n C and needs no l i b r a r i e s e x c e p t f o r l i b x v i d c o r e ,35∗ and maths− l i b .
38
Code d’xvid_encraw
36∗37∗ Use . / xv id_encraw− he lp f o r a l i s t o f o p t i o n s38∗39∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗ /40
41# inc lude < s t d i o . h>42# inc lude < s t d l i b . h>43# inc lude < s t r i n g . h>44# inc lude < math . h>45# i f n d e f WIN3246# inc lude < sys / t ime . h>47# e l s e48# inc lude < t ime . h>49# e n d i f50
51# inc lude " xv id . h "52
53# undef READ_PNM54
55/∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗56∗ Q u a l i t y p r e s e t s57∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗ /58s t a t i c xv id_mo t i on_ t cons t m o t i o n _ p r e s e t s [ ] = {59/∗ q u a l i t y 0 ∗ /600 ,61
62/∗ q u a l i t y 1 ∗ /63XVID_ME_ADVANCEDDIAMOND16,64
65/∗ q u a l i t y 2 ∗ /66XVID_ME_ADVANCEDDIAMOND16 | XVID_ME_HALFPELREFINE16 ,67
68/∗ q u a l i t y 3 ∗ /69XVID_ME_ADVANCEDDIAMOND16 | XVID_ME_HALFPELREFINE16 |70XVID_ME_ADVANCEDDIAMOND8 | XVID_ME_HALFPELREFINE8 ,71
72/∗ q u a l i t y 4 ∗ /73XVID_ME_ADVANCEDDIAMOND16 | XVID_ME_HALFPELREFINE16 |74XVID_ME_ADVANCEDDIAMOND8 | XVID_ME_HALFPELREFINE8 |75XVID_ME_CHROMA16 | XVID_ME_CHROMA8,76
77/∗ q u a l i t y 5 ∗ /78XVID_ME_ADVANCEDDIAMOND16 | XVID_ME_HALFPELREFINE16 |79XVID_ME_ADVANCEDDIAMOND8 | XVID_ME_HALFPELREFINE8 |80XVID_ME_CHROMA16 | XVID_ME_CHROMA8,81
82/∗ q u a l i t y 6 ∗ /83XVID_ME_ADVANCEDDIAMOND16 | XVID_ME_HALFPELREFINE16 | XVID_ME_EXTSEARCH16 |84XVID_ME_ADVANCEDDIAMOND8 | XVID_ME_HALFPELREFINE8 | XVID_ME_EXTSEARCH8 |85XVID_ME_CHROMA16 | XVID_ME_CHROMA8 ,86
87} ;88# d e f i n e ME_ELEMENTS ( s i z e o f( m o t i o n _ p r e s e t s ) /s i z e o f( m o t i o n _ p r e s e t s [ 0 ] ) )89
90s t a t i c xv id_vop_ t cons t v o p _ p r e s e t s [ ] = {91/∗ q u a l i t y 0 ∗ /920 ,93
94/∗ q u a l i t y 1 ∗ /950 ,96
97/∗ q u a l i t y 2 ∗ /98XVID_VOP_HALFPEL ,
39
Code d’xvid_encraw
99
100/∗ q u a l i t y 3 ∗ /101XVID_VOP_HALFPEL | XVID_VOP_INTER4V ,102
103/∗ q u a l i t y 4 ∗ /104XVID_VOP_HALFPEL | XVID_VOP_INTER4V ,105
106/∗ q u a l i t y 5 ∗ /107XVID_VOP_HALFPEL | XVID_VOP_INTER4V |108XVID_VOP_TRELLISQUANT ,109
110/∗ q u a l i t y 6 ∗ /111XVID_VOP_HALFPEL | XVID_VOP_INTER4V |112XVID_VOP_TRELLISQUANT | XVID_VOP_HQACPRED,113
114} ;115# d e f i n e VOP_ELEMENTS (s i z e o f( v o p _ p r e s e t s ) /s i z e o f( v o p _ p r e s e t s [ 0 ] ) )116
117/∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗118∗ Command l i n e g l o b a l v a r i a b l e s119∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗ /120
121# d e f i n e MAX_ZONES 64122
123s t a t i c xv id_enc_zone_ t ZONES[MAX_ZONES] ;124s t a t i c i n t NUM_ZONES = 0 ;125
126/∗ Maximum number o f f rames t o encode∗ /127# d e f i n e ABS_MAXFRAMENR 9999128
129s t a t i c i n t ARG_STATS = 0 ;130s t a t i c i n t ARG_DUMP = 0 ;131s t a t i c i n t ARG_LUMIMASKING = 0 ;132s t a t i c i n t ARG_BITRATE = 0 ;133s t a t i c i n t ARG_SINGLE = 0 ;134s t a t i c char ∗ARG_PASS1 = 0 ;135s t a t i c char ∗ARG_PASS2 = 0 ;136s t a t i c i n t ARG_QUALITY = ME_ELEMENTS − 1 ;137s t a t i c f l o a t ARG_FRAMERATE = 2 5 . 0 0 f ;138s t a t i c i n t ARG_MAXFRAMENR = ABS_MAXFRAMENR;139s t a t i c i n t ARG_MAXKEYINTERVAL = 0 ;140s t a t i c char ∗ARG_INPUTFILE = NULL;141s t a t i c i n t ARG_INPUTTYPE = 0 ;142s t a t i c i n t ARG_SAVEMPEGSTREAM = 0 ;143s t a t i c char ∗ARG_OUTPUTFILE = NULL;144s t a t i c i n t XDIM = 0 ;145s t a t i c i n t YDIM = 0 ;146s t a t i c i n t ARG_BQRATIO = 1 5 0 ;147s t a t i c i n t ARG_BQOFFSET = 1 0 0 ;148s t a t i c i n t ARG_MAXBFRAMES = 0 ;149s t a t i c i n t ARG_PACKED = 0 ;150s t a t i c i n t ARG_DEBUG = 0 ;151s t a t i c i n t ARG_VOPDEBUG = 0 ;152
153# i f n d e f READ_PNM154# d e f i n e IMAGE_SIZE ( x , y ) ( ( x )∗ ( y ) ∗3 / 2 )155# e l s e156# d e f i n e IMAGE_SIZE ( x , y ) ( ( x )∗ ( y )∗3 )157# e n d i f158
159# d e f i n e MAX(A, B ) ( ( ( A) >(B ) ) ? ( A ) : ( B ) )160# d e f i n e SMALL_EPS ( 1 e−10)161
40
Code d’xvid_encraw
162# d e f i n e SWAP( a ) ( ( ( ( a )&0 x000000f f ) < < 2 4 ) | ( ( ( a )&0 x0000f f00 ) < < 8 ) | \163( ( ( a )&0 x00 f f0000 ) > >8) | ( ( ( a )&0 x f f000000 ) > >24) )164
165/∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗166∗ Nasty g l o b a l va rs ;− )167∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗ /168
169s t a t i c i n t i ;170
171/∗ t h e pa th where t o save o u t p u t∗ /172s t a t i c char f i l e p a t h [ 2 5 6 ] = " . / " ;173
174/∗ I n t e r n a l s t r u c t u r e s ( hand les ) f o r encod ing and decod ing∗ /175s t a t i c vo id ∗ enc_hand le = NULL;176
177/∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗178∗ Loca l p r o t o t y p e s179∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗ /180
181/∗ P r i n t s program usage message∗ /182s t a t i c vo id usage ( ) ;183
184/∗ S t a t i s t i c a l f u n c t i o n s ∗ /185s t a t i c double msecond ( ) ;186
187/∗ PGM r e l a t e d f u n c t i o n s ∗ /188# i f n d e f READ_PNM189s t a t i c i n t read_pgmheader ( FILE∗ hand le ) ;190s t a t i c i n t read_pgmdata ( FILE∗ hand le ,191unsigned char ∗ image ) ;192# e l s e193s t a t i c i n t read_pnmheader ( FILE∗ hand le ) ;194s t a t i c i n t read_pnmdata ( FILE∗ hand le ,195unsigned char ∗ image ) ;196# e n d i f197s t a t i c i n t r e a d _ y u v d a t a ( FILE∗ hand le ,198unsigned char ∗ image ) ;199
200/∗ Encoder r e l a t e d f u n c t i o n s∗ /201s t a t i c i n t e n c _ i n i t ( i n t u s e _ a s s e m b l e r ) ;202s t a t i c i n t en c_s top ( ) ;203s t a t i c i n t enc_main (unsigned char ∗ image ,204unsigned char ∗ b i t s t r e a m ,205i n t ∗ key ,206i n t ∗ s t a t s _ t y p e ,207i n t ∗ s t a t s _ q u a n t ,208i n t ∗ s t a t s _ l e n g t h ,209i n t s t a t s [ 3 ] ) ;210
211/∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗212∗ Main f u n c t i o n213∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗ /214
215i n t216main ( i n t argc ,217char ∗ argv [ ] )218{219
220unsigned char ∗ mp4_buf fer = NULL;221unsigned char ∗ i n _ b u f f e r = NULL;222unsigned char ∗ o u t _ b u f f e r = NULL;223
224double enc t ime ;
41
Code d’xvid_encraw
225double t o t a l e n c t i m e = 0 . ;226f l o a t to ta lPSNR [ 3 ] = { 0 . , 0 . , 0 . } ;227
228i n t t o t a l s i z e ;229i n t r e s u l t ;230i n t m4v_size ;231i n t key ;232i n t s t a t s _ t y p e ;233i n t s t a t s _ q u a n t ;234i n t s t a t s _ l e n g t h ;235i n t u s e _ a s s e m b l e r = 0 ;236
237i n t input_num ;238i n t output_num ;239
240char f i l e n a m e [ 2 5 6 ] ;241
242FILE ∗ i n _ f i l e = s t d i n ;243FILE ∗ o u t _ f i l e = NULL;244
245p r i n t f ( " xv id_encraw − raw mpeg4 b i t s t r e a m encoder " ) ;246p r i n t f ( " w r i t t e n by C h r i s t o p h Lampert 2002−2003\ n \ n " ) ;247
248/∗ I s t h e r e a dumb XviD coder ?∗ /249i f (ME_ELEMENTS ! = VOP_ELEMENTS ) {250f p r i n t f ( s t d e r r , " P r e s e t s ’ a r r a y s shou ld have t h e same number o f e l e men ts−− " ) ;251f p r i n t f ( s t d e r r , " P l e a s e f i l l a bug t o xvid−devel@xvid . org \ n " ) ;252re turn (−1);253}254
255/∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗256∗ Command l i n e p a r s i n g257∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗ /258
259f o r ( i = 1 ; i < a rgc ; i ++ ) {260
261i f ( s t rcmp ( "−asm " , a rgv [ i ] ) = = 0 ) {262u s e _ a s s e m b l e r = 1 ;263} e l s e i f ( s t rcmp ( "−w" , a rgv [ i ] ) = = 0 & & i < a rgc − 1 ) {264i ++;265XDIM = a t o i ( a rgv [ i ] ) ;266} e l s e i f ( s t rcmp ( "−h " , a rgv [ i ] ) = = 0 & & i < a rgc − 1 ) {267i ++;268YDIM = a t o i ( a rgv [ i ] ) ;269} e l s e i f ( s t rcmp ( "−b i t r a t e " , a rgv [ i ] ) = = 0 & & i < a rgc − 1 ) {270i ++;271ARG_BITRATE = a t o i ( a rgv [ i ] ) ;272} e l s e i f ( s t rcmp ( "−s i n g l e " , a rgv [ i ] ) = = 0 ) {273ARG_SINGLE = 1 ;274} e l s e i f ( s t rcmp ( "−pass1 " , a rgv [ i ] ) = = 0 & & i < a rgc − 1 ) {275i ++;276ARG_PASS1 = argv [ i ] ;277} e l s e i f ( s t rcmp ( "−pass2 " , a rgv [ i ] ) = = 0 & & i < a rgc − 1 ) {278i ++;279ARG_PASS2 = argv [ i ] ;280} e l s e i f ( s t rcmp ( "−max_bframes " , a rgv [ i ] ) = = 0 & & i < a rgc− 1 ) {281i ++;282ARG_MAXBFRAMES = a t o i ( a rgv [ i ] ) ;283} e l s e i f ( s t rcmp ( "−packed " , a rgv [ i ] ) = = 0 ) {284ARG_PACKED = 1 ;285} e l s e i f ( s t rcmp ( "−b q u a n t _ r a t i o " , a rgv [ i ] ) = = 0 & & i < a rgc − 1 ) {286i ++;287ARG_BQRATIO = a t o i ( a rgv [ i ] ) ;
42
Code d’xvid_encraw
288} e l s e i f ( s t rcmp ( "−b q u a n t _ o f f s e t " , a rgv [ i ] ) = = 0 & & i < a rgc − 1 ) {289i ++;290ARG_BQOFFSET = a t o i ( a rgv [ i ] ) ;291
292} e l s e i f ( ( s t rcmp ( "−zq " , a rgv [ i ] ) = = 0 | | s t r cmp ( "−zw" , a rgv [ i ] )==0) && i < a rgc − 2 ) {293
294i f ( NUM_ZONES >= MAX_ZONES) {295f p r i n t f ( s t d e r r , " warn ing : too many zones ; zone i g n o r e d \ n " ) ;296con t inue ;297}298ZONES[NUM_ZONES ] . mode =299s t rcmp ( "−zq " , a rgv [ i ] ) = = 0 ? XVID_ZONE_QUANT : XVID_ZONE_WEIGHT;300i ++;301ZONES[NUM_ZONES ] . f rame = a t o i ( a rgv [ i ] ) ;302i ++;303ZONES[NUM_ZONES ] . i n c r e m e n t = (i n t ) ( a t o f ( a rgv [ i ] ) ∗ 1 0 0 ) ;304ZONES[NUM_ZONES ] . base = 1 0 0 ;305NUM_ZONES++;306
307} e l s e i f ( s t rcmp ( "−q u a l i t y " , a rgv [ i ] ) = = 0 & & i < a rgc − 1 ) {308i ++;309ARG_QUALITY = a t o i ( a rgv [ i ] ) ;310} e l s e i f ( s t rcmp ( "−f r a m e r a t e " , a rgv [ i ] ) = = 0 & & i < a rgc − 1 ) {311i ++;312ARG_FRAMERATE = ( f l o a t ) a t o f ( a rgv [ i ] ) ;313} e l s e i f ( s t rcmp ( "−m a x _ k e y _ i n t e r v a l " , a rgv [ i ] ) = = 0 & & i < a rgc − 1 ) {314i ++;315ARG_MAXKEYINTERVAL = a t o i ( a rgv [ i ] ) ;316} e l s e i f ( s t rcmp ( "− i " , a rgv [ i ] ) = = 0 & & i < a rgc − 1 ) {317i ++;318ARG_INPUTFILE = argv [ i ] ;319} e l s e i f ( s t rcmp ( "−s t a t s " , a rgv [ i ] ) = = 0 ) {320ARG_STATS = 1 ;321} e l s e i f ( s t rcmp ( "−dump" , a rgv [ i ] ) = = 0 ) {322ARG_DUMP = 1 ;323} e l s e i f ( s t rcmp ( "−lumimask ing " , a rgv [ i ] ) = = 0 ) {324ARG_LUMIMASKING = 1 ;325} e l s e i f ( s t rcmp ( "−t ype " , a rgv [ i ] ) = = 0 & & i < a rgc − 1 ) {326i ++;327ARG_INPUTTYPE = a t o i ( a rgv [ i ] ) ;328} e l s e i f ( s t rcmp ( "−nf rames " , a rgv [ i ] ) = = 0 & & i < a rgc − 1 ) {329i ++;330ARG_MAXFRAMENR = a t o i ( a rgv [ i ] ) ;331} e l s e i f ( s t rcmp ( "−save " , a rgv [ i ] ) = = 0 ) {332ARG_SAVEMPEGSTREAM = 1 ;333} e l s e i f ( s t rcmp ( "−debug " , a rgv [ i ] ) = = 0 ) {334i ++;335i f ( s s c a n f ( a rgv [ i ] , " 0x%x " , &ARG_DEBUG ) | | s s c a n f ( a rgv [ i ] , "%d " , &ARG_DEBUG ) ) ;336} e l s e i f ( s t rcmp ( "−o " , a rgv [ i ] ) = = 0 & & i < a rgc − 1 ) {337i ++;338ARG_OUTPUTFILE = argv [ i ] ;339} e l s e i f ( s t rcmp ( "−vop_debug " , a rgv [ i ] ) = = 0 ) {340ARG_VOPDEBUG = 1 ;341} e l s e i f ( s t rcmp ( "−he lp " , a rgv [ i ] ) ) {342usage ( ) ;343re turn ( 0 ) ;344} e l s e {345usage ( ) ;346e x i t (−1);347}348
349}350
43
Code d’xvid_encraw
351/∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗352∗ Arguments ch ec k i ng353∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗ /354
355i f ( XDIM < = 0 | | XDIM > = 2 0 4 8 | | YDIM < = 0 | | YDIM > = 2 0 4 8 ) {356f p r i n t f ( s t d e r r ,357" T ry ing t o r e t r e i v e wid th and h e i g h t from PGM header \ n " ) ;358ARG_INPUTTYPE = 1 ; /∗ pgm ∗ /359}360
361i f ( ARG_QUALITY < 0 ) {362ARG_QUALITY = 0 ;363} e l s e i f ( ARG_QUALITY >= ME_ELEMENTS) {364ARG_QUALITY = ME_ELEMENTS − 1 ;365}366
367i f ( ARG_FRAMERATE < = 0 ) {368f p r i n t f ( s t d e r r , "Wrong Framera te % s \ n " , a rgv [ 5 ] ) ;369re turn ( −1 ) ;370}371
372i f (ARG_MAXFRAMENR < = 0 ) {373f p r i n t f ( s t d e r r , "Wrong number o f f rames \ n " ) ;374re turn ( −1 ) ;375}376
377i f ( ARG_INPUTFILE = = NULL | | s t rcmp ( ARG_INPUTFILE , " s t d i n " ) = = 0 ) {378i n _ f i l e = s t d i n ;379} e l s e {380
381i n _ f i l e = fopen ( ARG_INPUTFILE , " rb " ) ;382i f ( i n _ f i l e = = NULL) {383f p r i n t f ( s t d e r r , " E r r o r open ing i n p u t f i l e % s \ n " , ARG_INPUTFILE ) ;384re turn ( −1 ) ;385}386}387
388i f ( ARG_INPUTTYPE ) {389# i f n d e f READ_PNM390i f ( read_pgmheader ( i n _ f i l e ) ) {391# e l s e392i f ( read_pnmheader ( i n _ f i l e ) ) {393# e n d i f394f p r i n t f ( s t d e r r ,395"Wrong i n p u t format , I want YUV e n c a p s u l a t e d i n PGM\ n " ) ;396re turn ( −1 ) ;397}398}399
400/∗ now we know t h e s i z e s , so a l l o c a t e memory∗ /401i n _ b u f f e r = (unsigned char ∗ ) ma l loc ( IMAGE_SIZE (XDIM , YDIM ) ) ;402i f ( ! i n _ b u f f e r )403goto f r ee_a l l _memory ;404
405/∗ t h i s shou ld r e a l l y be enough memory !∗ /406mp4_buf fer = (unsigned char ∗ ) ma l loc ( IMAGE_SIZE (XDIM , YDIM ) ∗ 2 ) ;407i f ( ! mp4_buf fer )408goto f r ee_a l l _memory ;409
410/∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗411∗ XviD PART S t a r t412∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗ /413
44
Code d’xvid_encraw
414
415r e s u l t = e n c _ i n i t ( u s e _ a s s e m b l e r ) ;416i f ( r e s u l t ) {417f p r i n t f ( s t d e r r , " Encore INIT problem , r e t u r n v a l u e %d \ n " , r e s u l t ) ;418goto r e l e a s e _ a l l ;419}420
421/∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗422∗ Main loop423∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗ /424
425i f ( ARG_SAVEMPEGSTREAM && ARG_OUTPUTFILE ) {426
427i f ( ( o u t _ f i l e = fopen (ARG_OUTPUTFILE , "w+b " ) ) = = NULL) {428f p r i n t f ( s t d e r r , " E r r o r open ing o u t p u t f i l e % s \ n " , ARG_OUTPUTFILE ) ;429goto r e l e a s e _ a l l ;430}431
432} e l s e {433o u t _ f i l e = NULL;434}435
436/∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗437∗ Encoding loop438∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗ /439
440t o t a l s i z e = 0 ;441
442r e s u l t = 0 ;443
444input_num = 0 ; /∗ i n p u t f rame c o u n t e r ∗ /445output_num = 0 ; /∗ o u t p u t f rame c o u n t e r∗ /446
447do {448
449char ∗ t ype ;450i n t s s e [ 3 ] ;451
452i f ( input_num >= ARG_MAXFRAMENR) {453r e s u l t = 1 ;454}455
456i f ( ! r e s u l t ) {457i f ( ARG_INPUTTYPE ) {458/∗ read PGM data ( YUV−f o rma t ) ∗ /459# i f n d e f READ_PNM460r e s u l t = read_pgmdata ( i n _ f i l e , i n _ b u f f e r ) ;461# e l s e462r e s u l t = read_pnmdata ( i n _ f i l e , i n _ b u f f e r ) ;463# e n d i f464} e l s e {465/∗ read raw data ( YUV−f o rma t ) ∗ /466r e s u l t = r e a d _ y u v d a t a ( i n _ f i l e , i n _ b u f f e r ) ;467}468}469
470/∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗471∗ Encode and decode t h i s f rame472∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗ /473
474enc t ime = msecond ( ) ;475m4v_size =476enc_main ( ! r e s u l t ? i n _ b u f f e r : 0 , mp4_buf fer , & key , & s t a t s _ t y p e ,
45
Code d’xvid_encraw
477&s t a t s _ q u a n t , & s t a t s _ l e n g t h , s s e ) ;478enc t ime = msecond ( )− enc t ime ;479
480/∗ Wri te t h e Frame s t a t i s t i c s∗ /481
482p r i n t f ( "%5d : key=%i , t ime = %6.0 f , l e n = %7d " , ! r e s u l t ? input_num :−1 ,483key , ( f l o a t ) enct ime , (i n t ) m4v_size ) ;484
485i f ( s t a t s _ t y p e > 0 ) { /∗ ! XVID_TYPE_NOTHING∗ /486
487sw i tch ( s t a t s _ t y p e ) {488case XVID_TYPE_IVOP :489t ype = " I " ;490break ;491case XVID_TYPE_PVOP :492t ype = "P" ;493break ;494case XVID_TYPE_BVOP :495t ype = "B" ;496break ;497case XVID_TYPE_SVOP :498t ype = "S" ;499break ;500d e f a u l t :501t ype = "U" ;502break ;503}504
505p r i n t f ( " | t ype=%s , quan t = %2d , l e n = %7d " , type , s t a t s _ q u a n t ,506s t a t s _ l e n g t h ) ;507
508# d e f i n e SSE2PSNR ( sse , width , h e i g h t ) \509( ( ! ( s s e ) ) ? 0 . 0 f : 4 8 . 1 3 1 f− 10∗ ( f l o a t ) log10 ( ( f l o a t ) ( s s e ) / ( (f l o a t ) ( ( w id th )∗ ( h e i g h t ) ) ) ) )510
511i f ( ARG_STATS ) {512p r i n t f ( " , psn r y = %2.2 f , psn r u = %2.2 f , psn r v = %2.2 f " ,513SSE2PSNR ( s s e [ 0 ] , XDIM , YDIM ) , SSE2PSNR ( s s e [ 1 ] , XDIM / 2 ,514YDIM / 2 ) ,515SSE2PSNR ( s s e [ 2 ] , XDIM / 2 , YDIM / 2 ) ) ;516
517to ta lPSNR [ 0 ] + = SSE2PSNR ( s s e [ 0 ] , XDIM , YDIM ) ;518to ta lPSNR [ 1 ] + = SSE2PSNR ( s s e [ 1 ] , XDIM/ 2 , YDIM / 2 ) ;519to ta lPSNR [ 2 ] + = SSE2PSNR ( s s e [ 2 ] , XDIM/ 2 , YDIM / 2 ) ;520}521
522}523# undef SSE2PSNR524
525p r i n t f ( " \ n " ) ;526
527i f ( m4v_size < 0 ) {528break ;529}530
531/∗ Update encod ing t ime s t a t s∗ /532t o t a l e n c t i m e + = enc t ime ;533t o t a l s i z e + = m4v_size ;534
535/∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗536∗ Save s t ream t o f i l e537∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗ /538
539i f ( m4v_size > 0 && ARG_SAVEMPEGSTREAM) {
46
Code d’xvid_encraw
540/∗ Save s i n g l e f i l e s ∗ /541i f ( o u t _ f i l e = = NULL) {542s p r i n t f ( f i l ename , "%sf rame%05d . m4v" , f i l e p a t h , output_num ) ;543o u t _ f i l e = fopen ( f i l ename , "wb" ) ;544f w r i t e ( mp4_buf fer , m4v_size , 1 , o u t _ f i l e ) ;545f c l o s e ( o u t _ f i l e ) ;546o u t _ f i l e = NULL;547output_num ++;548} e l s e {549
550/∗ Wri te mp4 data ∗ /551f w r i t e ( mp4_buf fer , 1 , m4v_size , o u t _ f i l e ) ;552
553}554}555
556input_num ++;557
558/∗ Read t h e header i f i t ’ s pgm st ream∗ /559i f ( ! r e s u l t && ARG_INPUTTYPE)560# i f n d e f READ_PNM561r e s u l t = read_pgmheader ( i n _ f i l e ) ;562# e l s e563r e s u l t = read_pnmheader ( i n _ f i l e ) ;564# e n d i f565} whi le ( 1 ) ;566
567
568
569/∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗570∗ C a l c u l a t e t o t a l s and ave rages f o r ou tpu t , p r i n t r e s u l t s571∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗ /572
573p r i n t f ( " Tot : enc t ime ( ms) =%7.2 f , l e n g t h ( b y t e s ) = %7 d \ n " ,574t o t a l e n c t i m e , (i n t ) t o t a l s i z e ) ;575
576i f ( input_num > 0 ) {577t o t a l s i z e / = input_num ;578t o t a l e n c t i m e / = input_num ;579to ta lPSNR [ 0 ] / = input_num ;580to ta lPSNR [ 1 ] / = input_num ;581to ta lPSNR [ 2 ] / = input_num ;582} e l s e {583t o t a l s i z e = −1;584t o t a l e n c t i m e =−1;585}586
587p r i n t f ( "Avg : enc t ime ( ms) =%7.2 f , f p s =%7.2 f , l e n g t h ( b y t e s ) = %7 d " ,588t o t a l e n c t i m e , 1 0 0 0 / t o t a l e n c t i m e , (i n t ) t o t a l s i z e ) ;589i f ( ARG_STATS ) {590p r i n t f ( " , psn r y = %2.2 f , psn r u = %2.2 f , psn r v = %2.2 f " ,591to ta lPSNR [ 0 ] , to ta lPSNR [ 1 ] , to ta lPSNR [ 2 ] ) ;592}593p r i n t f ( " \ n " ) ;594
595
596/∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗597∗ XviD PART Stop598∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗ /599
600r e l e a s e _ a l l :601
602i f ( enc_hand le ) {
47
Code d’xvid_encraw
603r e s u l t = enc _s t op ( ) ;604i f ( r e s u l t )605f p r i n t f ( s t d e r r , " Encore RELEASE problem r e t u r n v a l u e %d \ n " ,606r e s u l t ) ;607}608
609i f ( i n _ f i l e )610f c l o s e ( i n _ f i l e ) ;611i f ( o u t _ f i l e )612f c l o s e ( o u t _ f i l e ) ;613
614f r ee_a l l _memory :615f r e e ( o u t _ b u f f e r ) ;616f r e e ( mp4_buf fer ) ;617f r e e ( i n _ b u f f e r ) ;618
619re turn ( 0 ) ;620
621}622
623
624/∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗625∗ " s t a t i s t i c a l " f u n c t i o n s626∗627∗ t h e s e are no t needed f o r encod ing or decoding , bu t f o r measur ing628∗ t ime and q u a l i t y , t h e r e i n n o t h i n g s p e c i f i c t o XviD i n t h e s e629∗630∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗ /631
632/∗ Return t ime e l a p s e d t ime i n m i l i s e c o n d s s i n c e t h e program s t a r t e d∗ /633s t a t i c double634msecond ( )635{636# i f n d e f WIN32637s t r u c t t i m e v a l t v ;638
639g e t t i m e o f d a y (& tv , 0 ) ;640re turn ( t v . t v _ s e c ∗ 1 . 0 e3 + t v . t v _ u s e c∗ 1 . 0 e−3);641# e l s e642c l o c k _ t c l k ;643
644c l k = c l o c k ( ) ;645re turn ( c l k ∗ 1 0 0 0 / CLOCKS_PER_SEC ) ;646# e n d i f647}648
649/∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗650∗ Usage message651∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗ /652
653s t a t i c vo id654usage ( )655{656f p r i n t f ( s t d e r r , " Usage : x v i d _ s t a t [ OPTIONS ] \ n \ n " ) ;657f p r i n t f ( s t d e r r , " I n p u t o p t i o n s : \ n " ) ;658f p r i n t f ( s t d e r r , " − i s t r i n g : i n p u t f i l e n a m e ( d e f a u l t = s t d i n ) \ n " ) ;659f p r i n t f ( s t d e r r , " − t ype i n t e g e r : i n p u t d a t a t ype ( yuv = 0 , pgm = 1 ) \ n " ) ;660f p r i n t f ( s t d e r r , " −w i n t e g e r : f rame wid th ( [ 1 . 2 0 4 8 ] ) \ n " ) ;661f p r i n t f ( s t d e r r , " −h i n t e g e r : f rame h e i g h t ( [ 1 . 2 0 4 8 ] ) \ n " ) ;662f p r i n t f ( s t d e r r , " −nf rames i n t e g e r : number o f f rames t o encode \ n " ) ;663f p r i n t f ( s t d e r r , " \ n " ) ;664f p r i n t f ( s t d e r r , " Output o p t i o n s : \ n " ) ;665f p r i n t f ( s t d e r r , " −dump : save decoder o u t p u t \ n " ) ;
48
Code d’xvid_encraw
666f p r i n t f ( s t d e r r , " − save : save mpeg4 raw s t ream \ n " ) ;667f p r i n t f ( s t d e r r , " −o s t r i n g : o u t p u t f i l e n a m e \ n " ) ;668f p r i n t f ( s t d e r r , " \ n " ) ;669f p r i n t f ( s t d e r r , " BFrames o p t i o n s : \ n " ) ;670f p r i n t f ( s t d e r r , " −max_bframes i n t e g e r : max bf rames ( d e f a u l t = 0 ) \ n " ) ;671f p r i n t f ( s t d e r r , " − b q u a n t _ r a t i o i n t e g e r : bf rame q u a n t i z e r r a t i o ( d e f a u l t =150 ) \ n " ) ;672f p r i n t f ( s t d e r r , " − b q u a n t _ o f f s e t i n t e g e r : bf rame q u a n t i z e r o f f s e t ( d e f a u l t =100 ) \ n " ) ;673f p r i n t f ( s t d e r r , " \ n " ) ;674f p r i n t f ( s t d e r r , " Rate c o n t r o l o p t i o n s : \ n " ) ;675f p r i n t f ( s t d e r r , " − f r a m e r a t e f l o a t : t a r g e t f r a m e r a t e ( > 0 | d e f a u l t = 2 5 . 0 ) \ n " ) ;676f p r i n t f ( s t d e r r , " − b i t r a t e i n t e g e r : t a r g e t b i t r a t e \ n " ) ;677f p r i n t f ( s t d e r r , " − s i n g l e : s i n g l e pass mode \ n " ) ;678f p r i n t f ( s t d e r r , " −pass1 f i l e n a m e : twopass mode ( f i r s t pass ) \ n " ) ;679f p r i n t f ( s t d e r r , " −pass2 f i l e n a m e : twopass mode ( 2 nd pass ) \ n " ) ;680f p r i n t f ( s t d e r r , " −zq s t a r t i n g _ f r a m e f l o a t : b i t r a t e zone ; quan t \ n " ) ;681f p r i n t f ( s t d e r r , " −zw s t a r t i n g _ f r a m e f l o a t : b i t r a t e zone ; we igh t \ n " ) ;682f p r i n t f ( s t d e r r , " −m a x _ k e y _ i n t e r v a l i n t e g e r : maximum keyf rame i n t e r v a l \ n " ) ;683f p r i n t f ( s t d e r r , " \ n " ) ;684f p r i n t f ( s t d e r r , " Other o p t i o n s \ n " ) ;685f p r i n t f ( s t d e r r , " −asm : use assembly optmized code \ n " ) ;686f p r i n t f ( s t d e r r , " − q u a l i t y i n t e g e r : q u a l i t y ( [ 0 . . % d ] ) \ n " , ME_ELEMENTS− 1 ) ;687f p r i n t f ( s t d e r r , " −packed : packed mode \ n " ) ;688f p r i n t f ( s t d e r r , " − lumimask ing : use lumimask ing a l g o r i t h m \ n " ) ;689f p r i n t f ( s t d e r r , " − s t a t s : p r i n t s t a t s abou t encoded f rames \ n " ) ;690f p r i n t f ( s t d e r r , " −debug : a c t i v a t e s x v i d c o r e i n t e r n a l debugg ing o u t p u t \ n " ) ;691f p r i n t f ( s t d e r r , " −vop_debug : p r i n t some i n f o d i r e c t l y i n t o encoded f rames \ n " ) ;692f p r i n t f ( s t d e r r , " − he lp : p r i n t s t h i s he lp message \ n " ) ;693f p r i n t f ( s t d e r r , " \ n " ) ;694f p r i n t f ( s t d e r r , "NB : You can d e f i n e %d zones r e p e a t i n g t h e−z [qw ] " , MAX_ZONES) ;695f p r i n t f ( s t d e r r , " o p t i o n as many t i m e s as needed . \ n " ) ;696f p r i n t f ( s t d e r r , " \ n " ) ;697}698
699/∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗700∗ I n p u t and o u t p u t f u n c t i o n s701∗702∗ t h e are s m a l l and s i m p l e r o u t i n e s t o read and w r i t e PGM and YUV703∗ image . I t ’ s j u s t f o r conven ience , aga in n o t h i n g s p e c i f i c t o XviD704∗705∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗ /706
707# i f n d e f READ_PNM708s t a t i c i n t709read_pgmheader ( FILE∗ hand le )710{711i n t by tes , xs i ze , ys i ze , dep th ;712char dummy [ 2 ] ;713
714b y t e s = f r e a d (dummy , 1 , 2 , hand le ) ;715
716i f ( ( b y t e s < 2 ) | | ( dummy [ 0 ] ! = ’P ’ ) | | ( dummy [ 1 ] ! = ’ 5 ’ ) )717re turn ( 1 ) ;718
719f s c a n f ( hand le , "%d %d %d " , & xs i ze , & ys i ze , & dep th ) ;720i f ( ( x s i z e > 1 4 4 0 ) | | ( y s i z e > 2 8 8 0 ) | | ( dep th ! = 2 5 5 ) ) {721f p r i n t f ( s t d e r r , "%d %d %d \ n " , xs i ze , ys i ze , dep th ) ;722re turn ( 2 ) ;723}724i f ( ( XDIM = = 0 ) | | ( YDIM = = 0 ) ) {725XDIM = x s i z e ;726YDIM = y s i z e ∗ 2 / 3 ;727}728
49
Code d’xvid_encraw
729re turn ( 0 ) ;730}731
732s t a t i c i n t733read_pgmdata ( FILE∗ hand le ,734unsigned char ∗ image )735{736i n t i ;737char dummy ;738
739unsigned char ∗ y = image ;740unsigned char ∗ u = image + XDIM ∗ YDIM;741unsigned char ∗ v = image + XDIM ∗ YDIM + XDIM / 2 ∗ YDIM / 2 ;742
743/∗ read Y component o f p i c t u r e∗ /744f r e a d ( y , 1 , XDIM ∗ YDIM , hand le ) ;745
746f o r ( i = 0 ; i < YDIM / 2 ; i ++ ) {747/∗ read U ∗ /748f r e a d ( u , 1 , XDIM / 2 , hand le ) ;749
750/∗ read V ∗ /751f r e a d ( v , 1 , XDIM / 2 , hand le ) ;752
753/∗ Update p o i n t e r s ∗ /754u + = XDIM / 2 ;755v + = XDIM / 2 ;756}757
758/∗ I don ’ t know why , bu t t h i s seems needed∗ /759f r e a d (&dummy , 1 , 1 , hand le ) ;760
761re turn ( 0 ) ;762}763# e l s e764s t a t i c i n t765read_pnmheader ( FILE∗ hand le )766{767i n t by tes , xs i ze , ys i ze , dep th ;768char dummy [ 2 ] ;769
770b y t e s = f r e a d (dummy , 1 , 2 , hand le ) ;771
772i f ( ( b y t e s < 2 ) | | ( dummy [ 0 ] ! = ’P ’ ) | | ( dummy [ 1 ] ! = ’ 6 ’ ) )773re turn ( 1 ) ;774
775f s c a n f ( hand le , "%d %d %d " , & xs i ze , & ys i ze , & dep th ) ;776i f ( ( x s i z e > 1 4 4 0 ) | | ( y s i z e > 2 8 8 0 ) | | ( dep th ! = 2 5 5 ) ) {777f p r i n t f ( s t d e r r , "%d %d %d \ n " , xs i ze , ys i ze , dep th ) ;778re turn ( 2 ) ;779}780
781XDIM = x s i z e ;782YDIM = y s i z e ;783
784re turn ( 0 ) ;785}786
787s t a t i c i n t788read_pnmdata ( FILE∗ hand le ,789unsigned char ∗ image )790{791i n t i ;
50
Code d’xvid_encraw
792char dummy ;793
794/∗ read Y component o f p i c t u r e∗ /795f r e a d ( image , 1 , XDIM∗ YDIM ∗ 3 , hand le ) ;796
797/∗ I don ’ t know why , bu t t h i s seems needed∗ /798f r e a d (&dummy , 1 , 1 , hand le ) ;799
800re turn ( 0 ) ;801}802# e n d i f803
804s t a t i c i n t805r e a d _ y u v d a t a ( FILE∗ hand le ,806unsigned char ∗ image )807{808
809i f ( f r e a d ( image , 1 , IMAGE_SIZE (XDIM , YDIM ) , hand le ) ! =810( unsigned i n t ) IMAGE_SIZE (XDIM , YDIM) )811re turn ( 1 ) ;812e l s e813re turn ( 0 ) ;814}815
816/∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗817∗ R o u t i n e s f o r encod ing : i n i t encoder , f rame s tep , r e l e a s e encoder818∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗ /819
820/∗ sample p l u g i n ∗ /821
822i n t823rawenc_debug (vo id ∗ hand le ,824i n t opt ,825vo id ∗ param1 ,826vo id ∗ param2 )827{828sw i tch ( op t ) {829case XVID_PLG_INFO :830{831x v i d _ p l g _ i n f o _ t ∗ i n f o = ( x v i d _ p l g _ i n f o _ t ∗ ) param1 ;832
833i n fo −>f l a g s = XVID_REQDQUANTS;834re turn 0 ;835}836
837case XVID_PLG_CREATE :838case XVID_PLG_DESTROY:839case XVID_PLG_BEFORE :840re turn 0 ;841
842case XVID_PLG_AFTER :843{844x v i d _ p l g _ d a t a _ t ∗ d a t a = ( x v i d _ p l g _ d a t a _ t∗ ) param1 ;845i n t i , j ;846
847p r i n t f ( "−−−[ f rame : %5 i quan t : %2 i l e n g t h : %6 i ]−−−\n " ,848data−>frame_num , da ta−>quant , da ta−>l e n g t h ) ;849f o r ( j = 0 ; j < da ta−>mb_height ; j ++ ) {850f o r ( i = 0 ; i < da ta−>mb_width ; i ++)851p r i n t f ( "%2i " , da ta−>dquant [ j ∗ data−>d q u a n t _ s t r i d e + i ] ) ;852p r i n t f ( " \ n " ) ;853}854
51
Code d’xvid_encraw
855re turn 0 ;856}857}858
859re turn XVID_ERR_FAIL ;860}861
862
863# d e f i n e FRAMERATE_INCR 1001864
865
866/∗ I n i t i a l i z e encoder f o r f i r s t use , pass a l l needed paramete rs t o t h e codec∗ /867s t a t i c i n t868e n c _ i n i t ( i n t u s e _ a s s e m b l e r )869{870i n t x e r r ;871/ / x v i d _ p l u g i n _ c b r _ t cbr ;872x v i d _ p l u g i n _ s i n g l e _ t s i n g l e ;873x v i d _ p l u g i n _ 2 p a s s 1 _ t r c 2 p a s s 1 ;874x v i d _ p l u g i n _ 2 p a s s 2 _ t r c 2 p a s s 2 ;875/ / x v i d _ p l u g i n _ f i x e d _ t r c f i x e d ;876x v i d _ e n c _ p l u g i n _ t p l u g i n s [ 7 ] ;877x v i d _ g b l _ i n i t _ t x v i d _ g b l _ i n i t ;878x v i d _ e n c _ c r e a t e _ t x v i d _ e n c _ c r e a t e ;879
880/∗−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−881∗ XviD core i n i t i a l i z a t i o n882∗−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−∗ /883
884/∗ S e t v e r s i o n−− v e r s i o n che ck in g w i l l done by x v i d c o r e∗ /885memset(& x v i d _ g b l _ i n i t , 0 , s i z e o f( x v i d _ g b l _ i n i t ) ) ;886x v i d _ g b l _ i n i t . v e r s i o n = XVID_VERSION ;887x v i d _ g b l _ i n i t . debug = ARG_DEBUG;888
889
890/∗ Do we have t o enab le ASM o p t i m i z a t i o n s ?∗ /891i f ( u s e _ a s s e m b l e r ) {892
893# i f d e f ARCH_IS_IA64894x v i d _ g b l _ i n i t . c p u _ f l a g s = XVID_CPU_FORCE | XVID_CPU_IA64 ;895# e l s e896x v i d _ g b l _ i n i t . c p u _ f l a g s = 0 ;897# e n d i f898} e l s e {899x v i d _ g b l _ i n i t . c p u _ f l a g s = XVID_CPU_FORCE ;900}901
902/∗ I n i t i a l i z e XviD core−− Should be done once per __process__∗ /903x v i d _ g l o b a l (NULL , XVID_GBL_INIT , & x v i d _ g b l _ i n i t , NULL ) ;904
905/∗−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−906∗ XviD encoder i n i t i a l i z a t i o n907∗−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−∗ /908
909/∗ Vers ion aga in ∗ /910memset(& x v i d _ e n c _ c r e a t e , 0 ,s i z e o f( x v i d _ e n c _ c r e a t e ) ) ;911x v i d _ e n c _ c r e a t e . v e r s i o n = XVID_VERSION ;912
913/∗ Width and He igh t o f i n p u t f rames∗ /914x v i d _ e n c _ c r e a t e . w id th = XDIM;915x v i d _ e n c _ c r e a t e . h e i g h t = YDIM;916
917/∗ i n i t p l u g i n s ∗ /
52
Code d’xvid_encraw
918x v i d _ e n c _ c r e a t e . zones = ZONES;919x v i d _ e n c _ c r e a t e . num_zones = NUM_ZONES;920
921x v i d _ e n c _ c r e a t e . p l u g i n s = p l u g i n s ;922x v i d _ e n c _ c r e a t e . num_plug ins = 0 ;923
924i f ( ARG_SINGLE ) {925memset(& s i n g l e , 0 , s i z e o f( x v i d _ p l u g i n _ s i n g l e _ t ) ) ;926s i n g l e . v e r s i o n = XVID_VERSION ;927s i n g l e . b i t r a t e = ARG_BITRATE ;928
929p l u g i n s [ x v i d _ e n c _ c r e a t e . num_plug ins ] . func = x v i d _ p l u g i n _ s i n g l e ;930p l u g i n s [ x v i d _ e n c _ c r e a t e . num_plug ins ] . param = & s i n g l e ;931x v i d _ e n c _ c r e a t e . num_plug ins ++;932}933
934i f ( ARG_PASS2 ) {935memset(& rc2pass2 , 0 ,s i z e o f( x v i d _ p l u g i n _ 2 p a s s 2 _ t ) ) ;936r c 2 p a s s 2 . v e r s i o n = XVID_VERSION ;937r c 2 p a s s 2 . f i l e n a m e = ARG_PASS2 ;938r c 2 p a s s 2 . b i t r a t e = ARG_BITRATE ;939
940p l u g i n s [ x v i d _ e n c _ c r e a t e . num_plug ins ] . func = x v i d _ p l u g i n _ 2 p a s s 2 ;941p l u g i n s [ x v i d _ e n c _ c r e a t e . num_plug ins ] . param = & r c 2 p a s s 2 ;942x v i d _ e n c _ c r e a t e . num_plug ins ++;943}944
945i f ( ARG_PASS1 ) {946memset(& rc2pass1 , 0 ,s i z e o f( x v i d _ p l u g i n _ 2 p a s s 1 _ t ) ) ;947r c 2 p a s s 1 . v e r s i o n = XVID_VERSION ;948r c 2 p a s s 1 . f i l e n a m e = ARG_PASS1 ;949
950p l u g i n s [ x v i d _ e n c _ c r e a t e . num_plug ins ] . func = x v i d _ p l u g i n _ 2 p a s s 1 ;951p l u g i n s [ x v i d _ e n c _ c r e a t e . num_plug ins ] . param = & r c 2 p a s s 1 ;952x v i d _ e n c _ c r e a t e . num_plug ins ++;953}954
955i f ( ARG_LUMIMASKING) {956p l u g i n s [ x v i d _ e n c _ c r e a t e . num_plug ins ] . func = xv id_p lug in_ lum imask ing ;957p l u g i n s [ x v i d _ e n c _ c r e a t e . num_plug ins ] . param = NULL;958x v i d _ e n c _ c r e a t e . num_plug ins ++;959}960
961i f (ARG_DUMP) {962p l u g i n s [ x v i d _ e n c _ c r e a t e . num_plug ins ] . func = xv id_p lug in_dump ;963p l u g i n s [ x v i d _ e n c _ c r e a t e . num_plug ins ] . param = NULL;964x v i d _ e n c _ c r e a t e . num_plug ins ++;965}966
967# i f 0968i f ( ARG_DEBUG) {969p l u g i n s [ x v i d _ e n c _ c r e a t e . num_plug ins ] . func = rawenc_debug ;970p l u g i n s [ x v i d _ e n c _ c r e a t e . num_plug ins ] . param = NULL;971x v i d _ e n c _ c r e a t e . num_plug ins ++;972}973# e n d i f974
975/∗ No f a n c y t h r e a d t e s t s∗ /976x v i d _ e n c _ c r e a t e . num_threads = 0 ;977
978/∗ Frame r a t e − Do some q u i c k f l o a t f p s = f i n c r / f b a s e hack∗ /979i f ( ( ARG_FRAMERATE − ( i n t ) ARG_FRAMERATE) < SMALL_EPS ) {980x v i d _ e n c _ c r e a t e . f i n c r = 1 ;
53
Code d’xvid_encraw
981x v i d _ e n c _ c r e a t e . f b a s e = (i n t ) ARG_FRAMERATE;982} e l s e {983x v i d _ e n c _ c r e a t e . f i n c r = FRAMERATE_INCR;984x v i d _ e n c _ c r e a t e . f b a s e = (i n t ) ( FRAMERATE_INCR ∗ ARG_FRAMERATE) ;985}986
987/∗ Maximum key frame i n t e r v a l∗ /988i f ( ARG_MAXKEYINTERVAL > 0 ) {989x v i d _ e n c _ c r e a t e . m a x _ k e y _ i n t e r v a l = ARG_MAXKEYINTERVAL;990} e l s e {991x v i d _ e n c _ c r e a t e . m a x _ k e y _ i n t e r v a l = (i n t ) ARG_FRAMERATE ∗1 0 ;992}993
994/∗ Bframes s e t t i n g s∗ /995x v i d _ e n c _ c r e a t e . max_bframes = ARG_MAXBFRAMES;996x v i d _ e n c _ c r e a t e . b q u a n t _ r a t i o = ARG_BQRATIO;997x v i d _ e n c _ c r e a t e . b q u a n t _ o f f s e t = ARG_BQOFFSET;998
999/∗ Dropping r a t i o f rame−− we don ’ t need t h a t ∗ /1000x v i d _ e n c _ c r e a t e . f r a m e _ d r o p _ r a t i o = 0 ;1001
1002/∗ Globa l encoder o p t i o n s∗ /1003x v i d _ e n c _ c r e a t e . g l o b a l = 0 ;1004
1005i f ( ARG_PACKED)1006x v i d _ e n c _ c r e a t e . g l o b a l | = XVID_GLOBAL_PACKED;1007
1008i f ( ARG_STATS)1009x v i d _ e n c _ c r e a t e . g l o b a l | = XVID_GLOBAL_EXTRASTATS_ENABLE;1010
1011/∗ I use a s m a l l v a l u e here , s i n c e w i l l no t encode whole movies , bu t s h o r t c l i p s∗ /1012x e r r = xv i d _enco re (NULL , XVID_ENC_CREATE, & x v i d _ e n c _ c r e a t e , NULL ) ;1013
1014/∗ R e t r i e v e t h e encoder i n s t a n c e from t h e s t r u c t u r e∗ /1015enc_hand le = x v i d _ e n c _ c r e a t e . hand le ;1016
1017re turn ( x e r r ) ;1018}1019
1020s t a t i c i n t1021en c_s top ( )1022{1023i n t x e r r ;1024
1025/∗ Des t roy t h e encoder i n s t a n c e∗ /1026x e r r = xv i d _enco re ( enc_hand le , XVID_ENC_DESTROY , NULL , NULL ) ;1027
1028re turn ( x e r r ) ;1029}1030
1031s t a t i c i n t1032enc_main (unsigned char ∗ image ,1033unsigned char ∗ b i t s t r e a m ,1034i n t ∗ key ,1035i n t ∗ s t a t s _ t y p e ,1036i n t ∗ s t a t s _ q u a n t ,1037i n t ∗ s t a t s _ l e n g t h ,1038i n t s s e [ 3 ] )1039{1040i n t r e t ;1041
1042xv id_enc_ f rame_ t xv id_enc_ f rame ;1043x v i d _ e n c _ s t a t s _ t x v i d _ e n c _ s t a t s ;
54
Code d’xvid_encraw
1044
1045/∗ Vers ion f o r t h e f rame and t h e s t a t s∗ /1046memset(& xv id_enc_f rame , 0 ,s i z e o f( xv id_enc_ f rame ) ) ;1047xv id_enc_ f rame . v e r s i o n = XVID_VERSION ;1048
1049memset(& x v i d _ e n c _ s t a t s , 0 ,s i z e o f( x v i d _ e n c _ s t a t s ) ) ;1050x v i d _ e n c _ s t a t s . v e r s i o n = XVID_VERSION ;1051
1052/∗ Bind o u t p u t b u f f e r ∗ /1053xv id_enc_ f rame . b i t s t r e a m = b i t s t r e a m ;1054xv id_enc_ f rame . l e n g t h =−1;1055
1056/∗ I n i t i a l i z e i n p u t image f i e l d s ∗ /1057i f ( image ) {1058xv id_enc_ f rame . i n p u t . p l a n e [ 0 ] = image ;1059# i f n d e f READ_PNM1060xv id_enc_ f rame . i n p u t . csp = XVID_CSP_I420 ;1061xv id_enc_ f rame . i n p u t . s t r i d e [ 0 ] = XDIM;1062# e l s e1063xv id_enc_ f rame . i n p u t . csp = XVID_CSP_BGR ;1064xv id_enc_ f rame . i n p u t . s t r i d e [ 0 ] = XDIM∗3;1065# e n d i f1066} e l s e {1067xv id_enc_ f rame . i n p u t . csp = XVID_CSP_NULL ;1068}1069
1070/∗ S e t up core ’ s g e n e r a l f e a t u r e s∗ /1071xv id_enc_ f rame . v o l _ f l a g s = 0 ;1072i f ( ARG_STATS)1073xv id_enc_ f rame . v o l _ f l a g s | = XVID_VOL_EXTRASTATS;1074
1075/∗ S e t up core ’ s g e n e r a l f e a t u r e s∗ /1076xv id_enc_ f rame . v o p _ f l a g s = v o p _ p r e s e t s [ARG_QUALITY ] ;1077i f ( ARG_VOPDEBUG) {1078xv id_enc_ f rame . v o p _ f l a g s | = XVID_VOP_DEBUG;1079}1080
1081/∗ Frame t y p e−− l e t co re d e c i d e f o r us∗ /1082xv id_enc_ f rame . t ype = XVID_TYPE_AUTO;1083
1084/∗ Force t h e r i g h t q u a n t i z e r−− I t i s i n t e r n a l l y managed by RC p l u g i n s∗ /1085xv id_enc_ f rame . quan t = 0 ;1086
1087/∗ S e t up mot ion e s t i m a t i o n f l a g s∗ /1088xv id_enc_ f rame . mot ion = m o t i o n _ p r e s e t s [ARG_QUALITY ] ;1089
1090/∗ We don ’ t use s p e c i a l m a t r i c e s∗ /1091xv id_enc_ f rame . q u a n t _ i n t r a _ m a t r i x = NULL;1092xv id_enc_ f rame . q u a n t _ i n t e r _ m a t r i x = NULL;1093
1094/∗ Encode t h e f rame∗ /1095r e t =1096xv i d_e nco re ( enc_hand le , XVID_ENC_ENCODE, & xv id_enc_f rame ,1097&x v i d _ e n c _ s t a t s ) ;1098
1099∗key = ( xv id_enc_ f rame . o u t _ f l a g s & XVID_KEYFRAME ) ;1100∗ s t a t s _ t y p e = x v i d _ e n c _ s t a t s . t ype ;1101∗ s t a t s _ q u a n t = x v i d _ e n c _ s t a t s . quan t ;1102∗ s t a t s _ l e n g t h = x v i d _ e n c _ s t a t s . l e n g t h ;1103s s e [ 0 ] = x v i d _ e n c _ s t a t s . sse_y ;1104s s e [ 1 ] = x v i d _ e n c _ s t a t s . sse_u ;1105s s e [ 2 ] = x v i d _ e n c _ s t a t s . sse_v ;1106
55
Code d’xvid_encraw
1107re turn ( r e t ) ;1108}
Ce mémoire a été écrit avec la seule aide de logiciels libres dont LATEX, emacs, XviD et bien d’autresdont tous les auteurs méritent notre reconnaissance.
56