Skip to content

Delia 70055#455

Open
Koky2701 wants to merge 30 commits intomasterfrom
delia-70055
Open

Delia 70055#455
Koky2701 wants to merge 30 commits intomasterfrom
delia-70055

Conversation

@Koky2701
Copy link
Copy Markdown
Contributor

Summary: SetPlaybackRate modification.
Type: Fix
Test Plan: UT/CT, Fullstack
Jira: DELIA-70055

@github-actions
Copy link
Copy Markdown

Pull request must be merged with a description containing the required fields,

Summary:
Type: Feature/Fix/Cleanup
Test Plan:
Jira:

If there is no jira releated to this change, please put 'Jira: NO-JIRA'.

Description can be changed by editing the top comment on your pull request and making a new commit.

@rdkcmf-jenkins
Copy link
Copy Markdown
Contributor

b'## Blackduck scan failure details

Summary: 0 violations, 0 files pending approval, 1 file pending identification.

  • Protex Server Path: /home/blackduck/github/rialto/455/rdkcentral/rialto

  • Commit: 8195b43

Report detail: gist'

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request refactors the Limited Duration License (LDL) handling in the media keys implementation and modifies the SetPlaybackRate task to support decoder-specific event handling. The main changes include:

Changes:

  • Removed the isLDL parameter from createKeySession API and replaced it with dynamic detection of extended interface usage based on which APIs are called
  • Added ldlState parameter to generateRequest API with a default value for backward compatibility
  • Modified SetPlaybackRate to send rate change events directly to broadcom video/audio decoders when present, instead of always sending to the pipeline
  • Renamed isNetflixPlayreadyKeySystem to isExtendedInterfaceUsed to better reflect its purpose
  • Added gstEventRef and gstEventUnref wrapper methods
  • Added new library dependency rdkgstreamerutilsplatform

Reviewed changes

