32blogby Studio Mitsu

FFmpeg HDR a SDR: Guía de Tonemapping Que Funciona

Convierte video HDR a SDR con FFmpeg usando zscale+tonemap o libplacebo. Cubre algoritmos hable, reinhard y mobius, aceleración GPU, Dolby Vision y soluciones para colores lavados.

by omitsu18 min read
Contenido

Convertir video HDR a SDR con FFmpeg requiere tonemapping — un proceso que comprime el amplio rango de brillo y color de HDR (BT.2020/PQ) al rango más estrecho de SDR (BT.709). El comando más rápido y fiable es:

bash
ffmpeg -i input_hdr.mp4 \
  -vf "zscale=t=linear:npl=100,format=gbrpf32le,zscale=p=bt709,tonemap=hable:desat=0,zscale=t=bt709:m=bt709:r=tv,format=yuv420p" \
  -c:v libx264 -crf 18 -preset slow -c:a copy output_sdr.mp4

Esta guía cubre dos pipelines: el zscale+tonemap basado en CPU y el libplacebo con aceleración GPU, para que elijas el que mejor se adapte a tu flujo de trabajo.

Lo que vas a aprender

  • Por qué la conversión HDR→SDR necesita tonemapping (no basta con recodificar)
  • El pipeline CPU zscale+tonemap paso a paso
  • El pipeline GPU libplacebo con Vulkan
  • Qué algoritmo de tonemapping usar (hable, reinhard, mobius, bt.2390)
  • Cómo manejar HDR10, HLG, HDR10+ y Dolby Vision
  • Aceleración GPU con VAAPI, OpenCL y NVENC
  • Cómo corregir colores lavados, banding y problemas de metadatos

Por Qué No Puedes Simplemente Recodificar Video HDR

¿Alguna vez intentaste convertir un video HDR y el resultado parecía peor que un VHS? Si ejecutas ffmpeg -i hdr.mp4 -c:v libx264 output.mp4 sobre un video HDR, el resultado es desastroso: colores lavados, sombras aplastadas y luces quemadas. Es la pregunta más repetida en r/ffmpeg de Reddit y los foros de Doom9, y la respuesta siempre es la misma: necesitas tonemapping. Esto pasa por lo siguiente.

El video HDR usa tres propiedades que las pantallas SDR no pueden interpretar correctamente:

PropiedadHDR (típico)SDR
Función de transferenciaPQ (SMPTE ST 2084) o HLGGamma BT.709 (~2.4)
Primarios de colorBT.2020 (gamut amplio)BT.709 (gamut estándar)
Profundidad de bits10 bits8 bits
Brillo pico1.000–10.000 nits~100 nits

Cambiar el contenedor o códec no convierte estas propiedades. Necesitas un paso de tonemapping que remapee matemáticamente el rango amplio de brillo al rango SDR, además de una conversión de espacio de color de BT.2020 a BT.709.

Verifica Tu Entrada con ffprobe

Antes de convertir, confirma que tu fuente es realmente HDR:

bash
ffprobe -v quiet -show_streams -select_streams v:0 input_hdr.mp4 2>&1 | grep -E "color_|pix_fmt"

Deberías ver algo como:

pix_fmt=yuv420p10le
color_space=bt2020nc
color_transfer=smpte2084
color_primaries=bt2020
  • smpte2084 → HDR10/HDR10+ (transferencia PQ)
  • arib-std-b67 → HLG
  • bt2020nc → Matriz BT.2020 de luminancia no constante
  • yuv420p10le → 10 bits 4:2:0

Si todos los campos de color dicen bt709, el archivo ya es SDR — no necesitas conversión.

Para contenido HDR10 con metadatos estáticos (MaxCLL/MaxFALL), también puedes verificar con ffprobe -v quiet -show_frames -read_intervals "%+#1" input.mp4 | grep -E "mastering|content_light" — estos metadatos ayudan a los algoritmos de tonemapping a tomar mejores decisiones sobre cómo comprimir el rango de brillo.

Pipeline 1: zscale + tonemap (CPU)

El enfoque más compatible — funciona en cualquier compilación de FFmpeg que incluya los filtros zscale (de zimg) y tonemap. No requiere GPU.

La cadena de filtros completa

