From 00f3517d4b9e186dac427fd7f3709046a1bd86e9 Mon Sep 17 00:00:00 2001 From: Forge Dev Date: Sat, 11 Jul 2026 04:22:40 +0000 Subject: [PATCH] research: RCP2 wire protocol verified (WebSocket 9998/rcp, rcp_config handshake, per-channel CDL params, no live LUT upload) + ASC MHL v2.0 XSD findings --- docs/research/red-rcp2-protocol.md | 75 ++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 docs/research/red-rcp2-protocol.md diff --git a/docs/research/red-rcp2-protocol.md b/docs/research/red-rcp2-protocol.md new file mode 100644 index 0000000..0ae8c19 --- /dev/null +++ b/docs/research/red-rcp2-protocol.md @@ -0,0 +1,75 @@ +# RED RCP2 Protocol — verified findings + +Sources: +- `kjayasa/commander` — `components/rcp/rcp.cpp`: full RCP2 parameter table (293 params w/ types + supported JSON ops), extracted from official RED docs (910-0327 protocol + per-camera parameter PDFs) +- `intGus/komodo-remote` — `code.py`: working client against real Komodo, exact wire format + +## Transport (corrects our v1 driver) + +- **WebSocket**, `ws://:9998/rcp` — NOT raw TCP, NOT length-prefixed +- Text frames, one JSON object per frame +- Camera can push unsolicited notifications (e.g. RECORD_STATE changes) + +## Handshake + +First message after connect: +```json +{"type":"rcp_config","strings_decoded":0,"json_minified":1, + "include_cacheable_flags":0,"encoding_type":"html", + "client":{"name":"Forge"}} +``` +Camera replies once; then normal traffic. + +## Messages + +- Get: `{"type":"rcp_get","id":"RECORD_STATE"}` +- Set: `{"type":"rcp_set","id":"RECORD_STATE","value":"2"}` +- Param IDs = `RCP_PARAM_*` names **with `RCP_PARAM_` prefix stripped** +- Response/notification: `{"id":"RECORD_STATE","cur":{"val":}, ...}` — value under `cur.val` +- Other ops exist: `rcp_get_list`, `rcp_get_status`, `rcp_notification`, `rcp_subscribe` (see rcp.cpp enum) + +## Parameters we use + +| Purpose | Param (wire id) | Type | +|---|---|---| +| Rec state | `RECORD_STATE` | value; 0=idle 1=recording 2=toggle-request | +| Clip name | `CLIP_NAME` | status | +| ISO/EI | `ISO` | value | +| White balance | `COLOR_TEMPERATURE` | value | +| Tint | `TINT` | value | +| FPS | `SENSOR_FRAME_RATE` | value | +| Timecode | `TIMECODE` | status | +| CDL enable | `CDL_ENABLE` | value | +| CDL slope | `CDL_SLOPE_RED/GREEN/BLUE` | value (per channel!) | +| CDL offset | `CDL_OFFSET_RED/GREEN/BLUE` | value | +| CDL power | `CDL_POWER_RED/GREEN/BLUE` | value | +| CDL sat | `CDL_SATURATION` | value | +| Active LUT name | `APPLIED_CAMERA_LUT` | status (read-only) | +| Select camera LUT | `CAMERA_LUT` | value (selects from camera's stored list) | +| Import LUT from media | `MEDIA_LUT_IMPORT_TO_CAMERA` | action | + +## Capability corrections for our driver + +1. **CDL is per-channel scalar params**, not a JSON blob. 10 sets per full CDL push (9 SOP + sat). CDL_ENABLE=1 required. +2. **No live 3D LUT upload over RCP2.** `CAMERA_LUT` only selects LUTs already on camera; `MEDIA_LUT_IMPORT_*` pulls from inserted media. So RED live-grade path = **native CDL only**; creative LUT must be pre-loaded to camera or baked into monitor path elsewhere. + → capabilities: `supportsNativeCDL=true`, `lut3dSizes=[]`. +3. Gang: for RED slots, only the leading-CDL portion of a node stack is pushable live. Remainder LUT must be identity, else surface a warning state (grade preview ≠ camera monitor). + +# ASC MHL v2.0 — verified findings + +Source: `ascmitc/mhl-specification` + reference impl `ascmitc/mhl` (XSD fetched, stored below). + +Corrections to our v1 MHL writer: +- Root: `` +- Required: `` (creationdate, hostname, tool) AND `` (process ∈ in-place|transfer|flatten) +- Hash entries: `rel/pathhex` + — size is an ATTRIBUTE of path, hash algo is element name, action attribute tracks chain state +- Folder convention: manifests live in `ascmhl/` subfolder, named `NNNN__.mhl`, plus `ascmhl_chain.xml` +- Directory hashes optional (content + structure) + +XSD: https://raw.githubusercontent.com/ascmitc/mhl/master/xsd/ASCMHL.xsd + +# Other useful repos found + +- `ascmitc/mhl` — Python reference impl, good for cross-validation of our manifests +- Tangent Hub: no public TIPC repos of note; Tangent's official "Tangent Hub" SDK ships the mapping XML + TIPC docs with the installer (macOS phase task)