toruのブログ

月1くらいで記事書きたい。

ブラウザ上の動画の CMS 確認

目的

お断り

このページは技術解説記事ではなく、カラーマネジメントを確認するためのテストページです。

お詫び

  • 動画サイズが小さくてすみません。大きく表示したい方はブラウザの拡大機能をご利用ください

Test Videos (8 bit, 0-255 CV)

Color primaries, Transfer characteristics 動画 ソースの静止画(ICC Profile 無し)
BT.709, BT.709 zu1
BT.709, sRGB zu2
BT.709, Unknown zu3
BT.2020, ST2084 zu3

Test Videos ( with Color Checker )

Color primaries, Transfer characteristics 動画 ソースの静止画(ICC Profile 無し)
BT.709, BT.709 zu1
P3D65, BT.709 zu1
BT.2020, BT.709 zu2
P3D65, ST2084 zu3
BT.2020, ST2084 zu3

YouTube にアップロードした動画

  • 動画の解像度は 1080p に設定してください。
    • 原因は分かりませんが、筆者の PC では 720p, 480p ではカラーマネジメントが働かない現象が発生しています。
  • 動画の長さは 1秒です。すぐに再生が終わってしまうため「右クリック」→「ループ再生」を選択することをオススメします。
Color primaries, Transfer characteristics 動画
BT.709, BT.709
P3D65, BT.709
BT.2020, BT.709
P3D65, ST2084
BT.2020, ST2084

MP4 コンテナに収納された H.264 ファイルの色情報に関する調査

1. 背景

  • Google Chrome での動画再生のカラーマネジメントに関する調査をしたい
  • 検証用のテストパターンとして「MP4 コンテナに収納した H.264 の動画」を使用する予定である
  • しかし筆者は MP4 コンテナに収納された H.264 ファイルの色情報(※1)がどこに保存されるのか理解していなかった
  • そのため動画ファイルの色情報の保存場所について調査を行うことにした

※1 本記事において色情報は以下の3つの情報を意味する。

  • Color primaries
  • Transfer characteristics
  • Matrix coefficients

2. 目的

  • MP4 コンテナに収納された H.264 ファイルの色情報がどこに保存されるか調べる

3. 結論

MP4 コンテナに収納された H.264 ファイルの色情報は以下の2箇所に保存される。

  • (a) MP4 コンテナの 'moov' コンテナの 'colr' ボックス
  • (b) H264 の NAL の SPS の VUI

色情報が2箇所に保存されることが判明したので、Google Chrome がどちらの情報を参照するのか追加調査をした。 その結果、Google Chromeカラーマネジメント用に参照するのは (b) の VUI であり (a) の値は無視されることを確認した。

4. 詳細

4.1. 3種類の色情報の簡単な説明

冒頭で述べたとおり、本記事で扱う色情報は Color primaries, Transfer characteristics, Matrix coefficients の3種類である。 これらは動画ファイルの中で 2 Byte の数値データとして扱われる。それぞれの情報の意味を簡単に説明しておく。

  • Color primaries
    • R, G, B, W の色情報を意味する
    • 具体的な設定値の例を図1に示す。この図は Report ITU-R BT.2380-2[1] の Table 2.6 の一部である

f:id:takuver4:20210101102839p:plain
図1 Color primaries の例

  • Transfer characteristics
    • 伝達特性を意味する
    • 具体的な設定値の例を図2に示す。この図は Report ITU-R BT.2380-2[1] の Table 2.7 の一部である

f:id:takuver4:20210101102901p:plain
図2 Transfer characteristics の例

  • Matrix coefficients
    • RGB to YCbCr 変換に使用した Matrix の係数の情報を意味する
    • 具体的な設定値の例を図3に示す。この図は Report ITU-R BT.2380-2[1] の Table 2.8 の一部である

f:id:takuver4:20210101102925p:plain
図3 Matrix coefficients の例

4.2. MP4 コンテナと色情報

MP4コンテナに H.264 のバイトストリームデータや各種メタデータなどを格納できる。 ここでは MP4コンテナにメタデータとして保存できる色情報の詳細について述べる。

MP4コンテナは ISO Base Media File Format を拡張して作られたものである[2]。 MP4コンテナに保存できる色情報の詳細は、拡張元の ISO Base Media File Format で定義されている[3]。

具体的には 'colr' Box に情報が保存される。MP4Box.js のサイト[4]で実際のデータを表示した様子を図4 に示す。

f:id:takuver4:20210101105815p:plain
図4 MP4コンテナの色情報の例 (MP4Box.js を利用)

4.3. H264 のバイトストリームと色情報

MP4コンテナに格納された H.264のバイトストリームにも色情報は保存されている。具体的には NAL の SPS の VUI に保存される[5]。 h264-bitstream-viewer[6] を利用して VUI の情報を表示した例を図5 に示す。

f:id:takuver4:20210101132154p:plain
図5 h264-bitstream-viewer を利用して VUI を表示した例

4.4. Google Chrome では 'colr' と VUI のどちらが参照される?

色情報が保存される場所が2箇所だったので、どちらの情報が Google Chrome で使用されるのか確認した。 以下の表に示す通り2パターンの検証用ファイルを作成して確認した。

検証パターン1 検証パターン2
'colr' の情報 BT.709 (SDR) BT.2020 (HDR)
VUI の情報 BT.2020 (HDR) BT.709 (SDR)
Chrome で参照された情報 BT.2020 (HDR) BT.709 (SDR)

上記の結果より、VUI の情報が参照されることが確認できた。

検証に使用した動画データは以下の通り。

drive.google.com

5. 【参考】FFmpeg で MP4 コンテナに色情報を埋め込む方法

FFmpegエンコードする場合 -movflags write_colr を設定する必要がある[要出典]。このオプションが無い場合は VUI にしか情報が埋め込まれないので注意。 今回の検証では以下のようにエンコードを行った。

ffmpeg -color_primaries bt709 -color_trc bt709 -colorspace bt709 -r 24 -i input_png_seq_%4d.png -c:v libx264 -movflags write_colr -pix_fmt yuv444p -qp 0 -color_primaries bt709 -color_trc bt709 -colorspace bt709 output.mp4 -y

6. 感想

  • 2~3日で調査が終わるかと思ってたのだが、予想以上に時間がかかってしまった。
  • H264のパーサーを作っている人は凄いと思った。自分には無理ゲーだったので公開されているのを使わせて頂いた

7. 参考資料

[1] Report ITU-R BT.2380-2, "Television colorimetry elements", https://www.itu.int/dms_pub/itu-r/opb/rep/R-REP-BT.2380-2-2018-PDF-E.pdf

[2] Wikipedia(English), "MPEG-4 Part 14", https://en.wikipedia.org/wiki/MPEG-4_Part_14

[3] ISO/IEC 14496‐12:2015, "Information technology — Coding of audio-visual objects — Part 12: ISO base media file format", https://standards.iso.org/ittf/PubliclyAvailableStandards/

[4] MP4Box.js, "ISOBMFF Box Structure Viewer", https://gpac.github.io/mp4box.js/test/filereader.html

[5] Recommendation ITU-T H.264, "Advanced video coding for generic audiovisual services", https://www.itu.int/rec/T-REC-H.264

[6] h264-bitstream-viewer, https://mradionov.github.io/h264-bitstream-viewer/

OS のスクリーンショット機能とカラーマネジメントに関する簡単な調査

背景

目的

OS のスクリーンショットでキャプチャするRGB値は Google Chromeカラーマネジメント後の値であることを確認する。 別の言い方をすると、Google Chrome が 図1 のように動画の Color Management を行う場合、スクリーンショット機能は 図1の ②の値をキャプチャすることを確認する

f:id:takuver4:20201219133053p:plain
図1. WebブラウザGoogle Chrome)による色変換の例

結論

OS のスクリーンショット機能が図1 の ②の値をキャプチャしていることを確認した。

確認条件は以下の通り。

  • OS: Windows10 Pro, Version 20H2
  • Webブラウザ: Google Chrome, Version 87.0.4280.88
  • 動画ファイル: DaVinci Resolve で "Output color space" を "Rec.2100 ST2084" に設定して作成

検証方法

以下の順序で検証した。

感想

  • わざわざ確認するまでもない簡単な内容だったが念のため検証した
  • 予想通りの結果が得られてたので SDR でのカラマネ調査はスクリーンショットを活用して実施できそうである
    • 一方で HDR は色々と面倒くさそうな予感がしている
  • 本調査のスコープからは外れるが、カラーマネジメント後のRGB値は予想と大きく異なっており、不自然な色温度のズレが生じていた
    • 本件については別記事で調査する。かもしれない。

付録

検証に使用した動画へのリンクを以下に示す。

drive.google.com

10bit 精度で 1bit のズレも発生しないテストパターン動画(H.265)を作成する