bash
ffmpeg -i input_hdr.mp4 \
  -vf "zscale=t=linear:npl=100,format=gbrpf32le,zscale=p=bt709,tonemap=hable:desat=0,zscale=t=bt709:m=bt709:r=tv,format=yuv420p" \
  -c:v libx264 -crf 18 -preset slow \
  -c:a copy -movflags +faststart \
  output_sdr.mp4

Veamos qué hace cada filtro en la cadena:

Paso 1: Linealizar la función de transferencia

zscale=t=linear:npl=100

Convierte la curva PQ (cuantizador perceptual) a luz lineal. El parámetro npl=100 establece la luminancia pico nominal en 100 nits (referencia SDR estándar). Este es el punto de anclaje para la curva de tonemapping — todo lo que supere 100 nits se comprime.

Paso 2: Convertir a RGB en punto flotante

format=gbrpf32le

Cambia a RGB planar de 32 bits en punto flotante. Este formato intermedio evita pérdida de precisión durante los cálculos de color. El filtro tonemap necesita entrada RGB, y el punto flotante evita artefactos de banding por redondeo de enteros.

Paso 3: Convertir primarios de color

zscale=p=bt709

Mapea los colores del gamut amplio BT.2020 al gamut estándar BT.709. Los colores que caen fuera del gamut de BT.709 se recortan al color representable más cercano.

Paso 4: Aplicar tonemapping

tonemap=hable:desat=0

La curva fílmica Hable comprime el rango de brillo. desat=0 desactiva la desaturación de las luces altas — sin esto, las áreas brillantes pierden su color y se vuelven grisáceas.

Paso 5: Establecer propiedades de color de salida

zscale=t=bt709:m=bt709:r=tv

Aplica la curva gamma BT.709 (t=bt709), establece la matriz YCbCr en BT.709 (m=bt709) y restringe al rango TV (16–235).

Paso 6: Convertir a YUV de 8 bits

format=yuv420p

Conversión final a YUV 4:2:0 de 8 bits — el formato de píxeles SDR estándar con máxima compatibilidad de reproductores.

Pipeline 2: libplacebo (GPU vía Vulkan)

libplacebo es el motor de renderizado detrás de mpv. Maneja tonemapping, mapeo de gamut, dithering y gestión de color en un solo filtro acelerado por GPU — y produce resultados notablemente mejores que el pipeline CPU para la mayoría del contenido.

Comando básico de libplacebo

bash
ffmpeg -init_hw_device vulkan \
  -i input_hdr.mp4 \
  -vf "libplacebo=tonemapping=hable:peak_detect=true:gamut_mode=perceptual:colorspace=bt709:color_trc=bt709:color_primaries=bt709:range=limited:dithering=blue:format=yuv420p" \
  -c:v libx264 -crf 18 -preset slow \
  -c:a copy output_sdr.mp4

Por qué libplacebo es mejor

Característicazscale + tonemaplibplacebo
Detección de picoEstática (solo metadatos)Dinámica (histograma por fotograma)
Mapeo de gamutDesaturación básica6+ modos (perceptual, relativo, saturación)
DitheringNinguno (depende del filtro format)Integrado (blue noise, ordenado)
Algoritmos712 (incluyendo BT.2390, ST 2094-40)
Dolby VisionNo soportadoProfile 5/8.x soportado
Detección de cambio de escenaNingunaCon umbral configurable
Recuperación de contrasteNingunaIntegrada (0.30 por defecto)
ProcesamientoCPUGPU (Vulkan)

La mayor diferencia práctica es la detección dinámica de pico. En lugar de depender de metadatos estáticos MaxCLL (que a menudo son inexactos o faltan), libplacebo analiza el histograma de brillo real de cada fotograma y ajusta la curva de tonemapping en tiempo real. Esto evita que las escenas oscuras queden innecesariamente oscuras o que las brillantes se quemen.

libplacebo con decodificación hardware (NVIDIA)

bash
ffmpeg -init_hw_device vulkan=vk,disable_multiplane=1 \
  -filter_hw_device vk \
  -hwaccel cuda -hwaccel_output_format cuda \
  -i input_hdr.mp4 \
  -vf "hwupload=derive_device=vulkan,libplacebo=tonemapping=hable:peak_detect=true:colorspace=bt709:color_primaries=bt709:color_trc=bt709:gamut_mode=perceptual:format=yuv420p,hwdownload,format=yuv420p" \
  -c:v libx264 -crf 18 -preset slow \
  -c:a copy output_sdr.mp4

