Skip to content

RDKDEV-1681: Add Rialto Documentation - #601

Open
gourivarma3 wants to merge 3 commits into
rdkcentral:masterfrom
gourivarma3:feature/RDKDEV-1681
Open

gourivarma3 wants to merge 3 commits into
rdkcentral:masterfrom
gourivarma3:feature/RDKDEV-1681

Conversation

@gourivarma3

@gourivarma3 gourivarma3 commented Sep 9, 2026 •

Copy link
Copy Markdown

RDKDEV-1681: Add Rialto Documentation

Reason for Change: To add Component Documentation for Rialto

Test Procedure: https://jira.rdkcentral.com/jira/browse/RDKDEV-1681

Copilot AI lite review requested due to automatic review settings September 9, 2026 09:19

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The new documentation contains a couple of concrete API/config inaccuracies that should be corrected to avoid misleading integrators.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Adds a comprehensive component-level docs/README.md describing Rialto’s architecture, IPC model, lifecycle/state flows, configuration, and major internal modules to support onboarding and integration documentation for the project.

Changes:

  • Introduces a new high-level Rialto overview and design explanation (client/server split, IPC, shared memory data path).
  • Documents threading model, state flows, and key call flows using Mermaid diagrams.
  • Adds reference tables for internal modules, component interactions/events, and configuration parameters.
File summaries
File Description
docs/README.md New end-to-end architecture and integration documentation for Rialto, including diagrams and configuration reference.
Review details
  • Files reviewed: 1/1 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread docs/README.md Outdated
Comment thread docs/README.md Outdated
@gourivarma3 gourivarma3 changed the title RDKDEV-1681 Add Rialto Documentation RDKDEV-1681: Add Rialto Documentation Sep 15, 2026
Copilot AI review requested due to automatic review settings September 15, 2026 09:32
gourivarma3 and others added 2 commits September 15, 2026 15:02
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The documentation has unresolved accuracy issues across IPC, lifecycle, media flows, and configuration.

Get a fresh assessment by requesting another Copilot review.

Review details

Suppressed comments (25)

docs/README.md:56

  • CipherMode is part of the media-segment/pipeline data model (MediaCommon.h and IMediaPipeline.h), not an IMediaKeys API. Listing it under IMediaKeys can send integrators to the wrong interface; move the four modes to the AV pipeline/media-segment description.
- **EME / DRM Key Management**: Exposes `IMediaKeys` for managing Encrypted Media Extension (EME) key sessions, including key generation, licence updates, session persistence, DRM store management, and cipher mode configuration (CENC, CBC1, CENS, CBCS).

docs/README.md:69

  • File descriptors are not passed in-band in protobuf payloads. The field_is_fd fields are transmitted as Unix SCM_RIGHTS ancillary data and then inserted into the protobuf message by RialtoIpc; this should be described as out-of-band fd passing.
The IPC layer is purpose-built to meet Rialto's specific requirements: per-connection client identity (pid/uid), in-band file descriptor passing for sharing memory buffer descriptors, and first-class asynchronous event delivery from server to client. The protobuf service definitions in `proto/` describe all RPC methods and events for the media pipeline, DRM, web audio, control, and server manager channels.

docs/README.md:150

  • The overrides file is not limited to debug builds. ConfigHelper reads the base, SoC, and override paths whenever RIALTO_ENABLE_CONFIG_FILE is enabled, and the override path is a build-time RIALTO_CONFIG_OVERRIDES_PATH (default /opt/persistent/sky/rialto-config-overrides.json), not a JSON overrides field.
- **Configuration Files**: `rialto-config.json` (installed from `rialto-config.in.json`). The file specifies environment variables for `RialtoServer`, the server binary path, startup timeout, health-check interval, socket permissions, and number of pre-loaded server processes. On debug builds, an override file at the configured `overrides` path is also read.

