Hemos desarrollado una aplicación para transcodificar archivos .mov de origen en .ogg, .mp4 y .webm. Actualmente se ejecuta en la instancia g2.8xlarge de AWS EC2. Está funcionando (¡yay!).

Mi pregunta: aunque estoy pasando -threads 0 al comando ffmpeg (en realidad, establezco ffmpeg.threads configuración en php-ffmpeg ), el proceso en ejecución a veces solo se ejecuta en un único núcleo. ¿Por qué está pasando esto? Vea a continuación el resultado del htop comando:

resultado htop

Como puede ver , Core # 21 está al máximo. En unos segundos, cambiará a otro, en lugar de maximizar todos ellos como me gustaría y acelerar enormemente mi proceso de codificación. La situación es transitoria; durante algunas ejecuciones, todos los procesadores están al máximo, pero durante otros no lo están y solo usamos un procesador. Un colega mencionó que quizás el códec que estamos usando para algunos de los formatos no admite la ejecución de múltiples subprocesos durante la codificación, aunque todavía no puedo verificar que ese sea el comportamiento que estoy observando.

¿Es este el caso? Si es así, ¿qué códecs para los formatos anteriores nos permitirán transcodificar en estos formatos de destino mientras aprovechamos ¿Todo nuestro hardware disponible? Los códecs predeterminados establecidos para php-ffmpeg se encuentran a continuación;

 Video Audio Ogg libtheora libvorbis WebM libvpx libvorbis X264 libx264 libfaac 

Actualización

Mirando los procesos en ejecución, a continuación se muestra lo que termina siendo el comando ffmpeg que se ejecuta para un MP4 (actualmente saturando los 32 núcleos):

En realidad no estoy construyendo este comando directamente, php-ffmpeg sí, aunque creo que tengo al menos una modesta cantidad de control sobre lo que va en él (por ejemplo, no tengo idea de por qué hay varias -metadata:s:v:0 entradas al principio)

Comentarios

  • Hay ‘ una gran cantidad de factor yuck en esa línea de comando, aparte de las opciones duplicadas (-s tres veces , el final con un tamaño diferente). Establecer explícitamente un grupo de argumentos a sus valores predeterminados actuales (p. Ej., -i_qfactor, -subq, -qcomp) es extraño y podría dar malos resultados en el futuro con libx264. (Probablemente no, pero solo porque libx264 está bastante terminado, y es estable, no está en desarrollo. Si hiciera cosas como esta para x265, sería malo). De todos modos, 2-pass 1200k está bien, pero quizás prefieras el target -calidad crf. No ‘ ni especifica un -preset. 🙁
  • libfaac no es ‘ t tan bueno como libfdk_aac Sin embargo, si ‘ está usando esto en un servicio de pago, ‘ debe verificar la licencia de libfdk_aac. Además, esta línea de cmd no tiene -movflags +faststart
  • También es ‘ s posible que ffmpeg produzca múltiples salidas de la misma entrada. Solo tienes varias secuencias de opciones de salida nombre de archivo de salida en la línea de comandos. Así que, en general, ‘ no estoy muy impresionado con php-ffmpeg, si es que ‘ es el tipo de cmdline que se le ocurre. Tal vez puedas usarlo de manera diferente para que genere múltiples salidas a la vez, por lo que no habrá ‘ t ser un paso de theora de un solo subproceso. De todos modos, si funciona, entonces genial, pero ten cuidado con los cambios en los valores predeterminados del codificador y con el significado de los niveles x264 subme que cambian, de manera que yo y tu cmdline daña la calidad.
  • @Peter muchas gracias. Creo que la respuesta aquí realmente es que necesito depurar cómo se está construyendo ese cmd. Si realmente puedo introducir múltiples salidas en ese comando, creo que probablemente me daría la mejor oportunidad de maximizar la carga en el hardware
  • trac.ffmpeg .org / wiki / Creando% 20múltiples% 20salidas . Y sí, estoy de acuerdo en que ‘ probablemente sea lo mejor. De lo contrario, tiene una tarea que ‘ es de un solo subproceso durante parte de su tiempo, y carga todos sus núcleos durante otra parte del tiempo. Es difícil programar trabajos que se comporten de esa manera.

Respuesta

Por cierto, esta pregunta podría ser mejor en stackoverflow, o tal vez unix.stackexchange, o tal vez serverfault. Creo que este sitio está menos enfocado en preguntas que no involucran decisiones basadas en méritos creativos o al menos en la calidad de audio / video perceptual. Sin embargo, me preocupan los detalles técnicos, así que responderé.

FFmpeg usa multi-threading de forma predeterminada, por lo que probablemente no necesita -threads 0. Si su codificación tiene un cuello de botella en un decodificador o filtro de un solo subproceso, verá carga completa en un núcleo y carga ligera en muchos otros núcleos.

Una cosa que puede hacer es verificar mediainfo de su video de salida. x264 deja su configuración en una cadena ASCII en el encabezado h.264. Entonces, strings -n20 o mediainfo para obtener:

