Sommaire
Un autre décodeur pour quoi faire ?
dav1d est issu de la phase 1B du déploiement d’AV1, soit la phase d’optimisation du codec.
En l’état actuel, les codecs de nouvelle génération sont hautement complexes et dans les plus hautes résolutions, leur rendu ne peut être effectué simplement sur le processeur en temps réel. C’est pour cela que les résolutions 4K et 2K sont problématiques, notamment avec HEVC. L’augmentation de complexité en passant à AV1 empire les choses.
Les implémentations matérielles n’étant prévues que pour 2020, il est nécessaire d’avoir des décodeurs logiciels fortement optimisés et tirant parti des capacités vectorielles des processeurs pour que la vidéo codée en AV1 dans des résolutions standard et HD soit lisible sur un processeur actuel, en attendant l’arrivée des implémentations matérielles.
Un autre point important est la mise à disposition sous licence BSD 2 simplifiée, ce qui permet à l’industrie de réutiliser le code comme socle pour un décodeur purement matériel ou bien hybride.
Performance actuelles
Les optimisations assembleur ont d’abord été effectuées en utilisant le jeu d’instructions AVX2, disponibles à partir des processeurs Intel Haswell commercialisés sous le nom Core.
Le choix a aussi été fait de ne travailler dans un premier temps que les optimisations de traitement des transformations génériques et le format le plus courant : le Y’UV 4:2:0 en 8 bits.
De même, il a été choisi de faire une architecture permettant l’optimisation des fils d’exécution (threads) du processeur pour effectuer un décodage par tranche ou par image, mais aussi combiné. L’ordonnancement des tâches et des mécanismes d’exclusivité laisse envisager une optimisation à venir aussi de ce côté, avec dans l’idéal une progression presque linéaire dans la majorité des cas, en fonction du nombre de cœurs affectés.
On peut voir le décodage par tranche comme une parallélisation spatiale et le décodage par image comme une parallélisation temporelle. La parallélisation par tranche permet de décoder une image rapidement : c’est très utile pour les flux vidéos en temps réel et les images fixes (photos encodées en AV1). La parallélisation par image permet de décoder les images suivantes en avance.
Les optimisations x86 en assembleur (SIMD) sont effectuées pour différents niveaux d’instructions :
- AVX2, présent sur tous les processeurs récents, traite 256 bits en parallèle ;
- SSSE3, quelques générations avant, qui ne propose que 128 bits et un jeu d’opérations restreintes.
dav1d 0.1.0 ciblait AVX2. La version 0.2.0 propose donc la prise en charge du SSSE3 pour les anciens (4-5 ans) processeurs et processeurs 32 bits, ainsi que la prise en charge des ARM et ARM64 via le jeu d’instructions Neon.
Concernant les implémentations SSSE3 des codecs nouvelle génération, c’est un peu comme si on était revenu à l’époque de l’arrivée des décodeurs MP3 sur vos Pentium à 100 MHz : on sait faire avec de la vectorisation, mais on est vraiment à la limite du matériel.
Un doute sur votre processeur ? AVX2 ou SSSE3 dans /proc/cpuinfo
Les performances actuelles de dav1d 0.2.0 pour le jeu d’instructions AVX2 en comparaison avec aomdec sont :
Et là où dav1d fait la différence par son architecture est sur l’exécution en parallèle sur de multiples fils d’exécutions :
Pour les optimisations niveau SSSE3 qui viennent d’être ajoutées :
Sur le plan des optimisations pour les autres plates‐formes, la version ARM64 est actuellement déjà 60 % à 120 % plus rapide qu’aom, bien qu’elle n’ait reçu qu’une optimisation partielle, mais aussi bien plus rapide que dans dav1d 0.1.0 :
Je vous renvoie sur le blog d’Ewout qui effectue des tests réguliers pour l’article original, les stats complètes et les échantillons utilisés.
Reste en chantier le code assembleur concernant le sous‐échantillonnage de la chrominance (4:2:2, 4:4:4 et les profondeurs sur 10 et 12 bits sont à venir), mais aussi des améliorations plus globales sur le code C.
Utilisations
L’utilisation de dav1d en remplacement de libaom est une évidence pour les projets désirant proposer AV1 dans de bonnes conditions :
-
Firefox règle les derniers soucis d’intégration ;
-
VLC a déjà remplacé libaom par défaut dans sa branche de développement, et la prochaine version stable sur la branche 3.0 en bénéficiera aussi ;
- de manière identique, FFmpeg intégrera dav1d dans sa prochaine version stable ;
- Chromium travaille aussi à l’adoption du décodeur ;
- Handbrake.
++dav1d
Si dav1d propose bien une amélioration des performances considérable, on gardera en tête que le travail n’est pas achevé et que dans les cas non standards (4:4:4, > 8 bits…) l’absence d’optimisation assembleur ne permet rien de mieux, voire pire, que libaom. Encore beaucoup de travail en perspective donc.
AV1 est un codec complexe et innovant. Cependant, faire un décodeur rapide n’est le fait que d’optimiser « une recette » à appliquer. Un autre défi bien plus difficile à relever est celui de l’encodage. Toute la complexité d’un codec réside dans cette étape.
Parce que c’est la source de revenus dans le modèle économique d’AV1, une multitude d’encodeurs, le plus souvent propriétaires, arriveront bientôt. Reste donc à trouver une personne qui serait rav1e de parler du codeur AV1 libre écrit en Rust.