⚫ BW Camera, une webcam qui n'envoie plus la couleur

Convertit n'importe quelle webcam Linux en caméra virtuelle noir & blanc via V4L2 loopback, compatible Teams, Chrome, Zoom, OBS et tout consommateur V4L2/WebRTC.

YUYV, plans U/V réels I420, plans U/V = 128 (constants)

La visioconférence pèse lourd en bande passante et en énergie au poste de travail, plus que l'audio ou le partage d'écran : le flux vidéo concentre l'essentiel de ce coût. Une partie vient de la couleur, que l'encodeur recalcule et retransmet à chaque image, alors qu'un visage, un geste ou un tableau blanc restent compréhensibles en niveaux de gris.

BW Camera agit à la source : il neutralise la chrominance du flux avant qu'il n'atteigne l'application de visioconférence, ce qui permet à l'encodeur de la compresser à quasi-zéro. Le poste client, le réseau et l'infrastructure de visioconférence consomment donc moins d'énergie, à qualité perçue équivalente.

Voir sur GitHub Installer

Un levier parmi d'autres

La couleur n'est qu'un des trois leviers qui pèsent sur le coût d'un flux vidéo, indépendant des deux leviers classiques d'encodage. Les trois sont cumulables : WIDTH, HEIGHT et FPS sont des constantes de compilation dans bw_camera.c, à adapter selon l'usage.

Couleur

Chrominance neutralisée (U/V = 128). Résolution et fluidité intactes. Le levier de BW Camera.

Résolution

Moins de pixels par image à encoder et transmettre. Exemple : 480×360 au lieu de 640×480.

Fréquence (FPS)

Moins d'images par seconde, au prix de la fluidité. Exemple : 15 au lieu de 30.

Comment ça marche

Le format GREY natif est rejeté par Teams, Chrome et WebRTC : la sortie est donc encodée en I420, avec un plan Y réel et des plans U/V constants. L'image perçue est en niveaux de gris, et l'application accepte le flux sans modification. Toute la capture passe par l'API V4L2 du noyau Linux et son extension v4l2loopback.

/dev/video0
caméra physique · YUYV 640×480 @30fps
→
/dev/video20
v4l2loopback · I420 640×480
  1. VIDIOC_S_FMT source → YUYV
  2. VIDIOC_S_FMT destination → I420
  3. VIDIOC_REQBUFS / QBUF / DQBUF (streaming mmap, 4 buffers)
  4. Extraction du plan Y : octets pairs de chaque paire YUYV, sans conversion colorimétrique
  5. Plans U/V fixés à 128, calculés une seule fois
  6. write() de la frame I420 vers /dev/video20

En 30 secondes

git clone https://github.com/Institut-du-Numerique-Responsable/bw_camera.git
cd bw_camera && chmod +x install.sh && sudo ./install.sh

install.sh installe les dépendances, charge v4l2loopback, compile bw_camera et déploie un service systemd (Restart=always). Le flux noir & blanc apparaît en /dev/video20, prêt à être choisi comme caméra dans Teams, Chrome, Zoom ou OBS.

Prérequis

Linux, en-têtes noyau pour uname -r, module v4l2loopback (pré-compilé ou DKMS), une webcam exposant YUYV en streaming mmap (quasi tout le parc UVC), et gcc/libv4l-dev/v4l-utils/zstd.

Ce que fait install.sh

Dépendances, chargement du module, pré-configuration de /dev/video20 en I420, compilation, service systemd et démarrage automatique au boot.

Ce que contient le projet

FichierRôle
bw_camera.cProgramme principal : capture V4L2, extraction Y, écriture I420
MakefileCompilation (gcc -O2 -Wall)
start_bw_camera.shDémarrage/arrêt du binaire, chargement du module
install.shInstallation complète : dépendances, module, service systemd

Problèmes rencontrés

Quatre difficultés concrètes ont orienté les choix d'implémentation.

GREY rejeté par les applications de visio

V4L2 propose un format noir & blanc pur, plus léger que I420. Teams, Chrome et WebRTC n'acceptent pourtant en entrée que des formats couleur standard. Solution : sortir en I420 avec chrominance neutre (128) ; le gain se fait au niveau de l'encodeur de l'application plutôt que du flux brut.

VIDIOC_S_FMT n'échoue pas sur une résolution non supportée

Le pilote V4L2 ajuste silencieusement le format demandé sans retourner d'erreur. bw_camera relit systématiquement le format réellement négocié après l'ioctl pour détecter un ajustement ou une incompatibilité.

Écritures partielles et EAGAIN sur /dev/video20

Le write() vers v4l2loopback peut n'écrire qu'une partie de la frame, ou échouer temporairement si aucun consommateur n'est encore attaché. bw_camera boucle (write_full) jusqu'à écriture complète, avec une courte pause en cas de blocage.

Faux positif de détection de processus déjà lancé

pgrep -f ./bw_camera correspondait aussi au chemin de start_bw_camera.sh, provoquant une boucle de redémarrage sous systemd. Correction : pgrep -x bw_camera, qui ne matche que le nom exact du processus.

Pourquoi c'est important

Ce projet s'inscrit dans une démarche de sobriété numérique : réduire l'impact environnemental des usages numériques du quotidien par des choix techniques simples, portables et sans dépendance à une application tierce, plutôt que par la seule sensibilisation. Il s'appuie sur un format standard (I420) accepté par les applications existantes, sans exiger de plugin ni de configuration côté visioconférence.

Même logique côté outillage de développement avec green-claude, un skill qui applique les référentiels RGESN et GR491 au code produit par un assistant IA.