@@ -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
213254void 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
9561005bool 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,
0 commit comments