docs/README.md:161

  • Initializing, Spawning, and Shutdown are descriptive phases, not values of the public SessionServerState enum. The enum is UNINITIALIZED, INACTIVE, ACTIVE, NOT_RUNNING, ERROR, and SUSPENDED; the current wording omits failure and suspended paths.
The component transitions through the following states during its lifecycle: **Initializing** (read config, allocate resources) → **Spawning** (fork RialtoServer process, send SetConfiguration) → **Active** (client-facing socket ready, accepting IPC connections) → **Shutdown** (deactivate sessions, unmap shared memory, terminate RialtoServer).

docs/README.md:170

  • createServerManagerService() does not exist; the public factory is the free function rialto::servermanager::service::create(stateObserver) declared in ServerManagerServiceFactory.h.
    AppMgr->>RSM: createServerManagerService()

docs/README.md:215

  • createServerManagerService(config, stateObserver) is not the public API and reverses the actual factory parameter order. The header exposes service::create(stateObserver, config).
    AppMgr->>RSM: createServerManagerService(config, stateObserver)

docs/README.md:233

  • The application callback does not receive shmInfo here: MediaPipeline::notifyNeedMediaData currently passes nullptr, while the client library stores the server-provided offsets internally and addSegment() writes through its frame writer. The prose should not instruct applications to read offsets directly from this callback.
The client writes encoded media data into the shared memory buffer at the offset indicated by `shmInfo` in the `notifyNeedMediaData` callback, then calls `addSegment()` to notify the server. The server reads the data from shared memory and pushes it into the GStreamer source element on the `WorkerThread`, completing the cycle without any additional data copy over the socket.

docs/README.md:389

  • This repeated state list is also incomplete: SUSPENDED is a public enum value and is handled by the manager, including cleanup and later resurrection. Include it alongside the other SessionServerState values.
- **State / Lifecycle Management**: Session server state (UNINITIALIZED, INACTIVE, ACTIVE, NOT_RUNNING, ERROR) is tracked in the `RialtoServerManager`. On the server side, the `IPlaybackService` interface exposes `switchToActive()` and `switchToInactive()` to change service availability. Playback state (IDLE, PLAYING, PAUSED, SEEKING, SEEK_DONE, STOPPED, END_OF_STREAM, FAILURE) is managed within `GstGenericPlayer` and propagated via the `GstDispatcherThread`.

docs/README.md:407

  • The override mechanism is not debug-only and the path is not a JSON overrides setting. ConfigHelper reads RIALTO_CONFIG_OVERRIDES_PATH whenever config-file support is enabled; its default build path is /opt/persistent/sky/rialto-config-overrides.json.
| `/etc/rialto-config.json` (compiled-in default path) | Provides server manager runtime parameters: server binary path, environment variables, timeouts, socket permissions, pre-loaded server count, health-check interval, and log levels | On debug builds, a per-field override file at the configured `overrides` path is read and merged |

docs/README.md:130

  • RSMSpawner launches the RialtoServer executable, not the nested IPCServer component. This edge incorrectly implies that the IPC channel is the spawned process; connect the spawner to the RialtoServer process subgraph instead.
    RSMSpawner -->|spawns| IPCServer

docs/README.md:151

  • Because RialtoServerManager is a library, it is not a daemon that must be "running" independently. The required ordering is that the application manager creates the service object before calling initiateApplication(); please phrase this requirement in terms of service creation.
- **Startup Order**: `RialtoServerManager` must be running before any application requests `initiateApplication()`. The server manager spawns `RialtoServer` instances on demand; when `numOfPreloadedServers` is configured to a non-zero value, server processes are pre-launched at startup to reduce application connect latency.

docs/README.md:189

  • The recovery counter is not limited to unanswered pings: HealthcheckService records both ping timeouts and unsuccessful acknowledgements, and restarts after the configured number of failed checks. Describing only unanswered pings gives an incorrect recovery model.
During normal operation, the server manager sends periodic `PingRequest` messages to each `RialtoServer`. The server aggregates acknowledgements from its internal session objects and responds with an `AckEvent`. If the configured number of consecutive unanswered pings (`numOfPingsBeforeRecovery`) is exceeded, the server manager triggers recovery for that server instance.

