Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
2 changes: 1 addition & 1 deletion drm/ocdm/OcdmGstSessionAdapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<GstProtectionMeta*>(gst_buffer_get_protection_meta(buffer));

Expand Down
27 changes: 26 additions & 1 deletion externals/rdk/IIarm/DeviceIARMInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ Remove the entire folder externals/rdk/IARM
#include <libIARM.h>
#include <libIBus.h>
#include <iarmUtil.h>
#include <thread>
#include "libIBusDaemon.h"
#include <hostIf_tr69ReqHandler.h>
#include "tr181api.h"
#include "_base64.h"
#ifdef USE_PREINIT_DECODING
#include "power_controller.h"
#include <thread>
#include <system_error> // for std::system_error
#include <exception> // for std::exception base class
#endif
Expand Down Expand Up @@ -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<PlayerExternalsRdkInterface> 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))
Expand Down Expand Up @@ -415,6 +427,12 @@ static void HDMIEventHandler(const char *owner, IARM_EventId_t eventId, void *da
{
std::shared_ptr<PlayerExternalsRdkInterface> 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 :
Expand All @@ -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 :
Expand All @@ -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:
Expand Down
6 changes: 6 additions & 0 deletions externals/rdk/PlayerExternalsRdkInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,11 @@ void PlayerExternalsRdkInterface::SetResolution(int width, int height)
*/
void PlayerExternalsRdkInterface::SetHDMIStatus()
{
std::unique_lock<std::mutex> 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;
Expand Down Expand Up @@ -306,6 +311,7 @@ void PlayerExternalsRdkInterface::SetHDMIStatus()
}
catch (...) {
MW_LOG_WARN("DeviceSettings unknown exception caught\n");
try { device::Manager::DeInitialize(); } catch (...) {}
}

m_isHDCPEnabled = isHDCPEnabled;
Expand Down
3 changes: 2 additions & 1 deletion externals/rdk/PlayerExternalsRdkInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@

#include <memory>
#include "PlayerExternalsInterfaceBase.h"

#include <mutex>
/*
IARM Deprecation Note:
IARM is to be deprecated in favor of DeviceSettings and Firebolt Device API.
Expand All @@ -63,6 +63,7 @@ class PlayerExternalsRdkInterface : public PlayerExternalsInterfaceBase
, public device::Host::IVideoOutputPortEvents
#endif
{
std::mutex m_hdmiStatusMutex;
enum InitState{
NOT_INITIALIZED,
FIREBOLT,
Expand Down
28 changes: 25 additions & 3 deletions gst-plugins/drm/gst/gstcdmidecryptor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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,
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions gst-plugins/drm/gst/gstcdmidecryptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ struct _GstCDMIDecryptor

GMutex mutex;
GCond condition;
GCond sinkCapsCond;

GstEvent* protectionEvent;
const gchar* selectedProtection;
Expand Down
Loading