Skip to content

Commit b8d278a

Browse files
committed
others fixups
1 parent 7d065f5 commit b8d278a

File tree

2 files changed

+51
-13
lines changed

2 files changed

+51
-13
lines changed

src/decrypters/DrmEngine.cpp

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,24 @@ std::shared_ptr<DRM::IDecrypter> CreateDRM(std::string_view keySystem)
7777
return drm;
7878
}
7979

80+
/*!
81+
* \brief Get a DRMInfo by Key System
82+
* \param drmInfos The manifest DRM info
83+
* \param keySystem The Key System to search
84+
* \return The DRMInfo if found, otherwise nullptr
85+
*/
86+
DRM::DRMInfo* GetDRMInfoByKS(std::vector<DRM::DRMInfo>& drmInfos, std::string_view keySystem)
87+
{
88+
// If no key system is provided its assumend CENC content compatible with any DRM
89+
auto itDrmInfo = std::find_if(drmInfos.begin(), drmInfos.end(), [&](const DRMInfo& info)
90+
{ return info.keySystem == keySystem || info.keySystem.empty(); });
91+
92+
if (itDrmInfo != drmInfos.end())
93+
return &(*itDrmInfo);
94+
95+
return nullptr;
96+
}
97+
8098
} // unnamed namespace
8199

82100
void DRM::CDRMEngine::Initialize()
@@ -205,6 +223,21 @@ bool DRM::CDRMEngine::InitializeSession(std::vector<DRM::DRMInfo> drmInfos,
205223

206224
ConfigureClearKey(drmInfos);
207225

226+
auto& kodiProps = CSrvBroker::GetKodiProps();
227+
228+
// This is a kind of hack,
229+
// some services use manifests (usually SmoothStreaming) with PlayReady DRM only,
230+
// but they have also a Widevine license server that allow to play same stream with Widevine,
231+
// this will allow to force change the manifest DRMInfo KeySytem to Widevine and replace the init data
232+
bool isPRtoWVKeySystem{false};
233+
if (HasKeySystemSupport(KS_WIDEVINE) && drmInfos.size() == 1 &&
234+
drmInfos[0].keySystem == KS_PLAYREADY && kodiProps.GetDrmConfigs().size() == 1 &&
235+
kodiProps.HasDrmConfig(KS_WIDEVINE))
236+
{
237+
drmInfos[0].keySystem = KS_WIDEVINE;
238+
isPRtoWVKeySystem = true;
239+
}
240+
208241
if (!SelectDRM(drmInfos))
209242
{
210243
LOG::LogF(LOGERROR, "The stream is encrypted with a DRM not supported by this system");
@@ -213,34 +246,35 @@ bool DRM::CDRMEngine::InitializeSession(std::vector<DRM::DRMInfo> drmInfos,
213246
}
214247

215248
// Find a compatible DRM info
216-
auto itDrmInfo = std::find_if(drmInfos.begin(), drmInfos.end(), [&](const DRMInfo& info) {
217-
return info.keySystem == m_keySystem;});
249+
auto pDrmInfo = GetDRMInfoByKS(drmInfos, m_keySystem);
218250

219-
if (itDrmInfo == drmInfos.end()) // Should not happens
251+
if (!pDrmInfo)
220252
{
221253
LOG::LogF(LOGERROR, "The Key System \"%s\" does not match any DRMInfo", m_keySystem.c_str());
222254
m_status = EngineStatus::DRM_NOT_SUPPORTED;
223255
return false;
224256
}
225257

226-
DRM::DRMInfo& drmInfo = *itDrmInfo;
227-
const auto drmPropCfg = CSrvBroker::GetKodiProps().GetDrmConfig(drmInfo.keySystem);
258+
DRM::DRMInfo& drmInfo = *pDrmInfo;
259+
const auto drmPropCfg = kodiProps.GetDrmConfig(m_keySystem);
228260

229261
// Set custom init data PSSH provided from property,
230262
// can allow to initialize a DRM that could be also not specified
231263
// as supported in the manifest (e.g. missing DASH ContentProtection tags)
232-
if (!drmPropCfg.initData.empty())
264+
if (!drmPropCfg.initData.empty() || isPRtoWVKeySystem)
233265
{
234266
drmInfo.initData.clear();
235-
LOG::Log(LOGDEBUG, "Custom init PSSH provided by the \"license\" property");
267+
236268
std::vector<uint8_t> customInitData = BASE64::Decode(drmPropCfg.initData);
237269

238270
if (DRM::IsValidPsshHeader(customInitData))
239271
{
272+
LOG::Log(LOGDEBUG, "Use custom init PSSH provided by the \"license\" property");
240273
drmInfo.initData = customInitData;
241274
}
242275
else if (m_keySystem == DRM::KS_WIDEVINE) // Try to create a PSSH box, KID should be provided by manifest
243276
{
277+
LOG::Log(LOGDEBUG, "Make a Widevine init PSSH to replace PlayReady init data");
244278
drmInfo.initData =
245279
DRM::PSSH::MakeWidevine({DRM::ConvertKidStrToBytes(drmInfo.defaultKid)}, customInitData);
246280
}
@@ -513,14 +547,10 @@ bool DRM::CDRMEngine::SelectDRM(std::vector<DRM::DRMInfo>& drmInfos)
513547
// the lower index have the higher priority
514548
for (const std::string& ks : m_supportedKs)
515549
{
516-
auto itDrmInfo = std::find_if(drmInfos.begin(), drmInfos.end(), [&](const DRMInfo& info)
517-
{ return info.keySystem == ks || info.keySystem.empty(); });
550+
const DRM::DRMInfo* drmInfo = GetDRMInfoByKS(drmInfos, ks);
518551

519-
if (itDrmInfo != drmInfos.end())
552+
if (drmInfo)
520553
{
521-
if (itDrmInfo->keySystem.empty())
522-
itDrmInfo->keySystem = ks;
523-
524554
m_keySystem = ks;
525555
break;
526556
}
@@ -637,6 +667,11 @@ void DRM::CDRMEngine::DeleteSessionsByType(const DRMMediaType mediaType)
637667
m_sessions.end());
638668
}
639669

670+
bool DRM::CDRMEngine::HasKeySystemSupport(std::string_view keySystem) const
671+
{
672+
return std::find(m_supportedKs.cbegin(), m_supportedKs.cend(), keySystem) != m_supportedKs.cend();
673+
}
674+
640675
void DRM::CDRMEngine::Dispose()
641676
{
642677
LOG::Log(LOGDEBUG, "Dispose DRM Engine");

src/decrypters/DrmEngine.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ class ATTR_DLL_LOCAL CDRMEngine
108108
// \brief Delete all sessions by media type
109109
void DeleteSessionsByType(const DRMMediaType type);
110110

111+
// \brief Check if a Key System is supported
112+
bool HasKeySystemSupport(std::string_view keySystem) const;
113+
111114
std::vector<std::string> m_supportedKs; // Supported key systems, the lower index has higher priority
112115
std::string m_keySystem; // Choosen key system
113116
std::map<std::string, std::shared_ptr<DRM::IDecrypter>> m_drms; // KeySystem - DRM instance

0 commit comments

Comments
 (0)