前回の記事では、scene-referred環境でのLUTの扱いについて整理しました。

今回は同じタイミングで問い合わせがあった
・外部で編集されたconfig.ocioがFlameで読み込めない
・CDLがベイクされたEDLの扱い
・.CCCファイルを用いた運用
を整理していきます。

外部で編集されたconfig.ocioが読み込めない

編集されたconfig.ocioをFlameにインポートしたときのログを確認しました。

CLRMGT: ERROR: The heuristics currently only support scene-referred color spaces. Please set the interchange roles.

Failed loading '/Volumes/StorageMedia/Apple_Project/Import_CDL/setups/colour_mgmt/studio-config-v1.0.0_aces-v1.3_ocio-v2.1.ocio': [The heuristics currently only support scene-referred color spaces. Please set the interchange roles.]. Defaulting to RAW config.

1行目の意味
ディスプレイ変換を含む場合、自動推測では解決できないため、scene-referred以外の経路では、
interchange roleの明示が必要になります。

試しに、新規にダウンロードしたstudio.config.ocioを編集。

roles:
  aces_interchange: ACES2065-1
# cie_xyz_d65_interchange: CIE XYZ-D65 - Display-referred > コメントアウト
  color_picking: sRGB Encoded Rec.709 (sRGB)
  color_timing: ACEScct
  compositing_log: ACEScct
  data: Raw
  matte_paint: ACEScct
  scene_linear: ACEScg
  texture_paint: sRGB Encoded Rec.709 (sRGB)

同じエラーになることを確認

CLRMGT: ERROR: The heuristics currently only support scene-referred color spaces. Please set the interchange roles.

Failed loading '/Volumes/StorageMedia/Apple_Project/Import_CDL/setups/colour_mgmt/studio-config-v1.0.0_aces-v1.3_ocio-v2.1.ocio': [The heuristics currently only support scene-referred color spaces. Please set the interchange roles.]. Defaulting to RAW config.

Flame(というよりOCIO 2.x)は、ディスプレイ変換の共通インターチェンジとしてXYZが使われる設計です。

入力(scene)

reference / interchange space(CIE-XYZ D65)

display transform

表示

なぜXYZが必要になるか

ディスプレイは全部違う色域だからです:

  • Rec.709
  • P3
  • sRGB
  • HDR

これらを直接相互変換すると複雑になるので、全部いったんXYZに集めるという設計です。

補足

Flameが常にXYZで内部処理しているわけではありません。
ディスプレイパイプラインの解決時にXYZが中間として必要になります。

  • 内部作業 → ACEScg
  • 表示変換 → XYZ経由

DaVinci ResolveからCDLを作成

今回の検証を再現するために、DaVinci ResolveからCDLをベイクしたEDLを作成しました。

DaVinci Resolveカラーマネージメント設定

Primariesから調整

CDL調整から見た目、BT.1886 Rec.709のレンジにフィットするように、オリジナルのACES2065-1は、
コントラストとクロマを少しおさえています。

CDL書き出し(拡張子は.edl)

EDL確認

Figo:~ admin$ cat /Volumes/StorageMedia/Apple_Project/Import_CDL/setups/colour_mgmt/Resolve_CDL/edit.edl
TITLE: edit.edl
FCM: NON-DROP FRAME

001  AX       V     C        01:38:20:03 01:38:21:03 01:00:00:00 01:00:01:00  
*ASC_SOP (1.628218 1.628218 1.628218)(-0.161355 -0.161355 -0.161355)(1.000000 1.000000 1.000000)
*ASC_SAT 1.380000

002  AX       V     C        01:13:49:02 01:13:50:02 01:00:01:00 01:00:02:00  
*ASC_SOP (1.401167 1.401167 1.401167)(-0.122730 -0.122730 -0.122730)(1.102000 1.102000 1.102000)
*ASC_SAT 1.000000

003  AX       V     C        03:01:29:06 03:01:30:06 01:00:02:00 01:00:03:00  
*ASC_SOP (1.354002 1.354002 1.354002)(0.000000 0.000000 0.000000)(1.384000 1.384000 1.384000)
*ASC_SAT 1.400000

Figo:~ admin$ 

DaVinci Resolveから書き出されたCDL付きのEDLでは、ファイル名が保持されないため、
Record Timecode(イベント単位)でCDL情報が管理されています。

DeliverページのColor Space Tag / Gamma Tagがうまく反映されない?

ACES Output Transform > No Output Transform

