dav1d is An AV1 Decoder

46
11
mar.
2019
Audiovisuel

dav1d est une implémentation de décodeur d’AV1 destinée à un usage réel, en dehors du cadre du décodeur de référence libaom ; et un acronyme récursif. Destiné à être multi‑plate‑forme et open source, sa devise est « petit et rapide ». Ce projet est chapeauté par VideoLAN à l’instar des x264 et x265, pour les codecs H.264 et HEVC. Ce projet est financé partiellement par l’Alliance for Open Media (AOM).

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.

Phases de déploiement de l’AV1

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 :
Single Thread

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 :
Multi Thread

Pour les optimisations niveau SSSE3 qui viennent d’être ajoutées :
SSSE3

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 :
ARM64

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.

Aller plus loin

  • # Puissance requise pour la compression ?

    Posté par  . Évalué à 3.

    Un autre défi bien plus difficile à relever est celui de l'encodage. Toute la complexité d'un codec réside dans cette étape.

    Si j’ai bonne mémoire, le fossé entre x264 et x265 était déjà important en termes de puissance requise pour compresser une vidéo, x264 étant bien plus rapide. Est-ce le même genre de fossé auquel on a affaire ?

    Sait-on déjà plus ou moins combien de temps en plus il faudra, par rapport à x265, pour compresser une même vidéo en AV1 à qualité équivalente ?

    • [^] # Re: Puissance requise pour la compression ?

      Posté par  . Évalué à 5.

      Si j’ai bonne mémoire, le fossé entre x264 et x265 était déjà important en termes de puissance requise pour compresser une vidéo, x264 étant bien plus rapide. Est-ce le même genre de fossé auquel on a affaire ?

      HEVC réutilisait et étendait une partie des principes de H264 (directions de recherche, etc..).
      AV1 évite les brevets et donc utilise beaucoup de techniques pour lesquelles les algos d'optimisation restent à trouver.

      Sait-on déjà plus ou moins combien de temps en plus il faudra, par rapport à x265, pour compresser une même vidéo en AV1 à qualité équivalente ?

      En l'état, on doit être de l'ordre de 100 à 300x le temps réel en fonction des options/bitrate avec rav1e.

      L'encodeur AOM de référence lui se situait dans des ratios qu'on ne peut pas écrire sur 16bits non signé…

      • [^] # Re: Puissance requise pour la compression ?

        Posté par  . Évalué à 2. Dernière modification le 11 mars 2019 à 19:07.

        En l'état, on doit être de l'ordre de 100 à 300x le temps réel en fonction des options/bitrate avec rav1e.

        Sur quelle gamme de processeur ?

        L'encodeur AOM de référence lui se situait dans des ratios qu'on ne peut pas écrire sur 16bits non signé…

        Effectivement ça a bien avancé mais par rapport aux autres encodeurs AV1 propriétaires qui ont évolué de leur côté ça donne quoi en terme de vitesse et de qualité d'image et de compression ?

      • [^] # Re: Puissance requise pour la compression ?

        Posté par  . Évalué à 3.

        En l'état, on doit être de l'ordre de 100 à 300x le temps réel en fonction des options/bitrate avec rav1e.

        C’est très lent… mais je découvre sur le bugtracker de Handbrake qu’en avril 2018 il fallait plus d’un an pour encoder un film en HD (“Given the published numbers though, it sounds like encoding a feature length HD movie would take about 9000 hours (aka 1 year).”) D’après Facebook, le temps d’encodage était 5000 à 10000 fois plus lent que le x264…

        Ces chiffres sont énormes. On part vraiment de loin…

        • [^] # Re: Puissance requise pour la compression ?

          Posté par  (site web personnel) . Évalué à 9.

          C'est lent car AV1 propose beaucoup plus de choix pour chaque partie de l'encodage : le découpage en blocs (partitionnement), la taille des transformées, le type des transformées, les directions de prédiction intra, les prédictions "composées" inter-intra, la prédiction chroma-from-luma, etc.

          Tout tester pour avoir le meilleur encodage possible prend beaucoup de temps, mais en théorie il est toujours possible de ne garder qu'un sous-ensemble de toutes les possibilités pour aller plus vite.

          Je vous conseille cette conférence de Luc Trudeau : AV1 temps réel.

          Désolé, elle n'est postée que là, donc :

          youtube-dl -fbest https://www.facebook.com/SMPTEMTL/videos/253682505311403/
          

          blog.rom1v.com

        • [^] # Re: Puissance requise pour la compression ?

          Posté par  . Évalué à 2.

          Tu devrais regarder les chiffres des premiers encodeurs H264 et HEVC.

  • # Benchmark pour Rav1e

    Posté par  . Évalué à 4.

    Y a-t-il des comparatifs de performance entre libaom, dav1d et rav1e ?

    Je ne connaissais pas (encore) ce dernier, mais en tant qu'utilisateur, un petit graphique serait plaisant pour les yeux :)

    • [^] # Re: Benchmark pour Rav1e

      Posté par  . Évalué à 2. Dernière modification le 12 mars 2019 à 11:11.

      libaom contient un encodeur et un décodeur AV1.
      dav1d est seulement un décodeur AV1.
      rav1e est seulement un encodeur AV1.

      Si tu souhaites comparer les performances en terme de débit distorsion de rav1e par rapport à libaom ou à des encodeurs d'autres codec, il y a par exemple ce post:
      https://forum.doom9.org/showthread.php?p=1864882#post1864882
      Plus la courbe de débit distorsion est en haut à gauche, mieux c'est.

    • [^] # Re: Benchmark pour Rav1e

      Posté par  . Évalué à 3.

      rav1e est aussi sur https://arewecompressedyet.com/?

      • [^] # Re: Benchmark pour Rav1e

        Posté par  (site web personnel) . Évalué à 4.

        Ça a l'air intéressant mais il manque un "about". Ça sert à quoi ?

        • [^] # Re: Benchmark pour Rav1e

          Posté par  . Évalué à 7.

          C'est plutôt un outil de développement d'encodeurs vidéo. Il permet principalement de tracer rapidement des courbes de débit distorsion et de débit temps de compression.

          Le principe est que l'on peut lancer des runs en indiquant des hashs de commits et ensuite comparer leurs résultats pour savoir, par exemple, si une modification d'un encodeur est bénéfique ou non. Il est aussi possible de comparer différents encodeurs entre eux.

          Il faut cependant s'identifier et avoir une clef pour l'utiliser car ça peut potentiellement consommer beaucoup de ressources de calcul.
          L'utilisation typique est de lancer l'encodage de 30 séquences d'une seconde en 4 qualités différentes. Mais pour avoir le résultat en 30 minutes à moins de 0.1 FPS avec rav1e, il faut un certain nombre de CPUs…

  • # return -ENOMEM;

    Posté par  (site web personnel) . Évalué à 7. Dernière modification le 12 mars 2019 à 02:42.

    Oh non, pitié, pas eux aussi :-(

    Sérieux, je sais bien que c'est soit-disant autorisé par POSIX (sauf qu'ils ont mis à du temps à changer d'avis) et ANSI C, mais c'est moche, sujet à l'erreur, et ça casse la compilation sous Haiku :-(((

    Ben oué, sous BeOS et donc Haiku, les codes d'erreurs sont négatifs. Et ça marche très bien d'habitude, sauf quand des petits malins se disent "tiens, on va prendre un raccourcis". Bizarrement dans les BSD ça ne se fait pas, y a sûrement une raison. Il semble que ce soit une mauvaise habitude depuis Linux… et surtout dans le code pondu par Fabrice Bellard (QEMU & FFMPEG, ce dernier ayant inclus des macros pour corriger les codes sous Haiku) :)

    Du coup je vais bien m'amuser à corriger ce bazar pour que ça tourne un jour sous Haiku… S'ils acceptent le patch, parce qu'il y a toujours des gens pour râler que c'est pas POSIX (en général, ce sont les mêmes qui font des appels Linux dans leur code sans aucun test alors que c'est pas POSIX non plus, mais bon, Linux quoi).

    Donc oui c'est ptet autorisé, mais faut pas faire ça. Et oui ça crée des erreurs, j'en ai trouvé en portant OpenSound, des - qui manquaient, ou en trop (assignation à errno avec un -). Donc par pitié quand vous codez, évitez ça !

    • [^] # ?

      Posté par  (site web personnel) . Évalué à 7.

      Je ne comprends pas. Tu code un OS sur lequel la convention est d'utiliser des nombres négatifs et tu demandes que les autres personnes ne fasse pas ça ? :)

      Adhérer à l'April, ça vous tente ?

      • [^] # Re: ?

        Posté par  . Évalué à 2.

        Ca dépend. read et autre c'est un seul nombre négatif (-1) en cas d'erreur et de set errno à coté.

        • [^] # Re: ?

          Posté par  (site web personnel) . Évalué à 3.

          C'est surtout que d'un côté on manipule juste les symboles préprocesseur, de l'autre on ajoute des - partout à la main, et comme je l'ai dit, on en oublie.

    • [^] # Re: return -ENOMEM;

      Posté par  . Évalué à 3. Dernière modification le 14 mars 2019 à 01:28.

      En fait en lisant ton message je n'ai pas compris ce que tu estimais devoir être utilisé?
      - return -ENOMEM; et errno = -ENOMEM;
      - return ENOMEM; et errno = ENOMEM;
      - return -ENOMEM; et errno = ENOMEM;

  • # SSE3

    Posté par  (site web personnel) . Évalué à 0.

    Juste une petite remarque: il n'y a que deux « S » à « SSE3 »

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.