diff --git a/src/parser/DASHTree.cpp b/src/parser/DASHTree.cpp index 8b534d3a3..e0df59277 100644 --- a/src/parser/DASHTree.cpp +++ b/src/parser/DASHTree.cpp @@ -1364,18 +1364,48 @@ uint32_t adaptive::CDashTree::ParseAudioChannelConfig(pugi::xml_node node) std::string_view value = XML::GetAttrib(node, "value"); uint32_t channels{0}; - if (schemeIdUri == "urn:mpeg:dash:23003:3:audio_channel_configuration:2011" || - schemeIdUri == "urn:mpeg:mpegB:cicp:ChannelConfiguration") + if (schemeIdUri == "urn:mpeg:dash:outputChannelPositionList:2012") { + // A space-separated list of speaker positions, + // the number of channels is the length of the list + return static_cast(STRING::SplitToVec(value, ' ').size()); + } + else if (schemeIdUri == "urn:mpeg:dash:23003:3:audio_channel_configuration:2011" || + schemeIdUri == "urn:dts:dash:audio_channel_configuration:2012") + { + // The value is the number of channels channels = STRING::ToUint32(value); } else if (schemeIdUri == "urn:dolby:dash:audio_channel_configuration:2011" || schemeIdUri == "tag:dolby.com,2014:dash:audio_channel_configuration:2011") { - if (value == "F801") - channels = 6; - else if (value == "FE01") - channels = 8; + // A hex-encoded 16-bit integer, each bit represents a channel + uint32_t hexVal = STRING::HexStrToUint(value); + uint32_t numBits{0}; + while (hexVal) + { + if (hexVal & 1) + { + ++numBits; + } + hexVal = hexVal >> 1; + } + channels = numBits; + } + else if (schemeIdUri == "urn:mpeg:mpegB:cicp:ChannelConfiguration") + { + // Defined by https://dashif.org/identifiers/audio_source_metadata/ + static const size_t mapSize = 21; + static const int channelCountMapping[mapSize]{ + 0, 1, 2, 3, 4, 5, 6, 8, 2, 3, /* 0--9 */ + 4, 7, 8, 24, 8, 12, 10, 12, 14, 12, /* 10--19 */ + 14, /* 20 */ + }; + uint32_t pos = STRING::ToUint32(value); + if (pos > 0 && pos < mapSize) + { + channels = channelCountMapping[pos]; + } } if (channels == 0) {