From b7d0a80c562eb6aec4d3cf01e445ac21f1dc28f3 Mon Sep 17 00:00:00 2001 From: shripadbpersonal <105402691+shripadbpersonal@users.noreply.github.com> Date: Wed, 19 Nov 2025 12:05:33 -0500 Subject: [PATCH 1/8] Update AAMP-UVE-API.md --- jsbindings/jsbindings.cpp | 4 ++-- jsbindings/jsmediaplayer.cpp | 2 +- main_aamp.cpp | 16 +++++++++++++--- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/jsbindings/jsbindings.cpp b/jsbindings/jsbindings.cpp index 3a7ceb79d..ff75b4f09 100644 --- a/jsbindings/jsbindings.cpp +++ b/jsbindings/jsbindings.cpp @@ -4439,7 +4439,7 @@ static void AAMP_finalize(JSObjectRef thisObject) { //when finalizing JS object, don't generate state change events LOG_WARN(pAAMP," aamp->Stop(false)"); - _allocated_aamp->Stop(false); + _allocated_aamp->Stop(false, true); // sendStateChangeEvent=false, forceCleanup=true LOG_WARN(pAAMP,"delete aamp %p",_allocated_aamp); SAFE_DELETE(_allocated_aamp); } @@ -4831,7 +4831,7 @@ void __attribute__ ((destructor(101))) _aamp_term() { LOG_WARN_EX("stopping aamp"); //when finalizing JS object, don't generate state change events - _allocated_aamp->Stop(false); + _allocated_aamp->Stop(false, true); // sendStateChangeEvent=false, forceCleanup=true LOG_WARN_EX("stopped aamp"); delete _allocated_aamp; _allocated_aamp = NULL; diff --git a/jsbindings/jsmediaplayer.cpp b/jsbindings/jsmediaplayer.cpp index b18900d87..193f4d3f2 100644 --- a/jsbindings/jsmediaplayer.cpp +++ b/jsbindings/jsmediaplayer.cpp @@ -310,7 +310,7 @@ static void releaseNativeResources(AAMPMediaPlayer_JS *privObj) { //when finalizing JS object, don't generate state change events LOG_WARN(privObj," aamp->Stop(false)"); - privObj->_aamp->Stop(false); + privObj->_aamp->Stop(false, true); // sendStateChangeEvent=false, forceCleanup=true privObj->clearCallbackForAllAdIds(); if (privObj->_listeners.size() > 0) { diff --git a/main_aamp.cpp b/main_aamp.cpp index 36aa34195..bc6cc7784 100755 --- a/main_aamp.cpp +++ b/main_aamp.cpp @@ -35,6 +35,7 @@ #include "PlayerLogManager.h" #include "PlayerMetadata.hpp" #include "PlayerLogManager.h" +#include "AampDRMLicManager.h" #include #include @@ -353,7 +354,7 @@ void PlayerInstanceAAMP::TuneInternal(const char *mainManifestUrl, if ((state != eSTATE_IDLE) && (state != eSTATE_RELEASED) && (!IsOTAtoOTA)) { //Calling tune without closing previous tune - StopInternal(false); + StopInternal(false, false); } aamp->getAampCacheHandler()->StartPlaylistCache(); aamp->Tune(mainManifestUrl, autoPlay, contentType, bFirstAttempt, bFinalAttempt, traceUUID, audioDecoderStreamSync, refreshManifestUrl, mpdStitchingMode, std::move(sid),manifestData); @@ -3063,8 +3064,17 @@ void PlayerInstanceAAMP::StopInternal(bool sendStateChangeEvent) { aamp->TuneFail(true); } - AAMPLOG_MIL("aamp_stop PlayerState=%d",state); - aamp->Stop(); + AAMPLOG_MIL("aamp_stop PlayerState=%d forceCleanup=%d", state, forceCleanup); + + // Enhanced DRM cleanup for Deep Sleep scenarios + if (forceCleanup && aamp->mDRMLicenseManager) + { + AAMPLOG_WARN("Force cleanup: Clearing DRM sessions and failed key IDs for Deep Sleep"); + aamp->mDRMLicenseManager->clearDrmSession(true); + aamp->mDRMLicenseManager->clearFailedKeyIds(); + } + // Negate sendStateChangeEvent since no need to send state change event on Destrcutor call + aamp->Stop(!sendStateChangeEvent); // Revert all custom specific setting, tune specific setting and stream specific setting , back to App/default setting mConfig.RestoreConfiguration(AAMP_CUSTOM_DEV_CFG_SETTING); mConfig.RestoreConfiguration(AAMP_TUNE_SETTING); From 5384f8a63f2418348c00a1b345a9509acb7c254c Mon Sep 17 00:00:00 2001 From: shripad bankar Date: Wed, 19 Nov 2025 11:40:24 -0500 Subject: [PATCH 2/8] VPLAY-11809 : Enhance UveAAMP stop() API with DRM handle cleanup parameter to prevent Deep Sleep playback failures Reason for change: Linear and VOD playback fails after devices come out of Deep Sleep state due to stale DRM handles that are not properly released before entering Deep Sleep mode. The current stop() implementation does not provide a mechanism to force DRM handle cleanup, leading to tune failures with stale DRM sessions after device wake-up. Changes done: - Enhanced PlayerInstanceAAMP::Stop() API with optional forceCleanup parameter (default false) - Added DRM session cleanup logic using licenseManager->clearDrmSession(forceClearSession) and clearFailedKeyIds() - Updated JavaScript bindings to support both single parameter stop(forceCleanup) and two parameter stop(sendStateChangeEvent, forceCleanup) forms - Modified jsmediaplayer.cpp to handle argument parsing for backward compatibility - Updated UVE API documentation with usage examples for Deep Sleep scenarios - Enhanced mock files and test infrastructure to maintain compatibility - Added comprehensive logging for debugging Deep Sleep DRM cleanup operations This allows applications to call player.stop(true) before Deep Sleep to proactively clean up DRM resources and prevent playback failures after wake-up. Test Procedure: Priority: P2 Risks:Low --- AAMP-UVE-API.md | 26 +++++++++++++++++--- jsbindings/jsmediaplayer.cpp | 26 +++++++++++++++++--- main_aamp.cpp | 6 ++--- main_aamp.h | 6 +++-- test/utests/fakes/FakePlayerInstanceAamp.cpp | 2 +- test/utests/mocks/MockPrivateInstanceAAMP.h | 2 +- 6 files changed, 55 insertions(+), 13 deletions(-) diff --git a/AAMP-UVE-API.md b/AAMP-UVE-API.md index 8fa2c7999..66dbf3799 100644 --- a/AAMP-UVE-API.md +++ b/AAMP-UVE-API.md @@ -396,15 +396,34 @@ Note: starting in RDK 6.9, we support ability to start video paused on first fra --- -### stop() +### stop( forceCleanup ) +### stop( sendStateChangeEvent, forceCleanup ) - Supported UVE version 0.7 and above. - Stop playback and free resources associated with playback. -Usage example: + +**Single Parameter Form:** +|Name|Type|Description| +|----|----|-----------| +| forceCleanup | Boolean | Optional parameter. If True, forces DRM handle cleanup for Deep Sleep scenarios. Default is false. Prevents playback failures after device wake-up from Deep Sleep by clearing stale DRM sessions and failed key IDs. | + +**Two Parameter Form (Advanced Usage):** +|Name|Type|Description| +|----|----|-----------| +| sendStateChangeEvent | Boolean | If True, sends state change events during stop operation. Default is true. | +| forceCleanup | Boolean | If True, forces DRM handle cleanup for Deep Sleep scenarios. Default is false. | + +Usage examples: ```js { ..... - // for immediate stop of playback + // Standard stop - sends state change events player.stop(); + + // Stop with DRM cleanup before Deep Sleep + player.stop(true); + + // Advanced: Stop without state events, with DRM cleanup + player.stop(false, true); } ``` --- @@ -2527,6 +2546,7 @@ A subset of UVE APIs and Events are available when using UVE JS APIs for ATSC pl ##### stop - Stop playback and free resources +- Optional forceCleanup parameter for DRM cleanup in Deep Sleep scenarios ##### getAudioTrack - Get the index of the currently selected Audio track diff --git a/jsbindings/jsmediaplayer.cpp b/jsbindings/jsmediaplayer.cpp index 193f4d3f2..d0d259883 100644 --- a/jsbindings/jsmediaplayer.cpp +++ b/jsbindings/jsmediaplayer.cpp @@ -839,7 +839,7 @@ JSValueRef AAMPMediaPlayerJS_pause (JSContextRef ctx, JSObjectRef function, JSOb * @param[in] function JSObject that is the function being called * @param[in] thisObject JSObject that is the 'this' variable in the function's scope * @param[in] argumentCount number of args - * @param[in] arguments[] JSValue array of args + * @param[in] arguments[] JSValue array of args - Optional forceCleanup boolean parameter * @param[out] exception pointer to a JSValueRef in which to return an exception, if any * @retval JSValue that is the function's return value */ @@ -853,8 +853,28 @@ JSValueRef AAMPMediaPlayerJS_stop (JSContextRef ctx, JSObjectRef function, JSObj *exception = aamp_GetException(ctx, AAMPJS_MISSING_OBJECT, "Can only call stop() on instances of AAMPPlayer"); return JSValueMakeUndefined(ctx); } - LOG_WARN(privObj," _aamp->Stop()"); - privObj->_aamp->Stop(); + + bool sendStateChangeEvent = true; // Default for user-initiated stop + bool forceCleanup = false; + + if (argumentCount >= 1) + { + // For backward compatibility and UVE API design: + // - If 1 argument: treat as forceCleanup (boolean) + // - If 2 arguments: treat as (sendStateChangeEvent, forceCleanup) + if (argumentCount == 1) + { + forceCleanup = JSValueToBoolean(ctx, arguments[0]); + } + else if (argumentCount >= 2) + { + sendStateChangeEvent = JSValueToBoolean(ctx, arguments[0]); + forceCleanup = JSValueToBoolean(ctx, arguments[1]); + } + } + + LOG_WARN(privObj," _aamp->Stop() sendStateChangeEvent=%d forceCleanup=%d", sendStateChangeEvent, forceCleanup); + privObj->_aamp->Stop(sendStateChangeEvent, forceCleanup); LOG_TRACE("Exit"); return JSValueMakeUndefined(ctx); } diff --git a/main_aamp.cpp b/main_aamp.cpp index bc6cc7784..909f0f3e4 100755 --- a/main_aamp.cpp +++ b/main_aamp.cpp @@ -240,7 +240,7 @@ void PlayerInstanceAAMP::ResetConfiguration() /** * @brief Stop playback and release resources. */ -void PlayerInstanceAAMP::Stop(bool sendStateChangeEvent) +void PlayerInstanceAAMP::Stop(bool sendStateChangeEvent, bool forceCleanup) { if (aamp) { @@ -257,7 +257,7 @@ void PlayerInstanceAAMP::Stop(bool sendStateChangeEvent) //state will be eSTATE_IDLE or eSTATE_RELEASED, right after an init or post-processing of a Stop call if (state != eSTATE_IDLE && state != eSTATE_RELEASED) { - StopInternal(sendStateChangeEvent); + StopInternal(sendStateChangeEvent, forceCleanup); } //Release lock @@ -3056,7 +3056,7 @@ void PlayerInstanceAAMP::PersistBitRateOverSeek(bool bValue) /** * @brief Stop playback and release resources. */ -void PlayerInstanceAAMP::StopInternal(bool sendStateChangeEvent) +void PlayerInstanceAAMP::StopInternal(bool sendStateChangeEvent, bool forceCleanup) { aamp->StopPausePositionMonitoring("Stop() called"); AAMPPlayerState state = aamp->GetState(); diff --git a/main_aamp.h b/main_aamp.h index 18526373d..ff7d5191f 100644 --- a/main_aamp.h +++ b/main_aamp.h @@ -150,9 +150,10 @@ class PlayerInstanceAAMP /** * @brief Stop playback and release resources. * @param[in] sendStateChangeEvent - true if state change events need to be sent for Stop operation + * @param[in] forceCleanup - true to force DRM handle cleanup for Deep Sleep scenarios (default false) * @return void */ - void Stop(bool sendStateChangeEvent = true); + void Stop(bool sendStateChangeEvent = true, bool forceCleanup = false); /** * @fn ResetConfiguration @@ -1472,9 +1473,10 @@ class PlayerInstanceAAMP * @fn StopInternal * * @param[in] sendStateChangeEvent - true if state change events need to be sent for Stop operation + * @param[in] forceCleanup - true to force DRM handle cleanup for Deep Sleep scenarios * @return void */ - void StopInternal(bool sendStateChangeEvent); + void StopInternal(bool sendStateChangeEvent, bool forceCleanup); void* mJSBinding_DL; /**< Handle to AAMP plugin dynamic lib. */ static std::mutex mPrvAampMtx; /**< Mutex to protect aamp instance in GetState() */ diff --git a/test/utests/fakes/FakePlayerInstanceAamp.cpp b/test/utests/fakes/FakePlayerInstanceAamp.cpp index a867f95fb..56da0a5af 100644 --- a/test/utests/fakes/FakePlayerInstanceAamp.cpp +++ b/test/utests/fakes/FakePlayerInstanceAamp.cpp @@ -51,7 +51,7 @@ const std::vector & PlayerInstanceAAMP::GetTimedMetadata( void ) std::string session_id, const char *preprocessedManifest ) { } - void PlayerInstanceAAMP::Stop(bool sendStateChangeEvent) { } + void PlayerInstanceAAMP::Stop(bool sendStateChangeEvent, bool forceCleanup) { } void PlayerInstanceAAMP::ResetConfiguration() { } void PlayerInstanceAAMP::SetRate(float rate, int overshootcorrection) { } void PlayerInstanceAAMP::PauseAt(double position) { } diff --git a/test/utests/mocks/MockPrivateInstanceAAMP.h b/test/utests/mocks/MockPrivateInstanceAAMP.h index b9fce5102..df2e91f7e 100644 --- a/test/utests/mocks/MockPrivateInstanceAAMP.h +++ b/test/utests/mocks/MockPrivateInstanceAAMP.h @@ -28,7 +28,7 @@ class MockPrivateInstanceAAMP public: MOCK_METHOD(double, RecalculatePTS, (AampMediaType mediaType, const void *ptr, size_t len)); - MOCK_METHOD(void, Stop, (bool sendStateChangeEvent)); + MOCK_METHOD(void, Stop, (bool sendStateChangeEvent, bool forceCleanup)); MOCK_METHOD(void, StartPausePositionMonitoring, (long long pausePositionMilliseconds)); From 25ea52dd9c2ad0a8528c0a713bf4fc0173c17faf Mon Sep 17 00:00:00 2001 From: shripadbpersonal <105402691+shripadbpersonal@users.noreply.github.com> Date: Wed, 19 Nov 2025 12:05:33 -0500 Subject: [PATCH 3/8] Update AAMP-UVE-API.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- AAMP-UVE-API.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/AAMP-UVE-API.md b/AAMP-UVE-API.md index 66dbf3799..34ed71f09 100644 --- a/AAMP-UVE-API.md +++ b/AAMP-UVE-API.md @@ -402,13 +402,13 @@ Note: starting in RDK 6.9, we support ability to start video paused on first fra - Stop playback and free resources associated with playback. **Single Parameter Form:** -|Name|Type|Description| -|----|----|-----------| +| Name | Type | Description | +| ---- | ---- | ----------- | | forceCleanup | Boolean | Optional parameter. If True, forces DRM handle cleanup for Deep Sleep scenarios. Default is false. Prevents playback failures after device wake-up from Deep Sleep by clearing stale DRM sessions and failed key IDs. | **Two Parameter Form (Advanced Usage):** -|Name|Type|Description| -|----|----|-----------| +| Name | Type | Description | +| ---- | ---- | ----------- | | sendStateChangeEvent | Boolean | If True, sends state change events during stop operation. Default is true. | | forceCleanup | Boolean | If True, forces DRM handle cleanup for Deep Sleep scenarios. Default is false. | From 16006af73e45fc643e5e4e019871b53d94f7d7cf Mon Sep 17 00:00:00 2001 From: shripadbpersonal <105402691+shripadbpersonal@users.noreply.github.com> Date: Wed, 19 Nov 2025 12:05:33 -0500 Subject: [PATCH 4/8] Update AAMP-UVE-API.md --- jsbindings/jsmediaplayer.cpp | 2 +- main_aamp.cpp | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/jsbindings/jsmediaplayer.cpp b/jsbindings/jsmediaplayer.cpp index d0d259883..a2dfb84da 100644 --- a/jsbindings/jsmediaplayer.cpp +++ b/jsbindings/jsmediaplayer.cpp @@ -854,7 +854,7 @@ JSValueRef AAMPMediaPlayerJS_stop (JSContextRef ctx, JSObjectRef function, JSObj return JSValueMakeUndefined(ctx); } - bool sendStateChangeEvent = true; // Default for user-initiated stop + bool sendStateChangeEvent = false; // Default for user-initiated stop bool forceCleanup = false; if (argumentCount >= 1) diff --git a/main_aamp.cpp b/main_aamp.cpp index 909f0f3e4..d0f6c4bdb 100755 --- a/main_aamp.cpp +++ b/main_aamp.cpp @@ -3066,15 +3066,19 @@ void PlayerInstanceAAMP::StopInternal(bool sendStateChangeEvent, bool forceClean } AAMPLOG_MIL("aamp_stop PlayerState=%d forceCleanup=%d", state, forceCleanup); + // Negate sendStateChangeEvent since no need to send state change event on Destrcutor call + aamp->Stop(!sendStateChangeEvent); + // Enhanced DRM cleanup for Deep Sleep scenarios + // Must be done AFTER Stop() to ensure GStreamer pipeline is torn down + // and all encrypted buffers are flushed before destroying DRM sessions if (forceCleanup && aamp->mDRMLicenseManager) { AAMPLOG_WARN("Force cleanup: Clearing DRM sessions and failed key IDs for Deep Sleep"); aamp->mDRMLicenseManager->clearDrmSession(true); aamp->mDRMLicenseManager->clearFailedKeyIds(); } - // Negate sendStateChangeEvent since no need to send state change event on Destrcutor call - aamp->Stop(!sendStateChangeEvent); + // Revert all custom specific setting, tune specific setting and stream specific setting , back to App/default setting mConfig.RestoreConfiguration(AAMP_CUSTOM_DEV_CFG_SETTING); mConfig.RestoreConfiguration(AAMP_TUNE_SETTING); From f9931495273546e5c231c5736505fd76b68c2c4a Mon Sep 17 00:00:00 2001 From: shripadbpersonal <105402691+shripadbpersonal@users.noreply.github.com> Date: Wed, 19 Nov 2025 12:05:33 -0500 Subject: [PATCH 5/8] Update AAMP-UVE-API.md --- jsbindings/jsmediaplayer.cpp | 6 ++++-- main_aamp.cpp | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/jsbindings/jsmediaplayer.cpp b/jsbindings/jsmediaplayer.cpp index a2dfb84da..a33fa406f 100644 --- a/jsbindings/jsmediaplayer.cpp +++ b/jsbindings/jsmediaplayer.cpp @@ -854,8 +854,8 @@ JSValueRef AAMPMediaPlayerJS_stop (JSContextRef ctx, JSObjectRef function, JSObj return JSValueMakeUndefined(ctx); } - bool sendStateChangeEvent = false; // Default for user-initiated stop - bool forceCleanup = false; + bool sendStateChangeEvent = true; // Default: send state change events + bool forceCleanup = false; // Default: no DRM cleanup if (argumentCount >= 1) { @@ -864,10 +864,12 @@ JSValueRef AAMPMediaPlayerJS_stop (JSContextRef ctx, JSObjectRef function, JSObj // - If 2 arguments: treat as (sendStateChangeEvent, forceCleanup) if (argumentCount == 1) { + // stop(forceCleanup) - send events by default, cleanup based on argument forceCleanup = JSValueToBoolean(ctx, arguments[0]); } else if (argumentCount >= 2) { + // stop(sendStateChangeEvent, forceCleanup) - both explicit sendStateChangeEvent = JSValueToBoolean(ctx, arguments[0]); forceCleanup = JSValueToBoolean(ctx, arguments[1]); } diff --git a/main_aamp.cpp b/main_aamp.cpp index d0f6c4bdb..7ef933d45 100755 --- a/main_aamp.cpp +++ b/main_aamp.cpp @@ -188,7 +188,7 @@ PlayerInstanceAAMP::~PlayerInstanceAAMP() mScheduler.RemoveAllTasks(); if (state != eSTATE_IDLE && state != eSTATE_RELEASED) { - aamp->Stop( true ); + aamp->Stop(false); // Don't send state change events during destruction } std::lock_guard lock (mPrvAampMtx); aamp = NULL; @@ -354,7 +354,7 @@ void PlayerInstanceAAMP::TuneInternal(const char *mainManifestUrl, if ((state != eSTATE_IDLE) && (state != eSTATE_RELEASED) && (!IsOTAtoOTA)) { //Calling tune without closing previous tune - StopInternal(false, false); + StopInternal(true, false); } aamp->getAampCacheHandler()->StartPlaylistCache(); aamp->Tune(mainManifestUrl, autoPlay, contentType, bFirstAttempt, bFinalAttempt, traceUUID, audioDecoderStreamSync, refreshManifestUrl, mpdStitchingMode, std::move(sid),manifestData); From 37338596b146378d48087c36d61936174528ecca Mon Sep 17 00:00:00 2001 From: haripriya_molakalapalli Date: Tue, 2 Dec 2025 16:20:38 -0500 Subject: [PATCH 6/8] Call Stop with forceCleanup for clearing DRM session when setRateis invoked with magic number --- jsbindings/jsmediaplayer.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/jsbindings/jsmediaplayer.cpp b/jsbindings/jsmediaplayer.cpp index a33fa406f..ba50b0371 100644 --- a/jsbindings/jsmediaplayer.cpp +++ b/jsbindings/jsmediaplayer.cpp @@ -1987,6 +1987,17 @@ JSValueRef AAMPMediaPlayerJS_setPlaybackRate (JSContextRef ctx, JSObjectRef func { overshootCorrection = (int) JSValueToNumber(ctx, arguments[1], exception); } + // special magic playback rate triggers a forced DRM cleanup stop + // App can call: Stop(); SetRate(); SetRate(magic) + // When magic number is passed, invoke Stop without state events and force DRM cleanup + const float kForceCleanupMagicRate = 76234.0; // Magic number for triggering forced cleanup stop + if (rate == kForceCleanupMagicRate) + { + LOG_WARN(privObj,"Magic rate %.0f received - invoking Stop(sendStateChangeEvent=false, forceCleanup=true)", kForceCleanupMagicRate); + privObj->_aamp->Stop(false /*sendStateChangeEvent*/, true /*forceCleanup*/); + bRet = true; + } + else { LOG_WARN(privObj,"_aamp->SetRate(%f, %d)", rate, overshootCorrection); privObj->_aamp->SetRate(rate, overshootCorrection); From 888a26c2ab67c3d1441fbf826069b0717d9b8b5e Mon Sep 17 00:00:00 2001 From: haripriya_molakalapalli Date: Tue, 2 Dec 2025 16:20:38 -0500 Subject: [PATCH 7/8] Follow up commit - Cleanup triggered: Stop() and Destroy() called back-to-back; Stop() invoked without arguments and as part of Destroy/Release internal call to stop releases all the DRM resources --- main_aamp.cpp | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/main_aamp.cpp b/main_aamp.cpp index 7ef933d45..85da47bce 100755 --- a/main_aamp.cpp +++ b/main_aamp.cpp @@ -259,7 +259,15 @@ void PlayerInstanceAAMP::Stop(bool sendStateChangeEvent, bool forceCleanup) { StopInternal(sendStateChangeEvent, forceCleanup); } - + // Enhanced DRM cleanup for Deep Sleep scenarios + // Must be done AFTER Stop() to ensure GStreamer pipeline is torn down + // and all encrypted buffers are flushed before destroying DRM sessions + if (forceCleanup && aamp->mDRMLicenseManager) + { + AAMPLOG_WARN("Force cleanup: Clearing DRM sessions and failed key IDs for Deep Sleep"); + aamp->mDRMLicenseManager->clearDrmSession(true); + aamp->mDRMLicenseManager->clearFailedKeyIds(); + } //Release lock mScheduler.ResumeScheduler(); } @@ -3068,17 +3076,7 @@ void PlayerInstanceAAMP::StopInternal(bool sendStateChangeEvent, bool forceClean // Negate sendStateChangeEvent since no need to send state change event on Destrcutor call aamp->Stop(!sendStateChangeEvent); - - // Enhanced DRM cleanup for Deep Sleep scenarios - // Must be done AFTER Stop() to ensure GStreamer pipeline is torn down - // and all encrypted buffers are flushed before destroying DRM sessions - if (forceCleanup && aamp->mDRMLicenseManager) - { - AAMPLOG_WARN("Force cleanup: Clearing DRM sessions and failed key IDs for Deep Sleep"); - aamp->mDRMLicenseManager->clearDrmSession(true); - aamp->mDRMLicenseManager->clearFailedKeyIds(); - } - + // Revert all custom specific setting, tune specific setting and stream specific setting , back to App/default setting mConfig.RestoreConfiguration(AAMP_CUSTOM_DEV_CFG_SETTING); mConfig.RestoreConfiguration(AAMP_TUNE_SETTING); From 823d4b49cfa168d0254b8b2e97d0d8bbafaa2776 Mon Sep 17 00:00:00 2001 From: haripriya_molakalapalli Date: Tue, 2 Dec 2025 16:20:38 -0500 Subject: [PATCH 8/8] Follow up commit - Cleanup triggered: Stop() and Destroy() called back-to-back; Stop() invoked without arguments and as part of Destroy/Release internal call to stop releases all the DRM resources --- main_aamp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main_aamp.cpp b/main_aamp.cpp index 85da47bce..b87dcfa2f 100755 --- a/main_aamp.cpp +++ b/main_aamp.cpp @@ -3074,7 +3074,7 @@ void PlayerInstanceAAMP::StopInternal(bool sendStateChangeEvent, bool forceClean } AAMPLOG_MIL("aamp_stop PlayerState=%d forceCleanup=%d", state, forceCleanup); - // Negate sendStateChangeEvent since no need to send state change event on Destrcutor call + // Negate sendStateChangeEvent since no need to send state change event on destructor call aamp->Stop(!sendStateChangeEvent); // Revert all custom specific setting, tune specific setting and stream specific setting , back to App/default setting