From 0c2dc199b2781f89a7cc426a62527f0bc5095423 Mon Sep 17 00:00:00 2001 From: CastagnaIT Date: Thu, 17 Aug 2023 16:58:17 +0200 Subject: [PATCH] [AdaptiveTree] Parsing EC3-JOC --- src/Session.cpp | 8 +++++++- src/parser/DASHTree.cpp | 19 +++++++++++++++++++ src/parser/HLSTree.cpp | 7 +++++++ src/parser/HLSTree.h | 8 ++++++++ src/utils/Utils.h | 2 ++ 5 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/Session.cpp b/src/Session.cpp index 085392961..402936e84 100644 --- a/src/Session.cpp +++ b/src/Session.cpp @@ -978,8 +978,13 @@ void CSession::UpdateStream(CStream& stream) stream.m_info.SetCodecName(CODEC::NAME_DTS); else if (CODEC::Contains(codecs, CODEC::FOURCC_AC_3, codecStr)) stream.m_info.SetCodecName(CODEC::NAME_AC3); - else if (CODEC::Contains(codecs, CODEC::FOURCC_EC_3, codecStr)) + else if (CODEC::Contains(codecs, CODEC::NAME_EAC3_JOC, codecStr) || + CODEC::Contains(codecs, CODEC::FOURCC_EC_3, codecStr)) + { + // In the above condition above is checked NAME_EAC3_JOC as first, + // in order to get the codec string to signal DD+ Atmos in to the SetCodecInternalName stream.m_info.SetCodecName(CODEC::NAME_EAC3); + } else if (CODEC::Contains(codecs, CODEC::FOURCC_OPUS, codecStr)) stream.m_info.SetCodecName(CODEC::NAME_OPUS); else if (CODEC::Contains(codecs, CODEC::FOURCC_VORB, codecStr) || // Find "vorb" and "vorbis" case @@ -1010,6 +1015,7 @@ void CSession::UpdateStream(CStream& stream) } } + // Internal codec name can be used by Kodi to detect the codec name to be shown in the GUI track list stream.m_info.SetCodecInternalName(codecStr); } diff --git a/src/parser/DASHTree.cpp b/src/parser/DASHTree.cpp index e0df59277..afd715c8f 100644 --- a/src/parser/DASHTree.cpp +++ b/src/parser/DASHTree.cpp @@ -980,6 +980,25 @@ void adaptive::CDashTree::ParseTagRepresentation(pugi::xml_node nodeRepr, else if (adpSet->GetStreamType() == StreamType::AUDIO && repr->GetAudioChannels() == 0) repr->SetAudioChannels(2); // Fallback to 2 channels when no value is set + // Parse child tags + for (xml_node nodeSP : nodeRepr.children("SupplementalProperty")) + { + std::string_view schemeIdUri = XML::GetAttrib(nodeSP, "schemeIdUri"); + std::string_view value = XML::GetAttrib(nodeSP, "value"); + + if (schemeIdUri == "tag:dolby.com,2018:dash:EC3_ExtensionType:2018") + { + if (value == "JOC") + repr->AddCodecs(CODEC::NAME_EAC3_JOC); + } + else if (schemeIdUri == "tag:dolby.com,2018:dash:EC3_ExtensionComplexityIndex:2018") + { + uint32_t channels = STRING::ToUint32(value); + if (channels > 0) + repr->SetAudioChannels(channels); + } + } + // For subtitles that are not as ISOBMFF format and where there is no timeline for segments // we should treat them as a single subtitle file if (repr->GetContainerType() == ContainerType::TEXT && repr->GetMimeType() != "application/mp4" && diff --git a/src/parser/HLSTree.cpp b/src/parser/HLSTree.cpp index 433c9843b..865244e75 100644 --- a/src/parser/HLSTree.cpp +++ b/src/parser/HLSTree.cpp @@ -917,6 +917,9 @@ bool adaptive::CHLSTree::ParseRenditon(const Rendition& r, repr->SetAudioChannels(r.m_channels); // Set channels in the adptation set to help distinguish it from other similar renditions adpSet->SetAudioChannels(r.m_channels); + + if ((r.m_features & REND_FEATURE_EC3_JOC) == REND_FEATURE_EC3_JOC) + repr->AddCodecs(CODEC::NAME_EAC3_JOC); } repr->assured_buffer_duration_ = m_settings.m_bufferAssuredDuration; @@ -962,7 +965,11 @@ bool adaptive::CHLSTree::ParseMultivariantPlaylist(const std::string& data) rend.m_name = attribs["NAME"]; rend.m_language = attribs["LANGUAGE"]; if (streamType == StreamType::AUDIO) + { rend.m_channels = STRING::ToUint32(attribs["CHANNELS"]); + if (STRING::Contains(attribs["CHANNELS"], "/JOC")) + rend.m_features |= REND_FEATURE_EC3_JOC; + } rend.m_isDefault = attribs["DEFAULT"] == "YES"; rend.m_isForced = attribs["FORCED"] == "YES"; rend.m_characteristics = attribs["CHARACTERISTICS"]; diff --git a/src/parser/HLSTree.h b/src/parser/HLSTree.h index 62431f686..573c00dbe 100644 --- a/src/parser/HLSTree.h +++ b/src/parser/HLSTree.h @@ -57,6 +57,13 @@ class ATTR_DLL_LOCAL CHLSTree : public AdaptiveTree PLAYLIST::StreamType type) override; protected: + // \brief Rendition features + enum REND_FEATURE + { + REND_FEATURE_NONE, + REND_FEATURE_EC3_JOC = 1 << 0 + }; + // \brief Usually refer to an EXT-X-MEDIA tag struct Rendition { @@ -69,6 +76,7 @@ class ATTR_DLL_LOCAL CHLSTree : public AdaptiveTree uint32_t m_channels{0}; std::string m_characteristics; std::string m_uri; + int m_features{REND_FEATURE_NONE}; }; // \brief Usually refer to an EXT-X-STREAM-INF tag diff --git a/src/utils/Utils.h b/src/utils/Utils.h index 4862844da..c5c68eaaf 100644 --- a/src/utils/Utils.h +++ b/src/utils/Utils.h @@ -39,6 +39,8 @@ uint64_t GetTimestamp(); namespace CODEC { constexpr char* NAME_UNKNOWN = "unk"; // Kodi codec name for unknown codec +// Kodi internal codec name to signal DD+ Atmos ("joc"), not a ffmpeg definition +constexpr char* NAME_EAC3_JOC = "eac3-joc"; // IMPORTANT: Codec names must match the ffmpeg library definition // https://github.com/FFmpeg/FFmpeg/blob/master/libavcodec/codec_desc.c