この記事でわかること
- HDR(HDR10/HLG)とSDRの違い
zscaleフィルタを使ったHDR→SDR変換の基本コマンド- 色空間・カラープリミティブ・トランスファー関数の変換
- YouTube/Web配信向けのSDR出力設定
- よくあるエラーと対処法
テスト済みバージョン: FFmpeg 7.0で確認済み
対象 OS: Windows / macOS / Linux
HDR と SDR の違い
| 項目 | SDR(Standard Dynamic Range) | HDR(High Dynamic Range) |
|---|---|---|
| 色空間 | BT.709 | BT.2020 |
| 転送特性 | BT.709 (ガンマ) | PQ (HDR10) / HLG |
| ピクセル深度 | 8bit | 10bit |
| 輝度範囲 | 100 nit | 1000〜10000 nit |
HDR動画をSDR環境で再生すると、映像が白飛び・色ずれを起こすことがあります。適切なトーンマッピングで自然な見栄えのSDR映像に変換できます。
事前確認 — 動画のHDR情報を確認する
まず入力ファイルの色空間情報を確認します。
ffprobe -v quiet -select_streams v:0 \
-show_entries stream=color_space,color_transfer,color_primaries,pix_fmt \
-of default=noprint_wrappers=1 input.mp4
出力例(HDR10):
pix_fmt=yuv420p10le
color_space=bt2020nc
color_transfer=smpte2084
color_primaries=bt2020
出力例(HLG):
pix_fmt=yuv420p10le
color_space=bt2020nc
color_transfer=arib-std-b67
color_primaries=bt2020
基本コマンド — HDR10 → SDR(BT.709)
zscale を使ったトーンマッピング(推奨)
zscaleフィルタ(libzimgが必要)を使った高品質変換:
ffmpeg -i input_hdr.mp4 \
-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 -preset slow \
-c:a copy \
output_sdr.mp4
このフィルタチェーンは以下の処理を行います:
zscale=t=linear:npl=100— 線形光に変換(PQからリニア)format=gbrpf32le— 32bit浮動小数点に変換(精度確保)zscale=p=bt709— BT.2020からBT.709へのカラープリミティブ変換tonemap=hable— Hableトーンマッピングで輝度圧縮zscale=t=bt709:m=bt709:r=tv— BT.709ガンマ・matrix・制限レンジに変換format=yuv420p— 8bit YUV 4:2:0に変換
トーンマッピングアルゴリズムの比較
tonemap= で異なるアルゴリズムを指定できます。
# Hable(フィルムルック、推奨)
-vf "zscale=t=linear:npl=100,format=gbrpf32le,zscale=p=bt709,tonemap=hable,zscale=t=bt709:m=bt709:r=tv,format=yuv420p"
# Reinhard(シンプルで自然)
-vf "zscale=t=linear:npl=100,format=gbrpf32le,zscale=p=bt709,tonemap=reinhard,zscale=t=bt709:m=bt709:r=tv,format=yuv420p"
# Mobius(中間的なコントラスト)
-vf "zscale=t=linear:npl=100,format=gbrpf32le,zscale=p=bt709,tonemap=mobius,zscale=t=bt709:m=bt709:r=tv,format=yuv420p"
# Clip(単純クリッピング、最速だが白飛びあり)
-vf "zscale=t=linear:npl=100,format=gbrpf32le,zscale=p=bt709,tonemap=clip,zscale=t=bt709:m=bt709:r=tv,format=yuv420p"
| アルゴリズム | 特徴 | 推奨用途 |
|---|---|---|
| hable | ハイライトを自然に圧縮、コントラスト保持 | 汎用 |
| reinhard | シンプル、中性的な見た目 | 自然な映像 |
| mobius | ハイライトと影のバランス | ドキュメンタリー |
| clip | 単純カット、高速 | テスト・比較 |
HLG → SDR 変換
ffmpeg -i input_hlg.mp4 \
-vf "zscale=t=linear,format=gbrpf32le,zscale=p=bt709,tonemap=hable,zscale=t=bt709:m=bt709:r=tv,format=yuv420p" \
-c:v libx264 -crf 18 -preset slow \
-c:a copy \
output_sdr.mp4
HLGの場合は npl=100 の指定が不要です(HLGは相対輝度)。
colorspace フィルタを使う方法(zscale が使えない場合)
libzimgがない環境では colorspace フィルタを使用できます(精度はやや低下):
ffmpeg -i input_hdr.mp4 \
-vf "colorspace=bt709:iall=bt2020:fast=1,format=yuv420p" \
-c:v libx264 -crf 18 -preset slow \
-c:a copy \
output_sdr.mp4
YouTube アップロード向けの設定
YouTube はSDR映像で H.264、CRF 18〜20 推奨です。
ffmpeg -i input_hdr.mp4 \
-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 -preset slow \
-pix_fmt yuv420p \
-color_primaries bt709 \
-color_trc bt709 \
-colorspace bt709 \
-c:a aac -b:a 256k \
output_youtube_sdr.mp4
-color_primaries -color_trc -colorspace の3つのメタデータタグを明示することで、プレイヤーが正しい色空間を認識します。
一括変換スクリプト(フォルダ内のHDR動画をすべてSDRに変換)
#!/bin/bash
for f in *.mp4; do
ffmpeg -i "$f" \
-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 -preset slow \
-pix_fmt yuv420p \
-color_primaries bt709 -color_trc bt709 -colorspace bt709 \
-c:a copy \
"sdr_${f}"
done
トラブルシューティング
zscale が見つからない
No such filter: 'zscale'
FFmpegがlibzimgなしでビルドされています。
# macOS
brew install ffmpeg # Homebrewビルドはlibzimgを含む
# Ubuntu
sudo apt install ffmpeg # 最新版を確認
映像が緑色・ピンク色になる
色空間変換のパラメータが間違っています。ffprobe で color_transfer を確認し、HLG入力には t=arib-std-b67、HDR10には t=smpte2084 を指定してください。
映像が暗すぎる / 白飛びしている
トーンマッピングアルゴリズムを変更してみてください。暗い場合は npl 値を上げる(例: npl=203)か、reinhard を試します。
# npl値を上げてより明るいSDRに
-vf "zscale=t=linear:npl=203,format=gbrpf32le,zscale=p=bt709,tonemap=hable,zscale=t=bt709:m=bt709:r=tv,format=yuv420p"
ピクセルフォーマットエラー
10bitのHDR入力を libx264(8bit)に渡す際は format=yuv420p を必ず最後に指定します。
関連リソース
よく使うオプション・フィルタ・コーデック設定をまとめた PDF チートシートです。手元に置いておくと調べる時間を短縮できます。
関連記事
動作確認: ffmpeg 7.0 / Ubuntu 24.04
一次ソース: ffmpeg.org/ffmpeg-filters.html#zscale