Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
ff6014a
RDKEMW-18059 : Notified the key status notification to player
varatharajan568 May 5, 2026
d881a95
RDKEMW-18059 : Removed the interface added to retrieve the key status
varatharajan568 May 5, 2026
aa7da6a
Update AampDRMLicManager.cpp
varatharajan568 May 5, 2026
aee6dc3
Update AampDRMLicManager.h
varatharajan568 May 5, 2026
11fd423
Removed the GetKeyStatus api from DRM
varatharajan568 May 5, 2026
1a14a3c
Update AampDRMLicManager.h
varatharajan568 May 6, 2026
0e42b88
Update Fakeopencdmsessionadapter.cpp
varatharajan568 May 6, 2026
c5f8f24
Update AampConfig.cpp
varatharajan568 May 6, 2026
75ad1cb
Update aampMocks.cpp
varatharajan568 May 6, 2026
ee95b90
Potential fix for pull request finding
varatharajan568 May 7, 2026
14d05bc
Update opencdmsessionadapter.cpp
varatharajan568 May 7, 2026
a0f2e06
Addressed review comment
varatharajan568 May 7, 2026
2a36017
Modified the player status enum name
varatharajan568 May 7, 2026
7b88cdf
Merge branch 'dev_sprint_25_2' into feature/RDKEMW-18059
varatharajan568 May 8, 2026
6bdf5e0
Update AampConfig.cpp
varatharajan568 May 8, 2026
4a1f6e1
Update opencdmsessionadapter.cpp
varatharajan568 May 8, 2026
52974bf
Merge branch 'dev_sprint_25_2' into feature/RDKEMW-18059
varatharajan568 May 11, 2026
90add06
Added an var in-order to maintain the session key status
varatharajan568 May 11, 2026
b6f473c
Included AAMP level changes
varatharajan568 May 11, 2026
ab7520b
Merge branch 'dev_sprint_25_2' into feature/RDKEMW-18059_AAMP
varatharajan568 May 13, 2026
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
2 changes: 1 addition & 1 deletion AampConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ static const ConfigLookupEntryBool mConfigLookupTableBool[AAMPCONFIG_BOOL_COUNT]
{false,"appSrcForProgressivePlayback",eAAMPConfig_UseAppSrcForProgressivePlayback,false},
{false,"descriptiveAudioTrack",eAAMPConfig_DescriptiveAudioTrack,false},
{true,"reportBufferEvent",eAAMPConfig_ReportBufferEvent,false},
{false,"info",eAAMPConfig_InfoLogging,true},
{true,"info",eAAMPConfig_InfoLogging,true},
{false,"debug",eAAMPConfig_DebugLogging,false},
{false,"trace",eAAMPConfig_TraceLogging,false},
{true,"warn",eAAMPConfig_WarnLogging,false},
Expand Down
8 changes: 8 additions & 0 deletions aampgstplayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -558,12 +558,19 @@ static void HandleBusMessage(const BusEventData busEvent, AAMPGstPlayer * _this)
case MESSAGE_ERROR:
{
std::string errorDesc = "GstPipeline Error:" + busEvent.msg;
if (_this->aamp->HasHDCPProtectionError() &&
busEvent.msg.find("Rialto dropped a frame that failed to decrypt") != std::string::npos)
{
// Drop this error message as its due to HDCP output protection ie, HDMI un-plug.
return;
}
if (busEvent.msg.find("video decode error") != std::string::npos)
{
_this->aamp->SendErrorEvent(AAMP_TUNE_GST_PIPELINE_ERROR, errorDesc.c_str(), false);
}
else if (busEvent.msg.find("HDCP Compliance Check Failure") != std::string::npos)
{
// TODO: Replace with a common way for Rialto and non-Rialto pipelines.
_this->aamp->SendErrorEvent(AAMP_TUNE_HDCP_COMPLIANCE_ERROR, errorDesc.c_str(), false);
}
else if ((busEvent.msg.find("Internal data stream error") != std::string::npos) && _this->aamp->mConfig->IsConfigSet(eAAMPConfig_RetuneForGSTError))
Expand Down Expand Up @@ -639,6 +646,7 @@ static void HandleBusMessage(const BusEventData busEvent, AAMPGstPlayer * _this)
break;

case MESSAGE_APPLICATION:
// Should be deprecated
if (busEvent.msg.find("HDCPProtectionFailure") != std::string::npos)
{
AAMPLOG_ERR("Received HDCPProtectionFailure event.Schedule Retune ");
Expand Down
2 changes: 2 additions & 0 deletions middleware/drm/DrmCallbacks.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
*/

#include <string>
#include "DrmSession.h"

/**
* @class DrmCallbacks
Expand All @@ -36,6 +37,7 @@ class DrmCallbacks
public:
virtual void Individualization(const std::string& payload) = 0;
virtual void LicenseRenewal(DrmHelperPtr drmHelper, void* userData) = 0;
virtual void NotifyKeyStatus(PlayerKeyStatus keyStatus) = 0;
virtual ~DrmCallbacks() {};
};

Expand Down
16 changes: 16 additions & 0 deletions middleware/drm/DrmSession.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,22 @@
#include "DrmUtils.h"
#include "ContentSecurityManagerSession.h"

/**
* @enum PlayerKeyStatus
* @brief DRM key status values, independent of OCDM.
*/
typedef enum {
PLAYER_KEY_USABLE = 0,
PLAYER_KEY_EXPIRED,
PLAYER_KEY_RELEASED,
PLAYER_KEY_OUTPUT_RESTRICTED,
PLAYER_KEY_OUTPUT_RESTRICTED_HDCP22,
PLAYER_KEY_OUTPUT_DOWNSCALED,
PLAYER_KEY_STATUS_PENDING,
PLAYER_KEY_INTERNAL_ERROR,
PLAYER_KEY_HW_ERROR
} PlayerKeyStatus;

using namespace std;

#define PLAYREADY_KEY_SYSTEM_STRING "com.microsoft.playready"
Expand Down
60 changes: 59 additions & 1 deletion middleware/drm/ocdm/opencdmsessionadapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
* @brief Handles operation with OCDM session to handle DRM License data
*/
#include "opencdmsessionadapter.h"

#include "DrmHelper.h"
#include "PlayerUtils.h"

Expand All @@ -44,6 +43,46 @@
#include <set>
#define LICENSE_RENEWAL_MESSAGE_TYPE "1"

/**
* @fn toPlayerKeyStatus
* @brief Convert OCDM KeyStatus to PlayerKeyStatus.
* @param ocdmStatus The KeyStatus from OCDM.
* @return The corresponding PlayerKeyStatus.
*/
static PlayerKeyStatus toPlayerKeyStatus(KeyStatus ocdmStatus) {
switch (ocdmStatus) {
case Usable: return PlayerKeyStatus::PLAYER_KEY_USABLE;
case Expired: return PlayerKeyStatus::PLAYER_KEY_EXPIRED;
case Released: return PlayerKeyStatus::PLAYER_KEY_RELEASED;
case OutputRestricted: return PlayerKeyStatus::PLAYER_KEY_OUTPUT_RESTRICTED;
case OutputRestrictedHDCP22: return PlayerKeyStatus::PLAYER_KEY_OUTPUT_RESTRICTED_HDCP22;
case OutputDownscaled: return PlayerKeyStatus::PLAYER_KEY_OUTPUT_DOWNSCALED;
case StatusPending: return PlayerKeyStatus::PLAYER_KEY_STATUS_PENDING;
case HWError: return PlayerKeyStatus::PLAYER_KEY_HW_ERROR;
case InternalError: default: return PlayerKeyStatus::PLAYER_KEY_INTERNAL_ERROR;
}
}

/**
* @fn ShouldNotifyKeyStatus
* @brief Determine if a given KeyStatus should trigger a key status notification to the player.
* @param status The KeyStatus to evaluate.
* @return true if the status should trigger a notification, false otherwise.
*/
bool ShouldNotifyKeyStatus(KeyStatus status)
{
switch (status)
{
case OutputRestricted:
case Usable:
case OutputRestrictedHDCP22:
case OutputDownscaled:
return true;
default:
return false;
}
}

/**
* @fn OCDMSessionAdapter
* @brief OCDMSessionAdapter constructor
Expand All @@ -61,6 +100,7 @@ OCDMSessionAdapter::OCDMSessionAdapter(DrmHelperPtr drmHelper, DrmCallbacks *cal
m_challengeReady(),
m_challengeSize(0),
m_keyStatus(InternalError),
m_sessionKeyStatus(Usable),
m_keyStateIndeterminate(false),
m_keyStatusReady(),
m_OCDMSessionCallbacks(),
Expand Down Expand Up @@ -215,6 +255,7 @@ void OCDMSessionAdapter::processOCDMChallenge(const char destUrl[], const uint8_

void OCDMSessionAdapter::keyUpdateOCDM(const uint8_t key[], const uint8_t keySize) {
MW_LOG_INFO("at %p, with %p, %p", this , m_pOpenCDMSystem, m_pOpenCDMSession);
printf("keyUpdateOCDM-> Key: "); for (uint8_t i = 0; i < keySize; i++) printf("%02X", key[i]); printf("\n");
// Validate input parameters
if (key != nullptr && keySize > 0)
{
Expand All @@ -224,7 +265,12 @@ void OCDMSessionAdapter::keyUpdateOCDM(const uint8_t key[], const uint8_t keySiz
if (m_pOpenCDMSession)
{
m_keyStatus = opencdm_session_status(m_pOpenCDMSession, key, keySize);
MW_LOG_WARN("Key status from OCDM: %d", m_keyStatus);
m_keyStateIndeterminate = false;
if (m_keyStatus != Usable)
{
m_sessionKeyStatus = m_keyStatus;
}
}
else
{
Expand All @@ -248,6 +294,17 @@ void OCDMSessionAdapter::keyUpdateOCDM(const uint8_t key[], const uint8_t keySiz
void OCDMSessionAdapter::keysUpdatedOCDM() {
MW_LOG_INFO("at %p, with %p, %p", this , m_pOpenCDMSystem, m_pOpenCDMSession);
m_keyStatusReady.signal();
const KeyStatus notifyStatus = m_sessionKeyStatus;
m_sessionKeyStatus = Usable; // reset for next burst
if (m_drmCallbacks && (ShouldNotifyKeyStatus(notifyStatus) == true))
{
MW_LOG_INFO("keysUpdatedOCDM notifying key status %d", notifyStatus);
m_drmCallbacks->NotifyKeyStatus(toPlayerKeyStatus(notifyStatus));
}
else
{
MW_LOG_INFO("Key status %d does not trigger a notification to the player", notifyStatus);
}
}


Expand Down Expand Up @@ -423,6 +480,7 @@ void OCDMSessionAdapter:: clearDecryptContext()
std::lock_guard<std::mutex> keyLock(m_usableKeysMutex);
m_usableKeys.clear();
}
m_sessionKeyStatus = Usable;

m_eKeyState = KEY_INIT;
}
Expand Down
1 change: 1 addition & 0 deletions middleware/drm/ocdm/opencdmsessionadapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ class OCDMSessionAdapter : public DrmSession

std::string m_destUrl;
KeyStatus m_keyStatus;
KeyStatus m_sessionKeyStatus; // tracks any non-Usable key status received in a callback burst
bool m_keyStateIndeterminate;
std::vector<uint8_t> m_keyStored;
std::vector<std::vector<uint8_t>> m_usableKeys; // Store usable key IDs from ocdm_update_callback
Expand Down
24 changes: 24 additions & 0 deletions priv_aamp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1830,6 +1830,7 @@ PrivateInstanceAAMP::PrivateInstanceAAMP(AampConfig *config) : mReportProgressPo
, mThumbnailLastProgramDateTime(0)
, mLastSleThumbnailInfo()
, mLatencyMonitor(std::make_unique<AampLatencyMonitor>(this))
, mDRMKeyStatus(PlayerKeyStatus::PLAYER_KEY_STATUS_PENDING)
{
AAMPLOG_MIL("Create Private Player %d", mPlayerId);
mAampCacheHandler = new AampCacheHandler(mPlayerId);
Expand Down Expand Up @@ -11462,6 +11463,29 @@ void PrivateInstanceAAMP::Individualization(const std::string& payload)
SendEvent(event,AAMP_EVENT_ASYNC_MODE);
}

/**
* @brief DRM key status notification callback
*/
void PrivateInstanceAAMP::NotifyKeyStatus(PlayerKeyStatus keyStatus)
{
AAMPLOG_WARN("NotifyKeyStatus: keyStatus=%d", static_cast<int>(keyStatus));
// Check if we are coming out of a HDCP protection error state, means HDMI plugged in.
// Do a retune to recover the playback internally.
// Check before saving the new keyStatus so retune can be scheduled.
bool hdcpError = HasHDCPProtectionError();

// Update DRM key status. This will be checked when we receive a GStreamer playback error for HDCP errors.
SetDRMKeyStatus(keyStatus);
// Note - mDRMKeyStatus is persisted across sessions as the same URL could be retried again
// but the callback only fires once for the DRM session. For a new playback, a new session
// will be created, which will trigger the callback with KeyUsable status so the mDRMKeyStatus is updated properly.
if (hdcpError && (keyStatus == PlayerKeyStatus::PLAYER_KEY_USABLE))
{
// Retune is asynchronously scheduled so should not cause any deadlocks.
ScheduleRetune(eGST_ERROR_OUTPUT_PROTECTION_ERROR, eMEDIATYPE_VIDEO);
}
}

/**
* @brief Get current initial buffer duration in seconds
*/
Expand Down
26 changes: 26 additions & 0 deletions priv_aamp.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
#include "TextTrackInfo.h"
#include "AAMPAnomalyMessageType.h"
#include "AampDemuxDataTypes.h"
#include "DrmSession.h" // For PlayerKeyStatus

#define FAKE_TUNE_URL "file:///etc/manifest.mpd" /**< Fake tune URL for testing purposes */

Expand Down Expand Up @@ -1336,6 +1337,13 @@ class PrivateInstanceAAMP : public DrmCallbacks, public std::enable_shared_from_
* @return void
*/
void LicenseRenewal(DrmHelperPtr drmHelper,void* userData) override;
/**
* @fn NotifyKeyStatus
*
* @param[in] keyStatus - Key status received from OCDM
* @return void
*/
void NotifyKeyStatus(PlayerKeyStatus keyStatus) override;
/**
* @fn CurlTerm
*
Expand Down Expand Up @@ -4057,6 +4065,22 @@ class PrivateInstanceAAMP : public DrmCallbacks, public std::enable_shared_from_
*/
bool IsAdPlaying();

/**
* @brief Has encountered HDCP Output Protection Error
*/
bool HasHDCPProtectionError() { return mDRMKeyStatus.load() == PlayerKeyStatus::PLAYER_KEY_OUTPUT_RESTRICTED; }

/**
* @brief Has encountered HDCP Compliance Error
*/
bool HasHDCPComplianceError() { return mDRMKeyStatus.load() == PlayerKeyStatus::PLAYER_KEY_OUTPUT_RESTRICTED_HDCP22; }

/**
* @brief Set the DRM key status
* @param status - New DRM key status
*/
void SetDRMKeyStatus(PlayerKeyStatus status) { mDRMKeyStatus.store(status); }

protected:

/**
Expand Down Expand Up @@ -4353,5 +4377,7 @@ class PrivateInstanceAAMP : public DrmCallbacks, public std::enable_shared_from_
* video_muted and subtitle_muted.
*/
void SetCCStatusInternal(void);

std::atomic<PlayerKeyStatus> mDRMKeyStatus {PlayerKeyStatus::PLAYER_KEY_STATUS_PENDING}; /**< Key status for the current session */
};
#endif // PRIVAAMP_H
5 changes: 5 additions & 0 deletions test/utests/drm/mocks/aampMocks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,11 @@ void PrivateInstanceAAMP::UnlockGetPositionMilliseconds()
{
}

void PrivateInstanceAAMP::NotifyKeyStatus(PlayerKeyStatus keyStatus)
{
(void)keyStatus;
}

void PrivateInstanceAAMP::SetPreferredLanguages(const char *, const char *, const char *,
const char *, const char *, const Accessibility *,
const char *)
Expand Down
7 changes: 6 additions & 1 deletion test/utests/fakes/FakePrivateInstanceAAMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,11 @@ void PrivateInstanceAAMP::UnlockGetPositionMilliseconds()
{
}

void PrivateInstanceAAMP::NotifyKeyStatus(PlayerKeyStatus keyStatus)
{
(void) keyStatus;
}

void PrivateInstanceAAMP::SetPreferredLanguages(char const*, char const*, char const*, char const*, char const*, const Accessibility*, char const*)
{
}
Expand Down Expand Up @@ -1913,4 +1918,4 @@ bool PrivateInstanceAAMP::CheckForChunkEarlyAbort(CurlCallbackContext *context)

void PrivateInstanceAAMP::EnableLatencyMonitor(bool enabled)
{
}
}
Loading