The PlayReady OCDM (Open Content Decryption Module) component implements the Microsoft PlayReady DRM backend for WPEFramework (Thunder). It enables protected media playback by performing license acquisition, key binding, and hardware-accelerated content decryption through a standardized CDMi interface.

The component manages the complete lifecycle of a DRM session: parsing PlayReady PSSH initialization data extracted from the content manifest, generating a license challenge for dispatch to a license server, processing the license response to bind decryption keys, and decrypting encrypted media samples. The component is delivered as a shared object (Playready.drm) installed into the WPEFramework OCDM discovery directory and loaded by the WPEFramework OCDM Plugin (OpenCDMi) at runtime.

From a stack perspective, the component resides within WPEFramework (Thunder) and exposes the CDMi IMediaKeys and IMediaKeysExt interfaces to the WPEFramework OCDM Plugin (OpenCDMi) above it. Below, it depends on the PlayReady SDK for all DRM operations and on a platform-specific Secure Video Path (SVP) library (gst-svp-ext) for routing decrypted video content through protected memory without exposing it to normally accessible memory.

At the device level, the component allows PlayReady-protected video-on-demand and live streaming content to be played back on the device. At the module level, it manages the DRM application context lifecycle, session-scoped key state machines, license store maintenance, Secure Stop session tracking, and output protection policy enforcement.

```mermaid
flowchart LR

%% Apps Layer
    subgraph Apps["Apps & Runtimes"]
        FireboltApps["Firebolt Apps"]
        WPERuntime["WPE Runtime"]
    end

%% Middleware
    subgraph RDKMW["RDK Core Middleware"]
        OCDM["WPEFramework OCDM\n(OpenCDMi Plugin)"]
        PR["PlayReady OCDM\n(OpenCDMi Backend)"]
        Thunder["WPEFramework (Thunder)"]
    end

%% Vendor Layer
    subgraph VL["Vendor Layer"]
        PlayReadySDK["PlayReady SDK\n(SoC DRM Libraries)"]
        SvpGeneric["gst-svp-ext\n(Generic Interface)"]
        SvpHAL["gst-svp-ext\n(Platform HAL)"]
        SvpGeneric --> SvpHAL
    end

    subgraph Cloud["Cloud Services"]
        LicenseServer["License Server"]
    end

    Apps -->|"EME / OCDM API"| Thunder
    Thunder --> OCDM
    OCDM -->|"CDMi IMediaKeys"| PR
    PR -->|"Drm_* APIs\n(SoC DRM libs)"| PlayReadySDK
    PR -->|"svp_* APIs"| SvpGeneric
    PR -.->|"License Challenge / Response"| LicenseServer
```

Key Features & Responsibilities:


Design

The component is structured around two layers: a system-level context managed by the PlayReady class in MediaSystem.cpp, and a per-session context managed by MediaKeySession in MediaSession.cpp and MediaSessionExt.cpp. The system layer initializes the PlayReady platform and maintains the shared DRM_APP_CONTEXT that sessions within the same instance share. The session layer manages individual key state machines, license challenge-response cycles, and decrypt context binding. This separation allows multiple concurrent sessions — such as those needed for multi-period content or adaptive bitrate streams with multiple key IDs — to share a single application context while maintaining independent key states.

PlayReady SDK calls that use the shared DRM_APP_CONTEXT are serialized through a global CriticalSection (drmAppContextMutex_) to ensure thread safety. Platform initialization is guarded separately by prPlatformMutex_ using a reference counter so that concurrent callers do not double-initialize. Session construction is protected by prSessionMutex_.

The component's northbound interface is the CDMi IMediaKeys and IMediaKeysExt API consumed by the WPEFramework OCDM Plugin (OpenCDMi) — the Thunder plugin responsible for discovering and loading OpenCDMi backend shared libraries and routing EME-layer requests to them. Its southbound interface covers two paths: PlayReady SDK calls for all DRM operations (directed to SoC-provided DRM libraries), and gst-svp-ext calls for SVP secure memory management — gst-svp-ext provides a generic interface where GStreamer SVP-specific platform handling is passed through to the underlying platform HAL. Configuration is delivered as a JSON string at Initialize() time, from which the DRM data directory, store path, and HOME environment variable are extracted.

