FFmpeg es verdaderamente una herramienta múltiple para el procesamiento de medios. Como herramienta estándar de la industria, admite una amplia gama de códecs y formatos de contenedores de audio y video. También puede orquestar cadenas complejas de filtros para la edición y manipulación de medios. Para las personas que usan nuestras aplicaciones, FFmpeg juega un papel importante al permitir nuevas experiencias de video y mejorar la confiabilidad de las existentes.
meta realiza ffmpeg (la aplicación CLI principal) y sonda ff (una herramienta para obtener propiedades de archivos multimedia) binarios decenas de miles de millones de veces al día, lo que presenta desafíos únicos al manejar archivos multimedia. FFmpeg puede realizar fácilmente la transcodificación y edición de archivos individuales, pero nuestros flujos de trabajo tienen requisitos adicionales para satisfacer nuestras necesidades. Durante muchos años, tuvimos que confiar en nuestra propia bifurcación de FFmpeg desarrollada internamente para proporcionar funciones que se han agregado recientemente a FFmpeg, como codificación de subprocesos de múltiples carriles y cálculo de métricas de calidad en tiempo real.
Con el tiempo, nuestra bifurcación interna llegó a diferir significativamente de la versión anterior de FFmpeg. Al mismo tiempo, las nuevas versiones de FFmpeg brindaron soporte para nuevos códecs y formatos de archivos y mejoras en la confiabilidad, todo lo cual nos permitió incorporar contenido de video más diverso de los usuarios sin interrupciones. Esto requirió que admitiéramos las dos versiones recientes de código abierto de FFmpeg junto con nuestra bifurcación interna. Esto no solo creó un conjunto de características gradualmente divergentes, sino que también creó desafíos en torno a cambiar de forma segura nuestros cambios internos para evitar la regresión.
A medida que nuestra bifurcación interna se volvió cada vez más obsoleta, colaboramos con los desarrolladores de FFmpeg, FFlabs y VideoLAN, para desarrollar funciones en FFmpeg que nos permitieron desaprobar por completo nuestra bifurcación interna y confiar únicamente en la versión ascendente para nuestros casos de uso. Utilizando parches y refactorizaciones ascendentes, hemos podido llenar dos vacíos clave que anteriormente confiábamos en nuestra bifurcación interna para llenar: subprocesos, transcodificación multipista y métricas de calidad en tiempo real.
Creación de una transcodificación de varios carriles más eficiente para VOD y transmisión en vivo

Cuando un usuario carga un video a través de una de nuestras aplicaciones, generamos un conjunto de codificaciones para admitir la reproducción de transmisión dinámica adaptativa a través de HTTP (DASH). La reproducción DASH permite que el reproductor de video de la aplicación seleccione dinámicamente una codificación basada en señales como las condiciones de la red. Estas codificaciones pueden variar en resolución, códec, velocidad de fotogramas y nivel de calidad visual, pero se crean a partir de la misma codificación fuente y el reproductor puede cambiar sin problemas entre ellas en tiempo real.
En un sistema muy simple, líneas de comando FFmpeg separadas pueden generar las codificaciones para cada carril una por una en serie. Esto podría optimizarse ejecutando cada comando en paralelo, pero rápidamente se vuelve ineficiente debido al trabajo duplicado realizado por cada proceso.
Para solucionar este problema, se podrían generar múltiples salidas dentro de una única línea de comando FFmpeg, decodificando cuadros de un video una vez y enviándolos a la instancia del codificador de cada salida. Esto elimina una gran cantidad de gastos generales al deduplicar la decodificación de video y el tiempo de inicio del proceso en el que incurre cada línea de comando. Dado que procesamos más de mil millones de cargas de videos diariamente, cada una de las cuales requiere múltiples ejecuciones de FFmpeg, las reducciones en el procesamiento de datos por proceso aumentan significativamente la eficiencia.
Nuestra bifurcación interna de FFmpeg proporcionó una optimización adicional para esto: codificación de video paralelizada. Si bien los codificadores de video individuales a menudo tienen múltiples subprocesos internamente, las versiones anteriores de FFmpeg ejecutaban cada codificador en serie para un cuadro determinado cuando se usaban varios codificadores. Al ejecutar todas las instancias del codificador en paralelo, generalmente se puede lograr un mejor paralelismo.
Gracias a las contribuciones de los desarrolladores de FFmpeg, incluidos los de FFlabs y VideoLAN, se implementaron subprocesos más eficientes a partir de FFmpeg 6.0, con la guinda del pastel en 8.0. Esto estuvo directamente influenciado por el diseño de nuestra horquilla interna y fue una de las características más importantes en las que confiamos. Este desarrollo llevó a La refactorización más compleja de FFmpeg en décadas. y ha permitido codificaciones más eficientes para todos los usuarios de FFmpeg.
Para migrar completamente desde nuestra bifurcación interna, necesitábamos una característica más implementada en sentido ascendente: métricas de calidad en tiempo real.
Habilitación de mediciones de calidad en tiempo real durante la transcodificación de transmisiones en vivo

Las métricas de calidad visual, que proporcionan una representación numérica de la calidad visual percibida de los medios, se pueden utilizar para cuantificar la pérdida de calidad causada por la compresión. Estas métricas se clasifican como métricas de referencia o sin referencia, y las primeras comparan una referencia codificando a otro distorsionado codificación.
FFmpeg puede calcular varias métricas de calidad visual, como PSNR, SSIM y VMAF, utilizando dos codificaciones existentes en una línea de comando separada una vez completada la codificación. Esto está bien para uso sin conexión o VOD, pero no para transmisión en vivo, donde es posible que deseemos calcular métricas de calidad en tiempo real.
Para hacer esto, necesitamos insertar un decodificador de video después de cada codificador de video utilizado por cada carril de salida. Estos proporcionan mapas de bits para cada fotograma del vídeo. después Se ha aplicado compresión para que podamos comparar con el marco. antes compresión. En última instancia, podemos producir una métrica de calidad para cada carril codificado en tiempo real utilizando una única línea de comando FFmpeg.
Gracias a la decodificación «en bucle», que fue habilitada por los desarrolladores de FFmpeg, incluidos los de FFlabs y VideoLAN, a partir de FFmpeg 7.0, ya no necesitamos depender de nuestra bifurcación interna de FFmpeg para esta función.
Estamos aguas arriba cuando tendrá el mayor impacto en la comunidad.
Cosas como métricas de calidad en tiempo real, mientras que la transcodificación y los subprocesos más eficientes pueden generar ganancias de eficiencia para una serie de canalizaciones basadas en FFmpeg tanto dentro como fuera de Meta, y nos esforzamos por permitir estos desarrollos en sentido ascendente para el beneficio de la comunidad FFmpeg y la industria en general. Sin embargo, hay algunos parches que hemos desarrollado internamente y no tiene sentido contribuir en forma previa. Estos son muy específicos de nuestra infraestructura y no se generalizan bien.
FFmpeg admite decodificación, codificación y filtrado acelerados por hardware con dispositivos como NVDEC y NVENC de NVIDIA, Unified Video Decoder (UVD) de AMD y Quick Sync Video (QSV) de Intel. Cada dispositivo es compatible a través de una implementación de API estándar en FFmpeg, lo que permite una integración más sencilla y minimiza la necesidad de indicadores de línea de comandos específicos del dispositivo. Hemos agregado soporte para Metaprocesador de vídeo escalable (MSVP)nuestro ASIC personalizado para transcodificación de video, a través de las mismas API, lo que permite el uso de herramientas comunes en diferentes plataformas de hardware con idiosincrasias mínimas específicas de la plataforma.
Dado que MSVP solo se usa dentro de la propia infraestructura de Meta, crearía un desafío para los desarrolladores de FFmpeg admitirlo sin acceso al hardware para pruebas y validación. En este caso, tiene sentido mantener parches como este internamente, ya que no proporcionarían beneficios externos. Nos hemos encargado de cambiar la base de nuestros parches internos a versiones más nuevas de FFmpeg a lo largo del tiempo, utilizando una validación exhaustiva para garantizar la solidez y la corrección durante las actualizaciones.
Nuestro compromiso continuo con FFmpeg
Con una codificación de múltiples carriles más eficiente y métricas de calidad en tiempo real, pudimos eliminar por completo nuestra bifurcación FFmpeg interna para todos los canales de VOD y transmisión en vivo. Y gracias a las API de hardware estandarizadas en FFmpeg, hemos podido admitir nuestro MSVP ASIC junto con canalizaciones basadas en software con una fricción mínima.
FFmpeg ha resistido la prueba del tiempo con más de 25 años de desarrollo activo. Los desarrollos que mejoran la utilización de recursos, agregan soporte para nuevos códecs y funciones y aumentan la confiabilidad permiten un soporte sólido para una gama más amplia de medios. Para las personas en nuestras plataformas, eso significa permitir nuevas experiencias y mejorar la confiabilidad de las existentes. Planeamos continuar invirtiendo en FFmpeg en asociación con desarrolladores de código abierto, brindando beneficios a Meta, a la industria en general y a las personas que utilizan nuestros productos.
Reconocimientos
Nos gustaría reconocer las contribuciones de la comunidad de código abierto, nuestros socios en FFlabs y VideoLAN, y muchos ingenieros de Meta, incluidos Max Bykov, Jordi Cenzano Ferret, Tim Harris, Colleen Henry, Mark Shwartzman, Haixia Shi, Cosmin Stejerean, Hassene Tmar y Victor Loh.

