Skip to content

Commit 1489e59

Browse files
committed
add support for Dolby Vision
1 parent 4dcf7da commit 1489e59

File tree

8 files changed

+99
-8597
lines changed

8 files changed

+99
-8597
lines changed

package-lock.json

Lines changed: 0 additions & 8593 deletions
This file was deleted.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "codec-string",
3-
"version": "0.1.8",
3+
"version": "0.1.9",
44
"description": "decode the codecs= string in a media mime type",
55
"type": "module",
66
"engines": {

src/decode-dolby.js

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/**
2+
* @copyright: Copyright (c) 2025
3+
* @author: Paul Higgs
4+
* @file: decode-dolby.js
5+
*
6+
* Redistribution and use in source and binary forms, with or without
7+
* modification, are permitted provided that the following conditions are met:
8+
*
9+
* 1. Redistributions of source code must retain the above copyright notice,
10+
* this list of conditions and the following disclaimer.
11+
* 2. Redistributions in binary form must reproduce the above copyright
12+
* notice, this list of conditions and the following disclaimer in the
13+
* documentation and/or other materials provided with the distribution.
14+
*
15+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
25+
* THE POSSIBILITY OF SUCH DAMAGE.
26+
*
27+
*/
28+
29+
import { simpleHTML } from './formatters.js';
30+
import { expressions } from './regular_expressions.js';
31+
import { normal, error } from './decode.js';
32+
33+
const DEBUGGING = false;
34+
35+
// See DolbyVisionProfileLevels.pdf - available at https://dolby.my.salesforce.com/sfc/dist/version/download/?oid=00D700000009YuG&ids=068QQ00000bpfevYAA&d=/a/4u000000B3Ig/8qhPH.ETus3SaczpT9twKYXsYUtwstZpjlev3DBll.I&operationContext=DELIVERY&viewId=05HQQ00000ThR5t2AF&dpt=
36+
// and DolbyVisionInMPEGDASHSpecification.pdf - available at https://dolby.my.salesforce.com/sfc/dist/version/download/?oid=00D700000009YuG&ids=0684u00000V1DFXAA3&d=/a/4u000000l6FV/TqYPD0f0c3Zm40JJrFKFn1m29QdUxuVB.U_GzZzbXgE&operationContext=DELIVERY&viewId=05HQQ00000ThX6T2AV&dpt=
37+
38+
export function decodeDolbyVision(val) {
39+
if (!expressions.DolbyVision.regex.test(val)) return [error('Regex mismatch!'), error(expressions.DolbyVision.format)];
40+
const parts = val.split('.');
41+
// this check should not fail as the number of parts and the format are checked in the regular expression
42+
if (parts.length != 3) return [error(`DolbyVision format is "${expressions.AC4.format}"`)];
43+
44+
const profile = parseInt(parts[1]),
45+
level = parseInt(parts[2]);
46+
47+
let res = [];
48+
49+
switch (parts[0]) {
50+
case 'dvhe':
51+
res.push(normal('HEVC-based Dolby Vision codec.'));
52+
res.push(normal('Parameter sets (VPS, PPS, or SPS) are stored either in the sample entries or as part of the samples, or in both.'));
53+
break;
54+
case 'dvh1':
55+
res.push(normal('HEVC-based Dolby Vision codec.'));
56+
res.push(normal('Parameter sets (VPS, PPS, or SPS) are stored in the sample entries only.'));
57+
break;
58+
case 'dvav':
59+
res.push(normal('AVC-based Dolby Vision codec.'));
60+
res.push(normal('Parameter sets (PPS or SPS) are stored either in the sample entries or as part of the samples, or in both.'));
61+
break;
62+
case 'dva1':
63+
res.push(normal('AVC-based Dolby Vision codec.'));
64+
res.push(normal('Parameter sets (PPS or SPS) are stored either in the sample entries of the video stream or in the parameter set stream, but never in both.'));
65+
break;
66+
}
67+
68+
res.push([5,7,8,9,20].includes(profile)
69+
? normal(`Bitstream Profile ID: ${parts[1]}`)
70+
: error(`Unrecognised bitstream_profile_id (${parts[1]})`)
71+
);
72+
73+
res.push((level >= 1 && level <=13)
74+
? normal(`Level ID: ${parts[2]}`)
75+
: error(`Unrecognised level_id (${parts[2]})`)
76+
);
77+
78+
return res;
79+
}
80+
81+
82+
export function registerDolbyVision(addHandler) {
83+
const outputHTML = (label, messages) => simpleHTML(label, messages, DEBUGGING);
84+
85+
addHandler(['dvhe', 'dvh1', 'dvav', 'dva1'], 'Dolby Vision stream', decodeDolbyVision, outputHTML);
86+
}

src/decode.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ class parsing {
7979
setResult(result) {
8080
if (Array.isArray(result)) this.parsed = result;
8181
else if (typeof result == 'string') this.parsed = [].push(result);
82-
else this.parsed = [error('failed to interpret deciding result')];
82+
else this.parsed = [error('failed to interpret decoding result')];
8383
}
8484

8585
toHTML() {

src/handler.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { registerAC4 } from './decode-ac4.js';
22
import { registerAOM } from './decode-aom.js';
33
import { registerAVC } from './decode-avc.js';
44
import { registerAVS3 } from './decode-avs.js';
5+
import { registerDolbyVision } from './decode-dolby.js';
56
import { registerDTS } from './decode-dts.js';
67
import { registerEVC } from './decode-evc.js';
78
import { registerHEVC } from './decode-hevc.js';
@@ -44,6 +45,7 @@ const registerFactories = [
4445
registerAOM,
4546
registerAVC,
4647
registerAVS3,
48+
registerDolbyVision,
4749
registerDTS,
4850
registerEVC,
4951
registerHEVC,

src/index.cjs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ const { decodeAC4 } = require('./decode-ac4.js');
22
const { decodeAV1, decodeIAMF } = require('./decode-aom.js');
33
const { decodeAVC } = require('./decode-avc.js');
44
const { decodeAVS3, decodeAVS3audio, decodeAVS2audio } = require('./decode-avs.js');
5+
const { decodeDolbyVision } = require('./decode-dolby.js');
56
const { decodeDTS } = require('./decode-dts.js');
67
const { decodeEVC } = require('./decode-evc.js');
78
const { decodeHEVC } = require('./decode-hevc.js');
@@ -24,6 +25,7 @@ module.exports = {
2425
decodeAVS3,
2526
decodeAVS3audio,
2627
decodeAVS2audio,
28+
decodeDolbyVision,
2729
decodeDTS,
2830
decodeEVC,
2931
decodeHEVC,

src/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ export { decodeAC4 } from './decode-ac4.js';
22
export { decodeAV1, decodeIAMF } from './decode-aom.js';
33
export { decodeAVC } from './decode-avc.js';
44
export { decodeAVS3, decodeAVS3audio, decodeAVS2audio } from './decode-avs.js';
5+
export { decodeDolbyVision } from './decode-dolby.js';
56
export { decodeDTS } from './decode-dts.js';
67
export { decodeEVC } from './decode-evc.js';
78
export { decodeHEVC } from './decode-hevc.js';

src/regular_expressions.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,16 @@ export const expressions = {
5353
AVS3audio: {
5454
regex: /av3a\.[a-fA-F\d]{1,2}$/,
5555
format: "av3a.<codec_id>",
56-
description: "codec_is is 0 for general high rate coding, 1 for lossless, 2 for general full rate coding"
56+
description: "codec_id is 0 for general high rate coding, 1 for lossless, 2 for general full rate coding"
5757
},
5858
AVS2audio: {
5959
regex: /cavs\.[a-fA-F\d]{1,2}$/,
6060
format: "cavs.<codec_id>",
61-
description: "codec_is is 0 for general high rate coding, 1 for lossless"
61+
description: "codec_id is 0 for general high rate coding, 1 for lossless"
62+
},
63+
DolbyVision: {
64+
regex: /^(dvav|dvhe|dvh1|dva1)\.\d{2}\.\d{2}$/,
65+
format: "[Codec_type].[bitstream_profile_ID].[Dolby_Vision_Level_ID]"
6266
},
6367
VP9: {
6468
regex: /^vp09(\.\d{2}){3}(\.(\d{2})?){0,5}$/,

0 commit comments

Comments
 (0)