Decodifica en la GPU NVIDIA (CUDA), sube a Vulkan para tonemapping, luego baja para codificación CPU. Para un flujo completamente en GPU, reemplaza libx264 por h264_nvenc -cq 22.

Comparación de Algoritmos de Tonemapping

El filtro tonemap integrado de FFmpeg ofrece 7 algoritmos:

AlgoritmoComportamientoIdeal para
hableCurva S fílmica. Preserva detalle en sombras y lucesUso general. Estándar de la comunidad
reinhardPreservación de luminancia global. Salida ligeramente más brillanteContenido donde el brillo importa más que el contraste
mobiusPreserva precisión de color en rango, rolloff suave fuera de rangoTrabajo crítico en color
clipRecorte duro en el límite. Máxima precisión de color en rangoHDR de bajo rango dinámico (pico < 400 nits)
linearEscalado lineal de todo el rangoEfectos especiales, no para visualización normal
gammaTransferencia logarítmica entre curvasCasos de uso nicho
noneSin tonemapping, solo desaturación de valores fuera de rangoPruebas/depuración

Para la mayoría de conversiones HDR→SDR, empieza con hable + desat=0. Esta combinación es prácticamente un estándar en Stack Overflow y los foros de Doom9 — y con buena razón. Si el resultado es demasiado oscuro, prueba reinhard que produce una imagen más brillante a costa de algo de contraste. Servidores de medios como Jellyfin usan reinhard por defecto precisamente por esto.

Algoritmos exclusivos de libplacebo

libplacebo añade varios algoritmos que el filtro integrado no tiene:

  • bt.2390 — ITU-R BT.2390 EETF. El estándar de la industria broadcast para conversión HDR→SDR. Usa un rolloff de spline Hermite
  • bt.2446a — ITU-R BT.2446 Método A. Diseñado para contenido HDR masterizado donde preservar la intención creativa importa
  • st2094-40 — Usa metadatos dinámicos SMPTE ST 2094-40 (HDR10+) para tonemapping escena por escena
  • auto — El valor por defecto de libplacebo. Usa heurísticas internas para elegir el mejor algoritmo basándose en los metadatos de entrada

Manejo de Diferentes Formatos HDR

HDR10 (metadatos estáticos)

El formato más común. Usa transferencia PQ con metadatos estáticos MaxCLL/MaxFALL:

bash
# zscale+tonemap — funciona con todo el contenido HDR10
ffmpeg -i hdr10_input.mkv \
  -vf "zscale=t=linear:npl=100,format=gbrpf32le,zscale=p=bt709,tonemap=hable:desat=0,zscale=t=bt709:m=bt709:r=tv,format=yuv420p" \
  -c:v libx264 -crf 18 -c:a copy output_sdr.mp4

HLG (Hybrid Log-Gamma)

HLG es retrocompatible con SDR por diseño, así que la conversión es más simple. Aun así, el tonemapping da mejores resultados:

bash
ffmpeg -i hlg_input.mkv \
  -vf "zscale=tin=arib-std-b67:t=linear:npl=100,format=gbrpf32le,zscale=p=bt709,tonemap=hable:desat=0,zscale=t=bt709:m=bt709:r=tv,format=yuv420p" \
  -c:v libx264 -crf 18 -c:a copy output_sdr.mp4

Nota el tin=arib-std-b67 para indicar explícitamente que la entrada usa transferencia HLG.

HDR10+ (metadatos dinámicos)

HDR10+ añade metadatos de brillo por escena sobre HDR10. El filtro tonemap integrado ignora estos metadatos extra, pero libplacebo puede aprovecharlos:

bash
ffmpeg -init_hw_device vulkan \
  -i hdr10plus_input.mkv \
  -vf "libplacebo=tonemapping=st2094-40:peak_detect=true:colorspace=bt709:color_primaries=bt709:color_trc=bt709:format=yuv420p" \
  -c:v libx264 -crf 18 -c:a copy output_sdr.mp4

El algoritmo st2094-40 lee los metadatos dinámicos y ajusta el tonemapping por escena — las escenas oscuras se mantienen oscuras, las brillantes reciben compresión adecuada de luces.

Dolby Vision

El soporte de Dolby Vision en FFmpeg es limitado pero sigue mejorando. libplacebo puede manejar Profile 5 y 8.x:

