0. 更新履歴
日付 | Revision | 内容 |
---|---|---|
2023/05/20 | rev.1 | 新規作成 |
2023/05/24 | rev.2 | DCTL の Syntax Error の確認方法を追記 |
2023/06/02 | rev.3 | DCTL の printf デバッグ方法を追記 |
1. 背景
諸事情により DaVinci CTL (DCTL) を使って動画コンテンツの解析をしたくなった。 しかし、筆者は DCTL を全く触ったことが無かったため、まずは簡単な DCTL のコードを書いてみることにした。
2. 目的
- DCTL をとりあえず試してみる
- 実装で苦労した点をまとめておく
3. 結論
簡単な DCTL のコードを書き DaVinci 用のエフェクトを作成することに成功した。成果物の紹介と苦労した点を以下に示す。
3.1. 成果物の紹介
2020年に作成した HDRコンテンツ解析用 Luminance Map の生成コードを DCTL で書き、 DaVinci Resolve のエフェクトとして利用可能にした。
ソースコードは以下で公開している。動作の様子を動画1 に示す。
3.2. 実装で苦労した点
- ①エラーログが無く Syntax Error が出ないのでコードの文法誤りの検出が困難
C:\ProgramData\Blackmagic Design\DaVinci Resolve\Support\LUT\TY_DCTL\show_internal_value.dctl(3106): warning: parameter "rgb" was set but never used C:\ProgramData\Blackmagic Design\DaVinci Resolve\Support\LUT\TY_DCTL\show_internal_value.dctl(3148): error: identifier "rgb" is undefined 2 errors detected in the compilation of "C:\ProgramData\Blackmagic Design\DaVinci Resolve\Support\LUT\TY_DCTL\show_internal_value.dctl".
図1. DCTL Off 時の様子 | 図2. 閾値を 1.0 に設定した場合の様子 | 図3. 閾値を 10.0 に設定した場合の様子 |
2023/06/02 追記
ややトリッキーではありますが、DCTL で printf デバッグすることに成功しました。詳細は以下の記事を参照下さい。 trev16.hatenablog.com
4. DCTL について筆者が理解した点
以下で筆者が理解した点を参考情報として残しておく。 なお、今回作成した DCTL のプラグインは EDIT ページで実行する想定で作成した。 Colorページでの運用は今のところ考えていない(Colorページでも使えるとは思うが)。
4.1. DCTL のマニュアルは README.txt のみ
DaVinci Resolve の公式マニュアルには詳細の記述がない。
詳細マニュアルは DaVinci 起動時にメニューバーから Help --> Documentation --> Developer を選択した際に 開くウィンドウの先にある DaVinciCTL/README.txt のみである。
4.2. 生成した DCTLファイルは LUT と同じフォルダに配置する
作成した DCTL のコードは .dctl の拡張子で保存して、以下のフォルダに配置する。
- Mac OS X:
Library/Application Support/Blackmagic Design/DaVinci Resolve/LUT
- Windows:
C:\ProgramData\Blackmagic Design\DaVinci Resolve\Support\LUT
- Linux:
/home/resolve/LUT
意外なことに DCTL 用のフォルダではなく、LUT用のフォルダに配置 する仕様であった。 DaVinci 的には DCTL も LUT も内部的には似たような取り扱いなのかもしれない。
4.3. DCTL の処理は Timeline color space で行われる
非常に恥ずかしい話なのだが、筆者はこれまで DaVinci の EDITページで色処理を行う経験が殆どなく、 Timeline color space が何のために存在しているのか分かっていなかった(勝手に内部処理は Linear空間で行われると考えていた)。
今回 DCTL のコードを書くことで初めて Timeline color space の意味が理解できた。 筆者の理解は次の通りである。Timeline color space は Color Grading における ACEScct のように、信号処理の内容に応じて適切な色空間を選択するために存在している。
さて、そうなると Timeline color space の値域を正しく理解しておく必要がある。 なぜならば値域を理解しないことには DCTL のコードを書けないからである(HDR の場合は 1.0 を超える値を取り扱うので)。
筆者が調査したところ、0.0 ~ 1.0 に正規化された入力データを使用した場合の Timeline color space の値域は以下の表1となることが分かった。
入力の Gamma | Timeline の Gamma Linear |
Timeline の Gamma PQ |
Timeline の Gamma 2.4 |
---|---|---|---|
2.4 | 0.0 ~ 1.0 | 0.0 ~ 0.508 | 0.0 ~ 1.0 |
PQ | 0.0 ~ 100.0 | 0.0 ~ 1.0 | 0.0 ~ 6.81 |
設定によって値域が大きく異なるため、Timeline color space で処理を行う DCTL コードを書く際は、この点に注意する必要がある。
4.4. DCTL では CTL のコードをそのまま流用できない
筆者は当初、CTL のコードも include
して使い回せると考えていたのだが、そんなことは無かった。
以下は SMPTE ST 2084 の EOTF を CTL から DCTL に書き換えた際の diff である。 見て分かるように様々な変更が入るため CTL をそのまま流用するのは不可能であった。
--- st2084.ctl 2023-05-14 11:48:03.867909400 +0900 +++ st2084.dctl 2023-05-14 11:50:22.216460100 +0900 @@ -6,23 +6,23 @@ const float pq_C = 10000.0; -float ST2084_2_Y( float N ) +__DEVICE__ float ST2084_2_Y( float N ) { - float Np = pow( N, 1.0 / pq_m2 ); + float Np = _powf( N, 1.0 / pq_m2 ); float L = Np - pq_c1; if ( L < 0.0 ) L = 0.0; L = L / ( pq_c2 - pq_c3 * Np ); - L = pow( L, 1.0 / pq_m1 ); + L = _powf( L, 1.0 / pq_m1 ); return L * pq_C; // returns cd/m^2 } -float[3] ST2084_2_Y_f3( float in[3]) +__DEVICE__ float3 ST2084_2_Y_f3( float3 in ) { - float out[3]; - out[0] = ST2084_2_Y( in[0]); - out[1] = ST2084_2_Y( in[1]); - out[2] = ST2084_2_Y( in[2]); + float3 out; + out.x = ST2084_2_Y( in.x ); + out.y = ST2084_2_Y( in.y ); + out.z = ST2084_2_Y( in.z ); return out; }
主な変更箇所は以下の通りである。
- 関数定義の冒頭に
__DEVICE__
の接頭語がつく pow
を_powf
に変更float in[3]
がfloat3
に変わる- それにともないメンバのアクセスに
.x
,.y
,.z
の記述が必要
- それにともないメンバのアクセスに
5. 感想
思っていたより難易度が高かったが DCTL の基本的な書き方を理解できた。ここまで来れば応用は割と簡単なので、 今後は本来やりたかった処理を数週間かけて実装していきたい。