Configuraciones h264 para grandes áreas planas de color que cambia lentamente

Estoy haciendo una animación para un mapeo de proyección que simula el sol proyectando sombras sobre una estructura a medida que se mueve por el cielo. Básicamente, son solo grandes áreas planas de color que cambian durante unos cinco minutos a medida que el "sol" sale y se pone (en otra proyección). Se reproduce con un gizmo de reproducción de Brightsign, y estoy usando el perfil principal h.264 como códec en un mp4.

El problema que tengo es que la codificación no está tratando muy bien con el contenido. Aunque el color es completamente plano, cuando todos los píxeles cambian de valor con el tiempo, aparecen bandas de ruido y bloques. Son sutiles, pero molestos.

¿Hay algún ajuste que pueda hacer usando libx264 para optimizarlo para grandes áreas planas de color donde todos los píxeles cambian simultáneamente con el tiempo? No hay absolutamente ningún movimiento en el marco, solo el color de toda el área cambia, muy lentamente.

Mi comando ffmpeg actual es bastante genérico:

ffmpg -i input.mov -c:v libx264 -preset slow -profile main -crf 20 -pix_fmt yuv420p -an output.mp4
Incluya la ffmpegsalida completa de la consola. ¿Puede proporcionar una breve muestra de entrada? ¿Ayuda reducir -crfa ~18? ¿Hace -tune animationalguna diferencia? Si nada ayuda, puede considerar usar el gradfunfiltro de video durante la reproducción.

Respuestas (3)

Las bandas a las que te refieres bien podrían ser simplemente una limitación del espacio de color de 8 bits.

En teoría, la forma de resolver esto es utilizar un espacio de color de 10 o 12 bits en cada etapa, desde la renderización, la edición y la masterización, hasta la salida e incluso en la pantalla o el proyector. Sin embargo, su salida final probablemente se mostrará en un espacio de 8 bits por canal, le guste o no.

Entonces, la forma práctica de hacer esto es renderizar a color de 10 o 12 bits y difuminar a 8 bits desde el maestro. El tramado evitará la apariencia visual de bandas cuando se muestra a 8 bits por canal.

Tenga en cuenta que esto no es una limitación de h.264 o cualquier codificador, sino del espacio de color utilizado y la naturaleza libre de ruido de la animación renderizada; si la vida real fuera tan libre de ruido, también mostraría estas bandas en espacios de color de 8 bits. Es poco probable que haya alguna configuración que pueda elegir en su codificador para resolver esto. Para confirmar, renderice a un formato sin comprimir y probablemente aún verá las bandas.

Nota: el difuminado de un renderizado de 10 o 12 bits no es lo mismo que simplemente agregar algo de ruido a un difuminado de 8 bits existente; aunque esto puede disfrazar un poco las bandas simplemente haciéndolas menos distintivas, no lo resuelve. . Pero podrías hacerlo en un apuro.

gracias, pero probablemente no sean las limitaciones de la salida de 8 bits. Las bandas se producen con gradientes. Estas son áreas planas de color, con cada píxel del mismo valor. La compresión introduce bandas a medida que los píxeles cambian con el tiempo.
En ese caso, ¿ha jugado con valores de CRF más bajos? 20 puede no ser transparente en la mayoría de las áreas planas de color con animación. Con la animación renderizada, debería poder salirse con la suya con valores CRF mucho más bajos (como 16). Puede probar con algo de muy alta calidad como 10 o incluso sin pérdidas solo como punto de solución de problemas para ver si la cuantificación es un factor en absoluto.

Dependiendo de cómo se haya creado el contenido, es posible que se introduzcan bandas cuando esté convirtiendo su contenido del espacio de color RGB a YUV. Puede intentar hacer un h264 manteniendo el espacio de color RGB, aunque he leído que no es fácil. ¿Puedes usar otro códec?

Lo primero que intentaría es agregar -force_key_framesa su comando original, eliminar el ajuste preestablecido y reducir el -crfvalor. El siguiente ejemplo establece un fotograma clave cada segundo.

ffmpg -i input.mov -c:v libx264 -profile main \
    -force_key_frames expr:gte(t,n_forced*1) \
    -crf 15 -pix_fmt yuv420p -an output.mp4

Como segundo recurso, usaría una serie de imágenes png (en lugar de mov) como entrada y usaría un crf muy bajo. De esta manera, realmente puede asegurarse de que no haya bandas en su entrada y de que el material final sea de la más alta calidad. Si no puede renderizar directamente a png, convierta el material original.

Aquí hay un ejemplo:

# turn the original into pngs
ffmpeg -i input.mov -f image2 -threads 0 /tmp/%05d.png

# turn the pngs back into mp4 (assuming 25 fps)
ffmpeg -ar 48000 -ac 2 -f s16le -i /dev/zero -r 25/1 -f image2 \
  -i /tmp/%05d.png -c:a libfdk_aac -c:v libx264 \ 
  -profile main -vf "fps=fps=25" -force_key_frames expr:gte(t,n_forced*1) \
  -crf 10 -threads 0 -pix_fmt yuv420p output.mp4

PD. Debería acostumbrarse a incluir una pista de audio silenciosa para la reproducción de dispositivos multimedia debido a problemas de sincronización.