The DRM store is persisted on the filesystem at the path specified by the store-location configuration parameter and is managed by the PlayReady SDK. The component performs a cleanup pass at startup to remove expired licenses. In-memory licenses are removed when the session closes. Temporary persistent licenses acquired during a session are tracked and deleted on session close to prevent unbounded accumulation.

```mermaid
graph LR

    OCDM["WPEFramework\nOCDM Plugin (OpenCDMi)"]

    subgraph Component["PlayReady OCDM (Playready.drm)"]
        subgraph SysL["System Layer"]
            SysCtx["DRM_APP_CONTEXT"]
            SecStop["Secure Stop"]
            StoreOps["Store Ops"]
        end
        Mutex["drmAppContextMutex_"]
        subgraph SessL["Session Layer"]
            KeySM["Key State Machine"]
            LicAcq["License Acq"]
            DecCtx["Decrypt Contexts"]
        end
    end

    PlayReadySDK["PlayReady SDK\n(SoC DRM Libraries)"]
    SvpGeneric["gst-svp-ext\n(Generic Interface)"]
    SvpHAL["gst-svp-ext\n(Platform HAL)"]
    SvpGeneric --> SvpHAL

    OCDM -->|"System APIs"| SysL
    OCDM -->|"Session APIs"| SessL
    SysL --> Mutex
    SessL --> Mutex
    Mutex --> PlayReadySDK
    SessL -->|"svp_* calls"| SvpGeneric
```

Threading Model

Platform and Integration Requirements


Component State Flow

Initialization to Active State

The component is initialized when the WPEFramework OCDM Plugin (OpenCDMi) calls Initialize() on the system object. Platform-level PlayReady initialization is performed first (svpPlatformInitializePlayready), followed by JSON configuration parsing to extract the DRM data directory and store paths. The DRM path globals are set, directories are created, and the revocation buffer is allocated in CreateSystemExt(). The DRM application context is then initialized via Drm_Initialize(). If the store is found to be corrupt, it is deleted and initialization is retried automatically. After successful context setup, the revocation buffer is registered, the secure or anti-rollback clock is validated, and the revocation list is loaded. Finally, expired and removal-date licenses are removed from the store.

The component transitions through the following states during its lifecycle: Initializing (platform init, config parse) → SystemExtCreated (DRM path and revocation buffer allocated) → AppCtxInitialized (Drm_Initialize succeeded, revocation buffer registered, clock validated, revocation list loaded) → Active (serving CDMi calls and session creation) → Shutdown (store cleanup, Drm_Uninitialize, platform uninit).

```mermaid
sequenceDiagram
    participant OCDM as WPEFramework OCDM Plugin (OpenCDMi)
    participant PR as PlayReady OCDM (OpenCDMi Backend)
    participant SVP as gst-svp-ext (Generic)
    participant PRSDK as PlayReady SDK (SoC DRM)

    OCDM->>PR: Initialize(shell, configline)
    PR->>SVP: svpPlatformInitializePlayready()
    SVP-->>PR: Platform ready

    PR->>PR: OnSystemConfigurationAvailable(configline)
    PR->>PR: Parse JSON config (read-dir, store-location, home-path)
    PR->>SVP: svpGetDrmStoragePath()
    SVP-->>PR: Store path resolved

    PR->>PR: CreateSystemExt() — set DRM path globals, alloc revocation buffer

    PR->>PRSDK: Drm_Platform_Initialize(platformInitData)
    PRSDK-->>PR: Platform initialized

    PR->>SVP: svpGetDrmOEMContext()
    SVP-->>PR: OEM context

    PR->>PRSDK: Drm_Initialize(AppCtx, OemCtx, opaqueBuf, storeNameStr)
    PRSDK-->>PR: DRM_SUCCESS (or store corrupt → delete & retry)

    PR->>PRSDK: Drm_Revocation_SetBuffer(revocationBuf, size)
    PRSDK-->>PR: OK

    PR->>SVP: svpIsSecureClockInitNeed()
    SVP-->>PR: bool

    PR->>PRSDK: Drm_SecureTime_GetValue() / Drm_AntiRollBackClock_Init()
    PRSDK-->>PR: Clock validated

    PR->>SVP: svpLoadRevocationList()
    SVP-->>PR: Revocation list loaded

    PR->>PRSDK: Drm_StoreMgmt_CleanupStore(DELETE_EXPIRED | DELETE_REMOVAL_DATE)
    PRSDK-->>PR: Store cleaned

    PR-->>OCDM: Initialization complete — Component Active

    loop Runtime
        OCDM->>PR: CDMi API calls (sessions, decrypt, secure stop)
    end

    OCDM->>PR: Deinitialize()
    PR->>PRSDK: Drm_StoreMgmt_CleanupStore()
    PR->>PRSDK: Drm_Uninitialize()
    PR->>PRSDK: Drm_Platform_Uninitialize()
    PR->>SVP: svpPlatformUninitializePlayready()
    PR-->>OCDM: Deinitialized
```

Runtime State Changes

State Change Triggers:

Context Switching Scenarios:


Call Flows

Initialization Call Flow

```mermaid
sequenceDiagram
    participant OCDM as OCDM (OpenCDMi)
    participant PR as PlayReady OCDM (OpenCDMi Backend)
    participant SVP as gst-svp-ext (Generic)
    participant PRSDK as PlayReady SDK (SoC DRM)

    OCDM->>PR: Initialize(shell, configJSON)
    PR->>SVP: svpPlatformInitializePlayready()
    PR->>PR: Parse config (read-dir, store-location, home-path)
    PR->>SVP: svpGetDrmStoragePath(readDir, storePath, storeLocation)
    PR->>PR: CreateSystemExt() — set g_dstrDrmPath, alloc revocation buffer
    PR->>PRSDK: Drm_Platform_Initialize(platformInitData)
    PR->>SVP: svpGetDrmOEMContext()
    PR->>PRSDK: Drm_Initialize(AppCtx, OemCtx, opaqueBuf, storeNameStr)
    PR->>PRSDK: Drm_Revocation_SetBuffer(revocationBuf, REVOCATION_BUFFER_SIZE)
    PR->>PRSDK: Drm_SecureTime_GetValue() / Drm_AntiRollBackClock_Init()
    PR->>SVP: svpLoadRevocationList()
    PR->>PRSDK: Drm_StoreMgmt_CleanupStore(DELETE_EXPIRED | DELETE_REMOVAL_DATE)
    PR-->>OCDM: Ready
```

Session License Acquisition Call Flow

```mermaid
sequenceDiagram
    participant App as Application / WPE Runtime
    participant OCDM as OCDM (OpenCDMi)
    participant PR as PlayReady OCDM (OpenCDMi Backend)
    participant PRSDK as PlayReady SDK (SoC DRM)
    participant LS as License Server

    App->>OCDM: createMediaKeySession(initData)
    OCDM->>PR: CreateMediaKeySession(keySystem, initData, cdmData, ...)
    PR->>PR: parsePlayreadyInitializationData() — extract DRM header from PSSH
    PR->>PRSDK: Drm_Content_SetProperty(DRM_CSP_AUTODETECT_HEADER, drmHeader)
    PR->>PRSDK: DRM_HDR_GetAttribute() — extract Key IDs and header version
    PR-->>OCDM: MediaKeySession created (KEY_INIT)

    OCDM->>PR: Run(callback)
    PR->>PRSDK: Drm_LicenseAcq_GenerateChallenge(rights, customData, ..., &challenge, &batchID)
    PR-->>OCDM: callback.OnKeyMessage(challenge, silentURL)
    OCDM-->>App: keyMessage event (KEY_PENDING)

    App->>LS: POST challenge to license server
    LS-->>App: License response

    App->>OCDM: update(licenseResponse)
    OCDM->>PR: Update(licenseResponse)
    PR->>PRSDK: Drm_LicenseAcq_ProcessResponse(response, &licenseResponse)
    loop Per key acknowledgement in response
        PR->>PRSDK: Drm_Content_SetProperty(DRM_CSP_DECRYPTION_OUTPUT_MODE, HANDLE)
        PR->>PRSDK: Drm_Reader_Bind(rights, _PolicyCallback, &decryptContext)
        PR->>PRSDK: Drm_Reader_Commit(_PolicyCallback)
    end
    PR-->>OCDM: callback.OnKeyStatusUpdate("KeyUsable", keyId)
    PR-->>OCDM: callback.OnKeyStatusesUpdated()
    OCDM-->>App: keystatuseschange event (KEY_READY)
```

Decrypt Call Flow

```mermaid
sequenceDiagram
    participant OCDM as OCDM (OpenCDMi)
    participant PR as PlayReady OCDM (OpenCDMi Backend)
    participant SVP as gst-svp-ext (Generic)
    participant PRSDK as PlayReady SDK (SoC DRM)

    OCDM->>PR: Decrypt(inData, sampleInfo, properties)
    PR->>PR: Resolve current decrypt context by Key ID from sampleInfo
    PR->>SVP: svp_allocate_secure_buffers(pSVPContext, secBufInfo, encData, encDataLen)
    PR->>SVP: svp_buffer_alloc_token() / svp_buffer_to_token()
    PR->>PRSDK: Drm_Reader_DecryptMultipleOpaque(decryptContext, ivVector, regionMapping, encData)
    PRSDK-->>PR: decryptedLength, pDecryptedContent (secure handle)
    PR->>SVP: Write secure token to output buffer header
    PR-->>OCDM: CDMi_SUCCESS — output buffer contains SVP token
```

Internal Modules

Module / ClassDescriptionKey Files
PlayReadyImplements IMediaKeys and IMediaKeysExt. Manages the system-level DRM application context (DRM_APP_CONTEXT), configuration parsing, platform initialization, Secure Stop session enumeration and challenge/response, license store cleanup and deletion, and store integrity hashing. Maintains m_sessionCount and m_isAppCtxInitialized to guard against use-after-free when resetting the app context while sessions are active. Receives JSON configuration from the WPEFramework host at startup.MediaSystem.cpp
MediaKeySessionImplements IMediaKeySession and IMediaKeySessionExt. Manages per-session key state, license challenge generation, license response processing, dual decrypt context binding (SVP video + optional non-SVP audio), sample decryption, output protection policy evaluation, and session teardown including license cleanup. Exposes printGuid() and printUuid() diagnostic helpers for key ID logging.MediaSession.cpp, MediaSessionExt.cpp, MediaSession.h
PlayreadySessionBase class for MediaKeySession. Owns a session-local DRM_APP_CONTEXT and manages reference-counted DrmPlatformInitialize / Drm_Initialize for sessions that do not share the system-level context.MediaSession.cpp, MediaSession.h
CPRDrmPlatformReference-counted wrapper for Drm_Platform_Initialize and Drm_Platform_Uninitialize. Ensures the PlayReady platform is initialized exactly once across multiple concurrent callers using prPlatformMutex_. Retries on DRM_E_DEPRECATED_DEVCERT_READ_ERROR up to DEVCERT_RETRY_MAX times with DEVCERT_WAIT_SECS delay between attempts.MediaSession.cpp
SafeCriticalSectionRAII wrapper for WPEFramework::Core::CriticalSection. Acquires the lock on construction and releases it on destruction. Provides explicit unlock() and relock() methods for cases where the lock must be temporarily dropped within a scope.MediaSession.h
KeyIdUtility class encapsulating a 16-byte DRM key identifier. Supports GUID little-endian and UUID big-endian byte orderings and toggling between them. Provides base64 and hex string representations for logging and protocol use.MediaSession.h, MediaSession.cpp
__DECRYPT_CONTEXTPOD struct holding a KeyId, a primary DRM_DECRYPT_CONTEXT (oDrmDecryptContext) for SVP-protected video decryption, and a secondary DRM_DECRYPT_CONTEXT (oDrmDecryptAudioContext) for non-SVP audio decryption when svpIsAudioNeedNonSVPContext() returns true. Both contexts are zero-initialised on construction.MediaSession.h

Component Interactions

The component's interactions are with the WPEFramework OCDM Plugin — OpenCDMi (northbound, in-process), the PlayReady SDK / SoC DRM libraries (southbound, in-process), and gst-svp-ext (generic interface delegating to the platform SVP HAL) for secure memory management.

Interaction Matrix

Target Component / LayerInteraction PurposeKey APIs / Topics
WPEFramework OCDM Plugin (OpenCDMi)

OCDM Plugin (OpenCDMi)CDMi interface entry points — discovers and loads this OpenCDMi backend, routes EME requests to itIMediaKeys::CreateMediaKeySession, IMediaKeysExt::InitSystemExt, IMediaKeysExt::TeardownSystemExt, IMediaKeysExt::GetSecureStop, IMediaKeysExt::CommitSecureStop
IMediaKeySessionCallbackSession event delivery to the OCDM callerOnKeyMessage, OnKeyStatusUpdate, OnKeyStatusesUpdated, OnError
PlayReady SDK


DRM platform and application context lifecycleDrm_Platform_Initialize, Drm_Platform_Uninitialize, Drm_Initialize, Drm_Uninitialize, Drm_Reinitialize

Content header parsing and key selectionDrm_Content_SetProperty with DRM_CSP_AUTODETECT_HEADER, DRM_CSP_SELECT_KID, DRM_CSP_DECRYPTION_OUTPUT_MODE

License acquisitionDrm_LicenseAcq_GenerateChallenge, Drm_LicenseAcq_ProcessResponse

Decrypt context binding and content decryptionDrm_Reader_Bind, Drm_Reader_Commit, Drm_Reader_Close, Drm_Reader_DecryptMultipleOpaque

Revocation data managementDrm_Revocation_SetBuffer

Secure time and anti-rollback clockDrm_SecureTime_GetValue, Drm_AntiRollBackClock_Init

Secure Stop session managementDrm_SecureStop_EnumerateSessions, Drm_SecureStop_GenerateChallenge, Drm_SecureStop_ProcessResponse

License store maintenanceDrm_StoreMgmt_CleanupStore, Drm_StoreMgmt_DeleteLicenses, Drm_StoreMgmt_DeleteInMemoryLicenses
gst-svp-ext (Generic Interface → Platform HAL)


Platform PlayReady initialization and teardownsvpPlatformInitializePlayready, svpPlatformUninitializePlayready

DRM and platform context provisioningsvpGetDrmOEMContext, svpGetDrmPlatformInitData

DRM storage path resolutionsvpGetDrmStoragePath

Revocation list loading and clock initialization flagsvpLoadRevocationList, svpIsSecureClockInitNeed

Secure buffer lifecycle for decrypted videosvp_allocate_secure_buffers, svp_release_secure_buffers, svp_buffer_alloc_token, svp_buffer_to_token, svp_buffer_free_token, svp_token_size

SVP context lifecyclegst_svp_ext_get_context, gst_svp_ext_free_context

SVP buffer header inspection and updategst_svp_has_header, gst_svp_header_get_start_of_data, gst_svp_header_get_field, gst_svp_header_set_field

Per-stream decrypt path capability queriessvpIsAudioNeedNonSVPContext, svpIsVideoResCheckNeed, svpIsDynamicSVPEncEnabled, svpIsMultipleOpaqueSupportCTR
External Systems

License ServerLicense challenge dispatch and response retrievalHTTP POST (the caller handles transport; the component generates the challenge binary and processes the response binary)

Events Published

Event NameCallback / APITrigger ConditionSubscriber Components
Key messageIMediaKeySessionCallback::OnKeyMessageLicense challenge successfully generated in playreadyGenerateKeyRequest()OCDM Plugin (OpenCDMi) → EME layer → application
Key status updateIMediaKeySessionCallback::OnKeyStatusUpdateLicense bound successfully (KeyUsable), output restriction (KeyOutputRestricted, KeyOutputRestrictedHDCP, KeyOutputRestrictedHDCP22), license expired (LicenseExpired), license not found (LicenseNotFound), or internal error (KeyInternalError)OCDM Plugin (OpenCDMi) → application
Key statuses updatedIMediaKeySessionCallback::OnKeyStatusesUpdatedCompletion of all key status updates within an Update() cycle or persistent license pre-checkOCDM Plugin (OpenCDMi)
ErrorIMediaKeySessionCallback::OnErrorDecrypt failure or license challenge generation failureOCDM Plugin (OpenCDMi) → application

IPC Flow Patterns

Primary Request / Response Flow:

The WPEFramework OCDM Plugin (OpenCDMi) dispatches CDMi API calls directly in-process to the component's C++ interface. The component then invokes PlayReady SDK APIs synchronously under the protection of drmAppContextMutex_.

```mermaid
sequenceDiagram
    participant App as Application
    participant OCDM as OCDM (OpenCDMi)
    participant PR as PlayReady OCDM (OpenCDMi Backend)
    participant PRSDK as PlayReady SDK (SoC DRM)

    App->>OCDM: EME API call
    OCDM->>PR: CDMi method call (in-process)
    PR->>PRSDK: Drm_* API call (under drmAppContextMutex_)
    PRSDK-->>PR: DRM_RESULT
    PR-->>OCDM: CDMi_RESULT
    OCDM-->>App: EME result / event
```

Event Notification Flow:

Key status events are posted synchronously from within the Update() and playreadyGenerateKeyRequest() call paths by invoking the registered IMediaKeySessionCallback directly on the calling thread.

```mermaid
sequenceDiagram
    participant PRSDK as PlayReady SDK (SoC DRM)
    participant PR as PlayReady OCDM (OpenCDMi Backend)
    participant CB as IMediaKeySessionCallback
    participant App as Application

    PRSDK-->>PR: Drm_LicenseAcq_ProcessResponse() result
    PR->>CB: OnKeyStatusUpdate("KeyUsable", keyId)
    PR->>CB: OnKeyStatusesUpdated()
    CB-->>App: keystatuseschange event
```

Implementation Details

SDK and Component API Reference

PlayReady SDK APIs

Called by playready-rdk directly on SoC-provided PlayReady DRM libraries (path: playready-rdk → SoC DRM libraries).

PlayReady SDK APIPurposeImplementation File
Drm_Platform_InitializeInitialize the PlayReady platform layer using platform-specific init dataMediaSession.cpp
Drm_Platform_UninitializeUninitialize the PlayReady platform layerMediaSession.cpp
Drm_InitializeInitialize the DRM application context with an opaque buffer and store pathMediaSystem.cpp, MediaSession.cpp
Drm_UninitializeRelease the DRM application contextMediaSystem.cpp, MediaSession.cpp
Drm_ReinitializeRe-initialize an existing DRM application context on session reuseMediaSession.cpp
Drm_Content_SetPropertySet content properties: auto-detect header, select KID, set decryption output modeMediaSystem.cpp, MediaSession.cpp, MediaSessionExt.cpp
Drm_LicenseAcq_GenerateChallengeGenerate a license acquisition challenge from the DRM headerMediaSession.cpp, MediaSessionExt.cpp
Drm_LicenseAcq_ProcessResponseProcess a license server response and store acquired licensesMediaSession.cpp
Drm_Reader_BindBind a decrypt context to a license for the specified key IDMediaSession.cpp, MediaSessionExt.cpp
Drm_Reader_CommitCommit the bound reader context and apply output protection policyMediaSession.cpp, MediaSessionExt.cpp
Drm_Reader_CloseRelease a decrypt contextMediaSession.cpp
Drm_Reader_DecryptMultipleOpaqueDecrypt a multi-region encrypted buffer supporting multiple IV valuesMediaSession.cpp
Drm_Revocation_SetBufferRegister the revocation data buffer with the application contextMediaSystem.cpp, MediaSession.cpp
Drm_SecureTime_GetValueRead the secure clock value and type from the application contextMediaSystem.cpp
Drm_AntiRollBackClock_InitInitialize the anti-rollback clock when the secure clock is unavailableMediaSystem.cpp
Drm_SecureStop_EnumerateSessionsList active Secure Stop session IDs from the storeMediaSystem.cpp
Drm_SecureStop_GenerateChallengeGenerate a Secure Stop challenge for a given session IDMediaSystem.cpp
Drm_SecureStop_ProcessResponseProcess a Secure Stop server responseMediaSystem.cpp
Drm_StoreMgmt_CleanupStoreRemove expired and removal-date licenses from the DRM storeMediaSystem.cpp
Drm_StoreMgmt_DeleteLicensesDelete a specific license identified by KID and LIDMediaSession.cpp
Drm_StoreMgmt_DeleteInMemoryLicensesDelete all in-memory licenses associated with a batch IDMediaSession.cpp

gst-svp-ext Component APIs

Called by playready-rdk on the gst-svp-ext generic interface. GStreamer SVP-specific platform handling is passed through by gst-svp-ext to the underlying platform HAL layer (path: playready-rdk → gst-svp-ext generic → gst-svp-ext platform HAL).

gst-svp-ext APIPurposeImplementation File
svpPlatformInitializePlayreadyPerform SVP-layer PlayReady platform initializationMediaSystem.cpp
svpPlatformUninitializePlayreadyPerform SVP-layer PlayReady platform teardownMediaSystem.cpp
svpGetDrmOEMContextRetrieve the OEM DRM context pointer for Drm_InitializeMediaSystem.cpp, MediaSession.cpp
svpGetDrmPlatformInitDataRetrieve platform-specific initialization data for Drm_Platform_InitializeMediaSession.cpp
svp_allocate_secure_buffersAllocate protected memory regions for decrypted video contentMediaSession.cpp
svp_release_secure_buffersRelease protected memory regions after useMediaSession.cpp
svp_buffer_alloc_token / svp_buffer_to_tokenConvert a secure buffer handle to an opaque token for downstream pipeline consumptionMediaSession.cpp

Key Implementation Logic


Configuration

Key Configuration Files

Configuration FilePurposeOverride Mechanism
JSON configuration string (WPEFramework host)Specifies the DRM data directory path, DRM store file path, and HOME path for the component processDelivered by the WPEFramework configuration system at Initialize() time

Key Configuration Parameters

ParameterTypeDefaultDescription
read-dirstringFilesystem path to the directory containing PlayReady data files (device certificate and related assets).
store-locationstringFilesystem path to the PlayReady DRM store file where licenses are persisted.
home-pathstringValue set as the HOME environment variable for the component process; required for Secure Stop functionality to operate correctly.

Runtime Configuration Parameters

ParameterTypeDefaultDescription
PLAYREADY_RDK_LOG_LEVELinteger3 (DEBUG)Environment variable read at Initialize() time by InitializeLogLevel(). Accepted range 0–4 maps to ERROR, WARN, INFO, DEBUG, TRACE. Values outside the range are silently ignored and the default is applied.

Build-Time Configuration Parameters

Build-Time Option / DefineDefaultDescription
USE_SVPOn (unconditional)Enables Secure Video Path integration via gst-svp-ext. Applied unconditionally across all build configurations.
DRM_ERROR_NAME_SUPPORTOffWhen enabled, appends human-readable DRM error name strings to all PR_LOG output via DRM_ERR_NAME(dr)DRM_ERR_GetErrorNameFromCode().
DRM_ANTI_ROLLBACK_CLOCK_SUPPORTOffWhen enabled, allows falling back to the anti-rollback clock when the secure clock is unavailable.
PLAYREADY_VERSION_4_6OffWhen enabled, uses the PlayReady 4.6 SDK version string global instead of the legacy global.
NO_PERSISTENT_LICENSE_CHECKOffWhen enabled, PersistentLicenseCheck() unconditionally returns failure, preventing key reuse from a prior session and always forcing a fresh license request.
TEE_CONFIG_NEEDOffWhen enabled, includes the TEE configuration header and calls OEM_OPTEE_SetHandle() in the decrypt path.
CLEAN_ON_INITOn (hardcoded)Guards the CleanLicenseStore() call inside InitSystemExt() via #ifdef, but is hardcoded to #define CLEAN_ON_INIT 1 in the same file and not exposed via CMake, so that path always executes. CleanLicenseStore() is also called unconditionally, with no macro guard at all, from TeardownSystemExt() and DeleteSecureStore().
ENABLE_AMBIGUOUS_FIXOffWhen enabled, suppresses the extern DRM_CONST_STRING g_dstrDrmPath declaration in MediaSystem.cpp, resolving build errors on platforms where the symbol is already visible in scope via a platform SDK header or prior definition.

Configuration Persistence

The DRM store file at the path specified by store-location persists license data across reboots and is managed by the PlayReady SDK. In-memory licenses and temporary persistent licenses acquired during a session are deleted from the store when that session is closed.