docs/README.md:244

  • IMediaPipeline::load() requires the isLive argument, and the corresponding LoadRequest carries is_live. Omitting it from both steps makes this MSE call flow incomplete and can mislead users implementing the request.
    App->>RC: IMediaPipeline::load(MSE, mimeType, url)
    RC->>RS: LoadRequest (session_id, type, mime_type, url)

docs/README.md:250

  • Both the IPC event and the public callback carry the need-data request ID, but this flow omits it and also shows the callback arguments in the wrong order. Without that ID the client cannot correlate the response with the pending request.
    RS->>RC: NeedMediaDataEvent (source_id, frameCount, shmInfo)
    RC->>App: IMediaPipelineClient::notifyNeedMediaData(source_id, frameCount, shmInfo)

docs/README.md:253

  • HaveDataRequest includes num_frames as well as session_id, status, and request_id; the number of frames written is computed by the client before the IPC call. Please include this field in the flow so it reflects the actual request contract.
    RC->>RS: HaveDataRequest (session_id, status, requestId)

docs/README.md:200

  • setLogLevels() accepts LoggingLevels severity values and converts them to logging masks internally; it does not take raw masks as this wording suggests. Use "log level settings" here to match the public API.
- Receiving an updated `setLogLevels()` call propagates new log level masks to all running `RialtoServer` instances at runtime via the server manager IPC channel.

docs/README.md:421

  • The build default for logLevel is 3, which maps to the MILESTONE severity threshold. The current row omits the default and describes the configuration value as a raw bitmask, although the config parser accepts a severity level and performs the conversion.
| `logLevel`                     | uint   | —                                                                                                            | Default log level bitmask for all Rialto components at startup                                                        |

docs/README.md:423

  • extraEnvVariables is parsed as a list and its generated configuration default is an empty list ([]), not the string "". The current type/default combination is misleading for anyone constructing rialto-config.json.
| `extraEnvVariables`            | list   | `""`                                                                                                         | Additional environment variables merged into the server environment                                                   |

docs/README.md:67

  • RialtoClient does not translate every media operation into an RPC: MediaPipeline::addSegment() writes the segment into the mapped shared-memory buffer, and only haveData() sends the RPC. Please distinguish control RPCs from the shared-memory data path here.
Rialto is designed around strict process isolation. The `RialtoClient` library runs inside the containerised application and translates every media operation into a protobuf RPC call sent over a Unix domain socket. The `RialtoServer` process runs outside any container, holds access to GStreamer and DRM resources, and executes those operations on behalf of the client. This split ensures that hardware handles, DRM contexts, and GStreamer pipelines remain contained within the trusted server process.

docs/README.md:195

  • An ERROR state notification only causes the manager to notify IStateObserver; a restart is triggered by the health-check recovery path after numOfPingsBeforeRecovery failed pings, not by every StateChangedEvent(ERROR).
- A `StateChangedEvent(ERROR)` from `RialtoServer` indicates an unrecoverable server-side failure; the server manager notifies the registered `IStateObserver` and may restart the server process.

docs/README.md:233

  • addSegment() only writes a segment into the client's shared-memory frame writer; it does not notify the server. The client must call haveData(status, needDataRequestId) after adding segments, which is the call that sends HaveDataRequest.
The client writes encoded media data into the shared memory buffer at the offset indicated by `shmInfo` in the `notifyNeedMediaData` callback, then calls `addSegment()` to notify the server. The server reads the data from shared memory and pushes it into the GStreamer source element on the `WorkerThread`, completing the cycle without any additional data copy over the socket.

docs/README.md:394

  • MediaKeyErrorStatus::INTERFACE_NOT_IMPLEMENTED is also a public status in media/public/include/MediaCommon.h and is omitted from this documented set.
- **Error Handling Strategy**: GStreamer errors received as `GST_MESSAGE_ERROR` are translated into a `PlaybackState::FAILURE` notification to the client. OpenCDM errors are mapped to `MediaKeyErrorStatus` values (OK, FAIL, BAD_SESSION_ID, NOT_SUPPORTED, INVALID_STATE, BUFFER_TOO_SMALL, OUTPUT_RESTRICTED) returned synchronously from `IMediaKeys` methods. IPC-level failures result in the client receiving a failure response or a disconnect notification.

docs/README.md:323

  • This says every API call becomes a protobuf request, but addSegment() is handled locally by writing to the shared-memory buffer; only haveData() sends the corresponding protobuf request. Please scope this statement to the RPC/control path.
The client library serialises each API call into a protobuf request message and sends it over the per-application Unix domain socket. The server deserialises the request, executes the operation (typically enqueued onto `MainThread` or `WorkerThread`), and serialises the result back as a response message.

docs/README.md:265

  • The RialtoClient module description repeats the incorrect claim that all API calls become protobuf requests. MSE addSegment() is the notable shared-memory data-path exception and should be documented here too.
| `RialtoClient`            | Client-side library providing factory implementations for all public interfaces. Translates API calls into protobuf IPC requests and receives asynchronous event notifications from the server.                                                                                                                                       | `media/client/main/`, `media/client/ipc/`                                             |

docs/README.md:225

  • As in the earlier lifecycle sequence, StateChangedEvent(ACTIVE) is emitted from configureServices() before the SetConfigurationResponse is returned. Please swap these two messages so the documented ordering matches the RPC implementation.
    RS-->>RSM: SetConfigurationResponse
    RS-->>RSM: StateChangedEvent(ACTIVE)
  • Files reviewed: 1/1 changed files
  • Comments generated: 11
  • Review effort level: Lite

Comment thread docs/README.md Outdated
Comment thread docs/README.md Outdated
Comment thread docs/README.md Outdated
Comment thread docs/README.md Outdated
Comment thread docs/README.md Outdated
Comment thread docs/README.md
Comment thread docs/README.md Outdated
Comment thread docs/README.md Outdated
Comment thread docs/README.md Outdated
Comment thread docs/README.md Outdated
RDKDEV-1681: Add Rialto Documentation Reason for change: Add detailed documentation for the rialto and address review comments.

Test Procedure: Documentation and review

---------

Signed-off-by: Gouri G Varma <gouri_varma@comcast.com>
Copilot AI review requested due to automatic review settings September 23, 2026 10:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

The documentation contains unresolved inaccuracies and omissions across lifecycle, threading, API behavior, and configuration.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 10 Low severity

Open (10)
Resolved since last review (11)

Comment thread docs/README.md
- **EME / DRM Key Management**: Exposes `IMediaKeys` for managing Encrypted Media Extension (EME) key sessions, including key generation, licence updates, session persistence, DRM store management, and cipher mode configuration (CENC, CBC1, CENS, CBCS).
- **Web Audio Playback**: Exposes `IWebAudioPlayer` for mixing PCM audio streams into the current audio output, with priority-based resource allocation for platforms with a limited number of concurrent audio mixers.
- **Shared Memory Data Channel**: Provides a shared memory buffer whose file descriptor is passed from server to client via the `GetSharedMemory` control RPC, allowing media segment data to be transferred without redundant data copies across process boundaries.
- **Container Lifecycle Management**: `RialtoServerManager` spawns and manages one `RialtoServer` process per application, applies resource limits (maximum simultaneous playback sessions and web audio players), manages session server states (UNINITIALIZED, INACTIVE, ACTIVE, NOT_RUNNING, ERROR), and performs periodic health checks via a ping/ack protocol.
Comment thread docs/README.md

#### Runtime State Changes

During normal operation, the server manager sends periodic `PingRequest` messages to each `RialtoServer`. The server aggregates acknowledgements from its internal session objects and responds with an `AckEvent`. If the configured number of consecutive unanswered pings (`numOfPingsBeforeRecovery`) is exceeded, the server manager triggers recovery for that server instance.
Comment thread docs/README.md