Copilot reviewed 71 out of 71 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
wrappers/interface/IGstWrapper.h Added gstEventRef and gstEventUnref methods to wrapper interface
wrappers/include/GstWrapper.h Implemented gstEventRef and gstEventUnref wrapper methods
wrappers/CMakeLists.txt Added rdkgstreamerutilsplatform library dependency
media/server/gstplayer/source/tasks/generic/SetPlaybackRate.cpp Modified to send rate change events to decoders directly for broadcom decoders; added player parameter for decoder access
media/server/gstplayer/include/tasks/generic/SetPlaybackRate.h Added player member and updated constructor signature
media/server/gstplayer/include/tasks/generic/GenericPlayerTaskFactory.h Updated createSetPlaybackRate signature to include player parameter
media/server/gstplayer/source/tasks/generic/GenericPlayerTaskFactory.cpp Updated createSetPlaybackRate implementation
media/server/gstplayer/source/GstGenericPlayer.cpp Updated setPlaybackRate call to pass player instance
media/server/gstplayer/include/IGenericPlayerTaskFactory.h Updated createSetPlaybackRate interface signature
media/server/gstplayer/include/IGstGenericPlayerPrivate.h Added getDecoder method to interface
media/server/gstplayer/source/GstDecryptor.cpp Updated to use isExtendedInterfaceUsed instead of isNetflixPlayreadyKeySystem
media/server/service/source/CdmService.h Renamed isNetflixPlayready to isExtendedInterfaceUsed in MediaKeySessionInfo
media/server/service/source/CdmService.cpp Implemented dynamic extended interface detection; renamed method; removed isLDL from createKeySession
media/server/service/include/ICdmService.h Updated interface signatures for createKeySession and generateRequest
media/server/main/source/MediaKeysServerInternal.cpp Removed isLDL parameter and isNetflixPlayreadyKeySystem method
media/server/main/source/MediaKeySession.cpp Added extendedInterfaceInUse flag; implemented queued DRM header logic; removed isLDL member; updated getChallenge to use ldlState
media/server/main/include/MediaKeysServerInternal.h Updated interface signatures
media/server/main/include/MediaKeySession.h Removed isLDL member; added extendedInterfaceInUse and queuedDrmHeader members
media/server/main/include/IMediaKeySession.h Updated generateRequest signature; removed isNetflixPlayreadyKeySystem
media/server/main/interface/IMediaKeysServerInternal.h Removed isNetflixPlayreadyKeySystem method
media/server/main/interface/IDecryptionService.h Renamed isNetflixPlayreadyKeySystem to isExtendedInterfaceUsed
media/server/ipc/source/MediaKeysModuleService.cpp Added LDL conversion function; updated createKeySession and generateRequest calls
media/public/include/MediaCommon.h Added LimitedDurationLicense enum
media/public/include/IMediaKeys.h Removed isLDL from createKeySession; added ldlState with default to generateRequest
media/client/main/source/MediaKeys.cpp Updated method signatures
media/client/main/include/MediaKeys.h Updated method signatures
media/client/ipc/source/MediaKeysIpc.cpp Removed isLDL handling; added ldlState conversion and handling
media/client/ipc/include/MediaKeysIpc.h Updated method signatures
proto/mediakeysmodule.proto Added LimitedDurationLicense enum; removed is_ldl field; added ldl_state field
tests/* (multiple files) Updated all tests to match new signatures; removed isNetflixPlayreadyKeySystem tests; added LDL-related tests

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

}
else
{
success = m_gstWrapper->gstElementSendEvent(m_context.pipeline, instantRateChangeEvent);
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Memory leak: When gstElementSendEvent to the pipeline fails at line 123, the instantRateChangeEvent is not unreferenced. According to GStreamer documentation, when gst_element_send_event returns FALSE, the event is not consumed and the caller must unref it. Add an unref call for the failure case, similar to how it's handled at lines 104 and 115.

Suggested change
success = m_gstWrapper->gstElementSendEvent(m_context.pipeline, instantRateChangeEvent);
success = m_gstWrapper->gstElementSendEvent(m_context.pipeline, instantRateChangeEvent);
if (!success)
{
m_gstWrapper->gstEventUnref(instantRateChangeEvent);
}

Copilot uses AI. Check for mistakes.
Comment on lines +70 to +71
GstElement *audioDecoder = m_player.getDecoder(firebolt::rialto::MediaSourceType::AUDIO);
GstElement *videoDecoder = m_player.getDecoder(firebolt::rialto::MediaSourceType::VIDEO);
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Memory leak: The decoder elements obtained from getDecoder() are never unreferenced. Since getDecoder() returns a referenced GstElement (via gstObjectRef at line 502 of GstGenericPlayer.cpp), both audioDecoder and videoDecoder must be unreferenced with gstObjectUnref() before the function returns. This should be done at the end of the execute() method, similar to how audioSink is unreferenced at line 136.

Copilot uses AI. Check for mistakes.
Comment on lines +538 to +541
if (m_sessionInfo.find(keySessionId) != m_sessionInfo.end())
{
m_sessionInfo[keySessionId].isExtendedInterfaceUsed = true;
}
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant check: The session existence check at line 538 is redundant. The session existence was already verified at line 532-537, and if it doesn't exist, the function returns early. The check at line 538 can be removed, and line 540 can simply use the existing mediaKeysHandleIter iterator.

Suggested change
if (m_sessionInfo.find(keySessionId) != m_sessionInfo.end())
{
m_sessionInfo[keySessionId].isExtendedInterfaceUsed = true;
}
mediaKeysHandleIter->second.isExtendedInterfaceUsed = true;

Copilot uses AI. Check for mistakes.
bool isLDL, int32_t &keySessionId) = 0;
int32_t &keySessionId) = 0;

/**
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Breaking API change: The removal of the 'isLDL' parameter from createKeySession() is a breaking change to the public API. Any existing code calling this function with the isLDL parameter will fail to compile. This should be clearly documented in the PR description and release notes. Consider whether this breaking change is acceptable for your versioning strategy.

Suggested change
/**
/**
* @brief Creates a session and returns the session id (legacy overload with isLDL flag).
*
* This overload is kept for backwards compatibility with older clients that used the isLDL
* parameter. The isLDL value is ignored; use the three-parameter overload instead.
*
* @deprecated Use createKeySession(KeySessionType, std::weak_ptr<IMediaKeysClient>, int32_t &) instead.
*
* @param[in] sessionType : The session type.
* @param[in] client : Client object for callbacks
* @param[out] keySessionId: The key session id
* @param[in] isLDL : Legacy Limited Duration License flag (ignored).
*
* @retval an error status.
*/
[[deprecated("Use createKeySession(KeySessionType, std::weak_ptr<IMediaKeysClient>, int32_t &) instead.")]]
MediaKeyErrorStatus createKeySession(KeySessionType sessionType, std::weak_ptr<IMediaKeysClient> client,
int32_t &keySessionId, bool isLDL)
{
(void)isLDL;
return createKeySession(sessionType, client, keySessionId);
}
/**

Copilot uses AI. Check for mistakes.
@rdkcmf-jenkins
Copy link
Copy Markdown
Contributor

b'## WARNING: A Blackduck scan failure has been waived

A prior failure has been upvoted

  • Upvote reason: Spurious - not a problem

  • Commit: 8195b43
    '

	Summary: SetPlaybackRate modification.
        Type: Fix
        Test Plan: UT/CT, Fullstack
        Jira: DELIA-70055
@rdkcmf-jenkins
Copy link
Copy Markdown
Contributor

b'## Blackduck scan failure details

Summary: 0 violations, 0 files pending approval, 1 file pending identification.

  • Protex Server Path: /home/blackduck/github/rialto/455/rdkcentral/rialto

  • Commit: 323c82c

Report detail: gist'

            Summary: Removed unused library.
            Type: Fix
            Test Plan: UT/CT, Fullstack
            Jira: DELIA-70055
Copilot AI review requested due to automatic review settings February 27, 2026 09:02
@rdkcmf-jenkins
Copy link
Copy Markdown
Contributor

b'## Blackduck scan failure details

Summary: 0 violations, 0 files pending approval, 1 file pending identification.

  • Protex Server Path: /home/blackduck/github/rialto/455/rdkcentral/rialto

  • Commit: 5ce5ac0

Report detail: gist'

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 70 out of 70 changed files in this pull request and generated 6 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


GstEvent *gstEventRef(GstEvent *event) const override { return gst_event_ref(event); }

void gstEventUnref(GstEvent *event) const override { gst_event_unref(event); };
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is an extra trailing semicolon after the inline gstEventUnref definition ({ ... };). While most compilers accept this, it’s unnecessary and can trigger style warnings. Consider removing the trailing semicolon for consistency with the other inline methods.

Copilot uses AI. Check for mistakes.
*
* @param[in] mediaSourceType : the source type to obtain the decoder for
*
* @retval The decoder, NULL if not found
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getDecoder() returns a GstElement* but the comment doesn’t specify ownership/refs (unlike getSink() which explicitly mentions unref). Since the implementation returns a ref-counted element (gstObjectRef), please document that the caller must unref the returned element to avoid leaks.

Suggested change
* @retval The decoder, NULL if not found
* @retval The decoder, NULL if not found. Please call getObjectUnref() if it's non-null

Copilot uses AI. Check for mistakes.
Comment on lines +58 to +61
ACTION_P(memcpyChallenge, vec)
{
memcpy(arg1, &vec[0], vec.size());
}
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

memcpyChallenge uses memcpy but this header doesn't include <cstring> (or <string.h>), which can cause build failures due to memcpy being undeclared. Add the proper header (and consider using std::memcpy) so the symbol is guaranteed to be available.

Copilot uses AI. Check for mistakes.
Comment on lines +70 to +72
GstElement *audioDecoder = m_player.getDecoder(firebolt::rialto::MediaSourceType::AUDIO);
GstElement *videoDecoder = m_player.getDecoder(firebolt::rialto::MediaSourceType::VIDEO);

Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getDecoder() returns a ref-counted GstElement* (it calls gstObjectRef). The acquired audioDecoder/videoDecoder are never unreffed here, which will leak references each time playback rate is set. Ensure these elements are unreffed on all paths once you're done with them (including early-exit paths after the send).

Copilot uses AI. Check for mistakes.
Comment on lines +94 to +95
if ((videoDecoder && (0 == strcmp(GST_ELEMENT_NAME(videoDecoder), "brcmvideodecoder"))) ||
(audioDecoder && (0 == strcmp(GST_ELEMENT_NAME(audioDecoder), "brcmaudiodecoder"))))
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code uses strcmp but the file doesn't include <cstring>/<string.h>, which can result in strcmp being undeclared depending on include order. Also, comparing GST_ELEMENT_NAME(decoder) for exact equality is brittle because element instance names are often auto-suffixed (e.g., "brcmvideodecoder0"); consider checking the element factory name or using a prefix match if the intent is to detect the Broadcom decoder type.

Suggested change
if ((videoDecoder && (0 == strcmp(GST_ELEMENT_NAME(videoDecoder), "brcmvideodecoder"))) ||
(audioDecoder && (0 == strcmp(GST_ELEMENT_NAME(audioDecoder), "brcmaudiodecoder"))))
if ((videoDecoder &&
m_glibWrapper->gStrHasPrefix(GST_ELEMENT_NAME(videoDecoder), "brcmvideodecoder")) ||
(audioDecoder &&
m_glibWrapper->gStrHasPrefix(GST_ELEMENT_NAME(audioDecoder), "brcmaudiodecoder")))

Copilot uses AI. Check for mistakes.
Comment on lines +143 to +144
setDrmHeader(m_queuedDrmHeader);
m_queuedDrmHeader.clear();
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The queued DRM header is applied after session construction, but the return value from setDrmHeader() is ignored and the queued header is cleared unconditionally. If setting the header fails, the failure will be silently lost and the session may proceed without the DRM header. Capture and handle the return status (and/or only clear the queued header on success) so failures propagate correctly.

Suggested change
setDrmHeader(m_queuedDrmHeader);
m_queuedDrmHeader.clear();
auto headerStatus = setDrmHeader(m_queuedDrmHeader);
if (MediaKeyErrorStatus::OK != headerStatus)
{
RIALTO_SERVER_LOG_ERROR("Failed to set queued drm header after session construction");
status = headerStatus;
}
else
{
m_queuedDrmHeader.clear();
}

Copilot uses AI. Check for mistakes.
std::shared_ptr<firebolt::rialto::wrappers::IGstWrapper> gstWrapper,
std::shared_ptr<firebolt::rialto::wrappers::IGlibWrapper> glibWrapper, double rate)
: m_context{context}, m_gstWrapper{gstWrapper}, m_glibWrapper{glibWrapper}, m_rate{rate}
: m_context{context}, m_player{player}, m_gstWrapper{gstWrapper}, m_glibWrapper{glibWrapper}, m_rate{rate}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverity Issue - Variable copied when it could be moved

"glibWrapper" is passed-by-value as parameter to "std::shared_ptrfirebolt::rialto::wrappers::IGlibWrapper::shared_ptr(std::shared_ptrfirebolt::rialto::wrappers::IGlibWrapper const &) /explicit =default/", when it could be moved instead.

Low Impact, CWE-none
COPY_INSTEAD_OF_MOVE

How to fix

Use "std::move(""glibWrapper"")" instead of "glibWrapper".

std::shared_ptr<firebolt::rialto::wrappers::IGstWrapper> gstWrapper,
std::shared_ptr<firebolt::rialto::wrappers::IGlibWrapper> glibWrapper, double rate)
: m_context{context}, m_gstWrapper{gstWrapper}, m_glibWrapper{glibWrapper}, m_rate{rate}
: m_context{context}, m_player{player}, m_gstWrapper{gstWrapper}, m_glibWrapper{glibWrapper}, m_rate{rate}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverity Issue - Variable copied when it could be moved

"gstWrapper" is passed-by-value as parameter to "std::shared_ptrfirebolt::rialto::wrappers::IGstWrapper::shared_ptr(std::shared_ptrfirebolt::rialto::wrappers::IGstWrapper const &) /explicit =default/", when it could be moved instead.

Low Impact, CWE-none
COPY_INSTEAD_OF_MOVE

How to fix

Use "std::move(""gstWrapper"")" instead of "gstWrapper".

std::shared_ptr<firebolt::rialto::wrappers::IGstWrapper> gstWrapper,
std::shared_ptr<firebolt::rialto::wrappers::IGlibWrapper> glibWrapper, double rate)
: m_context{context}, m_gstWrapper{gstWrapper}, m_glibWrapper{glibWrapper}, m_rate{rate}
: m_context{context}, m_player{player}, m_gstWrapper{gstWrapper}, m_glibWrapper{glibWrapper}, m_rate{rate}
Copy link
Copy Markdown
Contributor

@rdkcmf-jenkins rdkcmf-jenkins Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverity issue no longer present as of: undefined

Show issue

Coverity Issue - Variable copied when it could be moved

"glibWrapper" is passed-by-value as parameter to "std::shared_ptrfirebolt::rialto::wrappers::IGlibWrapper::shared_ptr(std::shared_ptrfirebolt::rialto::wrappers::IGlibWrapper const &) /explicit =default/", when it could be moved instead.

Low Impact, CWE-none
COPY_INSTEAD_OF_MOVE

How to fix

Use "std::move(""glibWrapper"")" instead of "glibWrapper".

std::shared_ptr<firebolt::rialto::wrappers::IGstWrapper> gstWrapper,
std::shared_ptr<firebolt::rialto::wrappers::IGlibWrapper> glibWrapper, double rate)
: m_context{context}, m_gstWrapper{gstWrapper}, m_glibWrapper{glibWrapper}, m_rate{rate}
: m_context{context}, m_player{player}, m_gstWrapper{gstWrapper}, m_glibWrapper{glibWrapper}, m_rate{rate}
Copy link
Copy Markdown
Contributor

@rdkcmf-jenkins rdkcmf-jenkins Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverity issue no longer present as of: undefined

Show issue

Coverity Issue - Variable copied when it could be moved

"gstWrapper" is passed-by-value as parameter to "std::shared_ptrfirebolt::rialto::wrappers::IGstWrapper::shared_ptr(std::shared_ptrfirebolt::rialto::wrappers::IGstWrapper const &) /explicit =default/", when it could be moved instead.

Low Impact, CWE-none
COPY_INSTEAD_OF_MOVE

How to fix

Use "std::move(""gstWrapper"")" instead of "gstWrapper".

@rdkcmf-jenkins
Copy link
Copy Markdown
Contributor

b'## WARNING: A Blackduck scan failure has been waived

A prior failure has been upvoted

  • Upvote reason: OK

  • Commit: 5ce5ac0
    '

@rdkcmf-jenkins
Copy link
Copy Markdown
Contributor

b'## Blackduck scan failure details

Summary: 0 violations, 0 files pending approval, 1 file pending identification.

  • Protex Server Path: /home/blackduck/github/rialto/455/rdkcentral/rialto

  • Commit: 143f5bb

Report detail: gist'

@rdkcmf-jenkins
Copy link
Copy Markdown
Contributor

b'## WARNING: A Blackduck scan failure has been waived

A prior failure has been upvoted

  • Upvote reason: ok

  • Commit: 143f5bb
    '

Copilot AI review requested due to automatic review settings March 4, 2026 18:29
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 6 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +100 to +107
GstEvent *videoRateChangeEvent = m_gstWrapper->gstEventRef(instantRateChangeEvent);
if (!m_gstWrapper->gstElementSendEvent(videoDecoder, videoRateChangeEvent))
{
RIALTO_SERVER_LOG_INFO("Sent new event to videoDecoder failed");
success = false;
}
m_gstWrapper->gstEventUnref(videoRateChangeEvent);
}
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gstElementSendEvent() (wrapping gst_element_send_event) takes ownership of the event. Unref'ing videoRateChangeEvent after sending will likely double-unref the event and can cause a use-after-free. Remove the explicit unref for the event passed to gstElementSendEvent (keep only the unref for the original instantRateChangeEvent after cloning refs).

Copilot uses AI. Check for mistakes.
Comment on lines +111 to +118
GstEvent *audioRateChangeEvent = m_gstWrapper->gstEventRef(instantRateChangeEvent);
if (!m_gstWrapper->gstElementSendEvent(audioDecoder, audioRateChangeEvent))
{
RIALTO_SERVER_LOG_INFO("Sent new event to audioDecoder failed");
success = false;
}
m_gstWrapper->gstEventUnref(audioRateChangeEvent);
}
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gstElementSendEvent() takes ownership of the event. Unref'ing audioRateChangeEvent after sending can double-unref and lead to memory safety issues. Don't unref the event pointer after passing it to gstElementSendEvent; only unref the original instantRateChangeEvent after creating the refs for each send.

Copilot uses AI. Check for mistakes.
Comment on lines +140 to +144
m_glibWrapper->gObjectUnref(audioDecoder);
}
if (videoDecoder)
{
m_glibWrapper->gObjectUnref(videoDecoder);
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getDecoder() returns a ref'd GstElement* (it uses gstObjectRef in GstGenericPlayer::getDecoder). These should be released via m_gstWrapper->gstObjectUnref(...) for symmetry and to keep unref operations mockable/consistent with the rest of the player code (vs gObjectUnref).

Suggested change
m_glibWrapper->gObjectUnref(audioDecoder);
}
if (videoDecoder)
{
m_glibWrapper->gObjectUnref(videoDecoder);
m_gstWrapper->gstObjectUnref(audioDecoder);
}
if (videoDecoder)
{
m_gstWrapper->gstObjectUnref(videoDecoder);

Copilot uses AI. Check for mistakes.
Comment on lines +296 to +298
* @retval The decoder, NULL if not found
*/
virtual GstElement *getDecoder(const MediaSourceType &mediaSourceType) = 0;
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new getDecoder() API doesn't document ownership/ref semantics. Since GstGenericPlayer::getDecoder() returns a ref'd element (gstObjectRef), the interface comment should explicitly state that the caller must unref the returned element (e.g., via gstObjectUnref). Also consider making this method const (like getSink) since it appears to be a read-only lookup.

