Skip to content

Commit 385e881

Browse files
committed
Implemented TRC Color transfer characteristic
1 parent dcc79d8 commit 385e881

File tree

12 files changed

+190
-16
lines changed

12 files changed

+190
-16
lines changed

inputstream.adaptive/resources/language/resource.language.en_gb/strings.po

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -291,10 +291,11 @@ msgid "Select video stream"
291291
msgstr ""
292292

293293
#. Description of each list item in #30231 dialog window
294-
#. Do not translate placeholders: {codec} {quality}
294+
#. Do not translate placeholders: {codec} {quality} {hdr-type}
295+
#. Use of double graphes e.g. {whatyouwant{hdr-type}whatyouwant} allows you to add additional text printed only when a value is present
295296
#: src/common/RepresentationChooserAskQuality.cpp
296297
msgctxt "#30232"
297-
msgid "Video stream {codec} {quality}"
298+
msgid "Video stream {codec}{ [{hdr-type}]} {quality}"
298299
msgstr ""
299300

300301
#. Enum setting to set the test mode

src/Session.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,14 @@ void SESSION::CSession::UpdateStream(CStream& stream)
455455
stream.m_info.SetColorSpace(INPUTSTREAM_COLORSPACE_UNSPECIFIED);
456456
stream.m_info.SetColorRange(INPUTSTREAM_COLORRANGE_UNKNOWN);
457457
stream.m_info.SetColorPrimaries(INPUTSTREAM_COLORPRIMARY_UNSPECIFIED);
458-
stream.m_info.SetColorTransferCharacteristic(INPUTSTREAM_COLORTRC_UNSPECIFIED);
458+
459+
ColorTRC colorTRC = rep->GetColorTRC();
460+
if (colorTRC == ColorTRC::SMPTE2084)
461+
stream.m_info.SetColorTransferCharacteristic(INPUTSTREAM_COLORTRC_SMPTE2084);
462+
else if (colorTRC == ColorTRC::ARIB_STD_B67)
463+
stream.m_info.SetColorTransferCharacteristic(INPUTSTREAM_COLORTRC_ARIB_STD_B67);
464+
else
465+
stream.m_info.SetColorTransferCharacteristic(INPUTSTREAM_COLORTRC_UNSPECIFIED);
459466

460467
if (CODEC::Contains(codecs, CODEC::FOURCC_AVC_, codecStr) ||
461468
CODEC::Contains(codecs, CODEC::FOURCC_H264, codecStr))

src/common/AdaptationSet.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,18 @@ PLAYLIST::CAdaptationSet* PLAYLIST::CAdaptationSet::FindByCodec(
202202
return nullptr;
203203
}
204204

205+
CAdaptationSet* PLAYLIST::CAdaptationSet::FindByCodec(
206+
std::vector<std::unique_ptr<CAdaptationSet>>& adpSets, std::string codec, const ColorTRC trc)
207+
{
208+
auto itAdpSet = std::find_if(
209+
adpSets.cbegin(), adpSets.cend(), [&codec, &trc](const std::unique_ptr<CAdaptationSet>& item)
210+
{ return CODEC::Contains(item->GetCodecs(), codec) && item->GetColorTRC() == trc; });
211+
if (itAdpSet != adpSets.cend())
212+
return (*itAdpSet).get();
213+
214+
return nullptr;
215+
}
216+
205217
CAdaptationSet* PLAYLIST::CAdaptationSet::FindMergeable(
206218
std::vector<std::unique_ptr<CAdaptationSet>>& adpSets, CAdaptationSet* adpSet)
207219
{

src/common/AdaptationSet.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,16 @@ class ATTR_DLL_LOCAL CAdaptationSet : public CCommonSegAttribs, public CCommonAt
134134
static CAdaptationSet* FindByCodec(std::vector<std::unique_ptr<CAdaptationSet>>& adpSets,
135135
std::string codec);
136136

137+
/*!
138+
* \brief Find an adaptation set by codec string and TRC.
139+
* \param adpSets The adaptation set list where to search
140+
* \param codec The codec string
141+
* \return The adaptation set if found, otherwise nullptr
142+
*/
143+
static CAdaptationSet* FindByCodec(std::vector<std::unique_ptr<CAdaptationSet>>& adpSets,
144+
std::string codec,
145+
const ColorTRC trc);
146+
137147
/*!
138148
* \brief Find a mergeable adaptation set by comparing properties.
139149
* \param adpSets The adaptation set list where to search

src/common/ChooserAskQuality.cpp

Lines changed: 61 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -46,24 +46,74 @@ std::string CovertFpsToString(float value)
4646
return str;
4747
}
4848

49+
void ReplacePhValue(std::string& text,
50+
const std::string& phTextPart,
51+
const std::string& phName,
52+
const std::string& value)
53+
{
54+
std::string result;
55+
if (!value.empty())
56+
{
57+
result = phTextPart;
58+
STRING::ReplaceFirst(result, phName, value);
59+
// Placeholder contained within other parentheses e.g.: {some text {ph} some text}
60+
if (result.front() == '{')
61+
result.erase(0, 1);
62+
if (result.back() == '}')
63+
result.pop_back();
64+
}
65+
STRING::ReplaceFirst(text, phTextPart, result);
66+
}
67+
4968
std::string CreateStreamName(const CRepresentation* repr)
5069
{
5170
std::string streamName{kodi::addon::GetLocalizedString(30232)};
52-
STRING::ReplaceFirst(streamName, "{codec}", CODEC::GetVideoDesc(repr->GetCodecs()));
71+
const std::vector<std::string> phs = STRING::ExtractPlaceholders(streamName, '{', '}');
72+
73+
for (const std::string& ph : phs)
74+
{
75+
if (STRING::Contains(ph, "{codec}", true))
76+
{
77+
ReplacePhValue(streamName, ph, "{codec}", CODEC::GetVideoDesc(repr->GetCodecs()));
78+
}
79+
else if (STRING::Contains(ph, "{hdr-type}", true))
80+
{
81+
std::string hdrType;
82+
const ColorTRC colorTrc = repr->GetColorTRC();
83+
if (colorTrc == ColorTRC::SMPTE2084)
84+
{
85+
if (CODEC::Contains(repr->GetCodecs(), CODEC::FOURCC_DVH1) ||
86+
CODEC::Contains(repr->GetCodecs(), CODEC::FOURCC_DVHE))
87+
{
88+
hdrType = "DV";
89+
}
90+
else
91+
{
92+
hdrType = "HDR10";
93+
}
94+
}
95+
if (colorTrc == ColorTRC::ARIB_STD_B67)
96+
hdrType = "HLG";
5397

54-
float fps{static_cast<float>(repr->GetFrameRate())};
55-
if (fps > 0 && repr->GetFrameRateScale() > 0)
56-
fps /= repr->GetFrameRateScale();
98+
ReplacePhValue(streamName, ph, "{hdr-type}", hdrType);
99+
}
100+
else if (STRING::Contains(ph, "{quality}", true))
101+
{
102+
float fps{static_cast<float>(repr->GetFrameRate())};
103+
if (fps > 0 && repr->GetFrameRateScale() > 0)
104+
fps /= repr->GetFrameRateScale();
57105

58-
std::string quality = "(";
59-
if (repr->GetWidth() > 0 && repr->GetHeight() > 0)
60-
quality += StringUtils::Format("%ix%i, ", repr->GetWidth(), repr->GetHeight());
61-
if (fps > 0)
62-
quality += StringUtils::Format("%s fps, ", CovertFpsToString(fps).c_str());
106+
std::string quality = "(";
107+
if (repr->GetWidth() > 0 && repr->GetHeight() > 0)
108+
quality += StringUtils::Format("%ix%i, ", repr->GetWidth(), repr->GetHeight());
109+
if (fps > 0)
110+
quality += StringUtils::Format("%s fps, ", CovertFpsToString(fps).c_str());
63111

64-
quality += StringUtils::Format("%u Kbps)", repr->GetBandwidth() / 1000);
65-
STRING::ReplaceFirst(streamName, "{quality}", quality);
112+
quality += StringUtils::Format("%u Kbps)", repr->GetBandwidth() / 1000);
66113

114+
ReplacePhValue(streamName, ph, "{quality}", quality);
115+
}
116+
}
67117
return streamName;
68118
}
69119
} // unnamed namespace

src/common/CommonAttribs.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,10 @@ uint32_t PLAYLIST::CCommonAttribs::GetAudioChannels() const
8282
return m_audioChannels;
8383
return m_parentCommonAttributes->GetAudioChannels();
8484
}
85+
86+
const ColorTRC PLAYLIST::CCommonAttribs::GetColorTRC() const
87+
{
88+
if (m_colorTRC != ColorTRC::NONE || !m_parentCommonAttributes)
89+
return m_colorTRC;
90+
return m_parentCommonAttributes->GetColorTRC();
91+
}

src/common/CommonAttribs.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,18 @@ struct ProtectionScheme
3434
std::string licenseUrl;
3535
};
3636

37+
/*!
38+
* \brief Color Transfer Characteristics (TRC)
39+
* references from InputStream API interface and
40+
* https://en.wikipedia.org/wiki/Coding-independent_code_points
41+
*/
42+
enum class ColorTRC
43+
{
44+
NONE,
45+
SMPTE2084 = 16,
46+
ARIB_STD_B67 = 18,
47+
};
48+
3749
// CCommonAttribs class provide attribute data
3850
// of class itself or when not set of the parent class (if any).
3951
class ATTR_DLL_LOCAL CCommonAttribs
@@ -72,6 +84,9 @@ class ATTR_DLL_LOCAL CCommonAttribs
7284
bool HasProtectionSchemes() const { return !m_protSchemes.empty(); }
7385
std::vector<ProtectionScheme>& ProtectionSchemes() { return m_protSchemes; }
7486

87+
void SetColorTRC(ColorTRC trc) { m_colorTRC = trc; }
88+
const ColorTRC GetColorTRC() const;
89+
7590
protected:
7691
CCommonAttribs* m_parentCommonAttributes{nullptr};
7792
std::string m_mimeType;
@@ -84,6 +99,7 @@ class ATTR_DLL_LOCAL CCommonAttribs
8499
uint32_t m_sampleRate{0};
85100
uint32_t m_audioChannels{0};
86101
std::vector<ProtectionScheme> m_protSchemes;
102+
ColorTRC m_colorTRC{ColorTRC::NONE};
87103
};
88104

