Estoy tratando de codificar un video .mp4 de un conjunto de cuadros 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 me sale 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 escala y se puede solucionar agregando un argumento -vf.
Sin embargo, en mi caso no quiero escalar. Idealmente, quiero mantener las dimensiones exactamente iguales a los marcos. ¿Algún consejo? ¿Hay algún tipo de relación de aspecto que h264 impone?
-vf pad="width=ceil(iw/2)*2:height=ceil(ih/2)*2"
, que ni siquiera es una de las respuestas. La respuesta correcta a la pregunta de todos los demás es la de Lord Neckbeard."scale="
lugar de"pad="
si no quiere píxeles de relleno coloreados?Respuestas:
La respuesta a la pregunta original que no quiere escalar el video es:
Mando:
Básicamente, .h264 necesita dimensiones pares, por lo que este filtro:
Puede cambiar el color del relleno agregando un parámetro de filtro
:color=white
. Ver la documentación del pad .fuente
-vf pad="width=iw:height=ih+1:x=0:y=0:color=white"
. La documentación del pad ffmpeg está aquí: ffmpeg.org/ffmpeg-filters.html#pad-1 .-vf pad="width=ceil(iw/2)*2:height=ceil(ih/2)*2"
.Solo usa
-2
De la documentación del filtro de escala :
Ejemplos
Establezca el ancho en 1280, y la altura se calculará automáticamente para preservar la relación de aspecto, y la altura será divisible por 2:
Igual que el anterior, pero con una altura declarada en su lugar; dejando ancho para ser tratado por el filtro:
"divisible por 2"
Según lo requerido por x264, el "divisible por 2 para ancho y alto" es necesario para las salidas YUV 4: 2: 0 de submuestreo de croma. 4: 2: 2 necesitaría "divisible por 2 para el ancho", y 4: 4: 4 no tiene estas restricciones. Sin embargo, la mayoría de los jugadores que no están basados en FFmpeg solo pueden decodificar correctamente 4: 2: 0, por eso es que a menudo se ven
ffmpeg
comandos con la-pix_fmt yuv420p
opción cuando se emite video H.264.Consideración
Desafortunadamente, no puede usar
-2
tanto el ancho como la altura, pero si ya especificó una dimensión, entonces usar-2
es una solución simple.fuente
-vf scale=-2:-2
no funciona? En mi caso, quiero preservar el tamaño del archivo original tanto como sea posible. Lo que funcionó para mí fue-vf scale=-2:ih
. Pero no funciona si ambos h / w son desiguales.-2
depende del valor declarado de la otra dimensión.Size values less than -1 are not acceptable.
pero la respuesta de @Zbyszek funcionó perfectamente.ffmpeg
. Puede descargar una compilación estática .Si desea establecer un ancho de salida y tener una salida con la misma relación que la original
y no caer con este problema, entonces puedes usar
(Solo para personas que buscan cómo hacerlo con el escalado)
fuente
scale="trunc(oh*a/2)*2:720"
El problema con las
scale
soluciones aquí es que distorsionan la imagen / video fuente, que casi nunca es lo que quieres.En cambio, he encontrado que la mejor solución es agregar una almohadilla de 1 píxel a la dimensión impar. (Por defecto, el relleno es negro y difícil de notar).
El problema con las otras
pad
soluciones es que no se generalizan sobre dimensiones arbitrarias porque siempre se rellenan.Esta solución solo agrega una almohadilla de 1 píxel a la altura y / o el ancho si son impares:
Esto es ideal porque siempre hace lo correcto incluso cuando no se necesita relleno.
fuente
scale=iw+mod(iw,2):ih+mod(ih,2):flags=neighbor
. Esto solo puede aumentar cada dimensión en 1, si es necesario, y duplicará la última fila / columna.Probablemente 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í misma es un algoritmo de compresión con pérdida que genera 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 se submuestrean creando una muestra de tono por cada cuadrado de 2X2 de ese tono.
Si tiene un número impar de píxeles RGB, ya sea horizontal o verticalmente, tendrá datos incompletos para la última columna o fila de píxeles en el espacio de matiz submuestreado del marco YUV.
fuente
LordNeckbeard tiene la respuesta correcta, muy rápido
Para Android, no olvides agregar
fuente
--disable-asm
en su script de construcción x264 . Esto resulta en una lentitud innecesaria y significativa (puede verificar el registro ffmpeg y si se muestra,using cpu capabilties: none!
entonces eso es malo). No estoy seguro de por qué agregaron eso, pero no soy un desarrollador de Android.También puede usar la
bitand
función en lugar detrunc
:mordida (x, 65534)
hará lo mismo
trunc(x/2)*2
y es más transparente en mi opinión.(Considere 65534 un número mágico aquí;))
Mi tarea consistía en escalar automáticamente muchos archivos de video a la mitad de la resolución .
scale=-2,ih/2
conducir a imágenes ligeramente borrosasrazón:
scale
escala las dimensiones reales del marcosolución:
explicación:
setsar=1
significa que las dimensiones de salida ahora son finales, no se debe aplicar la corrección de la relación de aspectoAlguien puede encontrar esto útil.
fuente