FFMPEG (libx264) "altura no divisible por 2"


Estoy tratando de codificar un video .mp4 desde un conjunto de fotogramas usando FFMPEG usando el códec libx264.

Este es el comando que estoy ejecutando:

/usr/local/bin/ffmpeg -r 24 -i frame_%05d.jpg -vcodec libx264 -y -an video.mp4

A veces obtengo el siguiente error:

[libx264 @ 0xa3b85a0] height not divisible by 2 (520x369)

Después de buscar un poco, parece que el problema tiene algo que ver con el algoritmo de escalado y se puede solucionar agregando un argumento-vf.

Sin embargo, en mi caso no quiero hacer ninguna escala. Idealmente, quiero mantener las dimensiones exactamente las mismas que los marcos. Algún consejo? ¿Hay algún tipo de relación de aspecto que h264 impone?

Author: LordNeckbeard, 2013-12-31

6 answers

Después de jugar un poco con esto, creo que he respondido a mi propia pregunta. Aquí está la solución en caso de que alguien más se encuentre con un problema similar... Tuve que añadir el siguiente argumento al comando:

-vf "scale=trunc(iw/2)*2:trunc(ih/2)*2"

Orden:

ffmpeg -r 24 -i frame_%05d.jpg -vcodec libx264 -y -an video.mp4 -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2"

Básicamente .h264 necesita dimensiones uniformes por lo que este filtro:

  1. Divida la altura y la anchura originales por 2
  2. Redondearlo al píxel más cercano
  3. Multiplíquelo de nuevo por 2, convirtiéndolo así en un número par
 189
Author: Andy Hin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-21 10:07:46

Solo use -2

De la documentación del filtro de escala :

Si uno de los valores es -n con n > 1, el filtro de escala también utilizará valor que mantiene la relación de aspecto de la imagen de entrada, calculado de la otra dimensión especificada. Después de eso, sin embargo, hará asegúrese de que la dimensión calculada es divisible por n y ajuste la valor si es necesario.

Ejemplos

Establezca el ancho en 1280, y la altura automáticamente se calculará para preservar la relación de aspecto, y la altura será divisible por 2:

-vf scale=1280:-2

Igual que el anterior, pero con una altura declarada en su lugar; dejando ancho para ser tratado por el filtro:

-vf scale=-2:720

"divisible por 2"

Como lo requiere x264, el "divisible por 2 para ancho y alto" es necesario para las salidas submuestradas de croma YUV 4:2:0. 4:2:2 necesitaría "divisible por 2 para el ancho", y 4:4:4 no tiene estas restricciones. Sin embargo, la mayoría los reproductores no basados en FFmpeg solo pueden decodificar correctamente 4: 2: 0, por lo que a menudo se ven comandos ffmpeg con la opción -pix_fmt yuv420p cuando se emite vídeo H. 264.

Advertencia

Desafortunadamente no puede usar -2 tanto para width como para height, pero si ya especificó una dimensión, usar -2 es una solución simple.

 161
Author: LordNeckbeard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-30 17:15:49

Si desea establecer un ancho de salida y tener salida con la misma relación que el original

scale=720:-1 

Y no caer con este problema, entonces usted puede utilizar

scale="720:trunc(ow/a/2)*2"

(Solo para personas que buscan cómo hacer eso con escalado)

 55
Author: Zbyszek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-17 09:49:49

Es probable que se deba al hecho de que el video H264 generalmente se convierte de RGB a espacio YUV como 4:2:0 antes de aplicar la compresión (aunque la conversión de formato en sí es un algoritmo de compresión con pérdida que resulta en un ahorro de espacio del 50%).

YUV-420 comienza con una imagen RGB (Rojo Verde Azul) y la convierte en YUV (básicamente un canal de intensidad y dos canales de "tono"). Los canales de tono son subsampleados creando una muestra de tono por cada cuadrado de 2X2 de ese tono.

Si tiene un número impar de píxeles RGB horizontal o verticalmente, tendrá datos incompletos para la última columna o fila de píxeles en el espacio de tono subsampleado del marco YUV.

 18
Author: Adisak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-12 16:51:34

LordNeckbeard tiene la respuesta correcta, muy rápido

-vf scale=1280:-2

Para Android, no te olvides de añadir

"-preset ultrafast" and|or "-threads n"
 2
Author: fallouter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-30 19:19:39

También puedes usar la función bitand en lugar de trunc:

Bitand (x, 65534)

Hará lo mismo que trunc(x/2)*2 y es más transparente en mi opinión.
(Considerar 65534 un número mágico aquí;))


Mi tarea era escalar automáticamente muchos archivos de video a media resolución.

scale=-2,ih/2 conducen a imágenes ligeramente borrosas

Razón:

  • los videos de entrada tenían su relación de aspecto de visualización (DAR) set
  • scale escala las dimensiones reales del marco
  • durante la vista previa, los tamaños de los nuevos videos deben corregirse utilizando DAR que en caso de un video de muy baja resolución (360x288, DAR 16: 9) puede conducir a un desenfoque

Solución:

-vf "scale='bitand(oh*dar, 65534)':'bitand(ih/2, 65534)', setsar=1"

Explicación:

  • output_height = input_height / 2
  • output_width = output_height * original_display_aspect_ratio
  • ambos output_width y output_height ahora se redondean al número más pequeño más cercano divisible por 2
  • setsar=1 significa las dimensiones de salida ahora son finales, no se debe aplicar ninguna corrección de la relación de aspecto

Alguien podría encontrar esto útil.

 0
Author: endigo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-20 19:09:57