DeliverページのColor Space Tag / Gamma Tagは表示変換としては使われず、
元のscene-referredカラースペースが維持される

DaVinci Resolveのカラーパイプライン

  • Color science : ACEScct
  • Working space : ACEScct(ACESモードでは固定)
  • Output Transform : None (No Output Transform)

つまり、DaVinciResolve内部は

ACES2065-1 (source)
↓ IDT
ACEScct (grading working)
↓ CDL
ACEScct

ACES2065-1で書き出し (Output Transformが無効のため、display変換を通らずscene-referredのまま出力)

Tagged Colour Space > From File of Rules (OCIOコンフィグは、Flameデフォルト2.0)

CDLはscene-referred空間で定義されるため、ワーキングカラースペースがLOGエンコード (ACEScct)でも
リニアエンコード (ACES2065-1) でも同じ結果になります。

DaVinci Resolveガイド用としてFlameにインポート

次に、CDL(.edl)をFlameからインポートしてDaVinci Resolveと同じ結果になるか確認してみましょう。

CDLインポート時の注意点とカラーマネージメント

DaVinci Resolveから書き出したCDL(.edl)をインポート

EDLをインポートする場合、必ずフレームレートを確認
シーケンスレゾリューションも設定

Convert CDL Lookボタンを有効化してインポート

Convert CDL Look

CDLデータがEDLにベイクされている場合、Lookノードがセグメントに追加され、CDL情報がLookとして引き継がれます。

ACES2065-1フッテージをコンフォーム

DaVinci Resolveのリザルト(Rec.709 BT.1886 )とミスマッチ

なぜ、ミスマッチなのか?

DaVinci Resolve > ワーキングカラースペースはACEScct

ACES2065-1 (source)
↓ IDT
ACEScct (grading working)
↓ CDL
ACEScct

Colour Management (緑色) ノードをセグメントのソースに追加

Input Transform > Input Colour Space > From Source (ACES2065-1)

Working Colour Space > ACEScct (DaVinci Resolveのワーキングと合わせる)

Waveformで確認すると、BT.1886 Rec.709のレンジに収まっています

Colour Managementノードを全てのタイムラインセグメントにコピー

DaVinci Resolveから書き出したACES2065-1

Flameシーケンスセグメント(CDL)

LookノードからCDL情報を確認

CDL

CDLはショットごとの色補正をSlope・Offset・Power・Saturationの値で記録する標準フォーマットです。

今回確認できたこと

  • Resolve ワーキング = ACEScct
  • Resolve 書き出し = ACES2065-1
  • Flame シーケンス = ACEScct
  • CDL適用 → 同ポジ

つまり

scene-referred (LOGエンコード) ↔ scene-referred (リニアエンコード)間でもCDLは一致

まとめ

ここまでで、DaVinci Resolveから書き出したCDL(.edl)をFlameにインポート、
scene-referred環境でも同じ結果になることが確認できました。

ただし、EDLベースのCDL情報はイベント単位で記録されており、
そのままでは複数ショットをまとめて扱うには向いていません。

そこで次は、CDLを.cccファイルとしてまとめて、複数ショットの補正をひとつのファイルで管理できる形にしていきます。

CDL(.edl)から.cccファイルにまとめる

CDLはSlope・Offset・Power・Saturationの値で色補正を記録します。

.cccファイルは、cccidをキーにCDL値とショットを識別するファイル名をまとめて管理するフォーマットです。

.cccファイルフォーマット

<ColorCorrectionCollection xmlns="urn:ASC:CDL:v1.2">
  <ColorCorrection id="A230C0881_154515-154545">
    <Description>A230C0881[154515-154545].exr</Description>
    <SOPNode>
      <Slope>1.29 0.855 1.087</Slope>
      <Offset>0.029 -0.0145 0.0</Offset>
      <Power>1.0 1.058 1.0</Power>
    </SOPNode>
    <SATNode>
      <Saturation>1.116</Saturation>
    </SATNode>
  </ColorCorrection>
</ColorCorrectionCollection>

.cccファイルを作成するには、CDL値に加えてショットを識別するファイル名が必要になります。
まず、DaVinci ResolveからCDL(.edl)を書き出しましたが、ファイル名の情報は含まれていません。

Figo:~ admin$ cat /Volumes/StorageMedia/Apple_Project/Import_CDL/setups/colour_mgmt/Resolve_CDL/edit.edl 
TITLE: edit.edl
FCM: NON-DROP FRAME