bash
ffmpeg -init_hw_device vulkan \
  -i dolby_vision_input.mkv \
  -vf "libplacebo=tonemapping=hable:apply_dolbyvision=true:peak_detect=true:colorspace=bt709:color_primaries=bt709:color_trc=bt709:format=yuv420p" \
  -c:v libx264 -crf 18 -c:a copy output_sdr.mp4

Opciones de Aceleración GPU

El pipeline CPU de tonemap procesa contenido 4K a unos 10 fps. Si eso es demasiado lento, tienes varias opciones de GPU:

OpenCL (AMD/NVIDIA/Intel)

bash
ffmpeg -init_hw_device opencl=ocl \
  -filter_hw_device ocl \
  -i input_hdr.mp4 \
  -vf "format=p010,hwupload,tonemap_opencl=tonemap=hable:desat=0:t=bt709:m=bt709:p=bt709:format=nv12,hwdownload,format=nv12" \
  -c:v libx264 -crf 18 -c:a copy output_sdr.mp4

El filtro tonemap_opencl funciona en la mayoría de GPUs pero requiere formato de entrada P010 (10 bits).

VAAPI (Intel/AMD)

bash
ffmpeg -hwaccel vaapi -hwaccel_output_format vaapi \
  -i input_hdr.mp4 \
  -vf "tonemap_vaapi=format=nv12:t=bt709:m=bt709:p=bt709" \
  -c:v h264_vaapi -qp 18 -c:a copy output_sdr.mp4

El filtro tonemap_vaapi mantiene todo en la GPU — decodificación, tonemapping y codificación por hardware.

Pipeline completo NVIDIA (NVDEC → Vulkan → NVENC)

bash
ffmpeg -init_hw_device vulkan=vk,disable_multiplane=1 \
  -filter_hw_device vk \
  -hwaccel cuda -hwaccel_output_format cuda \
  -i input_hdr.mp4 \
  -vf "hwupload=derive_device=vulkan,libplacebo=tonemapping=hable:peak_detect=true:colorspace=bt709:color_primaries=bt709:color_trc=bt709:format=yuv420p,hwupload=derive_device=cuda" \
  -c:v h264_nvenc -cq 22 -preset p4 \
  -c:a copy output_sdr.mp4

La opción más rápida en hardware NVIDIA — decodificación por hardware (NVDEC), tonemapping en GPU (Vulkan/libplacebo) y codificación por hardware (NVENC). Espera más de 60 fps para contenido 4K en GPUs modernas.

Comparación de rendimiento (aproximado, 4K HEVC HDR10 → H.264 SDR)

PipelineVelocidadCalidad
zscale + tonemap (CPU)~10 fpsBuena
tonemap_opencl (GPU)~40 fpsBuena
tonemap_vaapi (Intel iGPU)~30 fpsAceptable
libplacebo Vulkan (GPU)~25 fpsLa mejor
NVDEC → libplacebo → NVENC~60 fpsLa mejor

Eligiendo el Codificador Para la Salida SDR

Después del tonemapping, necesitas codificar el resultado SDR. Referencia rápida:

CodificadorCRF/CQCaso de uso
libx264 -crf 18 -preset slow18–22Máxima compatibilidad. Se reproduce en todo
libx265 -crf 22 -preset medium20–24~40% menos tamaño que H.264 a misma calidad
libsvtav1 -crf 32 -preset 428–36Mejor compresión. Soporte de dispositivos creciendo
h264_nvenc -cq 22 -preset p420–26Codificación por hardware, rápida pero archivos más grandes

Para archivo, libx265 o libsvtav1 tienen sentido. Para compartir o previsualizaciones, libx264 es lo más seguro.

bash
# Ejemplo con SVT-AV1 — buena relación calidad/tamaño
ffmpeg -i input_hdr.mp4 \
  -vf "zscale=t=linear:npl=100,format=gbrpf32le,zscale=p=bt709,tonemap=hable:desat=0,zscale=t=bt709:m=bt709:r=tv,format=yuv420p" \
  -c:v libsvtav1 -crf 32 -preset 4 \
  -svtav1-params tune=0 \
  -c:a libopus -b:a 128k \
  output_sdr.mkv

Procesamiento por Lotes

Convierte múltiples archivos HDR con un bucle en shell:

bash
#!/bin/bash
# batch-hdr-to-sdr.sh — Convierte todos los .mkv HDR en el directorio actual

