Transcodificación con FFmpeg y preservación del espacio BT.601

De vez en cuando, es posible caer de forma inesperada en un territorio de video extraño. Por ejemplo, cuando sólo se desee cortar algunas grabaciones de pantalla de dispositivos móviles, tales como tabletas o teléfonos inteligentes, sólo para caer en la cuenta de que hay algo malo con los colores.

Material común y corriente

El drama comienza con un material de captura de pantalla, en apariencia normal e inocente, a primera vista. Quizás grabado en dispositivos Android 7, usando una aplicación de captura de pantalla (como «AZ Screen Recording», pero no la versión “Pro”). Y este material presenta dos propiedades ligeramente inusuales:

  • una velocidad de fotogramas altamente variable,

  • usa un espacio de color BT.601[1], en vez de usar BT.709[2], como hace la mayor parte del material actual en HD.

¿No debería causar problemas, no? Bueno…

Tal parece que el motor de medios usado por Kdenlive, MLT, puede mostrar algunos inconvenientes con material en video que tenga una velocidad de fotogramas altamente variable, del tipo entre 0,001 y 100+ fps. Los síntomas son sutiles, aún así ponen en riesgo la calidad de una producción: parece que MLT podría elegir un fotograma futuro muy diferente en regiones con una velocidad de fotogramas baja. Si bien esto no es un problema mientras haya una tasa de fotogramas suficientemente alta, podrá causar resultados extraños en otros lugares. Por ejemplo, la interacción táctil del usuario aparecerá incluso algunos segundos antes de que realmente se produzca. Esto probablemente se deba a una tasa de fotogramas muy baja durante el periodo de inactividad justo antes de la interacción del usuario.

La transcodificación a una velocidad de fotogramas fija es seguro una de las tareas sencillas para ffmpeg (este ejemplo asumirá un proyecto con una velocidad constante de 25 fps):

ffmpeg -i raw.mp4 -r 25 -crf 18 screen-rec.mp4

Una velocidad de fotogramas constante remediará los problemas mencionados más arriba, por lo que los resultados serán los esperados. Excepto que…

Transcodificación fácil: Malos colores

transcoding_color_change.webp

¡Desafortunadamente, el video resultante mostrará un desplazamiento en sus colores! Podría no resultar tan aparente a primera vista, pero a medida que se trabaje más con el material su presencia se tornará más notoria. En caso de que el material fuera a ser mezclado lado a lado, con otras versiones más procesadas del mismo, tales como fotogramas estáticos extraídos, esto se notará más aún.

Una inspección más minuciosa, tanto usando el panel de Propiedades del clip de Kdenlive, como ffprobe, revelarán que el archivo transcodificado carece del indicador de espacio de color BT.601. Aún así, ffmpeg no transformó los colores en absoluto, durante el proceso de transcodificación, sino que simplemente descartó la información del espacio de color usado!

Improvisación de contramedidas

kdenlive2308_clip_properties_color_space.webp

Redefiniendo las propiedades de Espacio de color en el panel Propiedades del clip

Por supuesto, Kdenlive siempre tiene la capacidad de redefinir las propiedades originales del clip, usando el panel de Propiedades del clip.

Simplemente seleccionar el video transcodificado en la Bandeja delproyecto. Luego, ir al panel Propiedades del clip y seleccionar allí la pestaña “Propiedades” document-edit. Activar la opción Espacio de color y luego seleccionar ITU-R 601 en el menú desplegable. Ahora, Kdenlive podrá aplicar el perfil de color correcto al clip.

Si bien es sencillo, este método tiene sus limitaciones: Se comportará de buena forma, mientras el trabajo se mantenga dentro de Kdenlive y su motor de procesamiento MLT. Sin embargo, tan pronto como fuera necesario utilizar herramientas de video externas, tales como ffmpeg, para la extracción de imágenes, el problema resurgirá, debido a que esas herramientas no podrán tomar en cuenta la redefinición del espacio de color realizada dentro de Kdenlive. Para corregir el problema definitivamente se deberá incorporar la información correcta de espacio de color dentro del propio video transcodificado.

Preservación de BT.601 durante la transcodificación

Para complicar las cosas, la transformación de espacio de color aparentemente obvia

-vf colormatrix=bt601:bt601

simplemente no funciona: ffmpeg devuelve un mensaje de error, advirtiendo que no es capaz de realizar una transformación de un espacio de color a sí mismo.

La pieza faltante del rompecabezas puede ser encontrada en el sitio Video Production Q&A de Stack Exchange, en una publicación de 2015 consultando «ffmpeg: explicitly tag h.264 as bt.601, rather than leaving unspecified?» (ffmpeg: ¿cómo etiquetar un archivo h.264 como bt.601, en vez de dejarlo sin especificar?).

Hay un detalle adicional al cual habrá que estar atento: BT.601 viene en variantes para PAL y NTSC, las cuales contienen cromaticidades de colores primarios, curvas de transferencia y espacios de color ligeramente distintos. Por lo tanto será importante comprobar el material en crudo, usando ffprobe (o MediaInfo), para saber cuál de estas variantes ha sido usada al grabar el material. Tener en cuenta que no importará en absoluto que la grabación de pantalla no tuviera una resolución estándar (SD), sin embargo sí importará el tipo de codificación de color que utilice.

El ADN PAL y NTSC

Entonces, ¿cómo es posible averiguar cuándo un determinado archivo de video, digamos raw.mp4, está usando el espacio de color de PAL o de NTSC? Como es de esperar, ffprobe viene al rescate. Pero, para no quedar perdidos entre los abundantes detalles técnicos que ffprobe proporcionará, necesitaremos domarlo, usando algunas opciones y grep:

ffprobe -v error -show_streams raw.mp4 | grep color_

Eso debería producir algo similar a lo siguiente:

color_range=tv
color_space=bt470bg
color_transfer=smpte170m
color_primaries=bt470bg

La línea color_space=… informará acerca de qué tipo de espacio de color está usando el archivo: PAL (si dice bt470bg) o NTSC (si dice smpte170m).

PAL

En caso de ser cromaticidades PAL (color_space=bt470bg), entonces será necesario transcodificar de la siguiente manera:

ffmpeg -i raw.mp4
-color_primaries bt470bg -color_trc gamma28 -colorspace bt470bg
-r 25 -crf 18 screen-rec.mp4

NTSC

Para cromaticidades NTSC (color_space=smpte170m), se necesitarán un conjunto de colores primarios, curva de transferencia y espacio de color diferentes:

ffmpeg -i raw.mp4
-color_primaries smpte170m -color_trc smpte170m -colorspace smpte170m
-r 25 -crf 18 screen-rec.mp4
transcoding_comparison.webp

En cualquier caso, Kdenlive y MLT serán ahora capaces de visualizar correctamente al video transcodificado, usando el espacio de color BT.601. Además de esto, otras herramientas que trabajen con medios podrán también detectar correctamente su perfil de color - a menos que su funcionamiento no fuera correcto o que no fueran capaces de entender el espacio de color BT.601 en absoluto.

Notas

Fuentes

El texto original fue enviado por el usuario TheDiveO al (ahora desaparecido) blog kdenlive.org. Para esta documentación, ha sido tomado desde kdenlive.org, y adaptado para que coincida con el estilo de esta documentación.