Skip to content

Commit d31387d

Browse files
authored
Minor adjustments to _getAudioTracksWithHighestEfficiency logic (Dash-Industry-Forum#4717)
1 parent 376068f commit d31387d

File tree

5 files changed

+145
-147
lines changed

5 files changed

+145
-147
lines changed

index.d.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2846,7 +2846,6 @@ declare namespace dashjs {
28462846
TRACK_SELECTION_MODE_HIGHEST_BITRATE: 'highestBitrate',
28472847
TRACK_SELECTION_MODE_HIGHEST_EFFICIENCY: 'highestEfficiency',
28482848
TRACK_SELECTION_MODE_WIDEST_RANGE: 'widestRange',
2849-
TRACK_SELECTION_MODE_HIGHEST_SELECTION_PRIORITY: 'highestSelectionPriority',
28502849
CMCD_MODE_QUERY: 'query',
28512850
CMCD_MODE_HEADER: 'header',
28522851
CMCD_AVAILABLE_KEYS: ['br', 'd', 'ot', 'tb', 'bl', 'dl', 'mtp', 'nor', 'nrr', 'su', 'bs', 'rtp', 'cid', 'pr', 'sf', 'sid', 'st', 'v'],

src/streaming/controllers/MediaController.js

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@ import Events from '../../core/events/Events.js';
3333
import EventBus from '../../core/EventBus.js';
3434
import FactoryMaker from '../../core/FactoryMaker.js';
3535
import Debug from '../../core/Debug.js';
36-
import { bcp47Normalize } from 'bcp-47-normalize';
37-
import { extendedFilter } from 'bcp-47-match';
36+
import {bcp47Normalize} from 'bcp-47-normalize';
37+
import {extendedFilter} from 'bcp-47-match';
3838
import MediaPlayerEvents from '../MediaPlayerEvents.js';
3939
import DashConstants from '../../dash/constants/DashConstants.js';
40-
import getNChanFromAudioChannelConfig from '../constants/AudioChannelConfiguration.js';
40+
import getNChanFromAudioChannelConfig from '../utils/AudioChannelConfiguration.js';
4141

4242
function MediaController() {
4343

@@ -417,7 +417,7 @@ function MediaController() {
417417
function matchSettingsLang(settings, track) {
418418
try {
419419
return !settings.lang ||
420-
(settings.lang instanceof RegExp) ?
420+
(settings.lang instanceof RegExp) ?
421421
(track.lang.match(settings.lang)) : track.lang !== '' ?
422422
(extendedFilter(track.lang, bcp47Normalize(settings.lang)).length > 0) : false;
423423
} catch (e) {
@@ -598,7 +598,7 @@ function MediaController() {
598598
// since this should not happen per IOP
599599
trackArr.forEach(function (track) {
600600
const tmp = track.audioChannelConfiguration.reduce(function (acc, audioChanCfg) {
601-
const nChan = getNChanFromAudioChannelConfig(audioChanCfg);
601+
let nChan = getNChanFromAudioChannelConfig(audioChanCfg) || 0;
602602
return acc + nChan;
603603
}, 0);
604604
let avgChan = tmp / track.audioChannelConfiguration.length;
@@ -636,8 +636,7 @@ function MediaController() {
636636
function getTracksWithHighestEfficiency(trackArr) {
637637
if (trackArr[0] && (trackArr[0].type === Constants.VIDEO)) {
638638
return _getVideoTracksWithHighestEfficiency(trackArr);
639-
}
640-
else if (trackArr[0] && (trackArr[0].type === Constants.AUDIO)) {
639+
} else if (trackArr[0] && (trackArr[0].type === Constants.AUDIO)) {
641640
return _getAudioTracksWithHighestEfficiency(trackArr);
642641
}
643642

Lines changed: 136 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -1,136 +1,136 @@
1-
/**
2-
* The copyright in this software is being made available under the BSD License,
3-
* included below. This software may be subject to other third party and contributor
4-
* rights, including patent rights, and no such rights are granted under this license.
5-
*
6-
* Copyright (c) 2025, Dash Industry Forum.
7-
* All rights reserved.
8-
*
9-
* Redistribution and use in source and binary forms, with or without modification,
10-
* are permitted provided that the following conditions are met:
11-
* * Redistributions of source code must retain the above copyright notice, this
12-
* list of conditions and the following disclaimer.
13-
* * Redistributions in binary form must reproduce the above copyright notice,
14-
* this list of conditions and the following disclaimer in the documentation and/or
15-
* other materials provided with the distribution.
16-
* * Neither the name of Dash Industry Forum nor the names of its
17-
* contributors may be used to endorse or promote products derived from this software
18-
* without specific prior written permission.
19-
*
20-
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY
21-
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22-
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23-
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
24-
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25-
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF USE, DATA, OR
26-
* PROFITS, OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27-
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28-
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29-
* POSSIBILITY OF SUCH DAMAGE.
30-
*/
31-
32-
33-
34-
// derived from ISO/IEC 23091-3
35-
const _mapping_CICP = {
36-
'0': undefined,
37-
'1': 1,
38-
'2': 2,
39-
'3': 3,
40-
'4': 4,
41-
'5': 5,
42-
'6': 5,
43-
'7': 7,
44-
'8': 2,
45-
'9': 3,
46-
'10': 4,
47-
'11': 6,
48-
'12': 7,
49-
'13': 22,
50-
'14': 7,
51-
'15': 10,
52-
'16': 9,
53-
'17': 11,
54-
'18': 13,
55-
'19': 11,
56-
'20': 13
57-
};
58-
59-
function _countBits(n) {
60-
return n == 0 ? 0 : n.toString(2).match(/1/g).length;
61-
}
62-
63-
function _getNChanFromBitMask(value, masks) {
64-
let nChan = undefined;
65-
let intVal = parseInt('0x' + value, 16);
66-
67-
let singleChannels = intVal & masks[0];
68-
let ChannelPairs = intVal & masks[1];
69-
nChan = _countBits(singleChannels) + 2 * _countBits(ChannelPairs);
70-
71-
return nChan;
72-
}
73-
74-
function _getNChanDolby2011(value) {
75-
if ( value.length !== 4 ) {
76-
return undefined;
77-
}
78-
79-
// see ETSI TS 103190-1, table F.1:
80-
// 0b1111100110001000: single channel flags
81-
// 0b0000011001110000: channel pair flags
82-
return _getNChanFromBitMask(value, [0b1111100110001000, 0b0000011001110000]);
83-
}
84-
85-
function _getNChanDolby2015(value) {
86-
if ( value.length !== 6 ) {
87-
return undefined;
88-
}
89-
90-
if ( value === '800000' ) {
91-
// object audio
92-
return 24;
93-
}
94-
95-
// see ETSI TS 103190-2, table A.27
96-
// 0b001101111000000010: single channel flags
97-
// 0b110010000110111101: channel pair flags
98-
return _getNChanFromBitMask(value, [0b001101111000000010, 0b110010000110111101]);
99-
}
100-
101-
function _getNChanDTSUHD(value) {
102-
if ( value.length > 8 ) {
103-
return undefined;
104-
}
105-
106-
// see ETSI TS 103491, table B-5
107-
// LFE to exclude: 0x00010000 + 0x00000020
108-
return _getNChanFromBitMask(value, [0xFFFEFFDF, 0x00000000]);
109-
}
110-
111-
function getNChanFromAudioChannelConfig(audioChannelConfiguration) {
112-
let nChan = undefined;
113-
114-
if ( !audioChannelConfiguration || !audioChannelConfiguration.schemeIdUri || !audioChannelConfiguration.value ) {
115-
return undefined;
116-
}
117-
118-
const scheme = audioChannelConfiguration['schemeIdUri'];
119-
const value = audioChannelConfiguration['value'];
120-
121-
if (scheme === 'urn:mpeg:dash:23003:3:audio_channel_configuration:2011' || scheme === 'urn:mpeg:mpegB:cicp:ChannelConfiguration') {
122-
// see ISO/IEC 23091-3
123-
nChan = _mapping_CICP[value];
124-
} else if (scheme === 'tag:dolby.com,2014:dash:audio_channel_configuration:2011') {
125-
nChan = _getNChanDolby2011(value);
126-
} else if (scheme === 'tag:dolby.com,2015:dash:audio_channel_configuration:2015') {
127-
nChan = _getNChanDolby2015(value);
128-
} else if (scheme === 'tag:dts.com,2014:dash:audio_channel_configuration:2012') {
129-
nChan = parseInt(value); // per ETSI TS 102 114,table G.2, this includes LFE
130-
} else if (scheme === 'tag:dts.com,2018:uhd:audio_channel_configuration') {
131-
nChan = _getNChanDTSUHD(value);
132-
}
133-
return nChan;
134-
}
135-
136-
export default getNChanFromAudioChannelConfig;
1+
/**
2+
* The copyright in this software is being made available under the BSD License,
3+
* included below. This software may be subject to other third party and contributor
4+
* rights, including patent rights, and no such rights are granted under this license.
5+
*
6+
* Copyright (c) 2025, Dash Industry Forum.
7+
* All rights reserved.
8+
*
9+
* Redistribution and use in source and binary forms, with or without modification,
10+
* are permitted provided that the following conditions are met:
11+
* * Redistributions of source code must retain the above copyright notice, this
12+
* list of conditions and the following disclaimer.
13+
* * Redistributions in binary form must reproduce the above copyright notice,
14+
* this list of conditions and the following disclaimer in the documentation and/or
15+
* other materials provided with the distribution.
16+
* * Neither the name of Dash Industry Forum nor the names of its
17+
* contributors may be used to endorse or promote products derived from this software
18+
* without specific prior written permission.
19+
*
20+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY
21+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23+
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
24+
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25+
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF USE, DATA, OR
26+
* PROFITS, OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27+
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29+
* POSSIBILITY OF SUCH DAMAGE.
30+
*/
31+
32+
33+
34+
// derived from ISO/IEC 23091-3
35+
const _mapping_CICP = {
36+
'0': undefined,
37+
'1': 1,
38+
'2': 2,
39+
'3': 3,
40+
'4': 4,
41+
'5': 5,
42+
'6': 5,
43+
'7': 7,
44+
'8': 2,
45+
'9': 3,
46+
'10': 4,
47+
'11': 6,
48+
'12': 7,
49+
'13': 22,
50+
'14': 7,
51+
'15': 10,
52+
'16': 9,
53+
'17': 11,
54+
'18': 13,
55+
'19': 11,
56+
'20': 13
57+
};
58+
59+
function _countBits(n) {
60+
return n == 0 ? 0 : n.toString(2).match(/1/g).length;
61+
}
62+
63+
function _getNChanFromBitMask(value, masks) {
64+
let nChan = undefined;
65+
let intVal = parseInt('0x' + value, 16);
66+
67+
let singleChannels = intVal & masks[0];
68+
let ChannelPairs = intVal & masks[1];
69+
nChan = _countBits(singleChannels) + 2 * _countBits(ChannelPairs);
70+
71+
return nChan;
72+
}
73+
74+
function _getNChanDolby2011(value) {
75+
if ( value.length !== 4 ) {
76+
return undefined;
77+
}
78+
79+
// see ETSI TS 103190-1, table F.1:
80+
// 0b1111100110001000: single channel flags
81+
// 0b0000011001110000: channel pair flags
82+
return _getNChanFromBitMask(value, [0b1111100110001000, 0b0000011001110000]);
83+
}
84+
85+
function _getNChanDolby2015(value) {
86+
if ( value.length !== 6 ) {
87+
return undefined;
88+
}
89+
90+
if ( value === '800000' ) {
91+
// object audio
92+
return 24;
93+
}
94+
95+
// see ETSI TS 103190-2, table A.27
96+
// 0b001101111000000010: single channel flags
97+
// 0b110010000110111101: channel pair flags
98+
return _getNChanFromBitMask(value, [0b001101111000000010, 0b110010000110111101]);
99+
}
100+
101+
function _getNChanDTSUHD(value) {
102+
if ( value.length > 8 ) {
103+
return undefined;
104+
}
105+
106+
// see ETSI TS 103491, table B-5
107+
// LFE to exclude: 0x00010000 + 0x00000020
108+
return _getNChanFromBitMask(value, [0xFFFEFFDF, 0x00000000]);
109+
}
110+
111+
function getNChanFromAudioChannelConfig(audioChannelConfiguration) {
112+
let nChan = undefined;
113+
114+
if ( !audioChannelConfiguration || !audioChannelConfiguration.schemeIdUri || !audioChannelConfiguration.value ) {
115+
return undefined;
116+
}
117+
118+
const scheme = audioChannelConfiguration['schemeIdUri'];
119+
const value = audioChannelConfiguration['value'];
120+
121+
if (scheme === 'urn:mpeg:dash:23003:3:audio_channel_configuration:2011' || scheme === 'urn:mpeg:mpegB:cicp:ChannelConfiguration') {
122+
// see ISO/IEC 23091-3
123+
nChan = _mapping_CICP[value];
124+
} else if (scheme === 'tag:dolby.com,2014:dash:audio_channel_configuration:2011') {
125+
nChan = _getNChanDolby2011(value);
126+
} else if (scheme === 'tag:dolby.com,2015:dash:audio_channel_configuration:2015') {
127+
nChan = _getNChanDolby2015(value);
128+
} else if (scheme === 'tag:dts.com,2014:dash:audio_channel_configuration:2012') {
129+
nChan = parseInt(value); // per ETSI TS 102 114,table G.2, this includes LFE
130+
} else if (scheme === 'tag:dts.com,2018:uhd:audio_channel_configuration') {
131+
nChan = _getNChanDTSUHD(value);
132+
}
133+
return nChan;
134+
}
135+
136+
export default getNChanFromAudioChannelConfig;

test/unit/test/streaming/streaming.constants.AudioChannelConfiguration.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import getNChanFromAudioChannelConfig from '../../../../src/streaming/constants/AudioChannelConfiguration.js';
1+
import getNChanFromAudioChannelConfig from '../../../../src/streaming/utils/AudioChannelConfiguration.js';
22
import {expect} from 'chai';
33

44
describe('AudioChannelConfiguration', function () {

test/unit/test/streaming/streaming.controllers.MediaController.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -762,7 +762,7 @@ describe('MediaController', function () {
762762

763763
describe('"highestSelectionPriority" mode', function () {
764764
beforeEach(function () {
765-
settings.update({ streaming: { selectionModeForInitialTrack: Constants.TRACK_SELECTION_MODE_HIGHEST_SELECTION_PRIORITY } });
765+
settings.update({ streaming: { selectionModeForInitialTrack: Constants.TRACK_SELECTION_MODE_HIGHEST_EFFICIENCY } });
766766
});
767767

768768
it('should select track with highest priority', function () {
@@ -915,7 +915,7 @@ describe('MediaController', function () {
915915
it('should select audio track with lowest bitrate per full channels (JOC extension)', function () {
916916
testSelectInitialTrack(
917917
'audio',
918-
{
918+
{
919919
bitrateList: [{ bandwidth: 768 }],
920920
audioChannelConfiguration: [{schemeIdUri: 'tag:dolby.com,2014:dash:audio_channel_configuration:2011', value: 'F8016'}],
921921
supplementalProperties: [{schemeIdUri: 'tag:dolby.com,2018:dash:EC3_ExtensionType:2018', value: 'JOC'}]

0 commit comments

Comments
 (0)