for f in *.mkv; do
  echo "Convirtiendo: $f"
  ffmpeg -y -i "$f" \
    -vf "zscale=t=linear:npl=100,format=gbrpf32le,zscale=p=bt709,tonemap=hable:desat=0,zscale=t=bt709:m=bt709:r=tv,format=yuv420p" \
    -c:v libx264 -crf 18 -preset medium \
    -c:a copy \
    -movflags +faststart \
    "${f%.mkv}_sdr.mp4"
done
echo "Listo. Se convirtieron $(ls -1 *_sdr.mp4 2>/dev/null | wc -l) archivos."

Para procesamiento por lotes con Python y seguimiento de progreso, consulta la guía de automatización con Python y FFmpeg.

Solución de Problemas Comunes

Si buscaste "ffmpeg hdr a sdr colores lavados" — no eres el único. Este es, por lejos, el problema más consultado en conversión HDR. Aquí están los problemas más probables y cómo resolverlos.

Colores lavados (washed out)

Es casi un rito de iniciación para cualquiera que convierte HDR por primera vez. Generalmente causada por:

  1. Sin tonemapping — recodificando sin el filtro tonemap
  2. Desaturación alta — el valor por defecto desat=2.0 es agresivo. Configúralo a 0
  3. Orden de filtros incorrecto — debes linealizar antes de hacer tonemapping

Solución: usa la cadena completa zscale+tonemap con desat=0, o cambia a libplacebo que lo maneja automáticamente.

Color banding (posterización)

Visible en degradados como cielos. Causado por la cuantización de 10 bits a 8 bits.

Opciones de solución:

  • Usa libplacebo con dithering=blue (lo mejor)
  • Mantén la salida en 10 bits: format=yuv420p10le + libx265 -crf 22 (H.265/AV1 usan 10 bits por defecto)
  • Añade grano de película para enmascarar el banding: libsvtav1 -svtav1-params film-grain=8

La salida es demasiado oscura

La curva fílmica de hable comprime las luces agresivamente. Algunos contenidos terminan más oscuros de lo esperado.

Solución:

  • Prueba tonemap=reinhard:desat=0 — produce una salida más brillante
  • Ajusta npl (luminancia pico nominal): valores más altos = salida más brillante. Prueba npl=200
  • Con libplacebo: contrast_recovery=0.5 puede recuperar algo de contraste en tonos medios

Metadatos HDR todavía presentes

Algunos reproductores detectan metadatos HDR residuales y aplican su propio tonemapping sobre el tuyo. Esto causa artefactos de doble procesamiento.

Solución: elimina los datos laterales después del tonemapping:

bash
# Añade esto al final de tu cadena de filtros, antes de format=yuv420p
...,sidedata=delete

ffprobe sigue mostrando BT.2020 después de la conversión

Los metadatos de color del archivo de salida podrían no estar configurados correctamente. Añade etiquetado explícito:

bash
ffmpeg -i input_hdr.mp4 \
  -vf "zscale=t=linear:npl=100,format=gbrpf32le,zscale=p=bt709,tonemap=hable:desat=0,zscale=t=bt709:m=bt709:r=tv,format=yuv420p" \
  -c:v libx264 -crf 18 \
  -colorspace bt709 -color_primaries bt709 -color_trc bt709 \
  -c:a copy output_sdr.mp4

Los flags -colorspace, -color_primaries y -color_trc establecen los metadatos correctos en el stream de salida.

Entendiendo la Ciencia del Color

Si quieres entender por qué la cadena de filtros funciona en ese orden, aquí está la ciencia del color detrás.

Los tres ejes de la conversión de color

EjeValor HDRValor SDRQué controla
Transferencia (EOTF/OETF)PQ (ST 2084) o HLG (ARIB STD-B67)Gamma BT.709Cómo se codifica el brillo como valores de señal
Primarios (gamut de color)BT.2020BT.709Qué colores del mundo real se pueden representar
Matriz (coeficientes YCbCr)bt2020ncbt709Cómo se mapea RGB a canales de luma + croma

Cada eje se convierte de forma independiente en el pipeline zscale+tonemap. libplacebo maneja los tres en una sola pasada internamente.

¿Por qué linealizar primero?

La función de transferencia PQ es perceptualmente uniforme — pasos iguales en el valor de señal corresponden a pasos iguales en el brillo percibido. Pero las matemáticas del tonemapping funcionan en luz lineal, donde duplicar el valor duplica la intensidad física de la luz. Si haces tonemapping en espacio PQ, la curva distorsiona sombras y luces de forma no uniforme.

