diff --git a/package-lock.json b/package-lock.json index 173940cab..d79ffae5b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,7 +18,7 @@ "devDependencies": { "@commitlint/cli": "^17.0.3", "@commitlint/config-conventional": "^17.0.3", - "@firebolt-js/openrpc": "3.0.0-next.3", + "@firebolt-js/openrpc": "rdkcentral/firebolt-openrpc#feature/x-subscriber-type", "@firebolt-js/schemas": "2.0.0", "@saithodev/semantic-release-backmerge": "^3.2.0", "@semantic-release/changelog": "^6.0.1", @@ -1071,8 +1071,7 @@ }, "node_modules/@firebolt-js/openrpc": { "version": "3.0.0-next.3", - "resolved": "https://registry.npmjs.org/@firebolt-js/openrpc/-/openrpc-3.0.0-next.3.tgz", - "integrity": "sha512-hhNtHIpNwwN99Zd4ZABnQ3MIEMPYDN5rSZPNad4ah4R5rmLypWv79vfHSPYeCrTTmoQCwwCFhpObjhJk0EVX/g==", + "resolved": "git+ssh://git@github.com/rdkcentral/firebolt-openrpc.git#daa0d06f64026ac1cf8416810854421756fbc377", "dev": true, "dependencies": { "ajv": "^8.3.0", diff --git a/package.json b/package.json index f019e95da..e80822d17 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "devDependencies": { "@commitlint/cli": "^17.0.3", "@commitlint/config-conventional": "^17.0.3", - "@firebolt-js/openrpc": "3.0.0-next.3", + "@firebolt-js/openrpc": "rdkcentral/firebolt-openrpc#feature/x-subscriber-type", "@firebolt-js/schemas": "2.0.0", "@saithodev/semantic-release-backmerge": "^3.2.0", "@semantic-release/changelog": "^6.0.1", diff --git a/requirements/images/specifications/media/media-pipeline/media/image1.png b/requirements/images/specifications/media/media-pipeline/media/image1.png new file mode 100644 index 000000000..a93c8d392 Binary files /dev/null and b/requirements/images/specifications/media/media-pipeline/media/image1.png differ diff --git a/requirements/images/specifications/media/media-pipeline/media/image2.png b/requirements/images/specifications/media/media-pipeline/media/image2.png new file mode 100644 index 000000000..a73586c8d Binary files /dev/null and b/requirements/images/specifications/media/media-pipeline/media/image2.png differ diff --git a/requirements/images/specifications/media/media-pipeline/media/image3.png b/requirements/images/specifications/media/media-pipeline/media/image3.png new file mode 100644 index 000000000..27a83ec3c Binary files /dev/null and b/requirements/images/specifications/media/media-pipeline/media/image3.png differ diff --git a/requirements/images/specifications/media/media-pipeline/media/image4.png b/requirements/images/specifications/media/media-pipeline/media/image4.png new file mode 100644 index 000000000..abd84556f Binary files /dev/null and b/requirements/images/specifications/media/media-pipeline/media/image4.png differ diff --git a/requirements/images/specifications/media/media-pipeline/media/image5.png b/requirements/images/specifications/media/media-pipeline/media/image5.png new file mode 100644 index 000000000..1b5275806 Binary files /dev/null and b/requirements/images/specifications/media/media-pipeline/media/image5.png differ diff --git a/requirements/specifications/json-schema/parameters.md b/requirements/specifications/json-schema/parameters.md new file mode 100644 index 000000000..caf80aac2 --- /dev/null +++ b/requirements/specifications/json-schema/parameters.md @@ -0,0 +1,3 @@ +TODO: write this spec... + +If a parameter schema has a default value, then the Firebolt SDK **SHOULD** insert that value when an explicit value is not provided by the calling app. diff --git a/requirements/specifications/media/media-info.md b/requirements/specifications/media/media-info.md new file mode 100644 index 000000000..897a8e125 --- /dev/null +++ b/requirements/specifications/media/media-info.md @@ -0,0 +1,523 @@ +# Media Info Requirements + +Document Status: Candidate Specification + +See [Firebolt Requirements Governance](../../governance.md) for more info. + +| Contributor | Organization | +| --------------- | -------------- | +| Anthony Borzota | Comcast | +| Jeremy LaCivita | Comcast | +| Stuart Harris | Sky | +| Farhan Mood | Liberty Global | + +## 1. Overview + +App developers need to know which audio and video formats can be successfully played on a Firebolt device and its attached display. + +An audio format includes values such as the audio container, codec, codec level, and bit rate of the audio stream. + +A video format may include values such as the video container, codec, HDR profile, and resolution of the video stream. + +Further, apps may also need to know about the media format currently playing in the media pipeline. + +An app may need to check IP video playback that it has initiated to see if Dolby Audio is in fact active (as opposed to just present in the encoded data) in order to display metadata or badges to the user. Apps may also be playing [user-cultivated media](./media-access.md), and therefore have no metadata about the format of the files. + +A first-party app may need to check all [Media Pipelines](./media-pipeline.md) for media format characteristics to display a global badge. + +Additionally, apps may need to know what is supported by the device, *before* initiating any media playback. + +As a W3C-based platform, there is no standard API for detecting media formats or codecs that works in all cases, short of inspecting the bytes of the media in the app itself. + +To solve this, Firebolt APIs will be created to detect the formats and codecs currently being decoded by the [Media Pipeline](./media-pipeline.md). Firebolt APIs will also be created to query whether the device supports playing content of various formats. + +### 1.1. User Stories + +### 1.2. As an OTT App developer + +I want to know what is supported by the device and it's active AV chain: + +- I want to know if a video or audio format (Dolby Vision, Dolby Atmos, HEVC, etc.) will work if playback is attempted. +- I want to know if a format profile or level (HEVC Main 10, VP9 Profile 2, etc.) is supported. +- I want to know how many audio output channels (e.g. 7.1, 5.1) are available. +- I want to know what resolutions and frame rates are supported (e.g. 1080p60). + +I want to know what kind of content I'm currently playing: + +- I want to know which video or audio format the media I'm currently playing is sending to the decoder. +- I want to know which video or audio format profile or level the media I'm currently playing is being sent to the decoder. +- I want to know how many audio output channels (e.g. 7.1, 5.1) are currently being sent to the decoder. +- I want to know what resolution and frame rate is currently being sent to the decoder. + +### 1.3. As a first-party App developer + +I want to show an audio/videophile overlay with detailed information: + +- I want to know all video or audio formats that are currently being sent to a decoder. +- I want to know all video or audio format profiles/levels currently being sent to a decoder. +- I want to know all audio output channel profiles (e.g. 7.1, 5.1) currently being sent to a decoder. +- I want to know all resolution and framerates currently being sent to a decoder. + +## 2. Table of Contents + +- [Media Info Requirements](#media-info-requirements) + - [1. Overview](#1-overview) + - [1.1. User Stories](#11-user-stories) + - [1.2. As an OTT App developer](#12-as-an-ott-app-developer) + - [1.3. As a first-party App developer](#13-as-a-first-party-app-developer) + - [2. Table of Contents](#2-table-of-contents) + - [3. Media Constants and Schemas](#3-media-constants-and-schemas) + - [3.1. Media Container Types](#31-media-container-types) + - [3.2. Media Codecs](#32-media-codecs) + - [3.3. Resolutions](#33-resolutions) + - [3.4. Resolution User-Friendly Name](#34-resolution-user-friendly-name) + - [3.5. Video Modes](#35-video-modes) + - [3.6. Media HDR Profiles](#36-media-hdr-profiles) + - [3.7. Color Depth](#37-color-depth) + - [4. Device Media Support](#4-device-media-support) + - [4.1. Video Format Supported](#41-video-format-supported) + - [4.1.1. Audio Format Supported](#411-audio-format-supported) + - [5. Display Properties](#5-display-properties) + - [5.1. Supported HDR Profiles](#51-supported-hdr-profiles) + - [5.2. Supported Color Depth](#52-supported-color-depth) + - [5.3. Display Size](#53-display-size) + - [5.4. Display Resolution](#54-display-resolution) + - [5.5. Display Resolution Name](#55-display-resolution-name) + - [5.5. Refresh Rate](#55-refresh-rate) + - [6. Device Properties](#6-device-properties) + - [6.1. Current Video Mode](#61-current-video-mode) + - [6.1. Video Modes Supported](#61-video-modes-supported) + - [6.2 Video Resolution](#62-video-resolution) + - [6.2 Current HDR Profile](#62-current-hdr-profile) + - [6.3 Supported HDR Profiles](#63-supported-hdr-profiles) + - [6.4 Supported HDCP Version](#64-supported-hdcp-version) + - [5.6. Is Source Frame Rate Used](#56-is-source-frame-rate-used) + - [6. Audio Output Properties](#6-audio-output-properties) + - [6.1. Mode](#61-mode) + - [7. Media Info](#7-media-info) + - [7.1. MediaInfo for Current App](#71-mediainfo-for-current-app) + - [7.1.1. Video Format](#711-video-format) + - [7.1.2. Audio Format](#712-audio-format) + - [7.2. Global MediaInfo](#72-global-mediainfo) + - [7.2.1. Active Video Formats](#721-active-video-formats) + - [7.2.2. Active Audio Formats](#722-active-audio-formats) + +## 3. Media Constants and Schemas + +### 3.1. Media Container Types + +The Firebolt `Media` module **MUST** have an `AudioContainer` enumeration of the following media container content types: + +- `audio/mpeg` +- `audio/mp4` +- `audio/ogg` +- `audio/webm` + +The Firebolt `Media` module **MUST** have a `VideoContainer` enumeration of the following media container content types: + +- `video/mpeg` +- `video/mp2t` +- `video/mp4` +- `video/webm` + +### 3.2. Media Codecs + +The Firebolt `Media` module **MUST** have an `AudioCodec` enumeration: + +| Name | Value | +|------------|--------------------------------------| +| `aac` | Advanced Audio Coding | +| `ac3` | Dolby Digital / Dolby Audio Codec 3 | +| `ac3plus` | AC3 Plus (Dolby Digital Plus or DD+) | +| `ac4` | Dolby Audio Codec 4 | +| `dts-x` | Digital Theater Systems X | +| `eac3` | Dolby Enhanced AC-3 | +| `mpeg3` | MPEG-1 Part 3 & MPEG-2 Part 3 | +| `opus` | IETF Opus | +| `truehd` | Dolby TrueHD | +| `vorbis` | Xiph.org Vorbis | + +The Firebolt `Media` module **MUST** have a `VideoCodec` enumeration: + +| Name | Description | +|---------|--------------------------------------| +| `avc` | Advanced Video Coding (H.264) | +| `hevc` | High Efficiency Video Coding (H.265) | +| `mpeg1` | MPEG-1 Part 2 Visual | +| `mpeg2` | MPEG-2 Part 2 Visual | +| `vp8` | Video Processor 8 | +| `vp9` | Video Processor 9 | +| `vp10` | Video Processor 10 | + +### 3.3. Resolutions + +For the purposes of the Firebolt API, a `Resolution` shall be defined by two values: the width and height, in pixels. + +For example, the resolution for a display may be defined as `[1920, 1080]`. + +Any methods relating to a resolution (such as the supported resolution of a display or the output resolution of a device) **MUST** return an array of two values: the width and height. + +### 3.4. Resolution User-Friendly Name + +The Firebolt `Media` module **MUST** have a `ResolutionName` enumeration: + +| Class | Applicable Resolutions | +|-----------|------------------------| +| `sd` | `576p` and lower | +| `hd` | `720p` | +| `fhd` | `1080p` | +| `uhd` | `2160` and higher | +| `unknown` | unknown or no display | + +### 3.5. Video Modes + +For the purposes of the Firebolt API, a `VideoMode` shall be defined as the shorthand resolution and frame rate of video content. + +The Firebolt `Media` module **MUST** have a `VideoMode` enumeration: + +- `480i` +- `480p` +- `576i25` +- `576p50` +- `576p60` +- `720p50` +- `720p60` +- `1080i25` +- `1080i50` +- `1080i60` +- `1080p24` +- `1080p30` +- `1080p50` +- `1080p60` +- `2160p30` +- `2160p50` +- `2160p60` +- `4320p60` + +Any methods relating to the video mode (such as a device's video output mode) **MUST** return `Media.VideoMode` values. + +### 3.6. Media HDR Profiles + +The Firebolt `Media` module **MUST** have an `HDRProfile` enumeration: + +- `dolbyVision` +- `hdr10` +- `hdr10plus` +- `hlg` +- `sdr` +- `unknown` + +### 3.7. Color Depth + +The Firebolt `Media` module **MUST** have an `ColorDepth` enumeration: + +- `0` +- `8` +- `10` +- `12` + +## 4. Device Media Support + +Apps need to know what types of media support the device is capable of. + +To facilitate this, the `Device` module will have a set of methods that return possible media capabilities supported by the current device configuration. + +These values do not change without a settings change or a firmware update. + +### 4.1. Video Format Supported + +The `Device` module **MUST** have a `videoFormatSupported` API that returns `true` or `false` depending on whether the format specified is supported by the current device and its AV chain. This API **MUST** return `boolean`. + +```javascript +const hdr10plusWithH265 = videoFormatSupported(Media.VideoCodec.HEVC, { + profile: "main10", + hdr: Media.HDRProfile.HDR10_PLUS +}) + +const hdr10plusWithVP9 = videoFormatSupported(Media.VideoCodec.VP9, { + profile: "p2", + hdr: Media.HDRProfile.HDR10_PLUS, + resolution: [3840, 2160] +}) +``` + +The `videoFormatSupported` API **MUST** have a required `codec` parameter with the type `Media.VideoCodec`. + +The `videoFormatSupported` API **MUST** have an optional `info` parameter which **MUST** be an object with zero or more of the following properties: + +| Property | Type | Description | +|--------------|------------------------|-------------| +| `container` | `Media.VideoContainer` | The content container format | +| `hdr` | `Media.HDRProfile` | The HDR profile that support is being checked for | +| `level` | `string` | The codec level:
**hevc**: `4.1`, `4.2`, `5.0`, `5.1`
**vp9**:`3.0`, `3.1`, `4.0`, `4.1`, `5.0`, `5.1` | +| `profile` | `string` | The codec profile:
**hevc**: `main`, `high`, `main10`
**vp9**: `p0`, `p2` | +| `resolution` | `array` | The resolution in width and height (e.g. `[1920, 1080]`) of the media content being requested | + +> **NOTE**: A device supporting a particular HDR profile and resolution does not mean that the current display also supports that profile and resolution. See `Display.hdrProfilesSupported()` for more info on detecting display HDR support. + +The `videoFormatSupported` API **MUST NOT** return `true` unless the format specified is supported with **all** of the properties specified in `options` *at the same time*. + +Use of the `videoFormatSupported` API requires access to the `use` role of the `xrn:firebolt:capability:device:info` capability. + +#### 4.1.1. Audio Format Supported + +The `Device` module **MUST** have an `audioFormatSupported` API that returns `true` or `false` depending on whether the format specified is supported by the current device configuration and its AV chain. This API **MUST** return a `boolean`. + +```javascript +const atmosWithAC4 = audioFormatSupported(Media.AudioCodec.AC4, { + atmos: true +}) + +const atmosWithEAC3 = audioFormatSupported(Media.AudioCodec.EAC3, { + atmos: true +}) +``` + +The `audioFormatSupported` API **MUST** have a required `codec` parameter with the type `Media.AudioCodec`. + +The `audioFormatSupported` API **MUST** have an optional `options` parameter which **MUST** be an object with zero or more of the following properties: + +| Property | Type | Description | +|----------------|-------------------------|-------------| +| `atmos` | `boolean` | Whether or not Dolby Atmos support for the given format is being requested | +| `channels` | `int` | Required number of audio channels | +| `codecLevel` | `string` | The codec level | +| `codecProfile` | `string` | The codec profile:
**aac**: `mp2lc`, `mp4he` | +| `container` | `Media.Container` | The container format type | +| `mode` | `Media.AudioOutputMode` | Specify which mode should be used to evaluate the request. Defaults to the current audio mode if not specified. | +| `sampleRate` | `number` | The sample rate being requested, in kHz | + +If the `options` parameter is provided, then the `audioFormatSupported` API **MUST NOT** return `true` unless the format specified is supported with **all** of the properties specified by `options` *all at the same time*. + +Use of the `audioFormatSupported` API requires access to the `use` role of the `xrn:firebolt:capability:device:info` capability. + +## 5. Display Properties + +Apps need to know various aspects of the current (or built-in) display on a device. + +These will be surfaced in a new `Display` module. + +Access to these APIs is governed by the `xrn:firebolt:capability:display:info` capability. + +### 5.1. Supported HDR Profiles + +The `Display` module **MUST** have an `hdrProfilesSupported` method that returns the display's supported HDR profiles as an array of `Media.HDRProfile` values. + +If no display is present, an empty array is returned. + +### 5.2. Supported Color Depth + +The `Display` module **MUST** have a `colorDepthSupported` method that returns a `Media.ColorDepth` value. + +If no display is present, a value of zero is returned. + +### 5.3. Display Size + +The `Display` module **MUST** have a `size` method that returns the width and height of the display, in centimeters. + +If no display is present, a value of zero is returned for both the width and height. + +### 5.4. Display Resolution + +The `Display` module **MUST** have a `resolution` method that returns the width and height of the display's native resolution. + +If no display is present, both returned values **MUST** be zero. + +### 5.5. Display Resolution Name + +The `Display` module **MUST** have a `resolutionName` method that returns a user-friendly name of the display's resolution as defined by `Media.ResolutionName`. + +If no display is present, a value of `unknown` is returned. + +### 5.5. Refresh Rate + +The `Display` module **MUST** have a `refreshRate` method that returns an number value for the refresh rate that the display supports (in Hz). + +If no display is present, a value of zero is returned. + +### 6. Device Properties + +Apps need to know various aspects of the device, including its media playing capabilities. + +These will be surfaced in the `Device` module. + +Access to these APIs is governed by the `xrn:firebolt:capability:device:info` capability. + +### 6.1. Current Video Mode + +The `Device` module **MUST** have a `videoMode` method that returns the current video modes used by the device. + +This method **MUST** return a value from the `Media.VideoMode` enum. + +If no display is present, a value of `unknown` is returned. + +### 6.1. Video Modes Supported + +The `Device` module **MUST** have a `videoModesSupported` method that returns an array of valid video modes that the device supports, regardless of any connected display. + +This method **MUST** return an array with one or more values from the `Media.VideoMode` enum. + +### 6.2 Video Resolution + +The `Device` module **MUST** have a `videoResolution` method that returns the width and height of the current video output resolution. + +If no display is present, both returned values **MUST** be zero. + +### 6.2 Current HDR Profile + +The `Device` module **MUST** have a `hdrProfile` method that returns the HDR profile currently used by the device for video output. + +This method **MUST** return a value from the `Media.HDRProfile` enum. + +### 6.3 Supported HDR Profiles + +The `Device` module **MUST** have an `hdrProfilesSupported` method that returns the HDR profiles that the device supports, regardless of any connected display. + +### 6.4 Supported HDCP Version + +The `Device` module **MUST** have a `hdcpVersionSupported` method that returns the latest HDCP version supported by the device. + +This method **MUST** return a value such as: + +- `1.4` +- `2.2` +- `unknown` + +### 5.6. Is Source Frame Rate Used + +The `Device` module **MUST** have a boolean `isSourceFrameRateUsed` API. + +This API **MUST** return `true` if the HDMI output frame rate is set to follow video source frame rate. + +Otherwise, this API **MUST** return `false`. + +## 6. Audio Output Properties +Apps need to know various aspects of the current (or built in) audio output system on a device. + +These will be surfaced in a new `AudioOutput` module. + +Access to these APIs is governed by the `xrn:firebolt:capability:audio-output:info` capability. + +### 6.1. Mode + +The `AudioOutput` module **MUST** include a `mode` string API that returns an `Media.AudioOutputMode` enum that is one of the following values: + +- `auto` +- `mono` +- `none` +- `passthrough` +- `stereo` +- `surround` +- `unknown` + +## 7. Media Info + +The Firebolt `MediaInfo` module consists of APIs to get information about any media actively being decoded by the Media Pipeline or an active HDMI input. + +### 7.1. MediaInfo for Current App + +Apps need a way to query the media info for media currently being played by the app. All of the following methods take a single `pipeline` parameter, which identifies the Media Pipeline in the current app's scope that is being queried, e.g.: + +```javascript +import { MediaInfo } from '@firebolt-js/sdk' + +MediaInfo.videoFormat(1) // return the video codec in the current app's media pipeline 1 +MediaInfo.videoFormat(2) // return the video codec in the current app's media pipeline 2 +``` + +**TODO**: where do we map video tags to ids? need a spec for this? same spec, new spec? +JL: i linked to the Media Pipeline spec and merged it into this branch... we should review. + +The `pipeline` parameter is required for the JSON-RPC request, however, the Firebolt SDK **SHOULD** provide a default value of `1` if it is not provided by the calling app. + +For example, the following would query the video format for the app's pipeline `1` in JavaScript (which supports default values for parameters). + +```javascript +MediaInfo.videoFormat() +``` + +#### 7.1.1. Video Format + +The `MediaInfo` module **MUST** have a `videoFormat` API that returns an `object` with the video codec (e.g. `avc`, `vp9`, etc.) and resolution of the media currently in the media pipeline (either playing or paused). + +The `videoFormat` result **MUST** have a `codec` property with one of the values from the `Media.VideoCodec` enum. + +The `videoFormat` result **MUST** have an `hdr` array property with zero or more `Media.HDRProfile` values. + +If a value is included in the `hdr` array then the media currently in the media pipeline **MUST** include the denoted HDR metadata in the decoded video. + +The `videoFormat` result **MUST** have a `resolution` property with a `Media.Dimensions` value. + +The `videoFormat` result **MAY** have a `codecProfile` string property that denotes the profile of the codec. + +The `videoFormat` result **MAY** have a `codecLevel` string property that denotes the level of the codec. + +The `videoFormat` API **MUST** be a Firebolt `property:readonly` API, and +have a corresponding `onVideoFormatChanged` notification. + +Use of the `videoFormat` APIs require access to the `use` role of the +`xrn:firebolt:capability:media-info:video-format` capability. + +#### 7.1.2. Audio Format + +The `MediaInfo` module **MUST** have a `audioFormat` API that returns an `object` with the +audio codec, e.g., AAC, AC3, etc., and sample rate of the media currently in the +media pipeline (either playing or paused). + +The `audioFormat` result **MUST** have a `codec` property with one of the values from the `Media.AudioCodec` enum. + +The `audioFormat` result **MUST** have a `channels` integer property that denotes the number of audio channels. + +The `audioFormat` result **MUST** have a `sampleRate` integer property that denotes the audio sample rate. + +The `audioFormat` result **MAY** have a `codecProfile` string property that denotes the profile of the codec. + +The `audioFormat` result **MAY** have a `codecLevel` string property that denotes the level of the codec. + +The `audioFormat` API **MUST** be a Firebolt `property:readonly` API, and have a corresponding `onAudioFormatChanged` notification. + +Use of the `audioFormat` APIs require access to the `use` role of the `xrn:firebolt:capability:media-info:audio-format` capability. + +### 7.2. Global MediaInfo + +First party apps need a way to query which media formats are currently being output to the [media pipeline](./media-pipeline.md), without caring about which pipeline. + +#### 7.2.1. Active Video Formats +The `MediaInfo` module **MUST** have a `activeVideoFormats` API that returns an array of `objects` with the video codec, e.g., H.265, VP9, etc., of the media currently in each media pipeline (either playing or paused). + +Each item in the `activeVideoFormats` result array **MUST** conform to the same requirements as the indivual results from the [`videoFormat` API](#611-video-format). + +Additionally, the `MediaInfo` module **MUST** have an `onActiveVideoFormatsChanged` notifier that fires whenever any pipeline starts, stops, or changes its current video format. + +Example: + +```typescript +const ishevc:boolean = await MediaInfo.activeVideoFormats().find(f => f.codec === Media.VideoCodec.HEVC) + +MediaInfo.activeVideoFormats((active) => { + const hevc = active.find(f => f.codec === Media.VideoCodec.HEVC) + console.log('HEVC codec is now ' + (hevc ? 'active' : 'inactive') + '.') +}) +``` + +Access to these APIs is gated by `manage` access to the `xrn:firebolt:capability:media-info:video-format` capability. + +#### 7.2.2. Active Audio Formats +The `MediaInfo` module **MUST** have a `activeAudioFormats` API that returns an `object` with the audio codec, e.g., AAC, AC3, etc., of the media currently in the media pipeline (either playing or paused). + +Each item in the `activeAudioFormats` result array **MUST** conform to the same requirements as the indivual results from the [`audioFormat` API](#612-audio-format). + +Additionally, the `MediaInfo` module **MUST** have an `onActiveAudioFormatsChanged` notifier that fires whenever any pipeline starts, stops, or changes its current audio format. + +Example: + +```typescript +const isaac:boolean = await MediaInfo.activeAudioFormats().find(f => f.codec === Media.AudioCodec.AAC) + +MediaInfo.activeAudioFormats((active) => { + const aac = active.find(f => f.codec === Media.AudioCodec.AAC) + console.log('AAC codec is now ' + (aac ? 'active' : 'inactive') + '.') +}) +``` + +Access to these APIs is gated by `manage` access to the `xrn:firebolt:capability:media-info:audio-format` capability. diff --git a/requirements/specifications/media/media-pipeline.md b/requirements/specifications/media/media-pipeline.md new file mode 100644 index 000000000..4bbdad9f2 --- /dev/null +++ b/requirements/specifications/media/media-pipeline.md @@ -0,0 +1,289 @@ +# Media Pipeline Requirements + +Document Status: Working Draft + +See [Firebolt Requirements Governance](./governance.md) for more info. + +**NOTE**: Update this link based on your directory depth ^^ + +| Contributor | Organization | +| -------------- | -------------- | +| Lucien Kennedy-Lamb | Sky | +| Bijal Shah | Sky | +| Yuri Pasquali | Sky | +| Stuart Pett | Sky | +| Wouter Meek | Comcast | +| Jeremy LaCivita | Comcast | +| Kevin Pearson | Comcast | +| Phillip Stroffolino | Comcast | + +## 1. Overview + +Playback of audio/video media is a first-class concern for Firebolt. As +such, Firebolt must provide a consistent, secure Media Pipeline API for +sending audio and video streams from an app container out to a decoder +and CDM for content decryption, decoding, and rasterization. + +Additionally, Firebolt browsers must leverage the same Media Pipeline +implementation as native apps, so that content plays back the same in +both environments and can have resources managed in the same way. + +This is achieved with the open source [Rialto Media +Pipeline](https://github.com/rdkcentral/rialto) API and implementation: + +TODO: we need a few additions to support Netflix: + +**TODO**: the rest of these need to move to Rialto: + + +- Preferred resolution/framerate +- atmos lock +- loudness eq +The audioSettings **MUST** include an `atmosOutputLock` boolean property. + +The audioSettings **MUST** include an `audioLoudnessEquivalence` boolean property. + +The audioSettings API **MUST** be a Firebolt `property:readonly` API, and +have a corresponding `onAudioSettingsChanged` notification. + +Use of the `audioSettings` and `onAudioSettingsChanged` APIs require access +to the `use` role of the `xrn:firebolt:capability:device:audio-settings` capability. + +**TODO**: Netflix needs to be able to *set* atmosOutputLock... + + +![Diagram Description automatically +generated](../../../../requirements/images/specifications/media/media-pipeline/media/image1.png) + +## 2. Table of Contents +- [Media Pipeline Requirements](#media-pipeline-requirements) + - [1. Overview](#1-overview) + - [2. Table of Contents](#2-table-of-contents) + - [3. Media Pipeline](#3-media-pipeline) + - [3.1. Media Pipeline Commands](#31-media-pipeline-commands) + - [3.2. MediaPipeline Notifications](#32-mediapipeline-notifications) + - [3.3. Media Pipeline Management](#33-media-pipeline-management) + - [4. W3C Media APIs](#4-w3c-media-apis) + - [4.1. MediaSource](#41-mediasource) + - [4.2. MediaElement](#42-mediaelement) + - [5. Supported Media](#5-supported-media) + - [5.1. Container formats](#51-container-formats) + - [5.2. Video codecs](#52-video-codecs) + - [5.3. Audio codecs](#53-audio-codecs) + - [6. Supported Decryption](#6-supported-decryption) + - [6.1. DRM Key Systems](#61-drm-key-systems) + - [6.2. Decryption Schemes](#62-decryption-schemes) + +## 3. Media Pipeline + +The Firebolt Media Pipeline consists of an API for passing audio & video +streams *out* of individual app containers *into* managed media sessions +that support decryption, decoding, and rasterization. Additionally there +is an API for sending notifications out of the decoder and into the app +container. + +The goal of this abstraction is to decouple individual Firebolt Apps and +containers from the underlying implementations of these features. +Additionally, this abstraction allows for the same component to manage +media sessions in a consistent manner regardless of implementation. + +To ensure consistency, all native containers, including browsers, that +run on Firebolt platforms **MUST** use Rialto as the only pipeline to +Media decoders and CDMs. + +The Media Pipeline API uses a client-server model to allow Firebolt +devices to manage media pipeline resources and visibility. This enables +multiple media pipeline sessions to be running at once, even though they +will not all have access to the underlying decoder. Command messages are +passed using an efficient binary RPC protocol. Media data is passed +using memory shared by only the app container and its respective Rialto +session server. + +![Timeline Description automatically +generated](../../../requirements/images/specifications/media/media-pipeline/media/image2.png) + +### 3.1. Media Pipeline Commands + +Media Pipeline commands go from the app to the Rialto Media Pipeline +server. + +This section describes the use cases that the Rialto API solves. For +actual API semantics, please refer to the Rialto Github repository. + +The MediaPipeline API **MUST** support pushing data into the Pipeline, +in response to a notification that more data is needed. + +The MediaPipeline API **MUST** support informing the Pipeline that it +has reached the end of a stream and no more data is available. + +The MediaPipeline API **MUST** support initializing (aka loading) a new +Media session, typically done before starting a new stream. + +The MediaPipeline API **MUST** support attaching one video and one audio +source buffer. + +The MediaPipeline API **MUST** support removing source buffers. + +The MediaPipeline API **MUST** support pausing and playing. + +The MediaPipeline API **MUST** support stopping playback, such that it +cannot be resumed without reinitializing. + +The MediaPipeline API **MUST** support setting the playback rate. + +The MediaPipeline API **MUST** support setting the current playback +position. + +The MediaPipeline API **MUST** support setting the video location and +dimensions. + +The MediaPipeline API **MUST** support dynamic audio decode switching to +support Netflix use cases. + +### 3.2. MediaPipeline Notifications + +Media Pipeline notifications come from the Rialto Media Pipeline server +to the app. + +This section describes the use cases that the Rialto API solves. For +actual API semantics, please refer to the Rialto Github repository. + +The MediaPipeline API **MUST** support notifying the app when more audio +or video data is needed in order for playback to continue without error. + +The MediaPipeline API **MUST** support notifying the app when a need for +more audio or video data is no longer relevant, e.g. due to switching +buffers or stopping. + +The MediaPipeline API **MUST** support notifying the app of the current +Media duration. + +The MediaPipeline API **MUST** support notifying the app of the current +Media position. + +The MediaPipeline API **MUST** support notifying the app of the current +native dimensions of the current Media. + +The MediaPipeline API **MUST** support notifying the app of the current +buffer state, e.g. buffered, idle, error. + +The MediaPipeline API **MUST** support notifying the app of the current +playback state, e.g. playing, paused, seeking, stopped. + +The MediaPipeline API **MUST** support notifying the app whether the +current media contains video and/or audio data. + +The MediaPipeline API **MUST** support notifying the app when frames of +video or samples of audio are dropped due to performance. + +The MediaPipeline API **MUST** support notifying the app when EIA/CEA +608/708 closed caption data is extracted and ready for presentation. + +### 3.3. Media Pipeline Management + +Rialto also exposes a management API for deciding which Rialto session +is active and visible. The Firebolt Execution Environment, typically +Ripple interacts with this API as apps move in and out of focus. + +![Diagram Description automatically +generated](../../../requirements/images/specifications/media/media-pipeline/media/image3.png) + +**TODO**: add decode pool requirements, e.g. minimum decoders for a +Firebolt platform, etc. \-- This needs to be written out. + +**TODO**: add colloquial description of API surface in Rialto Server +Manager. We need this written out for the management api. + +## 4. W3C Media APIs + +The Media Source API enables the entire functional scope of the W3C +MediaSource and MediaElement APIs, (e.g. MediaSource.addSourceBuffer, +video.src, video.play(), etc.) + +Firebolt browsers will use Rialto to implement `MediaElement` and +`MediaSource` APIs. + +### 4.1. MediaSource + +Browser MediaSource APIs **MUST** be powered by Rialto. Higher level +concerns such as source buffer management, etc., are outside the scope +of this document. + +When using MediaSource APIs, demuxing is the concern of the app, not the +browser. + +![Graphical user interface, application, Teams Description automatically +generated](../../../requirements/images/specifications/media/media-pipeline/media/image4.png) + +### 4.2. MediaElement + +Browser Media Element implementations **MUST** support progressive +download and demuxing of the following media container formats: + +- Progressive MPEG4 video + +- Progressive MP3 audio + +Demuxed segments **MUST** be sent to Rialto for decoding. + +MediaElement implementations **MUST** not support additional formats, +e.g. HLS or DASH. These formats should be parsed and fetched by a player +implemented on top of MSE. + +Legacy support for direct playback of HLS is outside the scope of this +document. + +![Graphical user interface, application Description automatically +generated](../../../requirements/images/specifications/media/media-pipeline/media/image5.png) + +## 5. Supported Media + +The Rialto Media Pipeline supports the following media types. + +### 5.1. Container formats + +The Media Pipeline **MUST** support the following container formats: + +- Demuxed MP4 audio and video streams, via MSE + +- MPEG 1 for audio-only playback (progressively fetched upstream) + +### 5.2. Video codecs + +The Media Pipeline **MUST** support the following video codecs: + +- AVC + +- HEVC + +- VP9 + +- H.264 + +### 5.3. Audio codecs + +The Media Pipeline **MUST** support the following audio codecs: + +- HE-AAC + +- AAC-LC + +- HE-AACv2 + +- MPEG-1 Audio Layer III (for audio-only media) + +## 6. Supported Decryption + +The Rialto Media Pipeline supports the following media decryption types. + +### 6.1. DRM Key Systems + +- Widevine + +- PlayReady + +- *I know there\'s **legacy use cases**\... do we call them out?* + +### 6.2. Decryption Schemes + +- CMAF CBCS decryption diff --git a/requirements/style-guide-and-template.md b/requirements/style-guide-and-template.md index 2a9a1ed1d..74c268768 100644 --- a/requirements/style-guide-and-template.md +++ b/requirements/style-guide-and-template.md @@ -24,19 +24,20 @@ Requirements documents are written using the [IETF Best Common Practice 14](http The key words "**MUST**", "**MUST NOT**", "**REQUIRED**", "**SHALL**", "**SHALL NOT**", "**SHOULD**", "**SHOULD NOT**", "**RECOMMENDED**", "**NOT RECOMMENDED**", "**MAY**", and "**OPTIONAL**" in this document are to be interpreted as described in [BCP 14](https://www.rfc-editor.org/rfc/rfc2119.txt) [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here. ## 2. Table of Contents -- [1. Overview](#1-overview) -- [2. Table of Contents](#2-table-of-contents) -- [3. Specification Style Requirements](#3-specification-style-requirements) - - [3.1. General Style Requirements](#31-general-style-requirements) - - [3.2. Firebolt Style Requirements](#32-firebolt-style-requirements) - - [3.3. Firebolt Method Templates](#33-firebolt-method-templates) -- [4. Example Section](#4-example-section) - - [4.1. Example Feature](#41-example-feature) +- [Requirements Style Guide](#requirements-style-guide) + - [1. Overview](#1-overview) + - [2. Table of Contents](#2-table-of-contents) + - [3. Specification Style Requirements](#3-specification-style-requirements) + - [3.1. General Style Requirements](#31-general-style-requirements) + - [3.2. Firebolt Style Requirements](#32-firebolt-style-requirements) + - [3.3. Firebolt Method Templates](#33-firebolt-method-templates) + - [4. Example Section](#4-example-section) + - [4.1. Example Feature](#41-example-feature) **NOTE**: This is a simple table of contents. It should include links to all headers in the document, except for the top-level header (i.e. `# Title`). It is recommended to use a Markdown plugin to generate this based on headers ranging from level two to level six. Delete this note from your actual spec :) ## 3. Specification Style Requirements -Firebolt uses method templates in order to code-generate consistent APIs. For example, methods with the `"property"` tag only need to have the `getter` editorially defined. The Firebolt OpenRPC tools will auto-generate the `setter` and `subscriber` as OpenRPC methods with matching types. Additionally, the Firebolt OpenRPC tools wil then code-generate the getter, setter, and subscriber as APIs in various languages using templates. +Firebolt uses method templates in order to code-generate consistent APIs. For example, methods with the `"property"` tag only need to have the `getter` editorially defined. The Firebolt OpenRPC tools will auto-generate the `setter` and `subscriber` as OpenRPC methods with matching types. Additionally, the Firebolt OpenRPC tools will then code-generate the getter, setter, and subscriber as APIs in various languages using templates. This enables both consistent APIs (all properties have a recongnizable pattern) and consistent SDK implementation, which reduces the code that needs to be tested. diff --git a/src/openrpc/audio_output.json b/src/openrpc/audio_output.json new file mode 100644 index 000000000..5b944a2cb --- /dev/null +++ b/src/openrpc/audio_output.json @@ -0,0 +1,40 @@ +{ + "openrpc": "1.2.4", + "info": { + "title": "Audio Output Properties", + "description": "A module for querying various aspects of the current (or built-in) audio output system of a device", + "version": "0.0.0" + }, + "methods": [ + { + "name": "mode", + "summary": "Return the audio mode currently supported by the platform.", + "tags": [ + { + "name": "capabilities", + "x-uses": [ + "xrn:firebolt:capability:audio-output:info" + ] + } + ], + "params": [], + "result": { + "name": "audioMode", + "summary": "The audio mode supported by the platform.", + "schema": { + "$ref": "https://meta.comcast.com/firebolt/schemas/media#/definitions/AudioOutputMode" + } + }, + "examples": [ + { + "name": "Default Example", + "params": [], + "result": { + "name": "Default Result", + "value": "stereo" + } + } + ] + } + ] +} diff --git a/src/openrpc/device.json b/src/openrpc/device.json index 04cdced4d..377d95b5d 100644 --- a/src/openrpc/device.json +++ b/src/openrpc/device.json @@ -308,7 +308,7 @@ }, "os": { "$ref": "https://meta.comcast.com/firebolt/types#/definitions/SemanticVersion", - "description": "**Deprecated** Use `firmware`, instead." + "description": "**Deprecated** Use firmware instead" }, "debug": { "type": "string", @@ -360,9 +360,87 @@ ] }, { - "name": "hdcp", - "summary": "Get the supported HDCP profiles", + "name": "name", + "summary": "The human readable name of the device", "params": [], + "tags": [ + { + "name": "property" + }, + { + "name": "capabilities", + "x-uses": [ + "xrn:firebolt:capability:device:name" + ] + } + ], + "result": { + "name": "value", + "summary": "the device friendly-name", + "schema": { + "type": "string" + } + }, + "examples": [ + { + "name": "Default example #1", + "params": [], + "result": { + "name": "Default Result", + "value": "Living Room" + } + }, + { + "name": "Default example #2", + "params": [], + "result": { + "name": "Default Result", + "value": "Kitchen" + } + } + ] + }, + { + "name": "onDeviceNameChanged", + "tags": [ + { + "name": "event" + }, + { + "name": "deprecated", + "x-since": "0.6.0", + "x-alternative": "Device.name()" + }, + { + "name": "capabilities", + "x-uses": [ + "xrn:firebolt:capability:device:name" + ] + } + ], + "summary": "Get the human readable name of the device", + "params": [], + "result": { + "name": "value", + "summary": "the device friendly-name", + "schema": { + "type": "string" + } + }, + "examples": [ + { + "name": "Default Example", + "params": [], + "result": { + "name": "Default Result", + "value": "Living Room" + } + } + ] + }, + { + "name": "hdcp", + "summary": "Get the supported HDCP versions available for content transmission", "tags": [ { "name": "property:readonly" @@ -372,18 +450,24 @@ "x-uses": [ "xrn:firebolt:capability:device:info" ] + }, + { + "name": "deprecated", + "x-since": "1.2.0", + "x-alternative": "Device.hdcpVersionSupported()" } ], + "params": [], "result": { - "name": "supportedHdcpProfiles", - "summary": "the supported HDCP profiles", + "name": "hdcp", + "summary": "The supported HDCP versions", "schema": { "$ref": "https://meta.comcast.com/firebolt/types#/definitions/BooleanMap" } }, "examples": [ { - "name": "Getting the supported HDCP profiles", + "name": "Default Example", "params": [], "result": { "name": "Default Result", @@ -396,9 +480,41 @@ ] }, { - "name": "hdr", - "summary": "Get the supported HDR profiles", + "name": "hdcpVersionSupported", + "summary": "Get the HDCP version supported by the device", + "tags": [ + { + "name": "property:readonly" + }, + { + "name": "capabilities", + "x-uses": [ + "xrn:firebolt:capability:device:info" + ] + } + ], "params": [], + "result": { + "name": "hdcpVersionSupported", + "summary": "The supported HDCP version", + "schema": { + "$ref": "#/components/schemas/HDCPVersion" + } + }, + "examples": [ + { + "name": "Default Example", + "params": [], + "result": { + "name": "Default Result", + "value": "2.2" + } + } + ] + }, + { + "name": "hdr", + "summary": "Returns an array of valid HDR profiles that the device supports", "tags": [ { "name": "property:readonly" @@ -408,18 +524,24 @@ "x-uses": [ "xrn:firebolt:capability:device:info" ] + }, + { + "name": "deprecated", + "x-since": "1.2.0", + "x-alternative": "Device.hdrProfilesSupported()" } ], + "params": [], "result": { - "name": "supportedHdrProfiles", - "summary": "the supported HDR profiles", + "name": "hdr", + "summary": "The supported HDR profiles", "schema": { "$ref": "https://meta.comcast.com/firebolt/types#/definitions/BooleanMap" } }, "examples": [ { - "name": "Getting the supported HDR profiles", + "name": "Default Example", "params": [], "result": { "name": "Default Result", @@ -433,10 +555,100 @@ } ] }, + { + "name": "hdrProfile", + "summary": "Get the current HDR profile set on the device for video output.", + "tags": [ + { + "name": "property:readonly" + }, + { + "name": "capabilities", + "x-uses": [ + "xrn:firebolt:capability:device:info" + ] + } + ], + "params": [], + "result": { + "name": "hdrProfile", + "summary": "The current HDR profile", + "schema": { + "$ref": "https://meta.comcast.com/firebolt/schemas/media#/definitions/HDRProfile" + } + }, + "examples": [ + { + "name": "Default Example", + "params": [], + "result": { + "name": "Default Result", + "value": "hdr10" + } + } + ] + }, + { + "name": "hdrProfilesSupported", + "summary": "Get the HDR profiles supported by the device, regardless of any connected display.", + "tags": [ + { + "name": "property:readonly" + }, + { + "name": "capabilities", + "x-uses": [ + "xrn:firebolt:capability:device:info" + ] + } + ], + "params": [], + "result": { + "name": "hdrProfilesSupported", + "summary": "The supported HDR profiles", + "schema": { + "type": "array", + "items": { + "$ref": "https://meta.comcast.com/firebolt/schemas/media#/definitions/HDRProfile" + } + } + }, + "examples": [ + { + "name": "Example with a device and display that both support HDR", + "params": [], + "result": { + "name": "Default Result", + "value": [ + "hdr10", + "hdr10plus", + "hlg" + ] + } + }, + { + "name": "Example with either a device or display that does not support HDR", + "params": [], + "result": { + "name": "Default Result", + "value": [ + "sdr" + ] + } + }, + { + "name": "Example where no display is present", + "params": [], + "result": { + "name": "Default Result", + "value": [] + } + } + ] + }, { "name": "audio", "summary": "Get the supported audio profiles", - "params": [], "tags": [ { "name": "property:readonly" @@ -448,6 +660,7 @@ ] } ], + "params": [], "result": { "name": "supportedAudioProfiles", "summary": "the supported audio profiles", @@ -457,7 +670,7 @@ }, "examples": [ { - "name": "Getting the supported audio profiles", + "name": "Default Example", "params": [], "result": { "name": "Default Result", @@ -473,8 +686,7 @@ }, { "name": "screenResolution", - "summary": "Get the current screen resolution", - "params": [], + "summary": "Get the width and height of the current screen resolution.", "tags": [ { "name": "property:readonly" @@ -484,18 +696,24 @@ "x-uses": [ "xrn:firebolt:capability:device:info" ] + }, + { + "name": "deprecated", + "x-since": "1.2.0", + "x-alternative": "Display.resolution()" } ], + "params": [], "result": { "name": "screenResolution", - "summary": "the resolution", + "summary": "The resolution", "schema": { "$ref": "#/components/schemas/Resolution" } }, "examples": [ { - "name": "Getting the screen resolution", + "name": "Default Example", "params": [], "result": { "name": "Default Result", @@ -509,8 +727,7 @@ }, { "name": "videoResolution", - "summary": "Get the current video resolution", - "params": [], + "summary": "Get the resolution of the current video output in pixels. Returns a zero value for width and height if no display is present.", "tags": [ { "name": "property:readonly" @@ -522,16 +739,17 @@ ] } ], + "params": [], "result": { "name": "videoResolution", - "summary": "the resolution", + "summary": "The resolution", "schema": { "$ref": "#/components/schemas/Resolution" } }, "examples": [ { - "name": "Getting the video resolution", + "name": "Default Example", "params": [], "result": { "name": "Default Result", @@ -544,80 +762,199 @@ ] }, { - "name": "name", - "summary": "The human readable name of the device", - "params": [], + "name": "audioFormatSupported", + "summary": "Check whether content of a given audio format is supported by the device's current configuration. These values may change as different AV inputs or peripherals are activated or connected.", "tags": [ - { - "name": "property" - }, { "name": "capabilities", "x-uses": [ - "xrn:firebolt:capability:device:name" + "xrn:firebolt:capability:device:info" ] } ], + "params": [ + { + "name": "codec", + "summary": "Audio codec used to check whether its supported.", + "required": true, + "schema": { + "$ref": "https://meta.comcast.com/firebolt/schemas/media#/definitions/AudioCodec" + } + }, + { + "name": "options", + "summary": "Additional options to use for checking whether an audio format is supported by the device. All values must be true for the content to be playable.", + "schema": { + "$ref": "#/components/schemas/AudioFormatOptions" + } + } + ], "result": { - "name": "value", - "summary": "the device friendly-name", + "name": "audioFormatSupported", + "summary": "Whether audio content of the given format is supported by the device's current configuration.", "schema": { - "type": "string" + "type": "boolean" } }, "examples": [ { - "name": "Default example #1", - "params": [], + "name": "Specify the audio codec and channels value to check", + "params": [ + { + "name": "codec", + "value": "aac" + }, + { + "name": "options", + "value": { + "channels": 2 + } + } + ], "result": { "name": "Default Result", - "value": "Living Room" + "value": true + } + } + ] + }, + { + "name": "videoFormatSupported", + "summary": "Check whether video content of the given format is supported by the device's current configuration. These values may change as different AV inputs or peripherals are activated or connected.", + "tags": [ + { + "name": "capabilities", + "x-uses": [ + "xrn:firebolt:capability:device:info" + ] + } + ], + "params": [ + { + "name": "codec", + "summary": "The video codec to check whether its supported by the device's current configuration.", + "required": true, + "schema": { + "$ref": "https://meta.comcast.com/firebolt/schemas/media#/definitions/VideoCodec" } }, { - "name": "Default example #2", - "params": [], + "name": "options", + "summary": "Additional options to use for checking whether a video is supported by the device. All values must be true for the content to be playable.", + "schema": { + "$ref": "#/components/schemas/VideoFormatOptions" + } + } + ], + "result": { + "name": "videoFormatSupported", + "summary": "Whether video content of the given format is supported by the device's current configuration.", + "schema": { + "type": "boolean" + } + }, + "examples": [ + { + "name": "Specify the video format to check", + "params": [ + { + "name": "codec", + "value": "avc" + }, + { + "name": "options", + "value": { + "resolution": [ + 1920, + 1080 + ] + } + } + ], "result": { "name": "Default Result", - "value": "Kitchen" + "value": true } } ] }, { - "name": "onDeviceNameChanged", + "name": "videoMode", + "summary": "Get the current video output mode of the device.", "tags": [ { - "name": "event" - }, + "name": "capabilities", + "x-uses": [ + "xrn:firebolt:capability:device:info" + ] + } + ], + "params": [], + "result": { + "name": "videoMode", + "summary": "The current video output mode.", + "schema": { + "$ref": "https://meta.comcast.com/firebolt/schemas/media#/definitions/VideoMode" + } + }, + "examples": [ { - "name": "deprecated", - "x-since": "0.6.0", - "x-alternative": "Device.name()" - }, + "name": "Default Example", + "params": [], + "result": { + "name": "Default Result", + "value": "1080p60" + } + } + ] + }, + { + "name": "videoModesSupported", + "summary": "Returns an array of valid video output modes that together the device and display support. Returns an empty array if no display is present.", + "tags": [ { "name": "capabilities", "x-uses": [ - "xrn:firebolt:capability:device:name" + "xrn:firebolt:capability:device:info" ] } ], - "summary": "Get the human readable name of the device", "params": [], "result": { - "name": "value", - "summary": "the device friendly-name", + "name": "videoModesSupported", + "summary": "An array of video output modes", "schema": { - "type": "string" + "type": "array", + "items": { + "$ref": "https://meta.comcast.com/firebolt/schemas/media#/definitions/VideoMode" + } } }, "examples": [ { - "name": "Getting the device name", + "name": "Default Example", "params": [], "result": { "name": "Default Result", - "value": "Living Room" + "value": [ + "720p50", + "720p60", + "1080i25", + "1080i50", + "1080i60", + "1080p24", + "1080p30", + "1080p50", + "1080p60" + ] + } + }, + { + "name": "Example with no display present", + "params": [], + "result": { + "name": "Default Result", + "value": [] } } ] @@ -625,7 +962,6 @@ { "name": "network", "summary": "Get the current network status and type", - "params": [], "tags": [ { "name": "property:readonly" @@ -637,6 +973,7 @@ ] } ], + "params": [], "result": { "name": "networkInfo", "summary": "the status and type", @@ -658,7 +995,7 @@ }, "examples": [ { - "name": "Getting the network info", + "name": "Default Example", "params": [], "result": { "name": "Default Result", @@ -733,7 +1070,7 @@ } }, { - "name": "With distributor id", + "name": "With distributor ID", "params": [ { "name": "accountId", @@ -754,57 +1091,176 @@ } } ] + }, + { + "name": "isSourceFrameRateUsed", + "summary": "Check whether the HDMI output frame rate is set to follow the video source frame rate.", + "tags": [ + { + "name": "capabilities", + "x-uses": [ + "xrn:firebolt:capability:device:info" + ] + } + ], + "params": [], + "result": { + "name": "isSourceFrameRateUsed", + "summary": "Whether the HDMI output frame rate is set to follow the video source frame rate.", + "schema": { + "type": "boolean" + } + }, + "examples": [ + { + "name": "Default Example", + "params": [], + "result": { + "name": "Default Result", + "value": true + } + } + ] } ], "components": { "schemas": { - "Resolution": { - "type": "array", - "items": [ - { + "AudioFormatOptions": { + "description": "Options for checking audio playback support", + "type": "object", + "properties": { + "atmos": { + "description": "Whether Dolby Atmos support is being requested", + "type": "boolean" + }, + "channels": { + "description": "The number of audio channels being requested", "type": "integer" }, + "codecLevel": { + "description": "The level of the audio codec", + "type": "string" + }, + "codecprofile": { + "description": "The profile of the audio codec", + "type": "string", + "enum": [ + "mp2lc", + "mp4he" + ] + }, + "container": { + "$ref": "https://meta.comcast.com/firebolt/schemas/media#/definitions/AudioContainer" + }, + "mode": { + "$ref": "https://meta.comcast.com/firebolt/schemas/media#/definitions/AudioOutputMode" + }, + "sampleRate": { + "description": "The sample rate of the audio, in kHz", + "type": "number" + } + } + }, + "AudioProfiles": { + "title": "AudioProfiles", + "allOf": [ { - "type": "integer" + "$ref": "https://meta.comcast.com/firebolt/types#/definitions/BooleanMap" + }, + { + "type": "object", + "propertyNames": { + "$ref": "https://meta.comcast.com/firebolt/types#/definitions/AudioProfile" + } } - ], - "additionalItems": false, - "minItems": 2, - "maxItems": 2 + ] }, - "NetworkType": { - "title": "NetworkType", + "HDCPVersion": { + "description": "The HDCP version", "type": "string", "enum": [ - "wifi", - "ethernet", - "hybrid" - ], - "description": "The type of network that is currently active" + "1.4", + "2.2", + "unknown" + ] }, "NetworkState": { - "title": "NetworkState", + "description": "The state of the network interface", "type": "string", "enum": [ "connected", "disconnected" - ], - "description": "The type of network that is currently active" + ] }, - "AudioProfiles": { - "title": "AudioProfiles", - "allOf": [ + "NetworkType": { + "description": "The type of network that is currently active", + "type": "string", + "enum": [ + "ethernet", + "hybrid", + "wifi" + ] + }, + "Resolution": { + "type": "array", + "items": [ { - "$ref": "https://meta.comcast.com/firebolt/types#/definitions/BooleanMap" + "type": "integer" }, { - "type": "object", - "propertyNames": { - "$ref": "https://meta.comcast.com/firebolt/types#/definitions/AudioProfile" - } + "type": "integer" } - ] + ], + "additionalItems": false, + "minItems": 2, + "maxItems": 2 + }, + "VideoFormatOptions": { + "description": "Options for checking video playback support", + "type": "object", + "properties": { + "atmos": { + "description": "Whether Dolby Atmos support is being requested", + "type": "boolean" + }, + "codecLevel": { + "description": "The level of the video codec", + "type": "string", + "enum": [ + "4.1", + "4.2", + "5.0", + "5.1", + "high", + "main" + ] + }, + "codecProfile": { + "description": "The profile of the video codec", + "type": "string", + "enum": [ + "high", + "main", + "main10", + "p0", + "p2" + ] + }, + "container": { + "$ref": "https://meta.comcast.com/firebolt/schemas/media#/definitions/VideoContainer" + }, + "frameRate": { + "description": "The frame rate of the video content", + "type": "integer" + }, + "hdr": { + "$ref": "https://meta.comcast.com/firebolt/schemas/media#/definitions/HDRProfile" + }, + "resolution": { + "$ref": "https://meta.comcast.com/firebolt/schemas/media#/definitions/Dimensions" + } + } } } } -} \ No newline at end of file +} diff --git a/src/openrpc/discovery.json b/src/openrpc/discovery.json index eb7530a35..8c620271a 100644 --- a/src/openrpc/discovery.json +++ b/src/openrpc/discovery.json @@ -1788,4 +1788,4 @@ } } } -} \ No newline at end of file +} diff --git a/src/openrpc/display.json b/src/openrpc/display.json new file mode 100644 index 000000000..f983774af --- /dev/null +++ b/src/openrpc/display.json @@ -0,0 +1,224 @@ +{ + "openrpc": "1.2.4", + "info": { + "title": "Display Properties", + "description": "A module for querying various aspects of the current (or built-in) display on a device", + "version": "0.0.0" + }, + "methods": [ + { + "name": "size", + "summary": "Get the width and height of the display panel (in centimeters).", + "tags": [ + { + "name": "capabilities", + "x-uses": [ + "xrn:firebolt:capability:display:info" + ] + } + ], + "params": [], + "result": { + "name": "size", + "summary": "The width and height of the display.", + "schema": { + "$ref": "https://meta.comcast.com/firebolt/schemas/media#/definitions/Dimensions" + } + }, + "examples": [ + { + "name": "Default Example", + "params": [], + "result": { + "name": "Default Result", + "value": [ + 2166, + 1920 + ] + } + } + ] + }, + { + "name": "colorDepth", + "summary": "Get the maximum color depth supported by the display panel.", + "params": [], + "tags": [ + { + "name": "capabilities", + "x-uses": [ + "xrn:firebolt:capability:display:info" + ] + } + ], + "result": { + "name": "colorDepth", + "summary": "The color depth supported by the display panel.", + "schema": { + "type": "integer" + } + }, + "examples": [ + { + "name": "Default Example", + "params": [], + "result": { + "name": "Default Result", + "value": 10 + } + }, + { + "name": "Example with no display", + "params": [], + "result": { + "name": "Default Result", + "value": 0 + } + } + ] + }, + { + "name": "resolution", + "summary": "Get the resolution of the display device in pixels. Returns a zero value for width and height if no display is present.", + "tags": [ + { + "name": "capabilities", + "x-uses": [ + "xrn:firebolt:capability:display:info" + ] + } + ], + "params": [], + "result": { + "name": "resolution", + "summary": "The resolution of the display device.", + "schema": { + "$ref": "https://meta.comcast.com/firebolt/schemas/media#/definitions/Dimensions" + } + }, + "examples": [ + { + "name": "Default Example", + "params": [], + "result": { + "name": "Default Result", + "value": [ + 1920, + 1080 + ] + } + }, + { + "name": "No Display Example", + "params": [], + "result": { + "name": "Default Result", + "value": [ + 0, + 0 + ] + } + } + ] + }, + { + "name": "hdrProfilesSupported", + "summary": "Returns an array of valid HDR profiles that the display supports.", + "tags": [ + { + "name": "capabilities", + "x-uses": [ + "xrn:firebolt:capability:display:info" + ] + } + ], + "params": [], + "result": { + "name": "hdrProfilesSupported", + "summary": "An array of valid HDR profiles that the display supports.", + "schema": { + "type": "array", + "items": { + "$ref": "https://meta.comcast.com/firebolt/schemas/media#/definitions/HDRProfile" + }, + "minItems": 1 + } + }, + "examples": [ + { + "name": "Default Example", + "params": [], + "result": { + "name": "Default Result", + "value": [ + "dolbyVision", + "hdr10", + "hdr10plus", + "hlg" + ] + } + } + ] + }, + { + "name": "refreshRate", + "summary": "Get the native refresh rate of the display device.", + "tags": [ + { + "name": "capabilities", + "x-uses": [ + "xrn:firebolt:capability:display:info" + ] + } + ], + "params": [], + "result": { + "name": "refreshRate", + "summary": "The refresh rate of the display device.", + "schema": { + "type": "number" + } + }, + "examples": [ + { + "name": "Default Example", + "params": [], + "result": { + "name": "Default Result", + "value": 60 + } + } + ] + }, + { + "name": "resolutionName", + "summary": "Get a user-friendly resolution name of the display device.", + "tags": [ + { + "name": "capabilities", + "x-uses": [ + "xrn:firebolt:capability:display:info" + ] + } + ], + "params": [], + "result": { + "name": "resolutionName", + "summary": "The resoltuion name of the display device.", + "schema": { + "$ref": "https://meta.comcast.com/firebolt/schemas/media#/definitions/ResolutionName" + } + }, + "examples": [ + { + "name": "Default Example", + "params": [], + "result": { + "name": "Default Result", + "value": "uhd" + } + } + ] + } + ] +} diff --git a/src/openrpc/media_info.json b/src/openrpc/media_info.json new file mode 100644 index 000000000..fd8e502cd --- /dev/null +++ b/src/openrpc/media_info.json @@ -0,0 +1,411 @@ +{ + "openrpc": "1.2.4", + "info": { + "title": "MediaInfo", + "description": "A module for query info about the media currently in the media pipeline (either playing or paused).", + "version": "0.0.0" + }, + "methods": [ + { + "name": "activeAudioFormats", + "summary": "Get a list of the active audio formats currently used across all media pipelines.", + "tags": [ + { + "name": "property:readonly" + }, + { + "name": "capabilities", + "x-manages": [ + "xrn:firebolt:capability:media-info:audio-format" + ] + } + ], + "params": [], + "result": { + "name": "activeAudioFormats", + "summary": "The active audio formats used across all pipelines.", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AudioFormat" + } + } + }, + "examples": [ + { + "name": "Default Example", + "params": [], + "result": { + "name": "Default Result", + "value": [ + { + "bitRate": 128, + "channels": 2, + "codec": "aac", + "codecProfile": "mp2lc", + "container": "audio/mp4", + "sampleRate": 48 + } + ] + } + } + ] + }, + { + "name": "activeVideoFormats", + "summary": "Get a list of the active video formats currently used across all media pipelines.", + "tags": [ + { + "name": "property:readonly" + }, + { + "name": "capabilities", + "x-manages": [ + "xrn:firebolt:capability:media-info:video-format" + ] + } + ], + "params": [], + "result": { + "name": "activeVideoFormats", + "summary": "The active video formats used across all pipelines.", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/VideoFormat" + } + } + }, + "examples": [ + { + "name": "Default Example", + "params": [], + "result": { + "name": "Default Result", + "value": [ + { + "codec": "hevc", + "codecLevel": "4.2", + "codecProfile": "main", + "container": "video/mp4", + "frameRate": 30, + "hdr": [ + "hdr10" + ], + "resolution": [ + 1920, + 1080 + ] + } + ] + } + } + ] + }, + { + "name": "audioFormat", + "summary": "Get the audio format currently used by the specified media pipeline.", + "tags": [ + { + "name": "property:readonly", + "x-session": "sessionId", + "x-session-name": "mediaSession" + }, + { + "name": "capabilities", + "x-uses": [ + "xrn:firebolt:capability:media-info:audio-format" + ] + } + ], + "params": [ + { + "name": "pipeline", + "required": true, + "schema": { + "$ref": "#/components/schemas/PipelineId" + } + } + ], + "result": { + "name": "audioFormat", + "summary": "Audio format used by the pipeline.", + "schema": { + "$ref": "#/components/schemas/AudioFormat" + } + }, + "examples": [ + { + "name": "Default Example", + "params": [ + { + "name": "pipeline", + "value": 0 + } + ], + "result": { + "name": "Default Result", + "value": { + "bitRate": 128, + "channels": 2, + "codec": "aac", + "container": "audio/mp4", + "sampleRate": 48 + } + } + } + ] + }, + { + "name": "onActiveAudioFormatsChanged", + "summary": "Get notified when the active audio formats used across all media pipelines starts, stops, or changes.", + "tags": [ + { + "name": "event" + }, + { + "name": "capabilities", + "x-manages": [ + "xrn:firebolt:capability:media-info:audio-format" + ] + } + ], + "params": [], + "result": { + "name": "onActiveAudioFormatsChanged", + "summary": "The updated audio formats used across all pipelines.", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AudioFormat" + } + } + }, + "examples": [ + { + "name": "Default Example", + "params": [], + "result": { + "name": "Default Result", + "value": [ + { + "bitRate": 128, + "channels": 2, + "codec": "aac", + "container": "audio/mp4", + "sampleRate": 48 + } + ] + } + } + ] + }, + { + "name": "onActiveVideoFormatsChanged", + "summary": "Get notified when the active video formats used across all media pipelines starts, stops, or changes.", + "tags": [ + { + "name": "event" + }, + { + "name": "capabilities", + "x-manages": [ + "xrn:firebolt:capability:media-info:video-format" + ] + } + ], + "params": [], + "result": { + "name": "onActiveVideoFormatsChanged", + "summary": "The updated video formats used across all pipelines.", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/VideoFormat" + } + } + }, + "examples": [ + { + "name": "Default Example", + "params": [], + "result": { + "name": "Default Result", + "value": [ + { + "codec": "hevc", + "codecLevel": "4.2", + "codecProfile": "main", + "container": "video/mp4", + "frameRate": 30, + "hdr": [ + "hdr10" + ], + "resolution": [ + 1920, + 1080 + ] + } + ] + } + } + ] + }, + { + "name": "videoFormat", + "summary": "Get the video format currently used by the specified media pipeline.", + "tags": [ + { + "name": "property:readonly", + "x-session": "sessionId", + "x-session-name": "mediaSession" + }, + { + "name": "capabilities", + "x-uses": [ + "xrn:firebolt:capability:media-info:video-format" + ] + } + ], + "params": [ + { + "name": "pipeline", + "required": true, + "schema": { + "$ref": "#/components/schemas/PipelineId" + } + } + ], + "result": { + "name": "videoFormat", + "summary": "Video format used by the pipeline.", + "schema": { + "$ref": "#/components/schemas/VideoFormat" + } + }, + "examples": [ + { + "name": "Default Example", + "params": [ + { + "name": "pipeline", + "value": 0 + } + ], + "result": { + "name": "Default Result", + "value": { + "codec": "hevc", + "codecLevel": "4.2", + "codecProfile": "main", + "container": "video/mp4", + "frameRate": 30, + "hdr": [ + "hdr10" + ], + "resolution": [ + 1920, + 1080 + ] + } + } + } + ] + } + ], + "components": { + "schemas": { + "AudioFormat": { + "type": "object", + "description": "Details on the audio content format.", + "properties": { + "bitRate": { + "description": "The audio bit rate in kbps.", + "type": "number" + }, + "channels": { + "description": "The number of audio channels.", + "type": "integer" + }, + "codec": { + "$ref": "https://meta.comcast.com/firebolt/schemas/media#/definitions/AudioCodec" + }, + "codecLevel": { + "$ref": "https://meta.comcast.com/firebolt/schemas/media#/definitions/AudioCodecLevel" + }, + "codecProfile": { + "$ref": "https://meta.comcast.com/firebolt/schemas/media#/definitions/AudioCodecProfile" + }, + "container": { + "$ref": "https://meta.comcast.com/firebolt/schemas/media#/definitions/AudioContainer" + }, + "sampleRate": { + "description": "The audio sample rate in kHz.", + "type": "number" + } + }, + "required": [ + "codec", + "channels", + "sampleRate" + ] + }, + "PipelineId": { + "type": "integer", + "description": "The media pipeline/session ID", + "minimum": 0, + "maximum": 15 + }, + "VideoFormat": { + "type": "object", + "description": "Details on the video content format.", + "properties": { + "codec": { + "$ref": "https://meta.comcast.com/firebolt/schemas/media#/definitions/VideoCodec" + }, + "codecLevel": { + "type": "string", + "enum": [ + "4.1", + "4.2", + "5.0", + "5.1", + "high", + "main" + ] + }, + "codecProfile": { + "type": "string", + "enum": [ + "high", + "main", + "main10", + "p0", + "p2" + ] + }, + "container": { + "$ref": "https://meta.comcast.com/firebolt/schemas/media#/definitions/VideoContainer" + }, + "frameRate": { + "type": "number" + }, + "hdr": { + "type": "array", + "items": { + "$ref": "https://meta.comcast.com/firebolt/schemas/media#/definitions/HDRProfile" + } + }, + "resolution": { + "$ref": "https://meta.comcast.com/firebolt/schemas/media#/definitions/Dimensions" + } + }, + "required": [ + "codec", + "hdr", + "resolution" + ] + } + } + } +} diff --git a/src/schemas/media.json b/src/schemas/media.json new file mode 100644 index 000000000..1fb2aae03 --- /dev/null +++ b/src/schemas/media.json @@ -0,0 +1,168 @@ +{ + "$id": "https://meta.comcast.com/firebolt/schemas/media", + "title": "Media", + "definitions": { + "AudioCodec": { + "type": "string", + "description": "Audio codec", + "enum": [ + "aac", + "ac3", + "ac3plus", + "ac4", + "dts-x", + "eac3", + "mpeg3", + "opus", + "truehd", + "unknown", + "vorbis" + ] + }, + "AudioCodecLevel": { + "description": "Audio codec level", + "type": "string", + "enum": [ + "3.0", + "3.1", + "4.0", + "4.1", + "4.2", + "5.0", + "5.1" + ] + }, + "AudioCodecProfile": { + "description": "Audio codec profile", + "type": "string", + "enum": [ + "high", + "main", + "main10", + "mp2lc", + "mp4he", + "p0", + "p2" + ] + }, + "AudioContainer": { + "description": "Audio container", + "type": "string", + "enum": [ + "audio/mpeg", + "audio/mp4", + "audio/ogg", + "audio/webm" + ] + }, + "AudioOutputMode": { + "description": "Aaudio output mode", + "type": "string", + "enum": [ + "auto", + "mono", + "none", + "passthrough", + "stereo", + "surround", + "unknown" + ] + }, + "ColorDepth": { + "description": "Color depth in number of bits", + "type": "integer", + "enum": [ + 0, + 8, + 10, + 12 + ] + }, + "Dimensions": { + "type": "array", + "description": "The dimensions specified as width and height.", + "items": [ + { + "type": "integer" + }, + { + "type": "integer" + } + ], + "additionalItems": false, + "minItems": 2, + "maxItems": 2 + }, + "HDRProfile": { + "type": "string", + "description": "HDR profile", + "enum": [ + "dolbyVision", + "hdr10", + "hdr10plus", + "hlg", + "sdr", + "unknown" + ] + }, + "ResolutionName": { + "description": "User-friendly resolution name", + "type": "string", + "enum": [ + "sd", + "hd", + "fhd", + "uhd", + "unknown" + ] + }, + "VideoCodec": { + "type": "string", + "description": "video codec", + "enum": [ + "avc", + "hevc", + "mpeg1", + "mpeg2", + "vp8", + "vp9", + "vp10" + ] + }, + "VideoContainer": { + "description": "Video container format", + "type": "string", + "enum": [ + "video/mpeg", + "video/mp2t", + "video/mp4", + "video/webm" + ] + }, + "VideoMode": { + "description": "Video output mode, the shorthand resolution and frame rate", + "type": "string", + "enum": [ + "480i", + "480p", + "576i25", + "576p50", + "576p60", + "720p50", + "720p60", + "1080i25", + "1080i50", + "1080i60", + "1080p24", + "1080p30", + "1080p50", + "1080p60", + "2160p30", + "2160p50", + "2160p60", + "4320p60", + "unknown" + ] + } + } +}