FFmpeg ist wirklich ein Multitool für die Medienverarbeitung. Als branchenübliches Werkzeug, Es unterstützt eine Vielzahl von Audio- und Video-Codecs und Containerformaten. Es kann auch komplexe Filterketten für die Medienbearbeitung und -manipulation orchestrieren. Für Nutzer unserer Apps, FFmpeg spielt eine wichtige Rolle bei der Ermöglichung neuer Videoerlebnisse und der Verbesserung der Zuverlässigkeit bestehender.

Meta läuft ffmpeg (die Haupt-CLI-Anwendung) Und ffprobe (ein Dienstprogramm zum Abrufen von Mediendateieigenschaften) Binärdateien zig Milliarden Mal am Tag, Dies stellt besondere Herausforderungen beim Umgang mit Mediendateien dar. FFmpeg kann problemlos mit der Transkodierung und Bearbeitung einzelner Dateien umgehen, aber unsere Arbeitsabläufe stellen zusätzliche Anforderungen, um unsere Bedürfnisse zu erfüllen. Viele Jahre lang waren wir auf uns selbst angewiesen, intern entwickelter Zweig von FFmpeg, um Funktionen bereitzustellen, die kürzlich zu FFmpeg hinzugefügt wurden, wie zum Beispiel: B. Threaded Multi-Lane-Codierung und Qualitätsmetrikberechnung in Echtzeit.

Im Laufe der Zeit, Unser interner Fork weicht erheblich von der Upstream-Version von FFmpeg ab. Gleichzeitig, Neue Versionen von FFmpeg brachten Unterstützung für neue Codecs und Dateiformate sowie Verbesserungen der Zuverlässigkeit, Dadurch können wir vielfältigere Videoinhalte von Benutzern ohne Unterbrechungen erfassen. Dies erforderte, dass wir zusätzlich zu unserem internen Fork beide aktuellen Open-Source-Versionen von FFmpeg unterstützen. Dies führte nicht nur zu einem allmählich divergierenden Funktionsumfang, aber auch Herausforderungen bei der sicheren Neubasierung unserer internen Änderungen, um Rückschritte zu vermeiden.

Da unser interner Fork immer veralteter wurde, Wir haben mit FFmpeg-Entwicklern zusammengearbeitet, FFlabs, und VideoLAN, um Funktionen in FFmpeg zu entwickeln, die es uns ermöglichten, unseren internen Fork vollständig zu eliminieren und uns für unsere Anwendungsfälle ausschließlich auf die Upstream-Version zu verlassen. Verwendung von Upstream-Patches und Refactorings, Wir konnten zwei wichtige Lücken schließen, die wir zuvor auf unserem internen Fork beheben mussten: mit Gewinde, Mehrspur-Transkodierung, und Echtzeit-Qualitätsmetriken.

Aufbau einer effizienteren Mehrspur-Transkodierung für VOD und Live-Streaming

Bild[1]-FFmpeg bei Meta: Medienverarbeitung im Maßstab für Windows 7,8,10,11-Winpcsoft.com
Eine Videotranskodierungspipeline, die mehrere Ausgaben mit unterschiedlichen Auflösungen erzeugt.

Wenn ein Benutzer ein Video über eine unserer Apps hochlädt, Wir generieren eine Reihe von Codierungen, um dynamisches adaptives Streaming über HTTP zu unterstützen (BINDESTRICH) Wiedergabe. Die DASH-Wiedergabe ermöglicht es dem Videoplayer der App, dynamisch eine Kodierung basierend auf Signalen wie Netzwerkbedingungen auszuwählen. Diese Kodierungen können sich in der Auflösung unterscheiden, Codec, Bildrate und visuelle Qualität, Sie werden jedoch aus derselben Quellkodierung erstellt und der Player kann nahtlos in Echtzeit zwischen ihnen wechseln.