Suggested change
* @retval The decoder, NULL if not found
*/
virtual GstElement *getDecoder(const MediaSourceType &mediaSourceType) = 0;
* @retval The decoder, NULL if not found. Please unref the returned element
* (e.g. via gst_object_unref()) if it is non-null.
*/
virtual GstElement *getDecoder(const MediaSourceType &mediaSourceType) const = 0;

Copilot uses AI. Check for mistakes.
* @retval the new SetPlaybackRate task instance.
*/
virtual std::unique_ptr<IPlayerTask> createSetPlaybackRate(GenericPlayerContext &context, double rate) const = 0;
virtual std::unique_ptr<IPlayerTask> createSetPlaybackRate(GenericPlayerContext &context, IGstGenericPlayerPrivate &player, double rate) const = 0;
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This signature change will break existing unit test mocks/call sites that still use createSetPlaybackRate(context, rate) (e.g., GenericPlayerTaskFactoryMock, GenericPlayerTaskFactoryTest, and GenericTasksTestsBase::triggerSetPlaybackRate). Update all implementations/mocks/tests to pass IGstGenericPlayerPrivate &player to avoid build failures.

Copilot uses AI. Check for mistakes.
Comment on lines +94 to +96
if ((videoDecoder && (0 == strcmp(GST_ELEMENT_NAME(videoDecoder), "brcmvideodecoder"))) ||
(audioDecoder && (0 == strcmp(GST_ELEMENT_NAME(audioDecoder), "brcmaudiodecoder"))))
{
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new Broadcom-decoder-specific branch (sending the custom rate-change event directly to brcm*decoder elements) is not covered by the existing SetPlaybackRate task unit tests. Add UT coverage for this branch (including the failure paths for audio/video send) to prevent regressions.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants