diff --git a/CHANGELOG.md b/CHANGELOG.md index 40b650d2..a8b32c34 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,12 +4,22 @@ All notable changes to this project will be documented in this file. Dates are d Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). +#### [0.2.0-r1](https://github.com/rdkcentral/middleware-player-interface/compare/0.2.0...0.2.0-r1) + +- RDKEMW-20220: Fix for the crash in "WPEWebProcess" during Deepsleep scenario [`#182`](https://github.com/rdkcentral/middleware-player-interface/pull/182) +- RDKEMW-20330: [Glass G1 UK -R40.23][Dhruv -40.11]observed "com.comcast.viper" crash on VIPA enabled devices contributing BERR/TECHFAULTOTT with fingerprint 61111371 [`#181`](https://github.com/rdkcentral/middleware-player-interface/pull/181) +- DELIA-70524: [Glass G1 UK -R40.23][Dhruv -40.11]observed "com.comcast.viper" crash on VIPA enabled devices contributing BERR/TECHFAULTOTT with fingerprint 61111371 [`#178`](https://github.com/rdkcentral/middleware-player-interface/pull/178) +- RDKEMW-20220: Fix for WPEWebProcess during deepsleep wakeup scenario [`616383b`](https://github.com/rdkcentral/middleware-player-interface/commit/616383bb39b8bfd896e28d8d504d8309350774de) +- Merge tag '0.2.0' into develop [`60bcc11`](https://github.com/rdkcentral/middleware-player-interface/commit/60bcc117beea5723aa8f58bfd112a13229069fff) + #### [0.2.0](https://github.com/rdkcentral/middleware-player-interface/compare/0.1.4...0.2.0) +> 12 June 2026 + - RDKEMW-19686 [Develop]Bringing RKDEMW-19683 , RDKEMW-19684, RDKEMW-19685 to middleware-player-interface [`#170`](https://github.com/rdkcentral/middleware-player-interface/pull/170) - Revert "VPAAMP-457 middleware changes" [`da9157e`](https://github.com/rdkcentral/middleware-player-interface/commit/da9157e565ce0ff78a87c893a4246f08476b61ed) +- RDKEMW-19921 - Changelog updates for 0.2.0 [`4b31316`](https://github.com/rdkcentral/middleware-player-interface/commit/4b3131614ff920a7d46219cdf07b5b816c80b760) - Merge tag '0.1.4' into develop [`7c07f2a`](https://github.com/rdkcentral/middleware-player-interface/commit/7c07f2a7f9e30f5699c86baa3d8f2709612f4dbc) -- dev_sprint_pli sync [`5537418`](https://github.com/rdkcentral/middleware-player-interface/commit/5537418a13f5ff3fecad2d89d79a9fdea76878d9) #### [0.1.4](https://github.com/rdkcentral/middleware-player-interface/compare/0.1.3...0.1.4) diff --git a/drm/ocdm/OcdmGstSessionAdapter.cpp b/drm/ocdm/OcdmGstSessionAdapter.cpp index f05993ed..999b1698 100755 --- a/drm/ocdm/OcdmGstSessionAdapter.cpp +++ b/drm/ocdm/OcdmGstSessionAdapter.cpp @@ -325,7 +325,7 @@ int OCDMGSTSessionAdapter::decrypt(GstBuffer *keyIDBuffer, GstBuffer *ivBuffer, /* Added GST_IS_CAPS check also before passing gst caps to OCDM decrypt() as gst_caps_is_empty returns false when caps object is not of type GST_TYPE_CAPS. This will avoid crash when caps is not of type GST_TYPE_CAPS. */ - if (OCDMGSTSessionDecrypt && !gst_caps_is_empty(caps) && GST_IS_CAPS(caps)) + if (OCDMGSTSessionDecrypt && caps != nullptr && GST_IS_CAPS(caps) && !gst_caps_is_empty(caps)) { GstProtectionMeta* protectionMeta = reinterpret_cast(gst_buffer_get_protection_meta(buffer)); diff --git a/externals/rdk/IIarm/DeviceIARMInterface.cpp b/externals/rdk/IIarm/DeviceIARMInterface.cpp index 234e6a06..165da049 100644 --- a/externals/rdk/IIarm/DeviceIARMInterface.cpp +++ b/externals/rdk/IIarm/DeviceIARMInterface.cpp @@ -38,13 +38,13 @@ Remove the entire folder externals/rdk/IARM #include #include #include +#include #include "libIBusDaemon.h" #include #include "tr181api.h" #include "_base64.h" #ifdef USE_PREINIT_DECODING #include "power_controller.h" -#include #include // for std::system_error #include // for std::exception base class #endif @@ -244,6 +244,18 @@ static void IARM_PowerChangeHandler (const PowerController_PowerState_t currentS { MW_LOG_INFO("Entering IARM_PowerChangeHandler:State Changed currentState: %d, newState: %d", currentState, newState); + + + std::shared_ptr pInstance = + PlayerExternalsRdkInterface::GetPlayerExternalsRdkInterfaceInstance(); + if (newState != POWER_STATE_ON) { + pInstance->SetPowerEvent(true); + MW_LOG_INFO(" Power transition to non-ON state, blocking HDMI events\n"); + } else { + pInstance->SetPowerEvent(false); + MW_LOG_INFO(" Power transition to ON, allowing HDMI events\n"); + } + bool isOnOrStandby = (newState == POWER_STATE_STANDBY || newState == POWER_STATE_ON); if((currentState == POWER_STATE_STANDBY_DEEP_SLEEP && isOnOrStandby) || (prevState == POWER_STATE_STANDBY_DEEP_SLEEP && currentState == POWER_STATE_STANDBY_LIGHT_SLEEP && isOnOrStandby)) @@ -415,6 +427,12 @@ static void HDMIEventHandler(const char *owner, IARM_EventId_t eventId, void *da { std::shared_ptr pInstance = PlayerExternalsRdkInterface::GetPlayerExternalsRdkInterfaceInstance(); + + if (pInstance->GetPowerEvent()) + { + MW_LOG_WARN(" Skipping HDMI event processing during power transition\n"); + return; + } switch (eventId) { case IARM_BUS_DSMGR_EVENT_HDMI_HOTPLUG : @@ -428,6 +446,10 @@ static void HDMIEventHandler(const char *owner, IARM_EventId_t eventId, void *da pInstance->SetHDMIStatus(); + // Dispatch to detached worker thread — do NOT block IARM dispatch thread + std::thread([pInstance]() { + pInstance->SetHDMIStatus(); + }).detach(); break; } case IARM_BUS_DSMGR_EVENT_HDCP_STATUS : @@ -439,6 +461,9 @@ static void HDMIEventHandler(const char *owner, IARM_EventId_t eventId, void *da hdcpStatus, hdcpStatusStr); pInstance->SetHDMIStatus(); + std::thread([pInstance]() { + pInstance->SetHDMIStatus(); + }).detach(); break; } default: diff --git a/externals/rdk/PlayerExternalsRdkInterface.cpp b/externals/rdk/PlayerExternalsRdkInterface.cpp index 107f202b..1b015ca9 100644 --- a/externals/rdk/PlayerExternalsRdkInterface.cpp +++ b/externals/rdk/PlayerExternalsRdkInterface.cpp @@ -228,6 +228,11 @@ void PlayerExternalsRdkInterface::SetResolution(int width, int height) */ void PlayerExternalsRdkInterface::SetHDMIStatus() { + std::unique_lock lock(m_hdmiStatusMutex, std::try_to_lock); + if (!lock.owns_lock()) { + MW_LOG_WARN("SetHDMIStatus: Already in progress on another thread, skipping\n"); + return; + } bool isConnected = false; bool isHDCPCompliant = false; bool isHDCPEnabled = true; @@ -306,6 +311,7 @@ void PlayerExternalsRdkInterface::SetHDMIStatus() } catch (...) { MW_LOG_WARN("DeviceSettings unknown exception caught\n"); + try { device::Manager::DeInitialize(); } catch (...) {} } m_isHDCPEnabled = isHDCPEnabled; diff --git a/externals/rdk/PlayerExternalsRdkInterface.h b/externals/rdk/PlayerExternalsRdkInterface.h index 2f35e7bc..567020f7 100644 --- a/externals/rdk/PlayerExternalsRdkInterface.h +++ b/externals/rdk/PlayerExternalsRdkInterface.h @@ -36,7 +36,7 @@ #include #include "PlayerExternalsInterfaceBase.h" - +#include /* IARM Deprecation Note: IARM is to be deprecated in favor of DeviceSettings and Firebolt Device API. @@ -63,6 +63,7 @@ class PlayerExternalsRdkInterface : public PlayerExternalsInterfaceBase , public device::Host::IVideoOutputPortEvents #endif { + std::mutex m_hdmiStatusMutex; enum InitState{ NOT_INITIALIZED, FIREBOLT, diff --git a/gst-plugins/drm/gst/gstcdmidecryptor.cpp b/gst-plugins/drm/gst/gstcdmidecryptor.cpp index dad25fbd..4482a34c 100755 --- a/gst-plugins/drm/gst/gstcdmidecryptor.cpp +++ b/gst-plugins/drm/gst/gstcdmidecryptor.cpp @@ -219,6 +219,7 @@ static void gst_cdmidecryptor_init( g_mutex_init(&cdmidecryptor->mutex); //GST_DEBUG_OBJECT(cdmidecryptor, "\n Initialized plugin mutex\n"); g_cond_init(&cdmidecryptor->condition); + g_cond_init(&cdmidecryptor->sinkCapsCond); cdmidecryptor->streamReceived = false; // Lock access to protect shared state to keep Coverity happy g_mutex_lock(&cdmidecryptor->mutex); @@ -269,8 +270,9 @@ void gst_cdmidecryptor_dispose(GObject * object) cdmidecryptor->sinkCaps = NULL; } - g_mutex_clear(&cdmidecryptor->mutex); + g_cond_clear(&cdmidecryptor->sinkCapsCond); g_cond_clear(&cdmidecryptor->condition); + g_mutex_clear(&cdmidecryptor->mutex); G_OBJECT_CLASS(gst_cdmidecryptor_parent_class)->dispose(object); } @@ -467,6 +469,7 @@ gst_cdmidecryptor_transform_caps(GstBaseTransform * trans, cdmidecryptor->sinkCaps = NULL; } cdmidecryptor->sinkCaps = gst_caps_copy(transformedCaps); + g_cond_signal(&cdmidecryptor->sinkCapsCond); g_mutex_unlock(&cdmidecryptor->mutex); GST_DEBUG_OBJECT(trans, "Set sinkCaps to %" GST_PTR_FORMAT, cdmidecryptor->sinkCaps); } @@ -512,6 +515,19 @@ static GstFlowReturn gst_cdmidecryptor_transform_ip( g_mutex_lock(&cdmidecryptor->mutex); mutexLocked = TRUE; + + if (cdmidecryptor->sinkCaps == NULL && cdmidecryptor->streamReceived) { + // Caps negotiation hasn't completed yet - wait briefly + gint64 end_time = g_get_monotonic_time() + 500 * G_TIME_SPAN_MILLISECOND; + while (cdmidecryptor->sinkCaps == NULL) { + if (!g_cond_wait_until(&cdmidecryptor->sinkCapsCond, &cdmidecryptor->mutex, end_time)) { + GST_WARNING_OBJECT(cdmidecryptor, "Timeout waiting for sinkCaps"); + result = GST_FLOW_NOT_SUPPORTED; + goto free_resources; + } + } + } + if (!protectionMeta) { GST_DEBUG_OBJECT(cdmidecryptor, @@ -520,12 +536,12 @@ static GstFlowReturn gst_cdmidecryptor_transform_ip( { // call decrypt even for clear samples in order to copy it to a secure buffer. If secure buffers are not supported // decrypt() call will return without doing anything - if (cdmidecryptor->drmSession != NULL) + if (cdmidecryptor->drmSession != NULL && cdmidecryptor->sinkCaps != NULL) errorCode = cdmidecryptor->drmSession->decrypt(keyIDBuffer, ivBuffer, buffer, subSampleCount, subsamplesBuffer, cdmidecryptor->sinkCaps); else { /* If drmSession creation failed, then the call will be aborted here */ result = GST_FLOW_NOT_SUPPORTED; - GST_ERROR_OBJECT(cdmidecryptor, "drmSession is **** NULL ****, returning GST_FLOW_NOT_SUPPORTED"); + GST_ERROR_OBJECT(cdmidecryptor, "drmSession or sinkCaps is NULL, returning GST_FLOW_NOT_SUPPORTED"); } } goto free_resources; @@ -638,6 +654,12 @@ static GstFlowReturn gst_cdmidecryptor_transform_ip( } } + if (cdmidecryptor->sinkCaps == NULL) { + GST_WARNING_OBJECT(cdmidecryptor, "sinkCaps is NULL, skipping decrypt"); + result = GST_FLOW_NOT_SUPPORTED; + goto free_resources; + } + errorCode = cdmidecryptor->drmSession->decrypt(keyIDBuffer, ivBuffer, buffer, subSampleCount, subsamplesBuffer, cdmidecryptor->sinkCaps); cdmidecryptor->streamEncrypted = true; diff --git a/gst-plugins/drm/gst/gstcdmidecryptor.h b/gst-plugins/drm/gst/gstcdmidecryptor.h index aeaff207..2e2cc33d 100644 --- a/gst-plugins/drm/gst/gstcdmidecryptor.h +++ b/gst-plugins/drm/gst/gstcdmidecryptor.h @@ -55,6 +55,7 @@ struct _GstCDMIDecryptor GMutex mutex; GCond condition; + GCond sinkCapsCond; GstEvent* protectionEvent; const gchar* selectedProtection;