- Application manager calls `changeSessionServerState(appId, INACTIVE)` to suspend an active session; the server manager sends a `SetState` RPC to the corresponding `RialtoServer`, which transitions its services to inactive, releasing active decoder resources.
- Application manager calls `changeSessionServerState(appId, NOT_RUNNING)` to terminate a session; the server manager signals the `RialtoServer` to shut down cleanly.
- A `StateChangedEvent(ERROR)` from `RialtoServer` indicates an unrecoverable server-side failure; the server manager notifies the registered `IStateObserver` and may restart the server process.
Comment thread docs/README.md

The following shows the data path for an MSE playback session from client API call to GStreamer data injection.

The client writes encoded media data into the shared memory buffer at the offset indicated by `shmInfo` in the `notifyNeedMediaData` callback, then calls `addSegment()` to notify the server. The server reads the data from shared memory and pushes it into the GStreamer source element on the `WorkerThread`, completing the cycle without any additional data copy over the socket.
Comment thread docs/README.md
App->>RC: IMediaPipeline::play()
RC->>IPC: PlayRequest (session_id)
IPC->>RS: Deserialise PlayRequest
RS->>RS: Enqueue play task on WorkerThread
Comment thread docs/README.md
Comment on lines +359 to +360
GstDisp->>RS: Notify EOS state
RS->>RS: Enqueue EOS task on MainThread
Comment thread docs/README.md

- **Event Processing**: GStreamer bus messages are polled by `GstDispatcherThread` in a loop and dispatched to `IGstDispatcherThreadClient` callbacks implemented by `GstGenericPlayer`. The player then enqueues corresponding state or notification events onto the `MainThread` for serialised processing and IPC dispatch. Need-data requests originate from the `GstSrc` element's need-data signal, also handled on the `WorkerThread`.

- **Error Handling Strategy**: GStreamer errors received as `GST_MESSAGE_ERROR` are translated into a `PlaybackState::FAILURE` notification to the client. OpenCDM errors are mapped to `MediaKeyErrorStatus` values (OK, FAIL, BAD_SESSION_ID, NOT_SUPPORTED, INVALID_STATE, BUFFER_TOO_SMALL, OUTPUT_RESTRICTED) returned synchronously from `IMediaKeys` methods. IPC-level failures result in the client receiving a failure response or a disconnect notification.
Comment thread docs/README.md

| Configuration File | Purpose | Override Mechanism |
| ---------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| `/etc/rialto-config.json` (compiled-in default path) | Provides server manager runtime parameters: server binary path, environment variables, timeouts, socket permissions, pre-loaded server count, health-check interval, and log levels | On debug builds, a per-field override file at the configured `overrides` path is read and merged |
Comment thread docs/README.md
| `socketGroup` | string | `""` | Group name applied via `chown` to the client-facing IPC socket file |
| `numOfPreloadedServers` | int | `0` | Number of `RialtoServer` processes to pre-launch at startup to reduce application connect latency |
| `numOfPingsBeforeRecovery` | int | `3` | Number of consecutive unanswered health-check pings before the server manager triggers recovery for a server instance |
| `logLevel` | uint | `3` | Default log level bitmask for all Rialto components at startup |
Comment thread docs/README.md
| `numOfPingsBeforeRecovery` | int | `3` | Number of consecutive unanswered health-check pings before the server manager triggers recovery for a server instance |
| `logLevel` | uint | `3` | Default log level bitmask for all Rialto components at startup |
| `environmentVariables` | list | `XDG_RUNTIME_DIR=/tmp`, `GST_REGISTRY=/tmp/rialto-server-gstreamer-cache.bin`, `WESTEROS_SINK_USE_ESSRMGR=1` | Environment variables set for every spawned `RialtoServer` process |
| `extraEnvVariables` | list | `""` | Additional environment variables merged into the server environment |

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants