davinci-resolve-mcp 2.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/AGENTS.md +85 -0
  2. package/CHANGELOG.md +802 -0
  3. package/CLAUDE.md +15 -0
  4. package/LICENSE +21 -0
  5. package/README.md +159 -0
  6. package/SECURITY.md +53 -0
  7. package/bin/davinci-resolve-mcp.mjs +376 -0
  8. package/docs/README.md +56 -0
  9. package/docs/SKILL.md +1145 -0
  10. package/docs/authoring/fuse-dctl-authoring.md +242 -0
  11. package/docs/authoring/script-plugin-authoring.md +195 -0
  12. package/docs/contributing.md +82 -0
  13. package/docs/guides/color-decision-guide.md +387 -0
  14. package/docs/guides/editorial-decision-guide.md +136 -0
  15. package/docs/guides/media-analysis-guide.md +615 -0
  16. package/docs/guides/multicam-setup-guide.md +138 -0
  17. package/docs/install.md +198 -0
  18. package/docs/integrations/workflow-integrations.md +120 -0
  19. package/docs/kernels/README.md +28 -0
  20. package/docs/kernels/audio-fairlight-kernel.md +86 -0
  21. package/docs/kernels/color-grade-kernel.md +103 -0
  22. package/docs/kernels/extension-authoring-kernel.md +101 -0
  23. package/docs/kernels/fusion-composition-kernel.md +91 -0
  24. package/docs/kernels/media-pool-ingest-kernel.md +147 -0
  25. package/docs/kernels/project-lifecycle-kernel.md +120 -0
  26. package/docs/kernels/render-deliver-kernel.md +92 -0
  27. package/docs/kernels/review-annotation-kernel.md +110 -0
  28. package/docs/kernels/timeline-conform-interchange-kernel.md +99 -0
  29. package/docs/kernels/timeline-edit-kernel.md +189 -0
  30. package/docs/notes/codec-plugin-notes.md +136 -0
  31. package/docs/notes/dctl-notes.md +234 -0
  32. package/docs/notes/fusion-template-notes.md +136 -0
  33. package/docs/notes/lut-notes.md +136 -0
  34. package/docs/notes/openfx-notes.md +120 -0
  35. package/docs/process/release-process.md +152 -0
  36. package/docs/reference/api-coverage.md +488 -0
  37. package/docs/reference/resolve_scripting_api.txt +1012 -0
  38. package/examples/README.md +53 -0
  39. package/examples/markers/README.md +81 -0
  40. package/examples/media/README.md +94 -0
  41. package/examples/timeline/README.md +98 -0
  42. package/install.py +1196 -0
  43. package/package.json +52 -0
  44. package/scripts/audit_api_parity.py +275 -0
  45. package/scripts/live_media_analysis_polish_probe.py +65 -0
  46. package/src/__init__.py +3 -0
  47. package/src/analysis_dashboard.py +4936 -0
  48. package/src/control_panel.py +13 -0
  49. package/src/granular/__init__.py +17 -0
  50. package/src/granular/common.py +727 -0
  51. package/src/granular/folder.py +287 -0
  52. package/src/granular/gallery.py +306 -0
  53. package/src/granular/graph.py +309 -0
  54. package/src/granular/media_pool.py +679 -0
  55. package/src/granular/media_pool_item.py +852 -0
  56. package/src/granular/media_storage.py +179 -0
  57. package/src/granular/project.py +1594 -0
  58. package/src/granular/resolve_control.py +521 -0
  59. package/src/granular/timeline.py +1074 -0
  60. package/src/granular/timeline_item.py +2251 -0
  61. package/src/resolve_mcp_server.py +43 -0
  62. package/src/server.py +15691 -0
  63. package/src/utils/__init__.py +3 -0
  64. package/src/utils/app_control.py +319 -0
  65. package/src/utils/audio_fairlight_live_probe.py +263 -0
  66. package/src/utils/cdl.py +20 -0
  67. package/src/utils/cloud_operations.py +192 -0
  68. package/src/utils/color_grade_live_probe.py +444 -0
  69. package/src/utils/dctl_templates.py +368 -0
  70. package/src/utils/extension_authoring_live_probe.py +292 -0
  71. package/src/utils/fuse_templates.py +1968 -0
  72. package/src/utils/fusion_composition_live_probe.py +284 -0
  73. package/src/utils/layout_presets.py +333 -0
  74. package/src/utils/mcp_stdio.py +32 -0
  75. package/src/utils/media_analysis.py +3618 -0
  76. package/src/utils/media_analysis_jobs.py +796 -0
  77. package/src/utils/media_pool_ingest_live_probe.py +592 -0
  78. package/src/utils/multicam.py +393 -0
  79. package/src/utils/object_inspection.py +287 -0
  80. package/src/utils/platform.py +157 -0
  81. package/src/utils/project_lifecycle_live_probe.py +376 -0
  82. package/src/utils/project_properties.py +601 -0
  83. package/src/utils/render_deliver_live_probe.py +384 -0
  84. package/src/utils/resolve_connection.py +77 -0
  85. package/src/utils/review_annotation_live_probe.py +352 -0
  86. package/src/utils/script_templates.py +1193 -0
  87. package/src/utils/sync_detection.py +887 -0
  88. package/src/utils/timeline_conform_live_probe.py +280 -0
  89. package/src/utils/timeline_kernel_live_probe.py +1091 -0
  90. package/src/utils/timeline_kernel_probe.py +185 -0
  91. package/src/utils/timeline_title_text.py +87 -0
  92. package/src/utils/update_check.py +610 -0
@@ -0,0 +1,99 @@
1
+ # Timeline Conform / Interchange Kernel
2
+
3
+ The Timeline Conform / Interchange kernel expands `timeline` into a safer
4
+ structure, source-range, gap/overlap, interchange, comparison, missing-media,
5
+ and relink-planning layer.
6
+
7
+ Live validation was run against DaVinci Resolve Studio 20.3.2.9 with a
8
+ disposable `_mcp_timeline_conform_probe_*` project and generated synthetic
9
+ video/audio media. Final release probe counts:
10
+
11
+ | Status | Count |
12
+ | --- | ---: |
13
+ | `supported` | 17 |
14
+ | `partially_supported` | 1 |
15
+ | `unsupported` | 0 |
16
+ | `version_or_page_dependent` | 0 |
17
+ | `not_applicable` | 0 |
18
+ | `error` | 0 |
19
+
20
+ The partially supported result was FCPXML round-trip survival: export and import
21
+ both worked, but the imported timeline did not preserve MediaPoolItem-name
22
+ linkage in the comparison snapshot. DRT round-trip matched exactly.
23
+
24
+ ## Added Actions
25
+
26
+ All actions are exposed through `timeline`.
27
+
28
+ | Action | Purpose |
29
+ | --- | --- |
30
+ | `conform_capabilities` | Return structure, analysis, interchange, relink-planning, and source-media safety boundaries. |
31
+ | `probe_timeline_structure` | Snapshot timeline identity, track counts, items, source ranges, media file paths, markers, and optional clip properties. |
32
+ | `detect_gaps_overlaps` | Report same-track gaps and overlaps from the current timeline snapshot. |
33
+ | `source_range_report` | Group source frame ranges by MediaPoolItem/file path, with optional handles and merging. |
34
+ | `export_timeline_checked` | Resolve export aliases and guard timeline export paths to temp locations by default. |
35
+ | `import_timeline_checked` | Guard timeline imports from temp locations and normalize import options. |
36
+ | `compare_timelines` | Compare current timeline to another timeline or two supplied snapshots. |
37
+ | `probe_interchange_roundtrip` | Export, import, compare, and optionally delete the imported timeline. |
38
+ | `detect_missing_media` | Detect missing/offline media using Resolve status fields and file-path existence. |
39
+ | `build_relink_plan` | Read-only search-root scan for relink candidates by missing file basename. |
40
+ | `conform_boundary_report` | Return capabilities, timeline structure, gaps/overlaps, source ranges, and missing-media summary. |
41
+
42
+ ## Interchange Matrix
43
+
44
+ | Format Alias | Export | Round Trip | Notes |
45
+ | --- | --- | --- | --- |
46
+ | `drt` | Supported | Supported | DRT export/import compared with zero differences in the live probe. |
47
+ | `fcpxml` | Supported | Partially supported | Resolve exported a folder containing `Info.fcpxml`; import worked after resolving the primary file, but MediaPoolItem-name linkage was not preserved. |
48
+ | `edl` | Supported | Not forced in release probe | Export succeeded to temp path. EDL round trips can be lossy by design. |
49
+ | `aaf` | Supported | Not forced in release probe | Export succeeded to temp path. AAF options and media relink behavior are build/content dependent. |
50
+ | `otio` | Supported | Not forced in release probe | Export succeeded to temp path. |
51
+
52
+ Supported aliases include `aaf`, `drt`, `edl`, `edl_cdl`, `edl_sdl`,
53
+ `edl_missing_clips`, `fcp7xml`, `fcpxml`, `fcpxml_1_8`, `fcpxml_1_9`,
54
+ `fcpxml_1_10`, and `otio`.
55
+
56
+ ## Supported Findings
57
+
58
+ - Timeline structure snapshots worked across video, audio, and subtitle track
59
+ categories.
60
+ - Same-track gap detection found the deliberate 24-frame video gap in the
61
+ generated timeline.
62
+ - Source range reporting grouped generated media paths with requested handles.
63
+ - Guarded exports succeeded for FCPXML, DRT, EDL, AAF, and OTIO.
64
+ - FCPXML directory-style exports are normalized with a `primary_file` path.
65
+ - DRT export/import/compare round-trip succeeded and cleaned up the imported
66
+ timeline.
67
+ - Synthetic-only unlink, missing-media detection, relink candidate planning,
68
+ and safe relink all worked through generated media.
69
+
70
+ ## Boundaries
71
+
72
+ - Interchange formats are not semantically equivalent. DRT is the strongest
73
+ project-native round-trip path; EDL and FCPXML can lose Resolve-specific
74
+ relationships.
75
+ - The public API exposes timeline items, source ranges, markers, and some media
76
+ references, but not full transition/effect/retime semantics for every format.
77
+ - `build_relink_plan` is intentionally read-only. Execute relinks through
78
+ `media_pool.safe_relink` only with synthetic or explicitly approved paths.
79
+ - Missing-media status fields vary by Resolve build. The kernel combines status
80
+ text with local file existence when a file path is available.
81
+ - Export and import helpers require temp paths by default because they write
82
+ interchange artifacts.
83
+
84
+ ## Live Probe
85
+
86
+ Run the live boundary probe with:
87
+
88
+ ```bash
89
+ python3.11 tests/live_timeline_conform_validation.py --output-dir /tmp/timeline-conform-probe
90
+ ```
91
+
92
+ The harness creates a disposable project, generates synthetic media, builds a
93
+ gapped timeline, probes structure, source ranges, gap/overlap detection,
94
+ interchange export/import/round-trip behavior, synthetic missing-media relink
95
+ planning, writes JSON and Markdown reports, deletes the project, and removes
96
+ generated media.
97
+
98
+ Use `--keep-open` only when you intentionally want to inspect the disposable
99
+ project by hand.
@@ -0,0 +1,189 @@
1
+ # Timeline Edit Kernel Boundary
2
+
3
+ The timeline edit kernel is the supported MCP layer for clip duplication,
4
+ range-copy workflows, and timeline-item state copying. It is built only on
5
+ DaVinci Resolve's public scripting API and preserves source media integrity:
6
+ it references existing Media Pool items and never transcodes, renders, proxies,
7
+ or creates derivatives of source media.
8
+
9
+ ## Live Probe Summary
10
+
11
+ The current boundary was validated on DaVinci Resolve Studio 20.3.2.9 with
12
+ disposable projects and generated synthetic media.
13
+
14
+ Final exhaustive probe result from May 9, 2026:
15
+
16
+ | Status | Count |
17
+ | --- | ---: |
18
+ | Supported | 255 |
19
+ | Partially supported | 4 |
20
+ | Unsupported | 138 |
21
+ | Version/page dependent | 4 |
22
+ | Errors | 0 |
23
+
24
+ The probe first runs the live duplicate/range validation harness, then creates
25
+ a separate disposable project to inspect runtime method availability, timeline
26
+ operations, item properties, keyframes, metadata, cache/voice/take/Fusion/grade
27
+ surfaces, and known API boundaries.
28
+
29
+ Run it with:
30
+
31
+ ```bash
32
+ python3.11 tests/live_duplicate_clips_validation.py --output-dir /tmp/timeline-kernel-probe
33
+ ```
34
+
35
+ The output directory receives both JSON and Markdown reports. Reports are
36
+ generated artifacts and should not be committed.
37
+
38
+ ## Supported Kernel Features
39
+
40
+ ### Clip duplication
41
+
42
+ `timeline(action="duplicate_clips")` duplicates existing video timeline items
43
+ by re-appending the same Media Pool item with the same source trim through
44
+ `MediaPool.AppendToTimeline([{clipInfo}])`.
45
+
46
+ Supported placement modes:
47
+
48
+ - `same_time`
49
+ - `offset`
50
+ - `at_playhead`
51
+ - `track_above`
52
+ - `after_source`
53
+ - `next_gap`
54
+
55
+ Supported placement controls:
56
+
57
+ - `clip_ids` from timeline item unique IDs
58
+ - `selected=True` when Resolve exposes selected/current item state
59
+ - `target_track_index`
60
+ - `track_offset`
61
+ - `record_frame`
62
+ - `record_frame_offset`
63
+
64
+ `copy_clips` is an alias for duplication. `move_clips` duplicates successfully
65
+ first, then deletes the original source items.
66
+
67
+ ### Linked audio
68
+
69
+ `include_linked=True` duplicates linked audio items alongside the source video
70
+ item when Resolve exposes linked item handles. The kernel restores the
71
+ video/audio link state on the duplicated items.
72
+
73
+ ### Range operations
74
+
75
+ The range tools build exact append operations from overlapping source segments:
76
+
77
+ - `copy_range`
78
+ - `duplicate_range`
79
+ - `overwrite_range`
80
+ - `lift_range`
81
+
82
+ `copy_range` and `duplicate_range` copy exact video/audio source segments from
83
+ explicit `start_frame`/`end_frame` values or the current mark in/out. The
84
+ destination uses `record_frame` and optional track targeting.
85
+
86
+ `overwrite_range` deletes whole destination items that overlap the destination
87
+ range, then appends the copied range.
88
+
89
+ `lift_range` deletes whole timeline items in a range. Partial overlaps are
90
+ blocked by default because Resolve does not expose a public razor/split
91
+ primitive. Passing `allow_partial_item_delete=True` confirms deletion of whole
92
+ overlapping items; it does not perform a partial trim.
93
+
94
+ ### Copyable item state
95
+
96
+ The kernel can copy these state groups when Resolve exposes readable/writable
97
+ item APIs for the current item type and page state:
98
+
99
+ - `transform`
100
+ - `crop`
101
+ - `composite`
102
+ - `audio`
103
+ - `retime`
104
+ - `dynamic_zoom`
105
+ - `scaling`
106
+ - `stabilization`
107
+ - `clip_color`
108
+ - `markers`
109
+ - `flags`
110
+ - `enabled`
111
+ - `cache`
112
+ - `voice_isolation`
113
+ - `fusion`
114
+ - `grades`
115
+ - `takes`
116
+ - `keyframes`
117
+
118
+ `copy_properties=True` copies all supported groups. A list or comma-separated
119
+ string can scope copying to specific groups. `copy_keyframes=True` adds the
120
+ `keyframes` group.
121
+
122
+ ### Capability reporting
123
+
124
+ `timeline(action="edit_kernel_capabilities")` returns the maintained support
125
+ map for supported, partially supported, and unsupported behavior.
126
+
127
+ `timeline(action="probe_edit_kernel_item")` is a read-only item probe. It
128
+ reports method availability, `GetProperty()` output, known property values,
129
+ keyframe counts, and linked item summaries.
130
+
131
+ `timeline(action="title_property_scan")` inspects undocumented title and
132
+ generator `TimelineItem.GetProperty()` keys for the selected item scope.
133
+ `set_title_text` and `bulk_set_title_text` use explicit or scanned keys when a
134
+ Resolve build accepts `SetProperty()` writes for title text payloads.
135
+
136
+ ## Partial Support
137
+
138
+ The probe classifies a feature as partially supported when Resolve exposes a
139
+ public API surface, but success can vary by item type, page, build, or current
140
+ UI state.
141
+
142
+ Current partial areas:
143
+
144
+ - Audio properties: some timeline audio `SetProperty` calls return false on
145
+ Resolve Studio 20.3.2.9.
146
+ - Dynamic zoom, scaling, and stabilization: copied through exposed
147
+ `TimelineItem.GetProperty`/`SetProperty` keys when the build accepts writes.
148
+ - Edit-page title and generator text: `title_property_scan` can expose
149
+ undocumented Text+ keys, but key names and write acceptance vary by item type,
150
+ page, and Resolve build.
151
+ - Cache and voice isolation: copied only when item-level read/write APIs are
152
+ callable for the item.
153
+ - Keyframes: copied for exposed properties, but Resolve does not expose enough
154
+ interpolation detail for full-fidelity readback in every case.
155
+
156
+ ## Unsupported Boundaries
157
+
158
+ These are blocked by Resolve's public scripting API, not by MCP plumbing:
159
+
160
+ - Transition cloning: no public timeline-item transition clone/read/write API.
161
+ - Razor/split edits: no direct public timeline split primitive.
162
+ - True partial lift: no safe partial-item delete without a split primitive.
163
+ - Source-less item cloning through append: titles, generators, Fusion
164
+ compositions, and subtitles can exist on the timeline, but source-less items
165
+ do not provide a Media Pool item that `AppendToTimeline([{clipInfo}])` can
166
+ clone.
167
+ - Deep speed-ramp semantics: exposed retime properties and supported keyframes
168
+ can be copied, but opaque speed-ramp curves are not independently inspectable.
169
+
170
+ ## Version/Page Dependent Behavior
171
+
172
+ Some behavior depends on Resolve's current page or bridge state:
173
+
174
+ - `selected=True` can fail to resolve selected/current timeline items when
175
+ Resolve does not expose selection state to the scripting bridge.
176
+ - After inserting or probing source-less items, some Resolve bridge states lose
177
+ a callable `Project.SetCurrentTimeline`; the probe reports this as
178
+ version/page dependent rather than a kernel failure.
179
+ - `probe_edit_kernel_item` is stable when the project has a current timeline;
180
+ if Resolve loses current timeline state, the harness records the bridge
181
+ condition separately.
182
+
183
+ ## Development Guardrails
184
+
185
+ - Use disposable projects and synthetic media for live validation.
186
+ - Never write to, transcode, render, proxy, or create derivatives of source
187
+ media while testing timeline-kernel behavior.
188
+ - Treat generated probe reports as local artifacts.
189
+ - Add new API experiments to the live probe when expanding the boundary map.
@@ -0,0 +1,136 @@
1
+ # DaVinci Resolve Codec Plugin Notes
2
+
3
+ Blackmagic's CodecPlugin README documents the DaVinci Resolve IO Encode Plugin
4
+ SDK. These plugins extend Resolve Studio's Deliver page with additional render
5
+ containers/codecs. They are native encode plugins, not a Python scripting API
6
+ surface.
7
+
8
+ The SDK is encode-focused: it enables additional codecs and container formats
9
+ that can be rendered directly from Resolve. It does not describe a decoder or
10
+ Media Pool import plugin API. Blackmagic notes that only CPU-based plugins are
11
+ currently supported.
12
+
13
+ ## Current MCP Surface
14
+
15
+ The MCP cannot build, install, load, or configure codec plugins directly.
16
+ Relevant existing render actions are:
17
+
18
+ - `render(action="get_formats")` wraps `Project.GetRenderFormats()`.
19
+ - `render(action="get_codecs", params={"format": "..."})` wraps
20
+ `Project.GetRenderCodecs(renderFormat)`.
21
+ - `render(action="set_format_and_codec", params={"format": "...", "codec": "..."})`
22
+ wraps `Project.SetCurrentRenderFormatAndCodec(format, codec)`.
23
+ - `render(action="get_format_and_codec")` wraps
24
+ `Project.GetCurrentRenderFormatAndCodec()`.
25
+ - `render(action="get_resolutions", params={"format": "...", "codec": "..."})`
26
+ wraps `Project.GetRenderResolutions(format, codec)`.
27
+ - `render(action="set_settings")`, `render(action="add_job")`, and
28
+ `render(action="start")` run the normal render pipeline once Resolve exposes
29
+ the desired format/codec.
30
+
31
+ After an IO encode plugin is installed and Resolve is restarted, plugin-provided
32
+ formats and codecs should appear through the same format/codec query actions.
33
+ There is no documented Resolve scripting method to list codec plugin bundles or
34
+ distinguish built-in codecs from plugin-provided codecs.
35
+
36
+ ## Plugin Packaging
37
+
38
+ Codec plugins are native binaries:
39
+
40
+ | Platform | Binary type |
41
+ |---|---|
42
+ | macOS | 64-bit dynamic library |
43
+ | Linux | 64-bit shared object |
44
+ | Windows | 64-bit DLL |
45
+
46
+ Plugins are packaged as `.dvcp.bundle` folders:
47
+
48
+ ```text
49
+ PLUGIN.dvcp.bundle
50
+ Contents/
51
+ ARCH_1/
52
+ PLUGIN.dvcp
53
+ ARCH_2/
54
+ PLUGIN.dvcp
55
+ ```
56
+
57
+ The plugin name must match in both the bundle name and binary name.
58
+
59
+ Supported architecture folder names:
60
+
61
+ | Platform | Architecture folder |
62
+ |---|---|
63
+ | macOS | `MacOS` for Universal2 or Arm64 |
64
+ | macOS Intel | `MacOS-x86-64`, checked before `MacOS` on Intel-only machines |
65
+ | Linux | `Linux-x86-64` |
66
+ | Windows | `Win64` |
67
+
68
+ ## Install Locations
69
+
70
+ Install the `.dvcp.bundle` into Resolve's `IOPlugins` folder:
71
+
72
+ | Platform | IOPlugins folder |
73
+ |---|---|
74
+ | macOS | `/Library/Application Support/Blackmagic Design/DaVinci Resolve/IOPlugins` |
75
+ | macOS App Store | `~/Library/Containers/com.blackmagic-design.DaVinciResolveAppStore/Data/Library/Application Support/IOPlugins` |
76
+ | Linux | `/opt/resolve/IOPlugins` |
77
+ | Windows | `%ProgramData%\Blackmagic Design\DaVinci Resolve\Support\IOPlugins` |
78
+
79
+ System-wide install paths may require administrator privileges. Installing or
80
+ replacing native codec plugins should remain an explicit user request.
81
+
82
+ ## Sample Plugin
83
+
84
+ The developer package includes `Examples/x264_encoder_plugin`, which wraps the
85
+ x264 encoder. The sample flow is:
86
+
87
+ 1. Build/install x264 from source.
88
+ 2. Point `.mk.defs` on macOS/Linux or `plugin2015.vcxproj` on Windows at the
89
+ x264 install path.
90
+ 3. Build with `make` on macOS/Linux or Visual Studio on Windows.
91
+ 4. Package the resulting binary into a `.dvcp.bundle` architecture folder.
92
+ 5. Copy the bundle to `IOPlugins`.
93
+ 6. Restart Resolve.
94
+
95
+ Once loaded, the plugin's supported containers should appear in the Deliver page
96
+ format list. If a plugin-supported container, or QuickTime, is selected, the
97
+ plugin's codecs should appear in the codec list and expose any plugin-specific
98
+ render-settings UI.
99
+
100
+ ## Practical Failure Checks
101
+
102
+ If a custom codec is missing from `render.get_formats` or `render.get_codecs`:
103
+
104
+ - Confirm Resolve Studio supports the plugin and has been restarted after
105
+ installation.
106
+ - Confirm the bundle suffix is `.dvcp.bundle`.
107
+ - Confirm the bundle and binary names match exactly.
108
+ - Confirm the architecture folder matches the current platform and CPU.
109
+ - Confirm the plugin binary is in `Contents/<ARCH>/PLUGIN.dvcp`.
110
+ - Confirm the plugin is an encode plugin for Deliver, not an import/decode
111
+ extension.
112
+ - Confirm any external codec library dependencies, such as x264, can be found by
113
+ the plugin at runtime.
114
+ - Query formats first, then codecs for the selected format. A codec may only
115
+ appear for specific containers.
116
+
117
+ ## Useful Future Additions
118
+
119
+ Good repo additions, if codec-plugin troubleshooting becomes common:
120
+
121
+ 1. A read-only IOPlugins inventory helper that scans known plugin folders and
122
+ reports `.dvcp.bundle` structure, architecture folders, and matching binary
123
+ names.
124
+ 2. Better `render.set_format_and_codec` failure text that suggests checking
125
+ `render.get_formats`, `render.get_codecs`, plugin install paths, and restart
126
+ requirements.
127
+ 3. A developer checklist for packaging `.dvcp.bundle` outputs from the bundled
128
+ x264 sample.
129
+ 4. No automatic native build/install flow by default. Codec plugins are native
130
+ executable code in system/plugin directories and should stay opt-in.
131
+
132
+ ## Source Media Integrity
133
+
134
+ Codec plugins affect render output from Resolve. They should not be used as a
135
+ reason to transcode, proxy, or replace source media unless the user explicitly
136
+ asks for that derivative workflow.
@@ -0,0 +1,234 @@
1
+ # DaVinci Resolve DCTL Notes
2
+
3
+ Blackmagic's DaVinciCTL README documents DaVinci Color Transform Language
4
+ (DCTL). DCTLs are GPU-accelerated, C-like pixel programs used by Resolve as
5
+ programmable color transforms, ResolveFX DCTL effects, DCTL transitions, and
6
+ custom ACES IDT/ODT transforms.
7
+
8
+ This is adjacent to, but not the same as, the Python scripting API used by the
9
+ MCP. The MCP can refresh Resolve's LUT list and set discovered LUT-style files
10
+ on Color page nodes, but it does not compile DCTL, encrypt DCTL, or manipulate
11
+ ResolveFX DCTL plugin UI controls directly.
12
+
13
+ ## Current MCP Surface
14
+
15
+ Relevant existing actions:
16
+
17
+ - `project_settings(action="refresh_luts")` wraps `Project.RefreshLUTList()`.
18
+ Call it after adding or editing `.dctl`, `.dctle`, or `.cube` files in
19
+ Resolve's LUT folders.
20
+ - `graph(action="set_lut", params={"node_index": 1, "lut_path": "..."})`
21
+ wraps `Graph.SetLUT(nodeIndex, lutPath)`. DCTLs that Resolve exposes through
22
+ LUT selection follow the same discovery constraints as LUTs.
23
+ - `graph(action="get_lut", params={"node_index": 1})` wraps `Graph.GetLUT()`.
24
+ - `graph(action="get_tools_in_node", ...)` may report ResolveFX tools present
25
+ in a Color page node, but the scripting API does not expose a general
26
+ "configure DCTL plugin parameter" helper.
27
+
28
+ There is no documented Resolve scripting method to list installed DCTLs, encrypt
29
+ DCTLs, choose a DCTL in the ResolveFX DCTL plugin, or apply a DCTL transition.
30
+
31
+ ## DCTL Types
32
+
33
+ Blackmagic describes two primary DCTL types:
34
+
35
+ - Transform DCTL: processes a single clip/frame. It can be applied as a LUT, via
36
+ the ResolveFX DCTL plugin, from the LUT browser, or from clip/node LUT
37
+ selection.
38
+ - Transition DCTL: blends two clips over time and is used through the OpenFX
39
+ DCTL Transition plugin under ResolveFX Color.
40
+
41
+ DCTL source files are plain text `.dctl` files. Resolve can encrypt a DCTL from
42
+ the LUT browser, producing an expiring `.dctle` file for distribution.
43
+
44
+ ## Transform Entry Points
45
+
46
+ Every transform DCTL must provide exactly one supported `transform()` entry
47
+ point. Common signatures are:
48
+
49
+ ```c
50
+ __DEVICE__ float3 transform(int p_Width, int p_Height, int p_X, int p_Y, float p_R, float p_G, float p_B)
51
+ __DEVICE__ float3 transform(int p_Width, int p_Height, int p_X, int p_Y, __TEXTURE__ p_TexR, __TEXTURE__ p_TexG, __TEXTURE__ p_TexB)
52
+ ```
53
+
54
+ Resolve 19.1 added transform DCTL with alpha for the ResolveFX DCTL plugin:
55
+
56
+ ```c
57
+ __DEVICE__ float4 transform(int p_Width, int p_Height, int p_X, int p_Y, float p_R, float p_G, float p_B, float p_A)
58
+ __DEVICE__ float4 transform(int p_Width, int p_Height, int p_X, int p_Y, __TEXTURE__ p_TexR, __TEXTURE__ p_TexG, __TEXTURE__ p_TexB, __TEXTURE__ p_TexA)
59
+ ```
60
+
61
+ Alpha mode tags:
62
+
63
+ ```c
64
+ DEFINE_DCTL_ALPHA_MODE_STRAIGHT
65
+ DEFINE_DCTL_ALPHA_MODE_PREMULTIPLY
66
+ ```
67
+
68
+ If no alpha tag is specified for an alpha transform, Resolve defaults to
69
+ premultiplied alpha.
70
+
71
+ ## Transition Entry Point
72
+
73
+ Transition DCTLs use a `transition()` function and read the global
74
+ `TRANSITION_PROGRESS` value, which runs from `0.0f` to `1.0f` over the
75
+ transition:
76
+
77
+ ```c
78
+ __DEVICE__ float4 transition(
79
+ int p_Width,
80
+ int p_Height,
81
+ int p_X,
82
+ int p_Y,
83
+ __TEXTURE__ p_FromTexR,
84
+ __TEXTURE__ p_FromTexG,
85
+ __TEXTURE__ p_FromTexB,
86
+ __TEXTURE__ p_FromTexA,
87
+ __TEXTURE__ p_ToTexR,
88
+ __TEXTURE__ p_ToTexG,
89
+ __TEXTURE__ p_ToTexB,
90
+ __TEXTURE__ p_ToTexA)
91
+ ```
92
+
93
+ Texture signatures can sample pixels with `_tex2D(texture, x, y)`.
94
+
95
+ ## Language Notes
96
+
97
+ DCTL is C-like and uses base C types plus Resolve-specific qualifiers and vector
98
+ types:
99
+
100
+ - `float2`, `float3`, `float4`
101
+ - `make_float2`, `make_float3`, `make_float4`
102
+ - `__TEXTURE__`
103
+ - `__DEVICE__`
104
+ - `__CONSTANT__`
105
+ - `__CONSTANTREF__`
106
+
107
+ Float literals need an `f` suffix, for example `1.2f`.
108
+
109
+ Useful global keys:
110
+
111
+ - `__RESOLVE_VER_MAJOR__` and `__RESOLVE_VER_MINOR__` for version guards.
112
+ - `DEVICE_IS_CUDA`, `DEVICE_IS_OPENCL`, and `DEVICE_IS_METAL` for backend guards.
113
+ - `TRANSITION_PROGRESS` in transition DCTLs.
114
+ - `TIMELINE_FRAME_INDEX` when running through the ResolveFX DCTL plugin.
115
+ When a DCTL is used as a LUT, this defaults to `1`.
116
+
117
+ Headers can be included relative to the `.dctl` file:
118
+
119
+ ```c
120
+ #include "ColorConversion.h"
121
+ ```
122
+
123
+ ## LUTs Inside DCTL
124
+
125
+ DCTL can reference external `.cube` LUTs:
126
+
127
+ ```c
128
+ DEFINE_LUT(FilmToVideo, ../LUT/Blackmagic Design/Blackmagic_46K_Film_to_Video.cube)
129
+ ```
130
+
131
+ It can also define inline cube LUTs with `DEFINE_CUBE_LUT(...) { ... }`
132
+ starting in Resolve 17. Use `APPLY_LUT(r, g, b, lutName)` to apply either kind.
133
+
134
+ Rules:
135
+
136
+ - Define LUTs before use.
137
+ - Multiple LUTs may be defined and applied in one DCTL.
138
+ - External LUTs must be `.cube` files.
139
+ - 1D and shaper LUTs use linear interpolation.
140
+ - 3D LUTs use the project's 3D LUT interpolation setting: trilinear or
141
+ tetrahedral.
142
+
143
+ See `docs/notes/lut-notes.md` for the cube file format itself.
144
+
145
+ ## Custom UI
146
+
147
+ Transform DCTLs used through the ResolveFX DCTL plugin can define UI controls
148
+ with `DEFINE_UI_PARAMS`. Resolve supports:
149
+
150
+ - `DCTLUI_SLIDER_FLOAT`
151
+ - `DCTLUI_SLIDER_INT`
152
+ - `DCTLUI_VALUE_BOX`
153
+ - `DCTLUI_CHECK_BOX`
154
+ - `DCTLUI_COMBO_BOX`
155
+ - `DCTLUI_COLOR_PICKER`
156
+
157
+ Each type can have up to 64 controls per DCTL. Resolve 19.1 added the color
158
+ picker, tooltips, incremental slider steps, and improved build-error handling.
159
+
160
+ Tooltips use:
161
+
162
+ ```c
163
+ DEFINE_UI_TOOLTIP(Target Color, "Choose target color")
164
+ ```
165
+
166
+ Build errors from the ResolveFX DCTL plugin appear in Resolve's DCTL Build Error
167
+ dialog. After editing a DCTL file, the plugin combo-box Reset rebuilds the
168
+ selected DCTL while preserving custom UI values when possible.
169
+
170
+ ## DCTL And ACES
171
+
172
+ Custom ACES DCTLs live outside the normal LUT folder and are loaded at Resolve
173
+ startup from:
174
+
175
+ | Platform | ACES transform root |
176
+ |---|---|
177
+ | macOS | `~/Library/Application Support/Blackmagic Design/DaVinci Resolve/ACES Transforms` |
178
+ | Windows | `%AppData%\Blackmagic Design\DaVinci Resolve\Support\ACES Transforms` |
179
+ | Linux | `~/.local/share/DaVinciResolve/ACES Transforms` |
180
+ | iPadOS | `On My iPad/DaVinciResolve/ACES Transforms` |
181
+
182
+ Use `IDT/` for Input Device Transforms and `ODT/` for Output Device Transforms.
183
+ Resolve discovers these at startup, not through `RefreshLUTList()`.
184
+
185
+ ACES DCTL modes:
186
+
187
+ - Non-parametric ACES transforms with
188
+ `DEFINE_ACES_PARAM(IS_PARAMETRIC_ACES_TRANSFORM: 0)`.
189
+ - Parametric ACES Transform V1 with `DEFINE_ACES_PARAM(...)`, supported for
190
+ ACES 1.1 through 1.3.
191
+ - Parametric ACES Transform V2 with `DEFINE_ACES_V2_PARAM(...)`, supported by
192
+ Resolve 20.1 for ACES 2.0.
193
+
194
+ V1 supports custom EOTF functions and skipping the standard ACES RRT. V2 uses
195
+ the newer `DEFINE_ACES_V2_PARAM` template and adds Gamma 2.2, but does not
196
+ support custom EOTF or skipping RRT.
197
+
198
+ ## Practical Failure Checks
199
+
200
+ If a DCTL does not appear or does not apply:
201
+
202
+ - Confirm the file is in Resolve's LUT directory for normal DCTL/plugin use, or
203
+ in the user ACES `IDT/` or `ODT/` folder for ACES transforms.
204
+ - Call `project_settings(action="refresh_luts")` after adding/editing normal
205
+ DCTL files; restart Resolve for ACES DCTLs.
206
+ - Confirm the file extension is `.dctl` or `.dctle`.
207
+ - Confirm the exact entry point signature and parameter names match the required
208
+ form.
209
+ - Confirm float constants use the `f` suffix where needed.
210
+ - Confirm external headers and `DEFINE_LUT` paths are relative to the DCTL file
211
+ or absolute.
212
+ - For transform-with-alpha behavior, confirm Resolve is 19.1+ and the alpha
213
+ mode tag matches the intended straight/premultiplied workflow.
214
+ - For animated/noise effects, remember `TIMELINE_FRAME_INDEX` is meaningful in
215
+ the DCTL plugin but defaults to `1` when used as a LUT.
216
+
217
+ ## Useful Future Additions
218
+
219
+ Good repo additions, if DCTL workflows become common:
220
+
221
+ 1. A read-only DCTL inventory helper that scans Resolve LUT roots and ACES
222
+ transform roots.
223
+ 2. A lightweight DCTL linter for entry point signatures, UI param count, include
224
+ paths, `DEFINE_LUT` paths, and obvious missing `f` suffixes.
225
+ 3. Better `graph.set_lut` failure text that mentions `.dctl` discovery,
226
+ `RefreshLUTList()`, and DCTL-vs-ResolveFX-plugin limitations.
227
+ 4. A small fixture set using Blackmagic's simple examples (`Gain.dctl`,
228
+ `GainDCTLPlugin.dctl`, `LUTApply.dctl`) for non-rendering parser tests.
229
+
230
+ ## Source Media Integrity
231
+
232
+ DCTLs process pixels in Resolve's grade/effects pipeline. Do not bake DCTL
233
+ results into camera originals, create transformed copies, or export/reimport
234
+ processed media unless the user explicitly asks for that workflow.