Skip to content

Commit b5fe0fc

Browse files
committed
fixups
1 parent 80e17b6 commit b5fe0fc

File tree

9 files changed

+192
-85
lines changed

9 files changed

+192
-85
lines changed

src/CompKodiProps.cpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -737,11 +737,21 @@ bool ADP::KODI_PROPS::CCompKodiProps::ParseDrmConfig(const std::string& data)
737737
{
738738
for (auto& jPairUnwrap : jDictLic["unwrapper_params"].GetObject()) // Iterate JSON dict
739739
{
740-
if (jPairUnwrap.name.IsString() && jPairUnwrap.value.IsString())
740+
if (!jPairUnwrap.name.IsString() ||
741+
!(jPairUnwrap.value.IsString() || jPairUnwrap.value.IsBool()))
741742
{
742-
drmCfg.license.unwrapperParams.emplace(jPairUnwrap.name.GetString(),
743-
jPairUnwrap.value.GetString());
743+
LOG::LogF(LOGERROR,
744+
"The license parameter \"unwrapper_params\" contains invalid values");
745+
break;
744746
}
747+
748+
std::string value;
749+
if (jPairUnwrap.value.IsString())
750+
value = jPairUnwrap.value.GetString();
751+
else if (jPairUnwrap.value.IsBool())
752+
value = jPairUnwrap.value.GetBool() ? "true" : "false";
753+
754+
drmCfg.license.unwrapperParams.emplace(jPairUnwrap.name.GetString(), value);
745755
}
746756
}
747757

