Pelajari cara menangani warna di FFmpeg: memahami HDR10 dan HLG, konversi HDR ke SDR dengan zscale dan tonemap, serta menyetel metadata warna agar video terlihat benar di semua perangkat.

Di episode 15 kalian belajar mempercepat encoding dengan GPU. Sekarang kita bicara tentang sesuatu yang sering luput dari perhatian sampai hasilnya terlihat salah: warna. Kalian mungkin pernah mengalami video yang tampak pucat dan keabu-abuan, atau terlalu gelap dan jenuh. Dalam banyak kasus, videonya tidak rusak — metadata warnanya yang salah, atau ada ketidakcocokan antara cara video itu dimaksudkan ditampilkan dengan cara perangkat menampilkannya.
Episode 16 ini membahas color handling di FFmpeg secara menyeluruh: apa itu HDR10 dan HLG, bagaimana filter zscale dan tonemap mengubah video HDR menjadi SDR, serta peran metadata warna seperti -color_primaries, -color_trc, dan -color_space. Setelah episode ini, kalian tidak akan lagi bertanya "kenapa video ini jadi abu-abu?" — kalian akan langsung tahu jawabannya.
Sebelum masuk ke HDR, kalian harus kenal tiga kata kunci yang mengatur bagaimana bit-bit warna ditafsirkan menjadi warna yang terlihat. Ketiganya bersama-sama disebut color metadata, dan ketiganya bisa disetel di FFmpeg:
Perhatikan bahwa ketiganya terpisah dan bisa dikombinasikan sesuka hati — dan di situlah sering terjadi kekacauan. Sebuah file bisa saja menyimpan resolusi 4K (BT.2020 wajar), tapi transfer function-nya tertulis BT.709. FFmpeg menampilkan metadata ini di output ffprobe:
ffprobe -v error -select_streams v:0 -show_entries stream=color_primaries,color_trc,color_space,input.mp4Hasilnya berupa baris seperti color_primaries=bt2020, color_trc=smpte2084, dan color_space=bt2020nc — kombinasi yang khas untuk video HDR10. Membaca metadata ini adalah langkah pertama dari semua pekerjaan warna.
Tip
Instalasi FFmpeg yang didistribusikan biasanya menambahkan metadata warna berdasarkan container dan codec secara otomatis, tapi tidak selalu benar. Jika `ffprobe{:bash}` menampilkan unknown untuk salah satu dari ketiganya, video itu belum "dikunci" warnanya — dan perangkat akan menebak-nebak. Menetapkan metadata secara eksplisit adalah cara memastikan semua orang membaca video kalian dengan interpretasi yang sama.
High Dynamic Range (HDR) adalah kemampuan merepresentasikan kecerahan dan warna yang jauh lebih luas daripada SDR: piksel yang lebih terang dari putih SDR, bayangan yang lebih dalam, dan warna yang lebih jenuh. Tapi HDR bukan satu standar tunggal — ada dua keluarga utama yang kalian akan temui:
HDR10. Berbasis transfer function PQ (SMPTE ST 2084), diwarnai dengan primaries BT.2020. Ia memakai static metadata: nilai kecerahan puncak yang sama untuk seluruh video. HDR10 adalah standar HDR paling umum di dunia, dan karena metadata-nya statis, penerapannya sederhana dan murah.
HLG (Hybrid Log-Gamma). Dirancang agar kompatibel dengan perangkat SDR dan HDR sekaligus — sinyal yang sama bisa ditampilkan layar SDR dan HDR tanpa konversi penuh. HLG banyak dipakai untuk siaran langsung dan televisi karena alasan kompatibilitas ini, sekaligus alasan mengapa HLG kadang terlihat "cukup baik" di layar SDR tanpa tonemapping.
Saat menulis metadata untuk HDR, kalian menyetel ketiganya sekaligus. Untuk HDR10 dengan libx265:
ffmpeg -i input.mp4 -c:v libx265 -crf 18 \
-x265-params colorprim=bt2020:transfer=smpte2084:colormatrix=bt2020nc:master-display=G(8500,39850)B(6550,2300)R(35400,14600)WP(15635,16450)L(10000000,100):max-cll=1000,400 \
-color_primaries bt2020 -color_trc smpte2084 -color_space bt2020nc \
output-hevc-hdr10.mkvPerhatikan dua lapis pengaturan: parameter -x265-params menulis metadata HDR ke dalam stream codec (termasuk master-display dan max-cll yang menyatakan kecerahan puncak layar target), sementara opsi -color_primaries, -color_trc, dan -color_space menulis metadata di level container. Pemutar modern membaca keduanya; ketidaklengkapan di salah satu lapis bisa membuat video ditafsirkan sebagai SDR biasa.
Sekarang bagian yang paling sering dibutuhkan: mengubah video HDR menjadi SDR agar bisa ditonton di layar dan platform yang tidak mendukung HDR. Prosesnya disebut tonemapping: memetakan rentang kecerahan luas dari HDR ke rentang sempit SDR, sambil berusaha mempertahankan detail bayangan dan highlight.
FFmpeg melakukannya dengan dua filter yang bekerja bersama. Filter zscale (berbasis perpustakaan zimg) melakukan konversi ruang warna dan presisi, dan filter tonemap memetakan kecerahan. Urutan kerjanya seperti menyortir arsip: pindahkan dulu semua data ke format kerja berpresisi tinggi, lakukan pemetaan, lalu ubah kembali ke format tujuan:
ffmpeg -i input-hdr10.mkv -vf "zscale=t=linear:npl=100,format=gbrpf32le,zscale=p=bt709,tonemap=hable,zscale=t=bt709:m=bt709:r=tv,format=yuv420p" \
-c:v libx264 -crf 18 output-sdr.mp4Mari kita bedah rantai filter ini, yang merupakan salah satu rantai paling terkenal di dunia FFmpeg:
zscale=t=linear mengubah transfer function PQ (HDR) menjadi linear — warna perlu dihitung dalam ruang linear agar pemetaan kecerahan bekerja benar.npl=100 menyatakan nominal peak luminance 100 nit, skala kecerahan yang dijadikan acuan tonemapping.format=gbrpf32le mengubah ke RGB presisi 32-bit float. Ini wajib: tonemapping yang dilakukan pada integer 8-bit akan membuang detail sebelum sempat dipetakan.tonemap=hable menerapkan kurva tonemapping (varian dari kurva film industry). Ada alternatif mobius yang mempertahankan kontras lebih baik untuk konten yang kurang ekstrem, dan clip yang paling sederhana.zscale=t=bt709:m=bt709:r=tv mengembalikan ke transfer BT.709 dengan matrix BT.709 dan range video (limited).format=yuv420p mengubah ke format penyimpanan SDR standar agar kompatibel dengan hampir semua pemutar.Hasilnya: video HDR yang terlihat normal di layar SDR, dengan highlight yang tetap mempertahankan teksturnya alih-alih terpotong menjadi putih polos.
Important
Tonemapping mengubah data — bukan sekadar konversi format. Detail yang dipetakan dari rentang 1000 nit ke 100 nit pasti mengalami kompresi, dan hasilnya bergantung pada isi scene. Karena itu jangan pernah menganggap hasil tonemap sebagai "master". Simpan master HDR asli, dan lakukan tonemap hanya untuk membuat versi distribusi SDR. Proses ini juga berat secara komputasi — kombinasi float 32-bit dan banyak pass menjadikannya salah satu pipeline terslow yang ada di FFmpeg.
Warning
Filter zscale membutuhkan FFmpeg yang dibangun dengan dukungan perpustakaan zimg. Jika kalian mendapat pesan "No such filter: 'zscale'", artinya build FFmpeg kalian tidak menyertakan libzimg. Beberapa build Linux memisahkan dukungan ini; cek dengan ffmpeg -filters | grep zscale. Alternatifnya, FFmpeg juga punya scale dengan parameter flags=hcq dan colorspace filter untuk kasus yang lebih sederhana, meski tanpa kualitas float 32-bit.
Tidak semua pekerjaan warna membutuhkan tonemapping. Sering kali yang dibutuhkan hanyalah menyetel metadata dengan benar — misalnya ketika kalian menerima file dari sumber yang metadata-nya kosong atau salah. FFmpeg menyediakan opsi output untuk ini:
ffmpeg -i input.mp4 -c copy -color_primaries bt709 -color_trc bt709 -color_space bt709 out.mp4Perhatikan -c copy: metadata warna adalah atribut stream yang bisa ditulis ulang tanpa re-encode, karena ia tidak menyentuh bit-bit video itu sendiri. Tiga opsi yang dipakai:
-color_primaries — pilih bt709 untuk HDTV, bt2020 untuk UHD/HDR.-color_trc — pilih bt709 untuk SDR, smpte2084 untuk HDR10, arib-std-b67 untuk HLG.-color_space — matrix: bt601 (SD), bt709 (HD), bt2020nc (UHD non-constant luminance).Aturan yang wajib diingat: metadata yang salah lebih berbahaya daripada metadata yang kosong. Jika kosong, perangkat memakai asumsi default yang umumnya wajar. Jika salah — misalnya tertulis BT.709 padahal video sesungguhnya BT.2020 — perangkat akan menampilkan warna yang jelas salah tanpa memberi tahu siapa pun. Selalu pastikan nilai yang kalian tulis sesuai dengan data video yang sebenarnya, bukan sekadar "yang terlihat keren".
Tip
Untuk mengubah ruang warna secara nyata (bukan sekadar menulis metadata), gunakan filter colorspace atau colormatrix — misalnya mengubah video BT.601 menjadi BT.709. Ingat bedanya: -color_primaries dan kawan-kawan hanya menulis label, sedangkan filter colorspace benar-benar mengubah piksel. Menulis label di atas data yang tidak cocok hanya akan membuat pembaca salah menafsirkan warna.
Pada episode 16 ini kalian telah membuka kotak pandora warna di FFmpeg: memahami tiga komponen metadata warna (primaries, transfer function, dan color matrix), membedakan HDR10 yang berbasis PQ dengan HLG yang hybrid, menulis metadata HDR10 yang lengkap untuk libx265, melakukan tonemapping HDR ke SDR dengan rantai zscale dan tonemap, serta menetapkan metadata warna secara manual dengan -color_primaries, -color_trc, dan -color_space.
Poin kunci yang perlu dibawa pulang:
-c copy bisa menulis ulang metadata warna tanpa re-encode.Warna adalah hal terakhir yang "tak terlihat" dalam pipeline video biasa. Sekarang kalian siap untuk membangun sesuatu yang benar-benar kompleks: menggabungkan video, menumpuk teks, memotong, dan mencampur banyak input sekaligus dalam satu graph.
Di episode 17 berikutnya kita akan membahas Filtergraph Kompleks — -filter_complex dengan label, filter split, overlay, xfade, hingga amix, serta cara menghasilkan banyak output dari satu graph. Pastikan tetap semangat!