Files
HyperDRM/docs/architecture.md
T
2026-10-06 22:26:27 +02:00

4.5 KiB

Runtime boundaries

The native service remains one translation unit because LG symbols are resolved at runtime. Its implementation headers share the context declared in service.c; they are included once in dependency order, not independent public libraries. Formatting must preserve include order (SortIncludes: Never).

Module Responsibility
service.c Runtime context, LG/Luna loading, registration and shutdown
service_api.h Start/stop, root restart, settings and autostart actions
service_calibration.h Bounded calibration lease, proposals, profiles, model discovery
service_status.h Read-only status serialization
capture_loop.h Scheduler, histogram acquisition, missing-data recovery and output
receiver_output.h Main asynchronous connection, transaction matching and frame coalescing
atomic_file.h Durable preference replacement and explicit commit outcomes
service_context.h / runtime_context.h Capture, receiver/layout and calibration session ownership
receiver_stream.h Independent, nonblocking receiver LED subscription
source_bridge.h Bounded color continuity during source transitions
handover.h Exclusive PicCap/histogram capture ownership

Connection stages are explicitly named in runtime_states.h: Disconnected → Connecting → Authenticating (when configured) → Layout → Subscribed. Any connection, authorization or parsing failure closes the connection and schedules a bounded retry. Up to eight buffered messages are consumed per tick, including ticks where no new bytes arrive. Buffer capacity and read budgets remain bounded. LED count/profile changes trigger a fresh layout subscription.

The color bridge uses Idle → Holding → WaitingFrame → Fading → Idle. It holds the last histogram frame while PicCap starts, clears its priority before observing a fresh PicCap frame, then blends for 500 ms. The transition expires after 3 seconds; real black bypasses the fade. The opposite direction seeds histogram continuity from a fresh receiver frame. Capture ownership remains in handover.h; the observer never acquires LG capture. Stop cancels the bridge and releases owned resources.

The UI calibration session uses Starting → Waiting → Measuring/Validating → Committing → finished. Each asynchronous callback checks its original session identity, so a cancelled session cannot modify a newly started session. Proposals remain unsaved until the user selects Save profile. The native lease still bounds the session if the UI disappears.

UI action errors take precedence over transient status errors. Polling cannot erase them; starting the next action clears them. Receiver settings, capture state, calibration state and presentation errors remain distinct.

VERSION generates app/package metadata and native/version.h. release.py tests portable logic locally, builds the ARM service and verifies the exact package. Hardware capture and Magic Remote behavior still require a later TV check; a host test is not evidence of LG hardware behavior.

The main receiver owns a ReceiverOutput context passed explicitly to begin, tick, frame, stop and close. Its lifecycle is Idle -> Connecting -> Login (optional) -> Layout -> Ready, with Failed on transport/protocol errors. Requests use a positive 32-bit tan, echoed by the receiver, to avoid acknowledging the wrong command. Each tick has a 64 KiB send budget and a 64 KiB read budget; buffered input has an eight-message budget and 2 MiB limit. An ACK can send the newest queued frame in the same tick without resetting that byte budget. There is one pending command and one replaceable frame, not an unbounded queue. Transaction deadlines are three seconds. Shutdown and cancellation release all owned buffers and sockets.

The source bridge receives CaptureContext explicitly; layout refresh receives ReceiverLayoutContext explicitly. Capture data, continuity, recovery counters and LG handles are grouped separately from receiver transport and calibration session lease/model-query/proposal fields. LG/Luna symbols, persisted calibration and handover ownership still have shared service scope; this refactor reduces globals rather than claiming complete isolation.

Transaction echo behavior is defined by the official implementations: Hyperion 2.0.16 JsonAPI and HyperHDR HyperAPI. This code check does not replace a deployment test against the user's receiver.