1. 背景

  • これまで幾つかのテストパターンを作ってきた
  • 動画の場合は ProRes や DNxHR などの業務用コーデックを使っていたがファイルサイズが大きくて困っていた(※1
  • H.265 の Lossless オプションを活用することでファイルサイズの削減と10bit精度での画質の維持(※2)が可能か調べることにした

※1 3840x2160, 60P を DNxHR の最高品質でエンコードすると 4秒で 1.62GB くらいになる
※2 「10bit精度での画質の維持」は 0~1023 の Code Value値が 1bitのズレも無く再現できることを意味する

2. おことわり

本記事は技術的に実現可能かどうかを調べただけの内容です。個人の趣味レベルの内容であり、業務レベルでの運用にはリスクが伴うと考えています。ネタ記事としてお楽しみください。

3. 目的

  • 10bit 精度で 1bit のズレも発生しない H.265 の動画を作成する条件を調べる
    • 今回の調査は Gray の Rampパターンが完全再現できることのみを確認する
    • Red, Green, Blue などの 色情報を持つデータについては確認しない
    • 動画の精度確認は動画ファイルを DaVinci Resolve で静止画シーケンスファイルにデコードして行う

4. 結論

  • テストパターン生成時に以下の4条件を満たすことで、10bit精度で 1bit のズレも生じない動画が作成可能
    • 動画ソースは 16bit 静止画シーケンスファイルとして用意する
    • 10bit のデータを 16bit に変換する際、10bit の 1023(0x3FF) が 16bit の 65324(0xFF2C) ~ 65352(0xFF48) となるように正規化する
    • ffmpeg で静止画シーケンスファイルをエンコードする際に lossless オプションを有効化する
    • ffmpeg で静止画シーケンスファイルをエンコードする際に bit深度のオプションを 12bit にする

5. 詳細

5.1. 最初の検証

5.1.1. 検証の準備

動画データは基本的に Limited Range で保存されるため、H.265 で 10bit精度の lossless エンコードしたとしても Full Range → Limited Range の変換が発生して bit欠損が生じてしまう。しかし 12bitエンコードすれば bit欠損が生じなくなると考えていた。

そこで筆者は以下に示す方法で 10bit精度の Rampパターンが 12bit の動画ファイルから再現可能か確認した。概要を図1に示す。

f:id:takuver4:20201205142831p:plain
図1. 検証環境の概要。FFmpeg と DaVinci は内部処理が全く分からないので ??? と書いてある

各ブロックの処理の詳細は以下の通り。

  • 処理①
    • Python で 10bit の Rampパターンのデータを生成(図2, 図3
      • 厳しいエンコード条件となるように背景は1フレームごとに値が変わるノイズデータとした
      • 最上段の 1 Line に 0~1023 の Rampパターンを入れた
    • 16bit に変換して png のシーケンスファイルとして保存
  • 処理②
    • FFmpeg で 12bit 精度で lossless エンコード
      • 作成した動画データは Google Drive 上 に置いた(クリックするとアクセスできます)
    • FFmpegffmpeg version 4.2.4-1ubuntu0.1 を使用
    • 使用したオプションは以下[1][2]
ffmpeg -color_primaries bt709 -color_trc bt709 -colorspace bt709 -r 24 -i input_seq_data_%4d.png -c:v libx265 -profile:v main444-12 -pix_fmt yuv444p12le -x265-params lossless=1 -color_primaries bt709 -color_trc bt709 -colorspace bt709 out.mp4
  • 処理③
    • DaVinci で 12bit の H.265 ファイルを 16bit TIFF で保存することで静止画シーケンスファイルを生成(※3
  • 処理④
    • 16bit の静止画シーケンスファイルを10bit精度に変換
    • 処理①で作成した Rampパターンと一致するかを確認
f:id:takuver4:20201206131749p:plain f:id:takuver4:20201206132248p:plain
図2. 作成した Rampパターンのスクリーンショット 図3. 図2の一部を拡大したもの

※3 本当は 10bit DPX で吐いて検証する予定だったのですが、なぜか DaVinci 17 Beta 3 の吐いた DPX を Python上で読むことができず 今回は TIFF で代用しました

5.1.2. 検証の結果

実際に 0~1023 CV の Ramp パターンを図1 の方法で再現した結果を表1に示す。予想とは異なり元の Ramp パターンを再現することはできなかった。

表1. Rampパターンを図1の④で再生成した結果
予想値 実際の値
0 0
1 1
2 2
3 3
252 253
253 254
254 255
255 256
508 510
509 510
510 512
511 512
764 766
765 767
766 768
767 769
1020 1023
1021 1023
1022 1023
1023 1023

表1 をよく見ると予想値の大きさに比例して誤差が大きくなっている。 この結果から筆者は 10bit Rampパターンを 16bit整数型に変換する際の係数のミスマッチによって誤差が生じていると推測した。

以後で、その推測に基づいて検証した内容を報告する。

5.2. 10bit to 16bit 変換

はじめに、整数型の 10bit のデータを 16bit に変換する方法についておさらいしておく。 筆者の知っている方法として次の2種類の方法がある。

  • (a) 16bitの最大値で正規化
    • 1023(0x3FF) → 65535(0xFFFF)
  • (b) bitシフト
    • 1023(0x3FF) → 65472(0xFFC0)

それぞれの動作イメージを図4、図5 に示す。

f:id:takuver4:20201205161421p:plain f:id:takuver4:20201206124039p:plain
図4. 16bitの最大値で正規化する例 図5. bitシフトで変換する例

(a), (b) と2種類書いてみたが実際のところ (a) を使うケースが殆どだと考えている。(b) は元のbit深度情報が分からないと正しい変換ができないため、使えるシーンが限定されるからである。 当然のことながら 5.1. の検証も (a) の方式で 10bit to 16bit 変換した。

しかし、表1 の結果を見ると値が大きくなっていることから、(a) の方式をそのまま使うのは NG であり 最大値を 65535(0xFFFF) よりも小さい値にする必要があると推測できる。

5.3. 適切な最大値の探索

表1の結果を踏まえて、筆者は正規化して 16bit変換する際の最大値(以後 "16bit の最大値"と略す)を 65280(0xFF00) や 65472(0xFFC0) に設定して再度実験を行った。しかし、残念ながら誤差は無くならなかった。

そこで探索によって誤差が発生しない 16bit の最大値を求めることにした。 以下の手順でテストデータを256種類作成し、それぞれの H.265 動画から 10bit の Ramp パターンが正確に復元できるかを調査した。

  • 16bit png の最大値を 0xFC00~0xFFFC まで 0x0004 刻みで変更
  • 16bit png のソースファイルから H.265 の YCbCr4:4:4,12bit の .mp4 ファイルを生成
  • DaVinci Resolve 17 Beta 3 でデコードし 16bit TIFF として出力
  • 16bit TIFF を 10bit に変換して(※4) 0~1023 の Code Value値が再現できているか確認

※4 この 16bit to 10bit 変換は 65535(0xFFFF) が 1023(0x3FF) となる変換式を使用しました。これまでの経験から DaVinci は 16bit のデータを扱う際に 0xFFFF が最大値となるように正規化することが分かっていたためです

5.4. 検証結果

16bit png の最大値を 0xFC00~0xFFFC まで 0x0004 刻みで変化させた際の理論値との誤差の累計をプロットした結果を図6 ~ 図7 に示す。 図より 10bit to 16bit 変換した際の最大値が 65324(0xFF2C) ~ 65352(0xFF48) の場合は誤差が0 となり 10bit の Rampパターンが完全に再現できることが分かる。

f:id:takuver4:20201206123836p:plain f:id:takuver4:20201206123847p:plain
図6. 誤差が0となる最大値の探索結果(全体) 図7. 誤差が0となる最大値の探索結果 (一部を拡大)

5.5. 考察

色々と気になる点が多く、業務での利用は困難だと思ってしまった。 気になった点をザッと列挙してみる。

  • 10bit の Rampパターンの再現には成功したが、最大値が 0xFF2C ~ 0xFF48 となるように正規化するのはマジックナンバー過ぎて気味が悪い
  • 図6, 図7 のデータをよく見ると 65320, 65360 付近で誤差が出たり出なかったりしていて不気味
  • 実は Dithering が適用されたりしてないか?(その辺の事前調査が全くできていない)
  • 図1 の ④ の 16bit to 10bit 変換は本当に正しいやり方となっているのか?
    • DaVinci の出力は 10bit DPX で行うべきだった(DaVinci 17 の DPX だけ手元の OpenImageIO だと開けないんですよ、何でですかね?)
  • そもそも FFmpeg について知らないことが多すぎて不安である

6. 感想

考察していると突っ込みどころがどんどん出てきてしまう内容であった。 もっと FFmpeg について詳しくなって いつか業務レベルで使えるようになりたい。

7. 付録

検証に使用した Pythonコードへのリンクを残しておく(カスタムした筆者の環境でしか動かないと思うが一応リンクを貼っておく)

7.1. 図1 の ①、②、④ の処理

github.com

  • ① は create_source_png_sequence
  • ② は encode_src_sequence
  • ④ は evaluate_reproduced_ramp

7.2. 図1 の ③ の処理

github.com

探索の際、DaVinci でデコードするファイルが多かったのでスクリプトで一括デコードした。 DaVinci で メニューバーの ”Workspace" → "Console" を選択し、出てきたウィンドウで ”Py3” を選択し、上記のソースを以下のようにして呼べば動く(事前に動画ファイルを指定されたフォルダに置いておく必要がある)。

import DV17_Decode as dv17
dv17.main_func2()

参考資料

[1] ニコラボ, "色の情報の扱いについて", https://nico-lab.net/setting_in_out_color_with_ffmpeg/

[2] FFmpeg, "H.265/HEVC Video Encoding Guide", https://trac.ffmpeg.org/wiki/Encode/H.265

Davinci 17 の RCM に関する簡単な調査

0. 背景

DaVinci 17 の Beta版がリリースされたので、早速インストールして Color Management について調べていたところ、DaVinci 16 と比較して色々と変わっていることが分かった。

自分は DaVinci を検証のための映像信号源として利用することが多いため、DaVinci の Color Management の機能を正しく理解しておく必要がある。 そこで最初の一歩として、Beta版に同梱されているマニュアル[1]を参照しながら Color Management の各パラメータが入力信号に対してどのように作用するか確認を行った。

1. おことわり

この記事は DaVinci Resolve Studio 17 Public Beta 2 で動作を確認したものです。 正式版では挙動が変わっている可能性がありますのでご注意ください。

2. 目的

  • DaVinci 17 の Project Settings の Color Management タブの Color Space & Transforms の概要を理解する
  • 言い換えると DaVinci 17 の RCM(Resolve Color Management) の概要を理解する

3. 結論

  • 図1 に示す処理の概要を理解した

    • DaVinci 17 から Input DRT, Output DRT と呼ばれる概念が追加された
    • Input DRT と Output DRT は Tone mapping を行う処理であり、Input DRT と Output DRT を適用した場合の特性は図2のようになる (※1)
    • また SDR to HDR 変換の前処理を自動で行う "Inverse DRT for SDR to HDR Conversion" と呼ばれる処理も追加された。特性を図3に示す
  • なお、新規に追加された DaVinci Wide Gamut Color Space と DaVinci Intermediate Gamma については調査不足のため本記事では取り扱わない

  • また、今回の調査結果は輝度方向の変換に特化した内容であり、色相や彩度の変化に関する調査は行っていない

f:id:takuver4:20201115074319p:plain
図1. Resolve Color Management's image processing pipeline ([1]より引用)

f:id:takuver4:20201129092908p:plain f:id:takuver4:20201129115353p:plain
図2. Input DRT、Output DRT を適用した場合の特性 図3. Inverse DRT for SDR to HDR Conversion の特性

※1 図2 は Timeline working luminance の輝度値と Output color space の ST2084 の 輝度値を一致させてプロットした。詳細は 4.2.3. を参照。

4. 詳細

ここから DaVinci 17 の RCM について確認した内容を書いていく。が、最初は念のために Color Management の概念の確認を行っておく。

4.1. 映像制作における Color Management

映像制作における Color Management は簡単に説明すると以下を行うものである。併せて概要を図4に示す。

  • 様々な色情報を持った Source を共通の色空間にマッピングする
  • 共通の色空間で処理を行う
  • ターゲット(映画館、Web配信、地上波など)に合わせた色空間で出力する

f:id:takuver4:20201121134528p:plain
図4. Color Management の概要

共通の色空間(図4だと Image Processing を行う場所)を経由することで、多種多様な色情報を持つ映像ソースの取り扱いがとても行いやすくなる。

4.2 DaVinci 17 の RCM

ここから本命の DaVinci 17 の RCM について述べる。まずは UI について述べる。

4.2.1. DaVinci 17 の RCM の UI

DaVinci 17 の初期設定は 図5 に示す通りシンプルな構成である。ユーザーが設定するのは Resolve color management preset と Output color space だけで良い。一方で Resolove color management preset を custom にすると図6に示す通り細かな設定が可能となる。今回は図1の各ブロックの処理を確認したいので custom で確認を行った。

f:id:takuver4:20201115092830p:plain f:id:takuver4:20201115092839p:plain
図5. custom以外の場合 図6. custom の場合

4.2.1. Input Color Space と Output Color Space

図1 の Input Color Space と Output Color Space について簡単に説明する。

Input Color Space は Source Media の色空間を解釈して Source Media を内部に取り込む。例えば (R, G, B) = (1.0, 0.0, 0.0) というデータがあったとして、 これを Gamma2.4-BT.709 の (x, y, Y) = (0.64, 0.33, 0.2126) と解釈して取り込んだり、ST2084-BT.2020 の (x, y, Y) = (0.708, 0.292, 26.27) と解釈して取り込んだりする。

Output Color Space は Timeline color space のデータを Final Output の色空間に変換して出力する。例えば、内部の (x, y, Y) = (0.3127, 0.3290, 1.0) を Gamma2.4-BT.709 の (R, G, B) = (1.0, 1.0, 1.0) として出力したり、ST2084-BT.2020 の (R, G, B) = (0.508, 0.508, 0.508) と出力したりする。

4.2.2. Input DRT

ここから、DaVinci 17 で新規追加となった DRT について説明する。まずは Input DRT について調べた結果を順に説明する。

DRT とは Display Rendering Transform の略称でありデータに対して Tone mapping を適用する処理である。 このうち Input DRT (のUI) に関してはマニュアル[1]で以下のように記載されている。

the Input DRT (Display Rendering Transform) drop-down menu provides a variety of different options to enable DaVinci Resolve to automatically tone map the image data of SDR and HDR clips to better match one another when they’re fit into the currently selected Timeline Color Space.

入力 DRT(Display Rendering Transform)ドロップダウンメニューには、現在選択されているタイムラインカラースペースにSDRとHDRクリップの画像データを合わせる際に、DaVinci Resolveが自動的にトーンマップを行い、お互いをよりよく一致させるためのさまざまなオプションが用意されています。(DeepLによる日本語訳)

この説明だけだと詳しい動作が分からないため実際に確認してみる。DaVinci の Input DRT のドロップダウンメニューには 図7-(a) に示す通り複数の選択肢がある。

f:id:takuver4:20201121155515p:plain:w640
図7. Input DRT のパラメータ

全てを確認するのは大変なので今回は "DaVinci" のみを確認する。また、図1 から分かるように Input DRT は "Timeline working luminance" というパラメータ(図7-(b))の影響も受ける。そこで次のようにして Input DRT の挙動を確認する。

まず 図8に示す Rampパターンを用意する。次に DaVinci の Color Management 設定を 図9 のようにする。 最後に Input DRT 設定を 図10 のパターンで変化させて Tone mapping の様子を確認する。

f:id:takuver4:20201121142721p:plain
f:id:takuver4:20201121143215p:plain f:id:takuver4:20201121145331p:plain
図8. テスト用のRampパターン 図9. Color Management 設定 図10. Input DRT のリスト

これらの準備をして Tone mapping を確認した結果を 図11 に示す。

f:id:takuver4:20201121160913p:plain:w640
図11. Input DRT の特性

Timeline working luminance で指定した輝度付近 がピーク輝度となるような Tone mapping が適用されることが分かる(グラフをよく見ると Tone mapping 後の輝度は設定した輝度より少しだけ低い)。

ただし SDR 100 の設定値に関しては明らかに異常だったので、パラメータを変更して追加調査をした。その結果、次の事が分かった。

  • Timeline working luminance を SDR 100 に設定するのは Output color space が SDR の時に限定される(と思われる

実際に Output color space を Gamma2.4 に変更して確認した結果を図12に示す。図12 を見ると変換後の最大輝度が 100 cd/m2 となるため、Timeline working luminance を SDR 100 に設定した場合は Output color space を SDR にするのが正しい使い方だと思われる

f:id:takuver4:20201127081249p:plain:w640
図12. Output color space を SDR(Gamma2.4) に変更して試した結果

4.2.3. Output DRT

続いて Output DRT について調査した結果を説明する。なお、ここから先の説明は出力が HDR の場合のみを対象とする。SDR 出力に関しては調査が済んでいないため報告しない。ご了承頂きたい。

筆者の調査で解ったことは以下の2点である。

  • (1) Output DRT は "Output color space の Gamma の ST2084 の輝度値" と強い関連がある
  • (2) Timeline working luminance の輝度値と Output color space の ST2084 の 輝度値は一致させると素直な特性になる

順を追って説明する。

まず、(1) の "Output color space の Gamma の ST2084 の輝度値" との強い関連について具体例を図13, 図14 に示す。

図13 は Timeline working luminance を HDR 1000、Output color space の ST2084 の 輝度値を 500, 1000, 2000, 4000, 10000(無印) と変化させた場合の Output DRT の特性 をプロットしたものである。図14 は 図13 の条件で Input DRT, Output DRT の両方を適用したトータルの特性をプロットしたものである。加えて設定画面のスクリーンショットを図15 に示す。

f:id:takuver4:20201129125007p:plain f:id:takuver4:20201129125018p:plain
図13. Output DRT の特性 図14. Input DRT, Output DRT の両方を合わせた特性

f:id:takuver4:20201129132529p:plain:w640
図15. 図13 を作成した際の設定

図13, 図14 より、Output DRT は "Output color space の Gamma の ST2084 の輝度値" と強い関係があることは読み取れる。 そして ST2084 の輝度値によって特性が大きく変化するため、目的に応じて適切な輝度値を設定する必要があると考える。

筆者が現時点で最も無難だと考えている方法は (2) に示した Timeline working luminance の輝度値と Output color space の ST2084 の輝度値を一致させる方法である。こうすることで、Input DRT で適用した Tone mapping の特性がそのまま出力にも反映される。

具体例を交えてもう少し詳しく説明しよう。例えば 図14 の 紫色の "HDR 1000, ST2084 10000 nit" に着目する。 この紫色の線では Input DRT で 1000 nit に Tone mapping が適用されるが、それを打ち消すような Tone mapping が Ourput DRT で適用されて最終的に何の変化も無くなっている(※2)。

一方で 図14 の 橙色の "HDR 1000, ST2084 1000 nit" に着目する。ここでは Input DRT の Tone mapping の特性がほぼそのまま残っている。なぜならば 図13 で Output DRT の特性を確認すると Linear な特性となっているからである。

ただ、これはあくまでも筆者の一意見であるため、本当にこの考え方が正しいかは不明である。 DaVinci 17 が正式版がリリースされれば付属のマニュアルにもっと詳しい情報が書かれると考える。

※2 Timeline color space では Tone mapping が適用されている状態なので、カラーグレーディング時にカラリストにとって扱いやすい状態になっているかもしれない。が、筆者はその辺りの知識が不足しており何とも言えない。

4.2.3. Output DRT with ER(Extended Range)

これまでスルーしてきたが、Timeline working luminance には 図16 に示すように ER(Extended Range) と呼ばれる設定が存在する。 このパラメータを指定した場合の挙動についても簡単に解説する。

f:id:takuver4:20201129133902p:plain:w640
図16. Extended Range のパラメータ

ER に関してはマニュアル[1]で以下のように記載されている。

These “extended range” settings each specify two values and provide more headroom for aggressive grading of highlights by enabling DaVinci Resolve to compress a greater range of out-of-bounds image data without clipping, which can result in a smoother look.

これらの「拡張範囲」設定はそれぞれ2つの値を指定し、DaVinci Resolveがクリッピングなしでより広い範囲の範囲外の画像データを圧縮できるようにすることで、ハイライトの積極的なグレーディングのためのヘッドルームを増やします。これにより、より滑らかな外観が得られます。(Google翻訳による翻訳)

例えば "HDR ER 1000/2000" という設定は Input DRT で 1000 nit ターゲットの Tone mapping が適用されるが、Output DRT での Tone mapping は 2000 nit が最大値となるように行われるため、Timeline color space では +1000 nit のヘッドルームができる。

具体的な特性を 図17, 図18 に示す。例えば 橙色の HDR ER 1000/4000 に注目してみる。図17 の Input DRT では 1000 nit に Tone mapping が適用されるが、図18 の Output DRT では 4000 nit までクリッピングが発生しておらず +3000 nit のヘッドルームが存在することが分かる。

f:id:takuver4:20201129135947p:plain f:id:takuver4:20201129140015p:plain
図17. ER settings 使用時の Input DRT の特性 図18. ER settings 使用時の Output DRT の特性

ここで1点注意事項がある。ER settings を使用する場合は ER settings の輝度値と Output color space の ST2084 の 輝度値を必ず一致させるべきである。例えば "HDR ER 1000/2000" を設定したのに Output color space で "ST2084 4000 nit" を指定した場合は、ヘッドルームが +1000 nit ではなく +3000 nit となってしまい意図と異なる挙動になるからである。

5. 感想

DaVinci 17 は SDR/HDR を効率よく扱うための仕組みが追加されており、プリセットで使用するユーザーにとっては大変扱いやすいように進化を遂げていると感じている。一方で、自分のように標準のプリセットを使わずに custom でマニアックな使い方をする場合は理解すべき新要素が多く、なかなか大変だと感じた。が、これで輝度方向の変換については概ね理解できたので、ひとまずは安心して使えそうである。

今回の記事では HDR の機能を調べるだけで終わってしまったので、どこかのタイミングで WCG 関連の新機能についても調査したい。

参考資料

[1] Blackmagic Design, "DaVinci Resolve New Features Guide", November 2020 Public Beta.

iccXML を利用した ICC profile の作成

背景

Gamut Mapping に関する勉強を進めるにあたり、Adobe CMM などの有名な CMM(Color management module) が内部でどのような変換を行っているか軽く調べようと考えた。しかし(本当に色々な人に怒られそうだが)自分は ICC profile に関する知識が非常に乏しく、直ぐには CMM の挙動を調査できない状況にあった。

そこで最初の一歩として、ICC profile の作成方法を調べて実際に作成してみることにした。

目的

  • ICC profile を作る
    • コンテンツ側の光源は D65 固定とする(もちろん PCS は D50)
    • Gamut は任意の値を指定可能とする
    • Transfer characteristics (ICC profile で言うところの TRC)は parametricCurveType で任意の値(γ=2.6 や sRGB など)を指定可能とする
    • Profile class は Display device profile のみを対象とする。印刷系の事は何も考えない

結論

  • iccXML というツールを使うことで好みの特性の ICC profile を作成することに成功した
  • ChromePhotoshop で簡易動作確認したところ特に問題なく動いた
    • 下図で作成した ICC profile が Chrome で扱われる例を示す(Google Chrome でご確認下さい)
      • (a) は ICC profile が無しの画像ファイル(色が異常)
      • (b) は作成した ICC profile を画像に埋め込んだファイル(色が正常)
    • 画像ファイルの詳細は本記事の後半で解説する
(a) (b)
Chrome で作成した ICC profile が扱われる例。(a) は profile無し。(b) は profile 有り。

結論に至るまでの流れ

ICC profile 生成ツールの調査

ICC の Webサイトを見ると SampleICC を使えば ICC profile が作れるようである[2]。 しかしソースコード一式を落としてドキュメントを読んでも作り方が分からず Sample ICC を使う方法は断念した(オイオイ)。

その後、色々とネット記事を見ていたところ以下の記事[3] が目に留まった。

https://www.it-swarm-ja.tech/ja/system-settings/%e3%82%ab%e3%83%a9%e3%83%bc%e3%83%97%e3%83%ad%e3%83%95%e3%82%a1%e3%82%a4%e3%83%ab%e3%81%ae%e5%90%8d%e5%89%8d%e3%82%92%e5%a4%89%e6%9b%b4%e3%81%97%e3%80%81icc%e3%83%95%e3%82%a1%e3%82%a4%e3%83%ab%e3%81%ab%e4%bf%9d%e5%ad%98%e3%81%95%e3%82%8c%e3%81%a6%e3%81%84%e3%82%8b%e3%82%bf%e3%82%a4%e3%83%88%e3%83%ab%e3%82%92%e5%a4%89%e6%9b%b4%e3%81%99%e3%82%8b%e3%81%ab%e3%81%af%e3%81%a9%e3%81%86%e3%81%99%e3%82%8c%e3%81%b0%e3%82%88%e3%81%84%e3%81%a7%e3%81%99%e3%81%8b%ef%bc%9f/960965094/www.it-swarm-ja.tech

この記事では iccToXml および iccFromXml というコマンドを使って .icc ファイルと .xml ファイルの変換を行っている。 この iccFromXml を使えば簡単に ICC profile が作成できると考えて利用することにした。

iccXML についての調査

ICC の Webサイトを見ると iccXML については以下のように書かれている[4]。

IccXml is a utility based on SampleICC/RefIccMax that converts an ICC profile to an XML encoding, and back from XML to a binary .icc file. Both source files and binary executables are included.

なるほど これは使えそうだ、と考えた。

iccXML のインストール

iccXML を使うには SampleICC および iccXML の双方が必要となる。前述の[3] の記事を参考に Ubuntu 20.04 でビルド&インストールを行った。

今回は以下の Dockerfile を利用してビルド&インストールした(ソースコードSourceForge から DL した )。

FROM ubuntu:20.04

ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y \
    build-essential \
    cmake \
    autoconf \
    libtool \
    libxml2-dev \
    libtiff5-dev

RUN mkdir -p /root/local/src
COPY SampleICC-1.6.8.tar.gz /root/local/src/
COPY IccXML-0.9.8.tar.gz /root/local/src/

RUN mkdir -p /work/src

RUN cd /root/local/src \
    && tar -xzf SampleICC-1.6.8.tar.gz \
    && cd SampleICC-1.6.8 \
    && ./configure \
    && make -j8 \
    && make install

RUN cd /root/local/src \
    && tar -xzf IccXML-0.9.8.tar.gz \
    && cd IccXML-0.9.8 \
    && ./configure \
    && make -j8 \
    && make install

RUN echo "/usr/local/lib" >> etc/ld.so.conf \
    && ldconfig

RUN rm -rf /root/local/src \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

雛形となるXMLファイルの準備

iccFromXml では xml ファイルから .icc ファイルを生成する。.xml ファイルの中身は目的に応じて内容を書き換えるが、 まずは雛形となる .xml ファイルを1つ準備することにした。今回は Photoshop が生成する Display P3 の ICC profile を雛形とした。 雛形は以下の通りに作った。

まず、Photoshop で Display P3 のプロファイル付きの適当な PNG画像を生成した。次に、ImageMagick を使って PNG画像から ICC profile を分離した[5]。

convert display_p3_img.png display_p3.icc

続いて iccToXml を使って .xml ファイルに変換した。

iccToXML display_p3.icc display_p3.xml

最後にエディタ上で .xml ファイルを編集して今回の作業では不要な Tag を削除した。 具体的には technologyTag を削除した。理由は technologyTag は Display device profile で mandatory の Tag では無かったからである。

Python を使った .xml ファイルの編集

さて、筆者は冒頭でも述べたとおり ICC profile のパラメータを色々と変更したいと考えている。 したがって ICC profile の元となる .xml ファイルを Pythonスクリプトで編集できることが好ましい。 そこで今回は Python の標準ライブラリである xml.etree.ElementTree を利用して .xml ファイルの書き換えを行うコードを書いた。

具体的には以下の内容を任意の値に書き換える Python スクリプトを書いた。

  • Profile header
    • Preferred CMM type
    • Profile version field
    • Date and time
    • Primary platform
    • Device manufacturer ※1
    • Device model ※1
    • Profile creator ※1
    • Profile ID ※2
  • Tagged element data
    • desc
    • sprt
    • chad
    • lumi
    • rTRC, gTRC, bTRC
    • rXYZ, gXYZ, bXYZ

※1 個人制作の ICC profile であり使用しない領域なので仕様書に従って 0x00 で埋めた
※2 MD5値を入れる領域だが iccFromXml コマンド実行時に計算されるため ここでは 0x00 で埋めた

.xml ファイルから .icc ファイルへの変換

Python スクリプトの吐き出す .xml ファイルを iccFromXml コマンドを使って以下の通りに変換した。

iccFromXml target_profile.xml target_profile.icc

作成した ICC profile の確認

Chome や Photoshop などのアプリケーションで試す前に、作成した ICC profile が規格に準拠しているかの確認を行った。 労力を考慮して以下の方針で確認することにした。

  • Profile header : バイナリエディタを使って頑張って目視確認
  • Tag table : ICC が提供している ProfileDump[6] を使って確認
  • Tagged element data : ICC が提供している ProfileDump[6] を使って確認

Profile header をバイナリエディタで確認した理由は、.xml ファイルで 0x00 に設定した Device manufacturer, Device model, Profile creator のフィールドが .icc ファイルでも 0x00 となっているか心配だったからである。結果としては以下の通り 0x00 となっていることが確認できた。 それ以外の Profile header も頑張って目視で確認した。

Profile header の 0x00 埋め確認の様子

Tag table と Tagged element data は ProfileDump の Validate Profile 機能を使って確認した。 ProfileDump を使用した理由は ICC の Webページ[7]に以下の記載があったからである。

For convenience of users a compiled version of the Profile Dump utility is available. This will read the contents of an ICC profile and run the SampleICC validation routine to test for conformance with the current ICC specification.

なお、その近くに "Profile Dump does not test for conformance with all aspects of the ICC specification" とも書かれていたが、 あくまで個人用途ICC profile であるため、今回は ProfileDump だけで十分だと判断した。

Pythonスクリプトで作成した .xml ファイルから変換した Gamma2.4, BT.2020 の ICC profile に対して Validate Profile 機能を使用すると以下のようになった(①を押すと②が表示された)。

ProfileDump の Validate Profile 機能を使用した様子

"NonComplaint!" というメッセージが出てしまっているが、同様のメッセージは Adobe製 の Display P3 の ICC profile でも出ていたので 今回は気にしない ことにした。

ChromePhotoshop での動作確認

最後の確認として ChromePhotoshop で Color Checker 画像を取り扱った。

最初に Chrome での確認について説明する。まず Gamma2.4_BT.709_D65 の ColorChecker を Gamma3.5_ACES-AP0_D65 に変換した。結果は下図の (a) の通りである。 当然だが普通の sRGB モニターでは異常な絵として表示される。

次に Gamma3.5_ACES-AP0_D65 の特性を記した ICC profile を作成し画像ファイルに埋め込んだ。結果は下図の (b) である。カラマネの働く Google Chrome で見ると正常な絵として表示される。これにより作成した ICC profile は Chrome で正しく認識されたと判断する。

(a) (b)
zu1 zu2
Chrome で作成した ICC profile が扱われる例。(a) は profile無し。(b) は profile 有り。

続いて Photoshop での確認について説明する。まず、 Gamma2.4_BT.709_D65 の特性を記した ICC profile を作成しOS にインストールした(Windows だと .icc ファイルを右クリックでメニューが出る)。次に Photoshop を起動して先ほど作成した (b) の画像を開いた後、プロファイル変換で下図の通りに Gamma2.4-BT709-D65 へと変換した。

Photoshop で自作の ICC profile を使ってプロファイル変換をする様子

プロファイル変換後の画像ファイルが下図の (c) である。そして念の為 ImageMagickICC profile を削除した画像ファイルが (d) である。(c) は Color Checker の表示であるし、(d) も (a) とは全く異なった絵となっているのでプロファイル変換は成功している、別の言い方をすると作成した ICC profile は Photoshop で正しく認識されたと考える※3。

※3 本来であれば各パッチの誤差を⊿E2000などで検証すべきなのだが、今回は簡易動作確認なので目視評価のみとした

(c) (d)
zu1 zu2
Photoshop にて ACES AP0 to BT.709 にプロファイル変換した例。(c) は profile有り。(d) は profile 無し。

付録

今回の作業で使用したソースやデータを参考までに添付しておく。例によって何か問題が起こっても保証しない。 またソースコードは筆者の Docker 環境でしか動作しないと思うので注意して頂きたい。

github.com

作成した .xml ファイルの例

  • Gamma2.4_BT.709_D65.xml
  • Gamma3.5_ACES-AP0_D65.xml

作成した .icc ファイルの例

  • Gamma2.4_BT.709_D65.icc
  • Gamma3.5_ACES-AP0_D65.icc

作成に使用したソースコード

  • icc_profile_calc_param.py
  • icc_profile_xml_control.py
  • debug_icc_profile.py

感想

念願の ICC profile 作成にひとまず成功した。今では Photoshop で生成した画像から ICC profile を奪い取る生活をしていたが、今後は自分が欲する任意の特性の profile を比較的簡単に作れそうであり良かった。

一方で PCS や Rendering Intent に関しては知識不足&経験不足な点が幾つもあるので、資料の熟読や各種CMMの動作確認を行って理解を深めていきたい。

参考資料

[1] International Color Consortium, "Specification ICC.1:2010 (Profile version 4.3.0.0)", http://www.color.org/specification/ICC1v43_2010-12.pdf

[2] International Color Consortium, "Profile viewing and testing resources", http://www.color.org/profileview2.xalter .

[3] it-swarm-ja.tech, "カラープロファイルの名前を変更し、ICCファイルに保存されているタイトルを変更するにはどうすればよいですか?", https://www.it-swarm-ja.tech/ja/system-settings/%e3%82%ab%e3%83%a9%e3%83%bc%e3%83%97%e3%83%ad%e3%83%95%e3%82%a1%e3%82%a4%e3%83%ab%e3%81%ae%e5%90%8d%e5%89%8d%e3%82%92%e5%a4%89%e6%9b%b4%e3%81%97%e3%80%81icc%e3%83%95%e3%82%a1%e3%82%a4%e3%83%ab%e3%81%ab%e4%bf%9d%e5%ad%98%e3%81%95%e3%82%8c%e3%81%a6%e3%81%84%e3%82%8b%e3%82%bf%e3%82%a4%e3%83%88%e3%83%ab%e3%82%92%e5%a4%89%e6%9b%b4%e3%81%99%e3%82%8b%e3%81%ab%e3%81%af%e3%81%a9%e3%81%86%e3%81%99%e3%82%8c%e3%81%b0%e3%82%88%e3%81%84%e3%81%a7%e3%81%99%e3%81%8b%ef%bc%9f/960965094/ .

[4] International Color Consortium, "Open source tools", http://www.color.org/opensource.xalter .

[5] awm-Tech, "ImageMagickICC プロファイルを扱う #3 コマンド解説", https://blog.awm.jp/2017/08/06/imicc/

[6] International Color Consortium, "iccMAX - Reference implementation and test suite", http://www.color.org/iccmax/index.xalter#reficcmax

[7] International Color Consortium, "SampleICC Profile Dump utility", http://www.color.org/profdump.xalter

Netflix, Amazon Prime Video で見つけたテスト用動画

1. 概要

HDR対応の配信サービスについて調べていたら、NetflixAmazon Prime Video にテスト用の動画があることを見つけた。メモとして残しておく。

2. Netflix

2.1. Test Patterns

シーン4 の "DOVI" の Prefix が付いている動画は HDR(自宅の BRAVIA で確認)。それ以外は SDR の模様。

www.netflix.com

2.2. Chimera HDR

1-2 のジェットコースターで頭に GoPro っぽいのを付けているオジサンの笑顔が好き。

www.netflix.com

3. Amazon Prime Video

3.1. Playback Quality Test Content

シーズン5と6がタイトル的には HDR なのだが、自宅の BRAVIA で再生したところ SDR だった(※1, ※2)。残念。

www.amazon.co.jp

※1 サーバー側で HDR to SDR に変換されたのではなく、そもそもアップロードしたファイルが SDR だったように見える。画面下部に「709」の文字もあったし。

※2 BRAVIA の Prime Video アプリのバージョンの問題かとも思ったが、「ジェームズ・メイの日本探訪」は普通に HDR で再生できているので、コンテンツ側の問題だと考えている。

4. 感想

自分が欲しいパターンとは違っていて、残念ながら自分の環境では上手く活用できそうにないなーと思った。