... Chroma subsampling : 4:2:0 Bit depth : 8 bits Scan type : Progressive Bits/(Pixel*Frame) : 0.051 Stream size : 455 MiB (89%) Writing library : x264 core 146 r2538+1 d48ec67 Encoding settings : cabac=1 / ref=6 / deblock=1:0:0 / analyse=0x3:0x133 / me=umh / subme=10 / psy=1 / psy_rd=0.70:0.10 / mixed_ref=1 / me_range=24 / chroma_me=1 / trellis=2 / 8x8dct=1 / cqm=0 / deadzone=21,11 / fast_pskip=1 / chroma_qp_offset=-3 / threads=4 / lookahead_threads=1 / sliced_threads=0 / nr=50 / decimate=1 / interlaced=0 / bluray_compat=0 / constrained_intra=0 / bframes=5 / b_pyramid=2 / b_adapt=2 / b_bias=0 / direct=3 / weightb=1 / open_gop=0 / weightp=2 / keyint=250 / keyint_min=25 / scenecut=40 / intra_refresh=0 / rc_lookahead=60 / rc=crf / mbtree=1 / crf=22.5 / qcomp=0.60 / qpmin=0 / qpmax=69 / qpstep=4 / ip_ratio=1.40 / aq=3:0.60 Color primaries : BT.709 Transfer characteristics : BT.709 Matrix coefficients : BT.709 

Nota los «hilos = 4» allí. Creo que lo configuré manualmente en mi i5 2500k de cuatro núcleos, en lugar de permitir que x264 use las CPU predeterminadas * 1.5, ya que tenía filtros de uso intensivo de CPU (hqdn3d y lanczos-downscale) en ejecución.

De todos modos, libx264 con un ajuste preestablecido como slower no debería tener ningún problemas para mantener ocupados muchos núcleos. Hay algunas partes de la codificación que son inherentemente seriales (p. Ej., La codificación CABAC del flujo de bits final), por lo que un video de alta tasa de bits que no gasta mucho tiempo de CPU refinando referencias (alto subme) a varios marcos (alto ref) puede mostrar un patrón de carga como el suyo (un hilo usa el 100% de la CPU, otros no).

I «No estoy 100% seguro de que los ajustes preestablecidos más rápidos sean menos paralelos, pero sé que CABAC es en serie.

Para obtener un paralelo masivo, libx264 podría usar una gran cantidad de RAM para mantener los marcos y seguir buscando 2 o más GOP, y codificarlos de forma independiente. Sin embargo, no tiene una opción para operar de esa manera.

Una forma de hacer uso de MUCHOS núcleos es ejecutar múltiples codificaciones separadas en paralelo, en lugar de solo una serie de codificación única usando todos los núcleos. Esto solo funciona si tiene varios archivos de entrada que desea codificar por separado. Está intercambiando la sobrecarga de subprocesos frente a más capacidad de memoria y ancho de banda (con un impacto en el almacenamiento en caché, a menos que sea en un sistema de varios sockets con L3 y DRAM separados para cada grupo de CPU, y tiene los procesos anclados a los núcleos, por lo que una codificación utiliza los núcleos en un socket y la otra en el otro).

Comentarios

  • Gracias por la información. Pregunté aquí principalmente porque ‘ no tengo ninguna pregunta sobre el » código » y más sobre lo que sucede detrás de escena y pensé que esto sería una mejor opción. Yo ‘ marcaré para que la atención del moderador migre y luego ellos pueden realizar la llamada.
  • Ahora mismo ‘ Está pegando un mensaje en una cola de AWS SQS que tiene un enlace a cada archivo. Esta instancia tiene un trabajo en ejecución que escucha esos mensajes, descarga el archivo, lo transcodifica y carga los archivos de salida una vez que se completa. Si estoy leyendo esto correctamente, ‘ estás diciendo que probablemente tendría más sentido para nosotros seguir adelante y lanzar algunos de estos procesos de trabajo y transcodificar varios archivos en paralelo en lugar de ¿Intentas enfocar todos los núcleos en un solo proceso?
  • Sí, si ‘ tienes problemas para saturar más núcleos, ‘ s está bien para ejecutar una codificación o 3 en paralelo. Creo que x264 debería poder saturar la mayoría de sus 32 núcleos, pero tal vez solo con un ajuste preestablecido más lento. Publique sus opciones de cmdline de ffmpeg y la salida de la consola en su pregunta. IDK si ‘ estás usando algo tonto y de baja calidad como -preset veryfast. Si es así, la decodificación de la entrada podría ser el cuello de botella de un solo hilo. O como dije, tal vez un filtro lento.
  • Usted ‘ seguramente querrá superponer la descarga / carga de un xcode con el uso de CPU de otro xcode, si ‘ no está planeando transmitir hacia / desde ffmpeg sobre la marcha para uso en producción. (Es puede ser posible obtener el equivalente de -movflags +faststart sobre la marcha, con un muxer diferente. Creo que leí algo sobre eso. De lo contrario, si ‘ Al generar mp4, es necesario enviarlo a un archivo para que ffmpeg pueda colocar el átomo moov en la parte delantera y mezclar los datos cuando la codificación esté lista.)
  • Oh, acabo de leer su Q con más detalle. Si ‘ está generando los 3 formatos de una vez (con la misma línea de comando ffmpeg, por lo que la decodificación de la entrada solo tiene que ocurrir una vez), entonces si uno de los 3 codificadores es de un solo subproceso, atascará todo el proceso. Creo que libtheora no es multiproceso. wiki.xiph.org/TheoraEncoders dice que había una bifurcación de subprocesos múltiples, pero murió. (¿Quizás nunca funcionó bien o no fue ‘ t compatible con otras mejoras del codificador? Podría haber muchas razones por las que no ‘ no se fusionó). lists.xiph.org/pipermail//theora-dev/2015-February/004374.html

Respuesta

libtheora es de un solo hilo. Hay una compilación experimental multiproceso, pero no se mantiene. Sugeriría ejecutarlo en paralelo con las otras codificaciones. Además, si es posible, use libfdk-aac sobre libfaac.Fidelidad de audio mucho mayor a la misma tasa de bits.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *