Je parlais la semaine dernière de la caméra de la PlayStation 2, la webcam EyeToy. Et cette webcam USB a une particularité intéressante techniquement : elle envoie un flux vidéo MPEG-2 à la console. C’est vraiment un cas particulier, et c’est limité à la console, même si on peut récupérer les images en trichant un peu (je l’ai fait).
La webcam date de 2003, pour une console sortie en 2000, avec une puissance de calcul limitée et un bus USB 1.1. Ce sont des contraintes fortes pour du traitement d’image, particulièrement quand le but est dans l’idéal de travailler à 60 images/s. Le bus USB 1.1 permet 12 Mb/s en théorie (vers 8 Mb/s en pratique) et c’est vraiment peu. A l’époque, on ne travaille pas avec une image non compressée comme les webcams actuelles (une image en 640 x 480 en 24 bits nécessite un peu plus de 7 Mb, pas loin de 10 Mb en 32 bits) mais directement en JPEG. C’est d’ailleurs le mode choisi par certains jeux de la console mais aussi celui qui est utilisé si vous branchez la webcam a un PC sous Windows ou à une distribution GNU/Linux. Le problème, c’est que même comme ça, la bande passante est faible et il faut décoder les images JPEG, ce qui n’est pas trivial. Le CPU de la console (Emotion Engine, un MIPS à ~300 MHz) est correct, mais décoder 30 ou 60 images/s en JPEG, ce n’est pas vraiment possible.
La solution de Sony à l’époque est assez intéressante, donc : le contrôleur de la webcam (OV519 de chez Omnivision) est capable d’encoder l’image en MPEG-2. C’est un mode caché, utilisé uniquement par la console. Pourquoi le MPEG-2 ? Parce que la PlayStation 2 est un lecteur de DVD et qu’elle contient un module de décompression, l’IPU, capable de décoder le MPEG-2 matériellement. C’est un peu le concept (abandonné) des webcams H.264 avant l’heure. L’astuce d’Omnivision pour éviter de mettre un encodeur complet dans son contrôleur, c’est de tricher un peu sur la façon d’encoder.
En MPEG-2, il y a trois types d’images. Les images I sont encodées totalement, avec un algorithme dédié. Les images P, elles, contiennent la différence avec l’image précédente (en simplifiant). Et les images B contiennent la différence avec l’image précédente et avec l’image suivante. Dans un encodage standard (par exemple un DVD), on va alterner les images : entre deux images I (complètes), on va placer des images P et B. La séquence dépend un peu des scènes et de la compression, mais vous avez compris l’idée. Les images P et B, logiquement, sont plus compactes que les images I, et donc on améliore la compression. Le but est d’obtenir un compromis entre la qualité et la compression, avec plus ou moins d’images I. Dans la webcam de Sony, l’idée d’Omnivision est simple : il n’y a que des images I. D’abord parce que c’est plus simple d’implémenter uniquement la compression des images I (contraintes de coûts), ensuite parce que ça simplifie le fonctionnement : devoir attendre d’avoir plusieurs images pour créer les images B ajoute de la latence et nécessite un peu de mémoire.
Dans la pratique, donc, la webcam peut filmer en 320 x 240 à 30 images/s (de ce que j’ai pu comprendre, ce n’est pas documenté) avec du MPEG-2 en IIIII (etc.). Ça permet à la console de décoder et traiter l’image matériellement. Je ne sors pas tout ça de mon chapeau : il y a un brevet qui explique tout en détails, et Richard Marks (qui a inventé l’EyeToy) l’explique dans une interview.
Comment tester ?
Bon, c’est ici que c’est compliqué. Parce que je voulais voir le résultat. J’avais trouvé quelques informations et des explications sur ce sujet lié à PCSX2, un émulateur de PlayStation 2. Un des développeurs avait mis un exemple de code qui permet de récupérer des images brutes depuis la webcam. Il m’a donné un peu de fil à retordre : il nécessite libusb et demande de désactiver la détection automatique de la caméra sous GNU/Linux (j’ai d’abord testé dans une machine virtuelle). Il y a deux lignes (en commentaires dans le fichier) pour exclure le pilote standard des distributions GNU/linux. Parce que par défaut, la webcam est reconnue et utilisable, mais uniquement en JPEG. Après quelques modifications du code avec l’aide de ChatGPT (je ne suis pas assez bon, et il a pu m’aider un peu, malgré quelques erreurs idiotes), j’ai réussi à obtenir un truc capable d’enregistrer des images brutes. Et je me suis aussi rendu compte que je pouvais lancer directement le code sous macOS, après avoir installé libusb. Je vous mets le code sur GitHub, mais c’est assez brut de décoffrage.
Une fois les frames obtenues, elles ne sont pas utilisables directement. D’abord, il y a quelques octets inutiles. J’ai donc fait un script basique qui élimine les 16 octets inutiles au début. Ensuite, ce n’est pas directement du MPEG-2, de ce que j’ai compris, mais un format Sony pour l’IPU. J’ai donc dû récupérer un projet open source un peu daté qui permet de décoder les images IPU (le décodeur, l’interface graphique). Je vous passe les détails pour compiler le programme sous Windows dans une machine virtuelle, mais en gros il va transformer un fichier .IPU en un fichier vidéo .M2V, lisible par VLC. La webcam accuse son âge : elle a une balance des blancs et des couleurs faussées dans mon bureau.
Le fichier contient une seule image en MPEG-2, en 320 x 240 à 30 images/s, mais a priori certains jeux passent à 60 images/s (Clumsy Shumsy a l’air dans le cas, peut-être dans une définition plus faible). Question taille, les images .IPU (avant conversion) font environ 10 ko. Pour comparer, j’ai juste branché la caméra sous Linux. Avec VLC, il est possible d’afficher le flux brut (Media -> Open Capture Device). Là, on peut faire un clic droit puis Record, ce qui va enregistrer le flux brut. En 640 x 480, j’ai 7,5 images/s. En 320 x 240, j’ai ~15 images/s. Dans les deux cas, le débit est variable, entre 1 et 2 Mb/s. Il est possible d’extraire les images JPEG (ffmpeg -i video.avi -vcodec copy frame%d.jpg) et la taille varie, mais c’est du même ordre que la frame I en MPEG-2 (vers 10 ko, en gros). Même avec des webcams plus modernes, l’USB 1.1 limite réellement, j’en avais parlé il y a quelques années.
Je n’ai pas trouvé comment obtenir une vidéo complète (une suite d’image), mais la démonstration se suffit à elle-même, à mon avis. Le petit programme montre que la caméra peut filmer directement en MPEG-2, spécifiquement pour la console de Sony. Une question que je me pose tout de même vient de la puce d’Omnivision. L’OV519 qui anime la webcam de Sony a été employé dans d’autres webcams du marché, et je me demande si les webcams de PC ont l’encodeur MPEG-2 (je suppose). Je testerais probablement un jour, mais je dois d’abord trouver une vieille webcam avec la bonne puce, ce qui n’est pas simple.
C’est d’ailleurs grâce aux webcams pour PC qu’il existe des pilotes pour l’EyeToy sous Windows ou sous GNU/Linux, ce sont juste des versions modifiées pour prendre en charge la webcam de Sony. C’est un problème qui ne se pose plus trop en 2025 : les webcams sont toutes UVC, un protocole standard bien pris en charge par les différents systèmes d’exploitation. Mais en 2003, ça n’existait pas et chaque webcam avait besoin de son propre pilote.
Dans tous les cas, la solution de Sony (et Omnivision) est plutôt intelligente et tire bien parti du matériel de la console sans trop exploser les coûts. Le principal problème, c’est surtout que c’est une webcam de 2003 : on a une image en 320 x 240 (640 x 480 dans certains cas) avec un capteur pas très sensible qui a tendance à fausser les couleurs. Mais c’était un peu la norme à l’époque.