89105
} // namespace PLAYLIST

src/parser/DASHTree.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,13 @@ void adaptive::CDashTree::ParseTagAdaptationSet(pugi::xml_node nodeAdp, PLAYLIST
569569
adpSet->AddSwitchingIds(value);
570570
else if (schemeIdUri == "http://dashif.org/guidelines/last-segment-number")
571571
adpSet->SetSegmentEndNr(STRING::ToUint64(value));
572+
else if (schemeIdUri == "urn:mpeg:mpegB:cicp:TransferCharacteristics")
573+
{
574+
if (value == "16")
575+
adpSet->SetColorTRC(ColorTRC::SMPTE2084);
576+
else if (value == "18")
577+
adpSet->SetColorTRC(ColorTRC::ARIB_STD_B67);
578+
}
572579
}
573580

574581
// Parse <BaseURL> tag (just first, multi BaseURL not supported yet)

src/parser/HLSTree.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1446,6 +1446,7 @@ bool adaptive::CHLSTree::ParseMultivariantPlaylist(const std::string& data)
14461446
}
14471447
var.m_groupIdAudio = attribs["AUDIO"];
14481448
var.m_groupIdSubtitles = attribs["SUBTITLES"];
1449+
var.m_videoRange = attribs["VIDEO-RANGE"];
14491450
var.m_uri = uri;
14501451

14511452
// Check if this uri has been already added
@@ -1639,15 +1640,24 @@ bool adaptive::CHLSTree::ParseMultivariantPlaylist(const std::string& data)
16391640
AddIncludedAudioStream(period, codecAudio);
16401641
}
16411642

1642-
// We group all video representations by codec fourcc, similar to the DASH specs
1643+
// We group all video representations by codec fourcc (and TRC) similar to the DASH specs
16431644
std::string codecFourcc = codecVideo.substr(0, codecVideo.find('.'));
1645+
1646+
// Determinate the TRC
1647+
ColorTRC colorTRC = ColorTRC::NONE;
1648+
if (var.m_videoRange == "PQ")
1649+
colorTRC = ColorTRC::SMPTE2084;
1650+
else if (var.m_videoRange == "HLG")
1651+
colorTRC = ColorTRC::ARIB_STD_B67;
1652+
16441653
// Find existing adaptation set with same codec fourcc ...
1645-
CAdaptationSet* adpSet = CAdaptationSet::FindByCodec(period->GetAdaptationSets(), codecFourcc);
1654+
CAdaptationSet* adpSet = CAdaptationSet::FindByCodec(period->GetAdaptationSets(), codecFourcc, colorTRC);
16461655
if (!adpSet) // ... or create a new one
16471656
{
16481657
auto newAdpSet = CAdaptationSet::MakeUniquePtr(period.get());
16491658
newAdpSet->SetStreamType(streamType);
16501659
newAdpSet->AddCodecs(codecFourcc);
1660+
newAdpSet->SetColorTRC(colorTRC);
16511661
adpSet = newAdpSet.get();
16521662
period->AddAdaptationSet(newAdpSet);
16531663
}

src/parser/HLSTree.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ class ATTR_DLL_LOCAL CHLSTree : public AdaptiveTree
101101
float m_frameRate{0};
102102
std::string m_groupIdAudio;
103103
std::string m_groupIdSubtitles;
104+
std::string m_videoRange;
104105
std::string m_uri;
105106
bool m_isUriDuplicate{false}; // Another variant have same uri
106107
};

0 commit comments

Comments
 (0)