In einem sehr einfachen System, Separate FFmpeg-Befehlszeilen können die Codierungen für jeden Track einzeln generieren. Dies könnte durch die parallele Ausführung jeder Anweisung optimiert werden, Dies wird jedoch aufgrund der doppelten Arbeit, die von jedem Prozess ausgeführt wird, schnell ineffizient.

Um das zu umgehen, Mehrere Ausgaben könnten innerhalb einer einzigen FFmpeg-Befehlszeile generiert werden, Dabei werden die Frames eines Videos einmal dekodiert und an die Encoder-Instanz jedes Ausgangs gesendet. Dadurch entfällt ein großer Teil des Videodekodierungs-Deduplizierungsaufwands und der Prozessstartzeit, die durch jede Befehlszeile verursacht werden. Vorausgesetzt, wir verarbeiten über 1 Milliarden Video-Uploads täglich, jeweils erfordern mehrere FFmpeg-Ausführungen, Reduzierungen der Rechennutzung pro Prozess führen zu erheblichen Effizienzsteigerungen.

Unser interner FFmpeg-Fork sorgte für zusätzliche Optimierung: parallelisierte Videokodierung. Während einzelne Video-Encoder häufig intern über Multithreading verfügen, Frühere Versionen von FFmpeg führten jeden Encoder seriell für einen bestimmten Frame aus, wenn mehrere Encoder verwendet wurden. Durch den parallelen Betrieb aller Encoder-Instanzen, insgesamt kann eine bessere Parallelität erreicht werden.

Dank der Beiträge von FFmpeg-Entwicklern, einschließlich derer bei FFlabs und VideoLAN, Ab FFmpeg wurde ein effizienteres Threading implementiert 6.0, mit dem letzten Schliff 8.0. Dies wurde direkt durch das Design unserer internen Gabel beeinflusst und war eines der Hauptmerkmale, auf die wir uns verlassen haben. Diese Entwicklung hat dazu geführt Das komplexeste Refactoring von FFmpeg seit Jahrzehnten und hat effizientere Kodierungen für alle FFmpeg-Benutzer ermöglicht.

Um vollständig von unserem internen Fork zu migrieren, Wir brauchten eine weitere vorimplementierte Funktion: Qualitätsmetriken in Echtzeit.

Ermöglicht Echtzeit-Qualitätsmetriken beim Transkodieren für Live-Streams

Bild[2]-FFmpeg bei Meta: Medienverarbeitung im Maßstab für Windows 7,8,10,11-Winpcsoft.com

Visuelle Qualitätsmetriken, die eine numerische Darstellung der wahrgenommenen visuellen Qualität von Medien liefern, kann verwendet werden, um den durch die Komprimierung verursachten Qualitätsverlust zu quantifizieren. Diese Metriken werden in Referenz- und Nicht-Referenzmetriken kategorisiert, ersteres vergleicht a Referenz Codierung zu einem anderen verzerrt Codierung.

FFmpeg kann verschiedene visuelle Qualitätsmetriken wie PSNR berechnen, SSIM und VMAF verwenden zwei vorhandene Kodierungen in einer separaten Befehlszeile, nachdem die Kodierung abgeschlossen ist. Dies ist für Offline- oder VOD-Anwendungsfälle in Ordnung, aber nicht für Live-Streaming, wo wir möglicherweise Qualitätsmetriken in Echtzeit berechnen möchten.

Dazu müssen wir nach jedem Video-Encoder, der von jeder Ausgabespur verwendet wird, einen Video-Decoder einfügen. Diese stellen Bitmaps für jedes Bild im Video bereit nach Damit wir die Frames vergleichen können, wurde eine Komprimierung angewendet vor Kompression. Am Ende, Mit einer einzigen FFmpeg-Befehlszeile können wir in Echtzeit eine Qualitätsmetrik für jeden codierten Track erstellen.

Dank der von FFmpeg-Entwicklern ermöglichten „In-Loop“-Dekodierung, einschließlich derer bei FFlabs und VideoLAN, Beginnend mit FFmpeg 7.0, Für diese Funktion müssen wir uns nicht mehr auf unseren internen FFmpeg-Fork verlassen.

Wir upstreamen, wenn es den größten Einfluss auf die Community hat

Dinge wie Echtzeit-Qualitätsmetriken beim Transkodieren und effizienteres Threading können die Effizienz einer Vielzahl von FFmpeg-basierten Pipelines sowohl innerhalb als auch außerhalb von Meta steigern, und wir sind bestrebt, diese Entwicklungen im Vorfeld zu ermöglichen, um der FFmpeg-Community und der Branche insgesamt zu helfen. Jedoch, Es gibt einige Patches, die wir intern entwickelt haben und deren Beitrag im Vorfeld keinen Sinn macht. Diese sind sehr spezifisch für unsere Infrastruktur und lassen sich nicht gut verallgemeinern.

FFmpeg unterstützt hardwarebeschleunigte Dekodierung, Kodierung und Filterung mit Geräten wie NVIDIAs NVDEC und NVENC, AMDs Unified Video Decoder (UVD), und Intels Quick Sync Video (QSV). Jedes Gerät wird durch eine Implementierung von Standard-APIs in FFmpeg unterstützt, Dies ermöglicht eine einfachere Integration und minimiert den Bedarf an gerätespezifischen Befehlszeilen-Flags. Wir haben Unterstützung für hinzugefügt Metaskalierbarer Videoprozessor (MSVP)unser maßgeschneiderter ASIC für die Videotranskodierung, über die gleichen APIs und ermöglicht den Einsatz gemeinsamer Tools auf unterschiedlichen Hardwareplattformen mit minimalen plattformspezifischen Besonderheiten.

Da MSVP nur innerhalb der Meta-eigenen Infrastruktur verwendet wird, Für FFmpeg-Entwickler wäre es eine Herausforderung, es ohne Zugriff auf die Hardware zum Testen und Validieren zu unterstützen. In diesem Fall, Es ist sinnvoll, solche Patches intern zu belassen, da sie äußerlich keinen Nutzen hätten. Wir haben die Verantwortung übernommen, unsere internen Patches im Laufe der Zeit auf neuere FFmpeg-Versionen umzustellen, Durchführung einer umfassenden Validierung, um Robustheit und Korrektheit während Upgrades sicherzustellen.

Unser anhaltendes Engagement für FFmpeg

Dank effizienterer Multi-Lane-Kodierung und Echtzeit-Qualitätsmetriken, Wir konnten unseren internen FFmpeg-Fork für alle VOD- und Live-Streaming-Pipelines vollständig eliminieren. Und dank standardisierter Hardware-APIs in FFmpeg, Wir konnten unseren MSVP-ASIC neben softwarebasierten Pipelines mit minimaler Reibung unterstützen.

FFmpeg hat den Test der Zeit mit überstanden 25 Jahre aktiver Entwicklung. Entwicklungen, die die Ressourcennutzung verbessern, Unterstützung für neue Codecs und Funktionen hinzufügen, und höhere Zuverlässigkeit ermöglichen eine robuste Unterstützung einer breiteren Palette von Medien. Für Menschen auf unseren Plattformen, Das bedeutet, neue Erfahrungen zu ermöglichen und die Zuverlässigkeit bestehender Erfahrungen zu verbessern. Wir planen, in Zusammenarbeit mit Open-Source-Entwicklern weiterhin in FFmpeg zu investieren, Meta Vorteile bringen, die gesamte Branche, und die Menschen, die unsere Produkte verwenden.

Danksagungen

Wir möchten die Beiträge der Open-Source-Community würdigen, unsere Partner in FFlabs und VideoLAN, und viele Meta-Ingenieure, darunter Max Bykov, Jordi Cenzano Frettchen, Tim Harris, Colleen Henry, Mark Shwartzman, Haixia Shi, Cosmin Stejerean, Hassene Tmar, und Victor Loh.