¿Por qué punto flotante?

Los enteros de 10 bits dan 1.024 niveles. Al convertir a luz lineal, la distribución se vuelve extremadamente no uniforme — la mayoría de los valores se agrupan cerca del cero. El punto flotante evita la pérdida de precisión que causaría banding en las áreas oscuras.

FAQ

¿Cuál es la diferencia entre HDR10 y HDR10+?

HDR10 usa metadatos estáticos — un único valor de brillo (MaxCLL/MaxFALL) para todo el video. HDR10+ añade metadatos dinámicos que cambian por escena, para que una escena oscura de película y una exterior brillante reciban cada una un tonemapping optimizado. El tonemap integrado de FFmpeg ignora los metadatos dinámicos, pero el algoritmo st2094-40 de libplacebo puede usarlos.

¿Qué algoritmo de tonemapping debería usar?

Empieza con hable (curva fílmica) + desat=0. Preserva detalle tanto en sombras como en luces. Si el resultado es demasiado oscuro, prueba reinhard para una salida más brillante. Para trabajo broadcast, usa bt.2390 vía libplacebo — es el estándar ITU. Para contenido HDR10+, usa st2094-40 que aprovecha los metadatos dinámicos.

¿Puedo hacer tonemapping de contenido Dolby Vision?

Parcialmente. libplacebo soporta Dolby Vision Profile 5 y 8.x con apply_dolbyvision=true. Profile 7 (doble capa) no está totalmente soportado — necesitarás extraer la capa base con dovi_tool primero. El pipeline integrado zscale+tonemap no soporta Dolby Vision en absoluto.

¿Por qué mi video convertido se ve lavado?

Tres causas comunes: (1) Recodificaste sin aplicar el filtro tonemap. (2) El parámetro desat es demasiado alto — configúralo a 0. (3) El orden de filtros está mal — debes linealizar (zscale=t=linear) antes del tonemapping. Consulta la sección Solución de Problemas Comunes para más detalles.

¿Es libplacebo mejor que zscale+tonemap?

En calidad, sí. La detección dinámica de pico, el dithering integrado y el mapeo de gamut avanzado de libplacebo producen resultados visualmente superiores en la mayoría de los casos. La contrapartida es que requiere soporte de GPU con Vulkan y una compilación personalizada de FFmpeg con --enable-libplacebo. Si solo necesitas una conversión rápida en un servidor sin GPU, zscale+tonemap funciona perfectamente.

¿Cómo mantengo la salida en 10 bits para evitar banding?

Reemplaza format=yuv420p por format=yuv420p10le en la cadena de filtros y usa un codificador compatible con 10 bits como libx265 o libsvtav1 (ambos usan 10 bits por defecto). H.264 es solo 8 bits en la mayoría de implementaciones.

¿Qué tan rápido es el tonemapping GPU vs CPU?

Con una fuente 4K HEVC HDR10: CPU zscale+tonemap corre alrededor de 10 fps, OpenCL alrededor de 40 fps, y NVDEC → libplacebo → NVENC más de 60 fps. La velocidad exacta depende de tu GPU, configuración del codificador y complejidad de la entrada. Consulta la sección Opciones de Aceleración GPU para comparaciones de pipelines.

¿El tonemapping pierde calidad?

Sí, cualquier conversión de un espacio de color/brillo más amplio a uno más estrecho es inherentemente con pérdida — no puedes representar 1.000 nits de rango de brillo en 100 nits sin compresión. El objetivo del tonemapping es minimizar la pérdida de calidad percibida. Usar hable o bt.2390 con desat=0, salida de 10 bits y dithering da el mejor resultado posible.

Conclusión

Para conversiones rápidas de HDR a SDR, el pipeline zscale+tonemap=hable:desat=0 maneja la gran mayoría del contenido sin problemas. Cuando la calidad importa o estás trabajando con HDR10+/Dolby Vision, libplacebo vale el esfuerzo de configuración.

Los puntos clave:

  • Siempre haz tonemapping — nunca recodifiques video HDR sin convertir el espacio de color
  • Usa desat=0 — la desaturación por defecto aplasta los colores de las luces
  • Usa format=gbrpf32le — los intermedios en punto flotante previenen el banding
  • Verifica con ffprobe — confirma que la salida reporte propiedades de color BT.709

Si trabajas con FFmpeg regularmente, también te pueden ser útiles: