Skip to content

Commit

Permalink
feat: Migration of LCEVC DIL (Decoder Integration Layer) to LCEVC Dec…
Browse files Browse the repository at this point in the history
… (Decoder) (#5459)
  • Loading branch information
v-nova-vinod committed Oct 3, 2023
1 parent ebacf32 commit c1e18d3
Show file tree
Hide file tree
Showing 16 changed files with 489 additions and 251 deletions.
4 changes: 2 additions & 2 deletions README.md
Expand Up @@ -148,14 +148,14 @@ HLS features **not** supported:

**Only supported on browsers with Media Source Extensions SourceBuffer support**

- MPEG-5 Part2 LCEVC decoding support (decoding provided by [lcevc_dil.js][], must be
- MPEG-5 Part2 LCEVC decoding support (decoding provided by [lcevc_dec.js][], must be
separately included)

- Integration documentation : [docs](docs/design/lcevc-integration.md)

- More on [MPEG-5 Part2 LCEVC][]

[lcevc_dil.js]: https://www.npmjs.com/package/lcevc_dil.js
[lcevc_dec.js]: https://www.npmjs.com/package/lcevc_dec.js
[MPEG-5 Part2 LCEVC]: https://www.lcevc.org


Expand Down
2 changes: 1 addition & 1 deletion build/types/lcevc
@@ -1,3 +1,3 @@
# LCEVC library.

+../../lib/lcevc/lcevc_dil.js
+../../lib/lcevc/lcevc_dec.js
25 changes: 25 additions & 0 deletions demo/common/assets.js
Expand Up @@ -1364,6 +1364,31 @@ shakaAssets.testAssets = [
/* source= */ shakaAssets.Source.VNOVA)
.addFeature(shakaAssets.Feature.DASH)
.addFeature(shakaAssets.Feature.HIGH_DEFINITION)
.addFeature(shakaAssets.Feature.MP2TS)
.addFeature(shakaAssets.Feature.OFFLINE)
.addFeature(shakaAssets.Feature.LCEVC)
.addDescription('LCEVC Enhanced eSports content selection.')
.setExtraConfig({
streaming: {
useNativeHlsOnSafari: false,
},
mediaSource: {
forceTransmux: true,
},
lcevc: {
enabled: true,
dynamicPerformanceScaling: true,
logLevel: 0,
drawLogo: false,
},
}),
new ShakaDemoAssetInfo(
/* name= */ 'Tears of Steel LCEVC H264 (HLS, MP4)',
/* iconUri= */ 'https://storage.googleapis.com/shaka-asset-icons/tears_of_steel.png',
/* manifestUri= */ 'https://d3mfda3gpj3dw1.cloudfront.net/vn2LvEps745ShGtQ/master.m3u8',
/* source= */ shakaAssets.Source.VNOVA)
.addFeature(shakaAssets.Feature.HLS)
.addFeature(shakaAssets.Feature.HIGH_DEFINITION)
.addFeature(shakaAssets.Feature.MP4)
.addFeature(shakaAssets.Feature.OFFLINE)
.addFeature(shakaAssets.Feature.LCEVC)
Expand Down
2 changes: 1 addition & 1 deletion demo/index.html
Expand Up @@ -39,7 +39,7 @@
<!-- MSS support is enabled by including this: -->
<script defer src="../node_modules/codem-isoboxer/dist/iso_boxer.min.js"></script>
<!-- MPEG-5 Part2 LCEVC support is enabled by including this: -->
<script defer src="../node_modules/lcevc_dil.js/dist/lcevc_dil.min.js"></script>
<script defer src="../node_modules/lcevc_dec.js/dist/lcevc_dec.min.js"></script>
<!-- MDL is enabled by including this: -->
<script defer src="../node_modules/material-design-lite/dist/material.min.js"></script>
<!-- MDL modal dialogs are enabled by including these: -->
Expand Down
28 changes: 14 additions & 14 deletions docs/design/lcevc-integration.md
Expand Up @@ -8,59 +8,59 @@ This article describes the V-Nova LCEVC Shaka Player integration.
# LCEVC Integration

## Adding V-Nova required files
### Importing DIL - Decoder Integration Layer
### Importing LCEVC Decoder

V-Nova LCEVC DIL Libraries are included using the same approach that the other external libraries are currently using. The necessary V-Nova LCEVC DIL files need to be imported in the HTML page that is going to be used by Shaka Player to decode LCEVC. Checks are inplace that make sure the necessary objects are available.
V-Nova LCEVC Decoder Libraries are included using the same approach that the other external libraries are currently using. The necessary V-Nova LCEVC Decoder files need to be imported in the HTML page that is going to be used by Shaka Player to decode LCEVC. Checks are inplace that make sure the necessary objects are available.

Npm package : <https://www.npmjs.com/package/lcevc_dil.js>
NPM package : <https://www.npmjs.com/package/lcevc_dec.js>

```javascript
<!-- MPEG-5 Part2 LCEVC support is enabled by including this: -->
<script defer src="../node_modules/lcevc_dil.js/dist/lcevc_dil.min.js"></script>
<script defer src="../node_modules/lcevc_dec.js/dist/lcevc_dec.min.js"></script>
```

To allow the Closure compiler to use the objects and methods that are exported by the DIL.js a new `extern` is created.
To allow the Closure compiler to use the objects and methods that are exported by the LCEVCdec.js a new `extern` is created.

### Defining an Extern for LCEVC

`externs/lcevc.js` exposes the functions from the LCEVC DIL library required for LCEVC Decoding.
`externs/lcevc.js` exposes the functions from the LCEVC Decoder library required for LCEVC Decoding.

## Integration point

### The shaka.lcevc.Dil class - (DIL : Decoder Integration Layer)
### The shaka.lcevc.Dec class - (DEC : Decoder)

The main logic of the LCEVC integration is located in the `lib/lcevc_dil.min.js` file. In this file the shaka.lcevc.Dil is exported to be used in the project. This class is in charge of creating the Dil object using the mentioned externs, checking if LCEVC DIL library is available, etc.
The main logic of the LCEVC integration is located in the `lib/lcevc_dec.min.js` file. In this file the shaka.lcevc.Dec is exported to be used in the project. This class is in charge of creating the Dec object using the mentioned externs, checking if LCEVC Decoder library is available, etc.

### Modifications in the player

The shaka.Player class, defined in the `lib/player.js` file, is the main player object for Shaka Player. There is a setter function for setting up a `canvas` element that is received from the user.
If shaka.ui is used the `canvas` is created in line with the video element in the same container overlaying the video element. If user provides a custom canvas using the setter function, The user is responsible for placing the canvas element in the desired position and resizing it.

`shaka.externs.LcevcConfiguration` is added to the `playerConfiguration` that is used as configuration for the LCEVC DIL Library.
`shaka.externs.LcevcConfiguration` is added to the `playerConfiguration` that is used as configuration for the LCEVC Decoder Library.

The Dil object is created in the `onLoad_()` event that is triggered when a new video is loaded in Shaka Player. Attaching to a media element is defined as:
The Dec object is created in the `onLoad_()` event that is triggered when a new video is loaded in Shaka Player. Attaching to a media element is defined as:

- Registering error listeners to the media element.
- Catching the video element for use outside of the load graph.

The Dil object is created only if LCEVC is supported (LCEVC libs are loaded on the page) and also when it was not already created in another `onLoad_()` event execution.
The LCEVC Decoder object is created only if LCEVC is supported (LCEVC libs are loaded on the page) and also when it was not already created in another `onLoad_()` event execution.


### Feeding the Dil
### Feeding the Dec

The logic that Shaka Player uses to communicate with the Media Source Extensions (MSE) is located in the `media/media_source_engine.js` file.

![image.png](lcevc-architecture.png)

`append_()` function that is used to feed the MSE Source Buffer is intercepted and modified to pass the video buffers to the LCEVC DIL Libraries before appending to the MSE Source Buffers.
`append_()` function that is used to feed the MSE Source Buffer is intercepted and modified to pass the video buffers and related time offsets to the LCEVC Decoder Libraries before appending to the MSE Source Buffers.

## Demo page

The relevant libraries are added in the Demo Page like so:

```javascript
<!-- MPEG-5 Part2 LCEVC support is enabled by including this: -->
<script defer src="../node_modules/lcevc_dil.js/dist/lcevc_dil.min.js"></script>
<script defer src="../node_modules/lcevc_dec.js/dist/lcevc_dec.min.js"></script>
```

And a new video sample with enhancement data is added to the `demo/common/assets.js` file under a new source `MPEG-5 Part 2 LCEVC`.
Expand Down
3 changes: 2 additions & 1 deletion docs/tutorials/index.json
Expand Up @@ -24,5 +24,6 @@
{ "selenium-grid-config": { "title": "Selenium Grid Config" } },
{ "faq": { "title": "Frequently Asked Questions" } },
{ "upgrade": { "title": "Upgrade Guide" } },
{ "upgrade-manifest": { "title": "ManifestParser Upgrade Guide" } }
{ "upgrade-manifest": { "title": "ManifestParser Upgrade Guide" } },
{ "lcevc": { "title": "LCEVC Quick Start" } }
]
118 changes: 118 additions & 0 deletions docs/tutorials/lcevc.md
@@ -0,0 +1,118 @@
# LCEVC Quick Start

#### Requirements

- Only supported on browsers with Media Source Extensions SourceBuffer support

- MPEG-5 Part2 LCEVC decoding support (decoding provided by [lcevc_dec.js][],
must be separately included)

##### Integration documentation : [docs](../design/lcevc-integration.md)

##### More on [MPEG-5 Part2 LCEVC][]

[lcevc_dec.js]: https://www.npmjs.com/package/lcevc_dec.js?activeTab=readme
[MPEG-5 Part2 LCEVC]: https://www.lcevc.org

#### Configure LCEVC

LCEVC Decoder library needs to be included in the HTML page:

- Local `npm install lcevc_dec.js`
```html
<script src="../node_modules/lcevc_dec.js/dist/lcevc_dec.min.js"></script>
```
- Or use `unpkg.com` for latest LCEVC Decoder libraries.
```html
<script src="https://unpkg.com/lcevc_dec.js@1.0.0/dist/lcevc_dec.min.js"></script>
```

Configuration to enable LCEVC enhancement:
```js
player.configure('lcevc.enabled', true);
```

#### LCEVC setup via UI library

Sample setup using the Shaka Player UI library:

```html
<!DOCTYPE html>
<html>
<head>
<!-- Shaka Player UI compiled library and default CSS for player controls: -->
<script src="dist/shaka-player.ui.js"></script>
<link rel="stylesheet" href="dist/controls.css" />

<!-- LCEVC decoder compiled library -->
<script src="https://unpkg.com/lcevc_dec.js@1.0.0/dist/lcevc_dec.min.js"></script>

<!-- Application source: -->
<script src="app.js"></script>
</head>

<body>
<!-- The data-shaka-player-container tag will make the UI library place the controls in this div. -->
<div data-shaka-player-container style="max-width:40em">
<!-- The data-shaka-player tag will make the UI library use this video element. -->
<video data-shaka-player id="video" style="width:100%;height:100%"></video>
</div>
</body>
</html>
```

```js
// app.js

const manifestUri = 'https://dyctis843rxh5.cloudfront.net/vnIAZIaowG1K7qOt/master.m3u8';

// Initialise Shaka Player with LCEVC enhancement.
async function init() {
// When using the UI, the player is made automatically by the UI object.
const video = document.getElementById('video');
const ui = video['ui'];
const controls = ui.getControls();
const player = controls.getPlayer();

// Enable the LCEVC enhancement.
player.configure('lcevc.enabled', true);

// Listen for error events.
player.addEventListener('error', onError);
controls.addEventListener('error', onError);

// Try to load a manifest.
// This is an asynchronous process.
try {
await player.load(manifestUri);
// This runs if the asynchronous load is successful.
console.log('The video has now been loaded!');
} catch (error) {
onError(error);
}
}

// Handle errors.
function onError(error) {
console.error('Error', error);
}

// Listen to the custom shaka-ui-loaded event, to wait until the UI is loaded.
document.addEventListener('shaka-ui-loaded', init);
// Listen to the custom shaka-ui-load-failed event, in case Shaka Player fails
// to load (e.g. due to lack of browser support).
document.addEventListener('shaka-ui-load-failed', onError);

```

#### User provided canvas

User can also provide a canvas to the player though `attachCanvas` function:

```js
player.attachCanvas(canvas);
```

Note: If external canvas is used, user is responsible for managing
the canvas. If no canvas is provided for Shaka UI library, the player
will generate and manage the canvas.
50 changes: 37 additions & 13 deletions externs/lcevc.js
@@ -1,25 +1,27 @@
/**
* @fileoverview Externs for LcevcDil
* @fileoverview Externs for LcevcDec
* compiler.
*
* @externs
*/

// This empty namespace is declared to check if LcevcDil libraries are loaded.
// This empty namespace is declared to check if LcevcDec libraries are loaded.
/** @const */
var libDPIModule = {};
var LcevcDil = {};
/** @const */
var LCEVCdec = {};

/**
* LCEVC DIL constructor
* LCEVC Dec constructor
* @constructor
*/
LcevcDil.LcevcDIL = class {
LCEVCdec.LCEVCdec = class {
/**
* @param {HTMLVideoElement} media
* @param {HTMLCanvasElement} canvas
* @param {shaka.extern.LcevcConfiguration} dilConfig
* @param {shaka.extern.LcevcConfiguration} lcevcConfig
*/
constructor(media, canvas, dilConfig) {
constructor(media, canvas, lcevcConfig) {
}

/**
Expand All @@ -30,13 +32,14 @@ LcevcDil.LcevcDIL = class {
* @param {!BufferSource} data Video Buffer Data.
* @param {string} type Type of Video Buffer Data.
* @param {number} variantId Variant that the fragment belongs to.
* @param {number} timestampOffset Timestamp offset for appended segments
*/
appendBuffer(data, type, variantId) {}
appendBuffer(data, type, variantId, timestampOffset) {}

/**
* Set current variant as variantId to the LCEVC decoder
* @param {!number} variantId
* @param {!boolean} autoBufferSwitch is lcevcDil mode that switches variant
* @param {!boolean} autoBufferSwitch is lcevcDec mode that switches variant
* when the downloaded buffer from last variant has finished playing and
* buffers from the new variant starts to play.
*/
Expand All @@ -49,15 +52,28 @@ LcevcDil.LcevcDIL = class {
setContainerFormat(containerFormat) {}

/**
* Close LCEVC DIL
* Set streaming Format for LCEVC Data Parsing.
* @param {!number} streamingFormat container type of the stream.
*/
setStreamingFormat(streamingFormat) {}

/**
* Close LCEVC DEC
*/
close() {}
};

/**
* The older module interface, for backward compatibility.
* Typed to the same interface, but under a different name.
* @type {typeof LCEVCdec.LCEVCdec}
*/
LCEVCdec.LcevcDil;

/**
* LCEVC Support Check
*/
LcevcDil.SupportObject = {
LCEVCdec.SupportObject = {

/**
* Check if canvas has WebGL support
Expand All @@ -72,10 +88,18 @@ LcevcDil.SupportObject = {
* LCEVC Support Checklist Result
* @type {boolean}
*/
LcevcDil.SupportObject.SupportStatus;
LCEVCdec.SupportObject.SupportStatus;

/**
* LCEVC Support CheckList Error if any.
* @type {string}
*/
LcevcDil.SupportObject.SupportError;
LCEVCdec.SupportObject.SupportError;

/**
* Typedef for the module interface. Both LCEVCdec (new module) and LcevcDil
* (old module) implement roughly the same interface.
*
* @typedef {typeof LCEVCdec}
*/
var LCEVCmodule;

0 comments on commit c1e18d3

Please sign in to comment.