001  AX       V     C        01:38:20:03 01:38:21:03 01:00:00:00 01:00:01:00  
*ASC_SOP (1.628218 1.628218 1.628218)(-0.161355 -0.161355 -0.161355)(1.000000 1.000000 1.000000)
*ASC_SAT 1.380000

Figo:~ admin$ 

.drx (DaVinci Resolve eXchange)も確認しましたが、
今回の用途ではファイル名が取得できなかったため諦めました。

最終的に、EDLからCDL値とソースタイムコードを取得し、XMLからファイル名とソースタイムコードを取得します。
両者のソースタイムコードをキーとして照合することで、CDL値とファイル名を紐付けることができます。

役割分担

EDL > CDL情報/ソースタイムコード

001  AX       V     C        01:38:20:03 01:38:21:03 01:00:00:00 01:00:01:00  
*ASC_SOP (1.628218 1.628218 1.628218)(-0.161355 -0.161355 -0.161355)(1.000000 1.000000 1.000000)
*ASC_SAT 1.38000

XML > ファイルネーム/ソースタイムコード

<name>A001C002_0904242F[141603-141626].exr</name>
<pathurl>file://ACES2065-1/A001C002_0904242F[141603-141626].exr</pathurl>
<timecode>
    <string>01:38:20:03</string>
    <displayformat>NDF</displayformat>
    <rate>

CDL(.edl)とXMLを元に.cccファイルを生成する簡易スクリプトも作成しました。
参考用として公開します。

edl_xml_to_ccc.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import re
import sys
import xml.etree.ElementTree as ET
from pathlib import Path

ASC_CDL_NS = "urn:ASC:CDL:v1.2"
ET.register_namespace("", ASC_CDL_NS)


def qname(tag):
    return f"{{{ASC_CDL_NS}}}{tag}"


def indent(elem, level=0):
    i = "\n" + level * "  "
    if len(elem):
        if not elem.text or not elem.text.strip():
            elem.text = i + "  "
        for child in elem:
            indent(child, level + 1)
        if not child.tail or not child.tail.strip():
            child.tail = i
    else:
        if level and (not elem.tail or not elem.tail.strip()):
            elem.tail = i


def make_cccid(base_name, used_ids):
    stem = Path(base_name).stem
    cccid = re.sub(r"[^A-Za-z0-9_-]+", "_", stem)
    if not cccid:
        cccid = "SHOT"

    original = cccid
    index = 1
    while cccid in used_ids:
        cccid = f"{original}_{index:03d}"
        index += 1

    used_ids.add(cccid)
    return cccid


def parse_triplet_text(text):
    parts = text.replace(",", " ").split()
    if len(parts) != 3:
        raise ValueError(f"Expected 3 values, got: {text}")
    return tuple(float(x) for x in parts)


def parse_edl_cdl_events(edl_path):
    """
    Resolve EDL から ASC_SOP / ASC_SAT をイベント順で拾う
    """
    events = []
    current = None

    sop_re = re.compile(
        r"\*+\s*ASC_SOP\s*\(\s*([^)]+?)\s*\)\s*\(\s*([^)]+?)\s*\)\s*\(\s*([^)]+?)\s*\)",
        re.IGNORECASE
    )
    sat_re = re.compile(
        r"\*+\s*ASC_SAT\s+([^\s]+)",
        re.IGNORECASE
    )
    event_re = re.compile(r"^\s*\d+\s+\S+\s+[VA]\s+[CDWKMFB]")

    with open(edl_path, "r", encoding="utf-8", errors="ignore") as f:
        for raw_line in f:
            line = raw_line.rstrip("\n")

            if event_re.match(line):
                if current and "slope" in current and "saturation" in current:
                    events.append(current)
                current = {}
                continue

            if current is None:
                continue

            m = sop_re.search(line)
            if m:
                current["slope"] = parse_triplet_text(m.group(1))
                current["offset"] = parse_triplet_text(m.group(2))
                current["power"] = parse_triplet_text(m.group(3))
                continue

            m = sat_re.search(line)
            if m:
                current["saturation"] = float(m.group(1))
                continue

    if current and "slope" in current and "saturation" in current:
        events.append(current)

    return events


def text_or_none(elem, path):
    child = elem.find(path)
    if child is not None and child.text is not None:
        return child.text.strip()
    return None


