Je m'appelle Dale Curtis et je suis responsable de l'ingénierie pour la lecture multimédia dans Chromium. Mon équipe est responsable des API Web pour la lecture vidéo, comme MSE et WebCodecs, ainsi que des éléments internes spécifiques à la plate-forme impliqués dans le démultiplexage, le décodage et le rendu audio et vidéo.
Dans cet article, je vais vous présenter l'architecture de rendu vidéo de Chromium. Bien que certains détails concernant l'extensibilité soient probablement spécifiques à Chromium, la plupart des concepts et des conceptions abordés ici s'appliquent à d'autres moteurs de rendu, voire à des applications de lecture natives.
L'architecture de lecture de Chromium a beaucoup changé au fil des ans. Bien que nous n'ayons pas commencé par l'idée d'une pyramide du succès, comme décrit dans le premier article de cette série, nous avons finalement suivi des étapes similaires: fiabilité, performances, puis extensibilité.
Au début, le rendu vidéo était assez simple : une simple boucle for choisissait le logiciel qui décode les images vidéo à envoyer au compositeur. Pendant des années, cette approche a été suffisamment fiable. Toutefois, à mesure que la complexité du Web a augmenté, le besoin de plus de performances et d'efficacité a conduit à des changements d'architecture. De nombreuses améliorations nécessitaient des primitives spécifiques à l'OS. Par conséquent, notre architecture devait également devenir plus extensible pour toucher toutes les plates-formes de Chromium.
Le rendu vidéo peut être divisé en deux étapes : choisir ce que vous souhaitez diffuser et diffuser ces informations de manière efficace. Par souci de lisibilité, je vais d'abord expliquer la diffusion efficace avant d'expliquer comment Chromium choisit ce qu'il diffuse.
Quelques termes et mise en page
Comme cet article porte sur le rendu, je ne vais que brièvement évoquer les aspects de démultiplexage et de décodage du pipeline.
Le décodage et le démultiplexage dans notre monde moderne soucieux de la sécurité nécessitent une attention particulière. Les analyseurs binaires sont des environnements cibles riches, et la lecture multimédia est remplie d'analyse binaire. Par conséquent, les problèmes de sécurité dans les analyseurs multimédias sont extrêmement courants.
Chromium applique une défense en profondeur pour réduire le risque de problèmes de sécurité pour nos utilisateurs. En pratique, cela signifie que le démultiplexage et le décodage logiciel se produisent toujours dans un processus à faible privilège, tandis que le décodage matériel se produit dans un processus disposant juste d'assez de privilèges pour communiquer avec le GPU du système.
Le mécanisme de communication inter-processus de Chromium s'appelle Mojo. Bien que nous n'entrions pas dans les détails de Mojo dans cet article, en tant que couche d'abstraction entre les processus, il constitue un élément essentiel du pipeline multimédia extensible de Chromium. Il est important de garder cela à l'esprit lorsque nous parcourons le pipeline de lecture, car il informe l'orchestration complexe des composants inter-processus qui interagissent pour recevoir, démultiplexer, décoder et enfin afficher des contenus multimédias.
Tant de bits
Pour comprendre les pipelines de rendu vidéo d'aujourd'hui, vous devez savoir pourquoi la vidéo est spéciale: la bande passante. La lecture en résolution 3 840 × 2 160 (4K) à 60 images par seconde utilise entre 9 et 12 Gbit/s de bande passante de mémoire. Même si les systèmes modernes peuvent atteindre une bande passante de pointe de plusieurs centaines de gigabits par seconde, la lecture vidéo représente toujours une part importante. Sans précaution, la bande passante totale peut facilement se multiplier en raison de copies ou de déplacements entre la mémoire du GPU et celle du CPU.
L'objectif de tout moteur de lecture vidéo moderne axé sur l'efficacité est de réduire la bande passante entre le décodeur et l'étape de rendu finale. Pour cette raison, le rendu vidéo est largement dissocié du pipeline de rendu principal de Chromium. Plus précisément, du point de vue de notre pipeline de rendu principal, la vidéo n'est qu'un trou de taille fixe avec une opacité. Chromium y parvient à l'aide d'un concept appelé surfaces, où chaque vidéo communique directement avec Viz.
En raison de la popularité de l'informatique mobile, la puissance et l'efficacité sont devenues des éléments importants de la génération actuelle. Par conséquent, le décodage et le rendu sont plus couplés que jamais au niveau matériel. La vidéo ressemble donc à un trou avec une opacité, même pour le système d'exploitation lui-même. Les décodeurs au niveau de la plate-forme ne fournissent souvent que des tampons opaques que Chromium transmet au système de composition au niveau de la plate-forme sous la forme de superpositions.
Chaque plate-forme dispose de sa propre forme de superposition avec laquelle ses API de décodage de plate-forme fonctionnent de concert. Windows propose Direct Composition et Media Foundation Transforms, macOS propose CoreAnimation Layers et VideoToolbox, Android propose SurfaceView et MediaCodec, et Linux propose VASurfaces et VA-API. Les abstractions de Chromium pour ces concepts sont gérées respectivement par les interfaces OverlayProcessor et mojo::VideoDecoder.
Dans certains cas, il est possible que ces tampons soient mappés dans la mémoire système. Ils n'ont donc pas besoin d'être opaques et ne consomment aucune bande passante tant qu'ils ne sont pas consultés. Chromium les appelle GpuMemoryBuffers. Sous Windows, ils sont pris en charge par des buffers DXGI, sous macOS par des IOSurfaces, sous Android par des AHardwareBuffers et sous Linux par des buffers DMA. Bien que la lecture vidéo n'ait généralement pas besoin de cet accès, ces tampons sont importants pour la capture vidéo afin de garantir une bande passante minimale entre l'appareil de capture et les éventuels encodeurs.
Étant donné que le GPU est souvent responsable à la fois du décodage et de l'affichage, l'utilisation de ces tampons opaques (souvent également) garantit que les données vidéo à bande passante élevée ne quittent jamais le GPU. Comme nous l'avons vu précédemment, conserver les données sur le GPU est extrêmement important pour l'efficacité, en particulier à des résolutions et des fréquences d'images élevées.
Plus nous pouvons tirer parti des primitives d'OS telles que les superpositions et les tampons GPU, moins la bande passante est utilisée pour mélanger inutilement des octets vidéo. En centralisant tout, du décodage au rendu, vous pouvez économiser une quantité incroyable d'énergie. Par exemple, lorsque Chromium a activé les superpositions sur macOS, la consommation d'énergie lors de la lecture vidéo en plein écran a été réduite de moitié. Sur d'autres plates-formes telles que Windows, Android et ChromeOS, nous pouvons utiliser des superpositions même en mode non plein écran, ce qui permet d'économiser jusqu'à 50% presque partout.
Affichage
Maintenant que nous avons vu les mécanismes de diffusion optimaux, nous pouvons voir comment Chromium choisit ce qu'il doit diffuser. La pile de lecture de Chromium utilise une architecture basée sur le "pull ", ce qui signifie que chaque composant de la pile demande ses entrées à celui situé en dessous de lui dans l'ordre hiérarchique. En haut de la pile se trouve le rendu des images audio et vidéo, suivi du décodage, du démultiplexage et enfin des E/S. Chaque frame audio affiché fait avancer une horloge qui permet de choisir les frames vidéo à afficher lorsqu'elle est combinée à un intervalle de présentation.
À chaque intervalle de présentation (à chaque actualisation de l'écran), le moteur de rendu vidéo est invité à fournir un frame vidéo par un CompositorFrameSink associé au SurfaceLayer mentionné précédemment. Pour les contenus dont la fréquence d'images est inférieure à la fréquence d'affichage, cela signifie que la même image est affichée plusieurs fois. Si la fréquence d'images est supérieure à la fréquence d'affichage, certaines images ne sont jamais affichées.
La synchronisation de l'audio et de la vidéo de manière agréable pour les spectateurs est bien plus complexe. Consultez Project Butter pour en savoir plus sur la fluidité optimale des vidéos dans Chromium. Il explique comment le rendu vidéo peut être décomposé en séquences idéales représentant le nombre de fois où chaque frame doit être affiché. Par exemple: "1 frame every display interval ([1], 60 fps in 60 Hz)", "1 frame every 2 intervals ([2], 30 fps in 60 Hz)" ou des modèles plus complexes comme [2:3:2:3:2] (25 FPS en 60 Hz) couvrant plusieurs images et intervalles d'affichage distincts. Plus un moteur de rendu vidéo se rapproche de ce modèle idéal, plus l'utilisateur a de chances de percevoir la lecture comme fluide.
Bien que la plupart des plates-formes Chromium génèrent des images par frame, ce n'est pas toujours le cas. Notre architecture extensible permet également le rendu par lot. Le rendu par lot est une technique d'efficacité qui consiste à informer le compositeur au niveau de l'OS de plusieurs images à l'avance et à gérer leur publication selon un calendrier temporel fourni par l'application.
L'avenir est maintenant ?
Nous nous sommes concentrés sur la façon dont Chromium exploite les primitives de l'OS pour offrir une expérience de lecture de premier ordre. Mais que faire des sites Web qui souhaitent aller au-delà de la lecture vidéo de base ? Pouvons-nous leur offrir les mêmes primitives puissantes que Chromium lui-même utilise pour lancer la prochaine génération de contenus Web ?
Nous pensons que la réponse est oui. L'extensibilité est au cœur de notre réflexion sur la plate-forme Web de nos jours. Nous avons collaboré avec d'autres navigateurs et développeurs pour créer de nouvelles technologies telles que WebGPU et WebCodecs afin que les développeurs Web puissent utiliser les mêmes primitives que Chromium lorsqu'ils communiquent avec l'OS. WebGPU est compatible avec les buffers GPU, et WebCodecs fournit des primitives de décodage et d'encodage de plate-forme compatibles avec les systèmes de superposition et de tampon GPU mentionnés ci-dessus.
Fin de la diffusion
Merci de votre attention, J'espère que vous avez mieux compris les systèmes de lecture modernes et comment Chromium alimente plusieurs centaines de millions d'heures de visionnage chaque jour. Pour en savoir plus sur les codecs et la vidéo Web moderne, je vous recommande de lire H.264 is magic (H.264 est magique) de Sid Bala, How Modern Video Players Work (Comment fonctionnent les lecteurs vidéo modernes) d'Erica Beaves et Packaging award-winning shows with award-winning technology (Packaging award-winning shows with award-winning technology) de Cyril Concolato.
Une illustration (la jolie !) par Una Kravets.