@@ -796,8 +806,6 @@ bool ADP::KODI_PROPS::CCompKodiProps::ParseDrmLegacyConfig(const std::string& da
796806
DrmCfg drmCfg;
797807
// As legacy behaviour its expected to force the unique drm configuration available
798808
drmCfg.priority = 1;
799-
// As legacy behaviour force single session (as in the old ISA versions <= v21)
800-
drmCfg.isForceSingleSession = true;
801809

802810
if (!licenseStr.empty())
803811
{

src/Session.cpp

Lines changed: 77 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ void SESSION::CSession::DeleteStreams()
5252
{
5353
LOG::Log(LOGDEBUG, "CSession::DeleteStreams()");
5454
m_streams.clear();
55+
m_timingStream = nullptr;
5556
}
5657

5758
/*----------------------------------------------------------------------
@@ -134,32 +135,29 @@ bool SESSION::CSession::Initialize(std::string manifestUrl)
134135
return true;
135136
}
136137

137-
void SESSION::CSession::CheckPlayableStreams()
138+
bool SESSION::CSession::CheckPlayableStreams()
138139
{
139140
auto& kodiPropCfg = CSrvBroker::GetKodiProps().GetConfig();
140141

142+
/*! @todo: Code commented, see todo below about: "Secure path on audio stream is not implemented"
143+
*
141144
if (kodiPropCfg.resolutionLimit == 0 &&
142145
kodiPropCfg.hdcpCheck == ADP::KODI_PROPS::HdcpCheckType::DEFAULT)
143146
{
144147
return;
145148
}
146-
149+
*/
147150
uint32_t adpIndex{0};
148151
CAdaptationSet* adp{nullptr};
149152

150153
while ((adp = m_adaptiveTree->GetAdaptationSet(adpIndex++)))
151154
{
152-
if (adp->GetStreamType() != StreamType::VIDEO)
153-
continue;
154-
155155
for (auto& repr : adp->GetRepresentations())
156156
{
157-
// Note to HDCP check:
158-
// HDCP check should be done by the DRM where in case of problems should block key's
159-
// for example with Widevine you will get "output-restricted" to key status
160-
// the following it's an additional check for custom manifest's
161-
if (kodiPropCfg.hdcpCheck == ADP::KODI_PROPS::HdcpCheckType::LICENSE &&
162-
!m_adaptiveTree->IsReqPrepareStream())
157+
//! @todo: Code changed, see todo below about: "Secure path on audio stream is not implemented"
158+
// if (kodiPropCfg.hdcpCheck == ADP::KODI_PROPS::HdcpCheckType::LICENSE &&
159+
// !m_adaptiveTree->IsReqPrepareStream())
160+
if (!m_adaptiveTree->IsReqPrepareStream())
163161
{
164162
// The LICENSE method assume that a service provide in the license response the HDCP parameters
165163
// currently a comparison is made between the license HDCP values and the one provided by the manifest.
@@ -168,27 +166,68 @@ void SESSION::CSession::CheckPlayableStreams()
168166
if (!repr->DrmInfos().empty())
169167
{
170168
kodi::addon::InputstreamInfo isInfo;
171-
if (m_drmEngine.InitializeSession(
172-
repr->DrmInfos(), DRM::DRMMediaType::VIDEO,
173-
m_adaptiveTree->m_currentPeriod->IsSecureDecodeNeeded(), isInfo, repr.get(), adp,
174-
false))
169+
DRM::DRMInfo initDrmInfo;
170+
171+
if (m_drmEngine.InitializeSession(repr->DrmInfos(), DRM::DRMMediaType::VIDEO,
172+
m_adaptiveTree->m_currentPeriod->IsSecureDecodeNeeded(),
173+
isInfo, repr.get(), adp, false, initDrmInfo))
175174
{
176175
if (!isInfo.GetCryptoSession().GetSessionId().empty())
177176
{
178-
const auto session = m_drmEngine.GetSession(isInfo.GetCryptoSession().GetSessionId());
177+
const auto session = m_drmEngine.GetSession(isInfo.GetCryptoSession().GetSessionId(),
178+
initDrmInfo.defaultKid);
179179
if (session)
180180
{
181-
const auto& caps = session->capabilities;
182-
183-
if (repr->GetHdcpVersion() > caps.hdcpVersion ||
184-
(caps.hdcpLimit > 0 && repr->GetWidth() * repr->GetHeight() > caps.hdcpLimit))
181+
//! @todo: HACK REQUIRED BECAUSE ---> Secure path on audio stream is not implemented for CDM Widevine ONLY (non-android) <---
182+
//! since audio streams that require Secure path decoder cannot be played
183+
//! we have no way to distinguish which ones they are other than to do a KID test with the DRM for each stream,
184+
//! this is an expensive method that could open many DRM sessions which will not be unused for playback.
185+
//! When in a future this will be implemented, all this code should be cleanup and removed
186+
//! and then leave it to CInputStreamAdaptive::OpenStream -> PrepareStream
187+
//! the task to initialize DRM session only to the requested streams.
188+
//! It can be tested e.g. with some Am@zon videos
189+
auto& caps = session->capabilities;
190+
191+
if (!session->drm->IsSecureDecoderAudioSupported() &&
192+
adp->GetStreamType() == StreamType::AUDIO &&
193+
caps.flags & DRM::DecrypterCapabilites::SSD_SECURE_PATH)
185194
{
186-
LOG::Log(LOGDEBUG, "Disabled stream repr ID \"%s\", AdpSet ID \"%s\", as not HDCP compliant",
195+
LOG::Log(LOGWARNING,
196+
"Disabled stream repr ID \"%s\", AdpSet ID \"%s\", "
197+
"Secure path decoder on audio stream is not supported",
187198
repr->GetId().data(), adp->GetId().data());
188199
repr->isPlayable = false;
200+
continue;
201+
}
202+
203+
// Note to HDCP check:
204+
// HDCP check should be done by the DRM where in case of problems should block key's
205+
// for example with Widevine you will get "output-restricted" to key status
206+
// the following it's an additional check for custom manifest's
207+
if (kodiPropCfg.hdcpCheck == ADP::KODI_PROPS::HdcpCheckType::LICENSE)
208+
{
209+
if (repr->GetHdcpVersion() > caps.hdcpVersion ||
210+
(caps.hdcpLimit > 0 && repr->GetWidth() * repr->GetHeight() > caps.hdcpLimit))
211+
{
212+
LOG::Log(
213+
LOGWARNING,
214+
"Disabled stream repr ID \"%s\", AdpSet ID \"%s\", as not HDCP compliant",
215+
repr->GetId().data(), adp->GetId().data());
216+
repr->isPlayable = false;
217+
continue;
218+
}
219+
189220
}
190221
}
191-
}
222+
}
223+
}
224+
else
225+
{
226+
if (m_drmEngine.GetStatus() == DRM::EngineStatus::DRM_ERROR ||
227+
m_drmEngine.GetStatus() == DRM::EngineStatus::DECRYPTER_ERROR)
228+
{
229+
return false; // return here, a bad status dont allow you to play streams
230+
}
192231
}
193232
}
194233
}
@@ -200,14 +239,16 @@ void SESSION::CSession::CheckPlayableStreams()
200239
{
201240
if (repr->GetWidth() * repr->GetHeight() > kodiPropCfg.resolutionLimit)
202241
{
203-
LOG::Log(LOGDEBUG,
242+
LOG::Log(LOGWARNING,
204243
"Disabled stream repr ID \"%s\", AdpSet ID \"%s\", it exceeds the resolution limits",
205244
repr->GetId().data(), adp->GetId().data());
206245
repr->isPlayable = false;
207246
}
208247
}
209248
}
210249
}
250+
251+
return true;
211252
}
212253

213254
void SESSION::CSession::InitializePeriod()
@@ -221,11 +262,13 @@ void SESSION::CSession::InitializePeriod()
221262

222263
m_chapterStartTime = GetChapterStartTime();
223264

224-
CheckPlayableStreams(); // Note: this could initialize DRM on all streams right here, instead of OpenStream
225-
226265
// Clean to create new SESSION::STREAM objects. One for each AdaptationSet/Representation
227266
m_streams.clear();
228267

268+
// Note: this could initialize DRM on all streams right here, instead of CInputStreamAdaptive::OpenStream
269+
if (!CheckPlayableStreams())
270+
return;
271+
229272
uint32_t adpIndex{0};
230273
CAdaptationSet* adp{nullptr};
231274

@@ -556,6 +599,8 @@ bool SESSION::CSession::PrepareStream(CStream* stream, uint64_t startPts)
556599
}
557600
}
558601

602+
DRM::DRMInfo initDrmInfo;
603+
559604
if (!repr->DrmInfos().empty())
560605
{
561606
DRM::DRMMediaType drmMediaType{DRM::DRMMediaType::UNKNOWN};
@@ -573,7 +618,7 @@ bool SESSION::CSession::PrepareStream(CStream* stream, uint64_t startPts)
573618

574619
if (!m_drmEngine.InitializeSession(repr->DrmInfos(), drmMediaType,
575620
period->IsSecureDecodeNeeded(), stream->m_info, repr, adp,
576-
m_adaptiveTree->IsChangingPeriod()))
621+
m_adaptiveTree->IsChangingPeriod(), initDrmInfo))
577622
{
578623
return false;
579624
}
@@ -589,7 +634,8 @@ bool SESSION::CSession::PrepareStream(CStream* stream, uint64_t startPts)
589634
if (!reader)
590635
return false;
591636

592-
const auto session = m_drmEngine.GetSession(stream->m_info.GetCryptoSession().GetSessionId());
637+
const auto session = m_drmEngine.GetSession(stream->m_info.GetCryptoSession().GetSessionId(),
638+
initDrmInfo.defaultKid);
593639

594640
if (adp->GetStreamType() == StreamType::VIDEO || adp->GetStreamType() == StreamType::VIDEO_AUDIO)
595641
{
@@ -777,6 +823,9 @@ bool SESSION::CSession::SeekTime(double seekTime, unsigned int streamId, bool pr
777823
{
778824
bool ret{false};
779825

826+
if (m_streams.empty())
827+
return false;
828+
780829
//we don't have pts < 0 here and work internally with uint64
781830
if (seekTime < 0)
782831
seekTime = 0;
@@ -955,7 +1004,7 @@ void SESSION::CSession::OnStreamChange(adaptive::AdaptiveStream* adStream)
9551004

9561005
bool SESSION::CSession::OnGetStream(int streamid, kodi::addon::InputstreamInfo& info)
9571006
{
958-
if (m_drmEngine.GetStatus() == DRM::EngineStatus::DRM_NOT_SUPPORTED ||
1007+
if (m_drmEngine.GetStatus() == DRM::EngineStatus::DRM_ERROR ||
9591008
m_drmEngine.GetStatus() == DRM::EngineStatus::DECRYPTER_ERROR)
9601009
{
9611010
// If the stream is protected with a unsupported DRM, we have to stop the playback,

src/Session.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class ATTR_DLL_LOCAL CSession : public adaptive::AdaptiveStreamObserver
3838
*/
3939
bool Initialize(std::string manifestUrl);
4040

41-
void CheckPlayableStreams();
41+
bool CheckPlayableStreams();
4242

4343
/*!
4444
* \brief Initialize adaptive tree period

0 commit comments

Comments
 (0)