def parse_xml_file_names(xml_path):
    """
    XML から clipitem 順の file name を拾う
    同じ file id の再利用があっても clipitem 順で並べる
    """
    tree = ET.parse(xml_path)
    root = tree.getroot()

    names = []

    for clipitem in root.findall(".//clipitem"):
        file_elem = clipitem.find("./file")
        if file_elem is None:
            continue

        file_name = text_or_none(file_elem, "./name")
        if file_name:
            names.append(file_name)

    return names


def add_cc(root, cccid, description, slope, offset, power, saturation):
    cc = ET.SubElement(root, qname("ColorCorrection"), {"id": cccid})

    desc = ET.SubElement(cc, qname("Description"))
    desc.text = description

    sop = ET.SubElement(cc, qname("SOPNode"))

    slope_node = ET.SubElement(sop, qname("Slope"))
    slope_node.text = f"{slope[0]:.10g} {slope[1]:.10g} {slope[2]:.10g}"

    offset_node = ET.SubElement(sop, qname("Offset"))
    offset_node.text = f"{offset[0]:.10g} {offset[1]:.10g} {offset[2]:.10g}"

    power_node = ET.SubElement(sop, qname("Power"))
    power_node.text = f"{power[0]:.10g} {power[1]:.10g} {power[2]:.10g}"

    sat = ET.SubElement(cc, qname("SATNode"))
    sat_node = ET.SubElement(sat, qname("Saturation"))
    sat_node.text = f"{saturation:.10g}"


def build_ccc_from_edl_and_xml(edl_path, xml_path, output_path):
    edl_events = parse_edl_cdl_events(edl_path)
    xml_names = parse_xml_file_names(xml_path)

    count = min(len(edl_events), len(xml_names))

    print(f"EDL CDL events : {len(edl_events)}")
    print(f"XML file names : {len(xml_names)}")
    print(f"Matched shots  : {count}")

    root = ET.Element(qname("ColorCorrectionCollection"))
    used_ids = set()

    for i in range(count):
        ev = edl_events[i]
        file_name = xml_names[i]
        cccid = make_cccid(file_name, used_ids)

        add_cc(
            root=root,
            cccid=cccid,
            description=file_name,
            slope=ev["slope"],
            offset=ev["offset"],
            power=ev["power"],
            saturation=ev["saturation"],
        )

    indent(root)
    ET.ElementTree(root).write(output_path, encoding="utf-8", xml_declaration=True)

    print("Done")
    print(f"EDL : {edl_path}")
    print(f"XML : {xml_path}")
    print(f"CCC : {output_path}")


def main():
    if len(sys.argv) != 4:
        print("Usage:")
        print("  ./edl_xml_to_ccc.py input.edl input.xml output.ccc")
        sys.exit(1)

    edl_path = sys.argv[1]
    xml_path = sys.argv[2]
    output_path = sys.argv[3]

    build_ccc_from_edl_and_xml(edl_path, xml_path, output_path)


if __name__ == "__main__":
    main()

.cccファイル作成

edit.edl / edit.xml / edl_xml_to_ccc.pyを同じ階層に配置

Figo:~ admin$ cd /Volumes/StorageMedia/Apple_Project/Import_CDL/setups/colour_mgmt/Resolve_CDL/
Figo:Resolve_CDL admin$ tree .
.
├── edit.edl
├── edit.xml
└── edl_xml_to_ccc.py

1 directory, 3 files
Figo:Resolve_CDL admin$ 

python実行 > edl / xml / cccファイル名

Figo:Resolve_CDL admin$ python3 edl_xml_to_ccc.py edit.edl edit.xml edit.ccc
EDL CDL events : 3
XML file names : 3
Matched shots  : 3
Done
EDL : edit.edl
XML : edit.xml
CCC : edit.ccc
Figo:Resolve_CDL admin$ 

生成された.cccファイル

生成されたedit.cccファイルの内容は以下のようになります。

生成された.cccファイルの先頭部分(抜粋)

<ColorCorrectionCollection xmlns="urn:ASC:CDL:v1.2">
  <ColorCorrection id="A001C002_0904242F_141603-141626_"> > id = cccid
    <Description>A001C002_0904242F[141603-141626].exr
    <SOPNode>
      <Slope>1.628218 1.628218 1.628218
      <Offset>-0.161355 -0.161355 -0.161355
      <Power>1 1 1
    </SOPNode>
      <Saturation>1.38
    </SATNode>
edit.ccc
<?xml version='1.0' encoding='utf-8'?>
<ColorCorrectionCollection xmlns="urn:ASC:CDL:v1.2">
  <ColorCorrection id="A001C002_0904242F_141603-141626_">
    <Description>A001C002_0904242F[141603-141626].exr</Description>
    <SOPNode>
      <Slope>1.628218 1.628218 1.628218</Slope>
      <Offset>-0.161355 -0.161355 -0.161355</Offset>
      <Power>1 1 1</Power>
    </SOPNode><SATNode>
      <Saturation>1.38</Saturation>
    </SATNode>
  </ColorCorrection><ColorCorrection id="B004C0023_106298-106321_">
    <Description>B004C0023.[106298-106321].exr</Description>
    <SOPNode>
      <Slope>1.401167 1.401167 1.401167</Slope>
      <Offset>-0.12273 -0.12273 -0.12273</Offset>
      <Power>1.102 1.102 1.102</Power>
    </SOPNode><SATNode>
      <Saturation>1</Saturation>
    </SATNode>
  </ColorCorrection><ColorCorrection id="A003C013_220415_R07B_261342-261365_">
    <Description>A003C013_220415_R07B[261342-261365].exr</Description>
    <SOPNode>
      <Slope>1.354002 1.354002 1.354002</Slope>
      <Offset>0 0 0</Offset>
      <Power>1.384 1.384 1.384</Power>
    </SOPNode><SATNode>
      <Saturation>1.4</Saturation>
    </SATNode>
  </ColorCorrection>
</ColorCorrectionCollection>

.cccファイルをインポート

先ほど作成した.cccファイルは、3カットのColorCorrectionだったので、ダミーのColorCorrectionを追加し、
Lookノードでの切り替え確認を行うための簡易スクリプトも作りました。

Figo:Resolve_CDL admin$ tree .
.
├── add_dummy_ccc.py > ダミーのColorCorrectionを追加する簡易スクリプト
├── edit.ccc
├── edit.edl
├── edit.xml
└── edl_xml_to_ccc.py

1 directory, 5 files
Figo:Resolve_CDL admin$ 
add_dummy_ccc.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import sys
import random
import re
import xml.etree.ElementTree as ET
from pathlib import Path

ASC_CDL_NS = "urn:ASC:CDL:v1.2"
ET.register_namespace("", ASC_CDL_NS)


def qname(tag):
    return f"{{{ASC_CDL_NS}}}{tag}"


def indent(elem, level=0):
    i = "\n" + level * "  "
    if len(elem):
        if not elem.text or not elem.text.strip():
            elem.text = i + "  "
        for child in elem:
            indent(child, level + 1)
            if not child.tail or not child.tail.strip():
                child.tail = i + "  "
        if not elem[-1].tail or not elem[-1].tail.strip():
            elem[-1].tail = i
    else:
        if level and (not elem.tail or not elem.tail.strip()):
            elem.tail = i


def make_dummy_values(index):
    base = index * 0.01

    slope = (
        round(1.0 + base, 6),
        round(1.0 - base * 0.5, 6),
        round(1.0 + base * 0.3, 6)
    )

    offset = (
        round(base * 0.1, 6),
        round(-base * 0.05, 6),
        round(0.0, 6)
    )

    power = (
        1.0,
        round(1.0 + base * 0.2, 6),
        1.0
    )

    saturation = round(1.0 + base * 0.4, 6)

    return slope, offset, power, saturation


def make_cccid_from_description(description):
    stem = Path(description).stem
    cccid = re.sub(r"[^A-Za-z0-9_-]+", "_", stem)
    cccid = cccid.strip("_")
    if not cccid:
        cccid = "SHOT"
    return cccid


def make_unique_dummy_description(existing_descriptions):
    """
    既存Descriptionと絶対に重複しない名前を作る
    """
    while True:
        cam = random.choice(["A", "B", "C"])
        roll = random.randint(1, 999)
        cut = random.randint(1, 9999)
        start = random.randint(100000, 999999)
        end = start + random.randint(20, 40)

        description = f"{cam}{roll:03d}C{cut:04d}[{start}-{end}].exr"

        if description not in existing_descriptions:
            existing_descriptions.add(description)
            return description


def make_unique_cccid(description, existing_ids):
    """
    Descriptionベースでidを作り、既存idと重複しないようにする
    """
    base_id = make_cccid_from_description(description)
    cccid = base_id
    suffix = 1

    while cccid in existing_ids:
        cccid = f"{base_id}_{suffix:03d}"
        suffix += 1

    existing_ids.add(cccid)
    return cccid


def add_color_correction(root, cccid, description, slope, offset, power, saturation):
    cc = ET.SubElement(root, qname("ColorCorrection"), {"id": cccid})

    desc = ET.SubElement(cc, qname("Description"))
    desc.text = description

    sop = ET.SubElement(cc, qname("SOPNode"))

    slope_node = ET.SubElement(sop, qname("Slope"))
    slope_node.text = f"{slope[0]} {slope[1]} {slope[2]}"

    offset_node = ET.SubElement(sop, qname("Offset"))
    offset_node.text = f"{offset[0]} {offset[1]} {offset[2]}"

    power_node = ET.SubElement(sop, qname("Power"))
    power_node.text = f"{power[0]} {power[1]} {power[2]}"

    sat_parent = ET.SubElement(cc, qname("SATNode"))
    sat_node = ET.SubElement(sat_parent, qname("Saturation"))
    sat_node.text = f"{saturation}"


def add_dummy_entries(input_ccc, output_ccc, count):
    tree = ET.parse(input_ccc)
    root = tree.getroot()

    cc_path = f".//{qname('ColorCorrection')}"
    desc_path = f"./{qname('Description')}"

    existing_ids = set()
    existing_descriptions = set()

    for cc in root.findall(cc_path):
        cccid = cc.attrib.get("id")
        if cccid:
            existing_ids.add(cccid)

        desc = cc.find(desc_path)
        if desc is not None and desc.text:
            existing_descriptions.add(desc.text.strip())

    for i in range(1, count + 1):
        description = make_unique_dummy_description(existing_descriptions)
        cccid = make_unique_cccid(description, existing_ids)
        slope, offset, power, saturation = make_dummy_values(i)

        add_color_correction(
            root=root,
            cccid=cccid,
            description=description,
            slope=slope,
            offset=offset,
            power=power,
            saturation=saturation,
        )

    cc_list = root.findall(qname("ColorCorrection"))

    for cc in cc_list:
        root.remove(cc)

    random.shuffle(cc_list)

    for cc in cc_list:
        root.append(cc)

    indent(root)
    tree.write(output_ccc, encoding="utf-8", xml_declaration=True)

    print("Done")
    print(f"Input : {input_ccc}")
    print(f"Output: {output_ccc}")
    print(f"Added : {count} dummy entries")
    print(f"Total : {len(cc_list)} ColorCorrection entries")


def main():
    if len(sys.argv) != 3:
        print("Usage:")
        print("  ./add_dummy_ccc.py input.ccc output.ccc")
        sys.exit(1)

    input_ccc = sys.argv[1]
    output_ccc = sys.argv[2]

    add_dummy_entries(input_ccc, output_ccc, 30)


if __name__ == "__main__":
    main()

ColorCorrectionを追加した.cccファイル(edit_33.ccc)を作成

Figo:Resolve_CDL admin$ python3 add_dummy_ccc.py edit.ccc edit_33.ccc
Done
Input : edit.ccc
Output: edit_33.ccc
Added : 30 dummy entries
Total : 33 ColorCorrection entries
Figo:Resolve_CDL admin$ tree .
.
├── add_dummy_ccc.py
├── edit_33.ccc >>>>> ColorCorrection30追加
├── edit.ccc
├── edit.edl
├── edit.xml
└── edl_xml_to_ccc.py

1 directory, 6 files
Figo:Resolve_CDL admin$ 

追加した.cccファイルをFlameからインポート
Convert CDL to Lookは無効化

シーケンス名を変更してコンフォーム

Colour Managementノード(緑色)追加してDaVinci ResolveワーキングカラースペースACEScctにトランスフォーム

Lookノード追加

Importボタンから.cccファイルのロケーションに移動

.cccファイルを選択すると、cc ID(cccid)がハイライト

Flameから.cccファイルのインポートは可能です。
ただし、cccidによる各セグメントへの自動適用には対応しておらず、手動での切り替えとなります。

まとめ

.cccファイルはLookノードから読み込むことができ、
複数のCDLを手動で切り替える運用が可能になります。

ただし、cccidとタイムラインセグメントを自動的に紐付ける仕組みはなく、
実運用ではショット数が増えると管理が煩雑になります。

なお、PythonからLookノードへ自動振り分ける方法についても確認していますが、
これについては次回以降の記事で整理します。

次回は、scene-referred環境におけるACESの役割を整理し、
CDLおよび.cccファイル運用の前提となるカラーマネージメントについて確認します。