Performance improvements in play request and flush (#428) - #432
muthushiamsankar wants to merge 56 commits into
Conversation
Summary: Performance improvements in play request and flush Type: Fix Test Plan: UT/CT, Fullstack Jira: ENTDAI-1750 ENTDAI-1738 ENTDAI-485
Summary: Change Wayland Display for TextTrack Type: Fix Test Plan: UT/ CT, Fullstack Jira: ENTDAI-2218
Summary: Fixed playback info reporting for not asynchronous playbacks Type: Fix Test Plan: UT/CT, Fullstack Jira: ENTDAI-2231
…minor changes added to make code safer. (#437) Summary: Session server app changed to shared ptr to avoid invalid ptrs. Some minor changes added to make code safer. Type: Fix Test Plan: UT/CT, Fullstack Jira: VPLAY-12448
Summary: Asure correct data & flush order during multiple flushes Type: Fix Test Plan: UT/CT, Fullstack Jira: NO-JIRA
Summary: Removed gstreamer interaction during RemoveSource Type: Fix Test Plan: UT/CT, Fullstack Jira: LLAMA-18057
Summary: Allow to switch audio codec, when audio is re-attached Type: Fix Test Plan: UT/CT, Fullstack Jira: LLAMA-18057
Summary: Microsoft Playready support for Amazon Prime RDK app Type: Feature Test Plan: UT/CT, Fullstack Jira: NO-JIRA
Summary: Re-enabled CT Type: Fix Test Plan: UT/CT, Fullstack Jira: NO-JIRA
Summary: 'report-decode-errors' and 'queued-frames' properties missing from RialtoMSEVideoSink Type: Feature Test Plan: UT/CT, Fullstack Jira: RDKEMW-12692
Summary: Added support for getting text-sink in getSink method Type: Fix Test Plan: UT/CT, Fullstack Jira: VPLAY-12522
Summary: Removed blocking get_state calls from aml codec switch Type: Fix Test Plan: UT/CT, Fullstack Jira: DELIA-70115
…from RialtoMSEVideoSink (#462) Summary: Temporary revert of 'report-decode-errors' and 'queued-frames' properties missing from RialtoMSEVideoSink. It revealed issues in some apps. Type: Feature Test Plan: UT/CT, Fullstack Jira: RDKEMW-12692
Summary: Switch unnecessary copy constructors with move semantics
Type: Fix
Test Plan: UT/CT, Fullstack
Jira: RDKEMW-12966
RDKEMW-21391: Max-time and max-buffers usage in appsrc queue Reason for change: Max-time and max-buffers property used instead of max-bytes if available in appsrc queue size setting Test Procedure: https://ccp.sys.comcast.net/browse/RDKEMW-21929
RDKEMW-22713: Fix crash in CdmService Reason for change: Fix crash in CdmService::releaseKeySession (avoid accessing m_mediaKeys with an invalid handle) Test Procedure: Rialto CI
| bool OcdmSystem::getSupportedRobustnessLevels(std::vector<std::string> &robustnessLevels) | ||
| { | ||
| robustnessLevels.clear(); | ||
| char **buffer = nullptr; | ||
| uint16_t count = 0; | ||
| OpenCDMError status = opencdm_system_supported_robustness(m_systemHandle, &buffer, &count); | ||
| if (status == ERROR_NONE && buffer != nullptr && count > 0) | ||
| { | ||
| for (uint16_t i = 0; i < count; ++i) | ||
| { | ||
| if (buffer[i] != nullptr) | ||
| { | ||
| robustnessLevels.push_back(std::string(buffer[i])); | ||
| free(buffer[i]); | ||
| } | ||
| } | ||
| free(buffer); | ||
| return true; | ||
| } | ||
| if (buffer != nullptr) | ||
| { | ||
| free(buffer); | ||
| } | ||
| return false; | ||
| } |
| void Timer::cancel() | ||
| { | ||
| m_active = false; | ||
| m_cv.notify_one(); | ||
|
|
||
| if (std::this_thread::get_id() == m_thread.get_id()) | ||
| { | ||
| if (m_thread.joinable()) | ||
| { | ||
| m_thread.detach(); | ||
| } | ||
| return; | ||
| } | ||
|
|
||
| if (std::this_thread::get_id() != m_thread.get_id() && m_thread.joinable()) | ||
| if (m_thread.joinable()) | ||
| { | ||
| m_cv.notify_one(); | ||
| m_thread.join(); | ||
| } |
RDKDEV-1509: Fix for native build - biolerplate removed Reason for change: Remove left over boilerplate (looks like a copy-paste from stubs/wpeframework-core/CMakeLists.txt, which creates real SHARED library - .cpp files are present there). WPEFrameworkCOM here is INTERFACE-only (no .cpp files) - setting SOVERSION/VERSION on an INTERFACE target and installing it produces no installed artifacts at all — it's a no-op. It might be silently accepted in some environments, but might also result in compile error. The error I get in Ubuntu 20 env with gcc 9.4.0 and cmake 3.16.3 is: CMake Error at stubs/wpeframework-com/CMakeLists.txt:81 (set_target_properties): INTERFACE_LIBRARY targets may only have whitelisted properties. The property "VERSION" is not allowed. Test Procedure: Rialto CI Co-authored-by: Marcin Wojciechowski <105790697+skywojciechowskim@users.noreply.github.com>
There was a problem hiding this comment.
🔵 Needs a closer look
There are confirmed correctness risks (Timer self-detach/lifetime use-after-free potential, and SessionServerApp kill state not updated) that should be addressed before approval.
Review details
Suppressed comments (2)
common/source/Timer.cpp:105
- Timer::cancel() detaches the worker thread when called from within the timer thread. If the callback deletes the Timer (e.g. owner resets a unique_ptr in the callback), the thread continues executing and still accesses members like m_active after the callback returns, which becomes a use-after-free. The implementation needs to ensure the timer thread never dereferences
thisafter a callback that may destroy the object (e.g. move all thread-shared state into a separate shared state object, or prevent destruction on the timer thread and guarantee a join from another thread).
serverManager/common/source/SessionServerApp.cpp:301 - SessionServerApp::kill() no longer clears m_pid after issuing SIGKILL. That leaves the object thinking a process is still running and can cause repeated kill attempts or incorrect state transitions later (including in other code paths that check m_pid > 0).
- Files reviewed: 300/407 changed files
- Comments generated: 0 new
- Review effort level: Lite
RDKEMW-15126: Suspended state introduced Reason for change: Introduced the new Rialto Server state - Suspended Test Procedure: https://ccp.sys.comcast.net/browse/CATR-58251
There was a problem hiding this comment.
🟡 Changes recommended
There are confirmed correctness issues in newly added code paths (e.g., robustness-level query returning false on successful empty results, and a timer cancellation/detach pattern that can lead to use-after-free if a timer is destroyed from its own callback).
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (1)
common/source/Timer.cpp:99
Timer::~Timer()always callscancel(), andcancel()detaches the worker thread when it is invoked from within that same worker thread. If a timer is destroyed from inside its own callback (executing on the timer thread), the object can be freed while the thread lambda still continues and accessesthis(e.g., loop conditionm_active/ finalm_active = false), leading to a use-after-free race. Consider refactoring the thread to capture a shared state object (owned by bothTimerand the thread) so the thread never touches freedthis, or otherwise prevent destruction from the callback thread safely.
- Files reviewed: 300/437 changed files
- Comments generated: 3
- Review effort level: Lite
| #include "opencdm/open_cdm_ext.h" | ||
| #include <stdexcept> | ||
|
|
| * @param[in] args : Additional arguments depending on the operation | ||
| * | ||
| * @retval on success returns the new socket fd | ||
| */ | ||
| virtual int fcntl(int fd, int op, int args) const = 0; |
…lush calls (#583) RDKEMW-23222: Fix sending additional GST segment after back to back flush calls Reason for change: Fix sending additional GST segment after back to back flush calls Test Procedure: https://ccp.sys.comcast.net/browse/CATR-57946 --------- Co-authored-by: Sasa Mudri <Sasa_Mudri@comcast.com>
There was a problem hiding this comment.
🔵 Needs a closer look
There are correctness and API-safety issues in the new timer cancel/detach behavior and wrapper/system interfaces (plus a concrete playback-rate segment start bug) that should be addressed before approval.
Review details
Suppressed comments (2)
Previously missed (1) — in code that hasn't changed since the last review.
media/server/gstplayer/source/tasks/generic/SetPlaybackRate.cpp:81
audioGstSegmentPositionis initialized to -1; assigning it directly tosegment->start(aGstClockTime/unsigned) will wrap to a huge value if a rate change happens before the first audio segment is pushed.
common/source/Timer.cpp:97
Timer::cancel()detaches the worker thread when called from the timer thread itself. If the timer object is destroyed from inside the callback, the detached thread continues and still accessesthis(e.g., the loop condition andm_active = false), which can lead to use-after-free.
- Files reviewed: 300/437 changed files
- Comments generated: 0 new
- Review effort level: Lite
RDKEMW-24139: Support same caps audio switch Reason for change: Fixes issue with audio codec change when same caps are provided Test Procedure: https://ccp.sys.comcast.net/browse/CATR-57946 --------- Co-authored-by: Sasa Mudri <Sasa_Mudri@comcast.com>
There was a problem hiding this comment.
🔵 Needs a closer look
There are at least one confirmed concurrency-lifetime risk in Timer::cancel() (self-detach with this capture) and a test robustness issue around unchecked open() results that should be addressed before approval.
Review details
Suppressed comments (1)
common/source/Timer.cpp:97
Timer::cancel()detaches the timer thread when called from the timer thread itself. This avoids self-join, but it makes it possible for theTimerobject to be destroyed while the thread function still accessesthis(e.g., if the callback triggersTimerdestruction), leading to use-after-free. Consider refactoring so the worker thread only captures shared state (e.g.,std::shared_ptr<State>holdingm_active/m_callback) and theTimerobject can be safely destroyed even if cancellation/destruction happens on the timer thread.
- Files reviewed: 300/437 changed files
- Comments generated: 0 new
- Review effort level: Lite
RDKEMW-19123: Fix race condition in ServerManager Reason for change: Fixes race condition between concurrent teardown of ServiceCtx and re-connection of the preloaded Session Server Test Procedure: https://ccp.sys.comcast.net/browse/CATR-57539 --------- Co-authored-by: Sasa Mudri <Sasa_Mudri@comcast.com>
There was a problem hiding this comment.
🔵 Needs a closer look
There is a confirmed timer lifecycle/threading hazard (detach on self-cancel with a this-capturing worker thread) that can lead to use-after-free when destroyed from the callback thread.
Review details
Suppressed comments (1)
common/source/Timer.cpp:97
- The timer thread lambda captures
this; if the Timer is destroyed from its own callback thread,cancel()detaches and returns, but the thread continues after the callback and will still read members (e.g. the loop conditionm_active), which becomes a use-after-free risk. Detaching also makes it easy to silently leak work if callbacks re-arm timers.
- Files reviewed: 300/444 changed files
- Comments generated: 0 new
- Review effort level: Lite
RDKEMW-18181: CPU and Memory metrics Reason for change: Add automatic metrics collection for CPU and Memory usage for both the client and server sessions. Report data on >10% change or state transition. Test Procedure: Rialto CI --------- Signed-off-by: Douglas Adler <douglas.adler@yahoo.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…#604) BCM-1983: Add audio/x-vorbis & video/x-vp8 to recognizable mime types Reason for change: Failures in vorbis/vp8 playback Test Procedure: Any vorbis/vp8 playback via direct link, https://wpt.live/webrtc/protocol/video-codecs.https.html
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
One or more issues must be addressed before approval.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 4
Open (9)
Signal initialization failure to prevent waiters blocking forever · New Invalidate socket after cleanup to prevent descriptor reuse closure · New Restore installation of WPEFrameworkCOM package and target · New Timer::cancel() detaches the worker thread when called from the timer thread itself. This avoids… Preserve configured Wayland display for text-track sink · New This file callsfree(...)but does not include<cstdlib>(it currently relies on transitive…open("/dev/null", ...)can fail (returning -1). The current test unconditionally calls… getSupportedRobustnessLevels currently returns false when the underlying OpenCDM call succeeds but… Thefcntlwrapper comment says it returns “the new socket fd”, butfcntl()can return many…
| auto glibWrapper = firebolt::rialto::wrappers::IGlibWrapperFactory::getFactory()->getGlibWrapper(); | ||
| if (!glibWrapper) | ||
| { | ||
| RIALTO_SERVER_LOG_ERROR("Failed to create the glib wrapper"); | ||
| return; |
| if (m_socks[0] >= 0) | ||
| { | ||
| m_linuxWrapper->close(m_socks[0]); | ||
| } |
| INTERFACE | ||
| third-party/Source | ||
| ) |
| const std::string kDisplay{"westeros-asplayer-subtitles"}; | ||
| GstRialtoTextTrackSink *self = GST_RIALTO_TEXT_TRACK_SINK(sink); | ||
| try | ||
| { | ||
| self->priv->m_textTrackSession = | ||
| firebolt::rialto::server::ITextTrackSessionFactory::getFactory().createTextTrackSession(display); | ||
| firebolt::rialto::server::ITextTrackSessionFactory::getFactory().createTextTrackSession(kDisplay); |
| // Update previous sample | ||
| { | ||
| std::lock_guard<std::mutex> lock{m_mutex}; | ||
| m_previousSample = |
| auto report{sessionState.aggregator.finalize(kNowMs)}; | ||
| StateTransitionReport transitionReport; | ||
| transitionReport.context = context; | ||
| transitionReport.metrics = report; |
| auto report{m_globalAggregator.finalize(kNowMs)}; | ||
| StateTransitionReport transitionReport; | ||
| transitionReport.context = "global"; | ||
| transitionReport.metrics = report; |
…#597) RDKEMW-23040: Property applied before brcmvidfilter NULL→READY Reason for change: It's a race between two independent processes, and a race has two possible outcomes each run. Property applied before brcmvidfilter NULL→READY → configured in time → PASS and property applied after brcmvidfilter NULL→READY → missed the window → FAIL Test Procedure: https://ccp.sys.comcast.net/browse/RDKEMW-23040 --------- Co-authored-by: Kokinovic <akokin261@cable.comcast.com>
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Unresolved critical and moderate findings affect thread safety, lifecycle safety, initialization, display handling, installation, and DRM behavior.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 5
Open (10)
Unsynchronized shutdown flag causes a data race · New Restore installation of WPEFrameworkCOM package and target Invalidate socket after cleanup to prevent descriptor reuse closure Signal initialization failure to prevent waiters blocking forever Timer::cancel() detaches the worker thread when called from the timer thread itself. This avoids… Preserve configured Wayland display for text-track sink This file callsfree(...)but does not include<cstdlib>(it currently relies on transitive…open("/dev/null", ...)can fail (returning -1). The current test unconditionally calls… getSupportedRobustnessLevels currently returns false when the underlying OpenCDM call succeeds but… Thefcntlwrapper comment says it returns “the new socket fd”, butfcntl()can return many…
| int m_serverId; | ||
| std::unique_ptr<common::ISessionServerAppManager> &m_sessionServerAppManager; | ||
| int m_socket; | ||
| bool m_isServerShuttingDown{false}; |
RDKEMW-23564: Media Capabilities from yaml file Implementation Reason for change: Add AudioDecoderCapabilities and VideoDecoderCapabilities with YAML config parsing, IPC serialization and unit test coverage. Test Procedure: https://ccp.sys.comcast.net/browse/RDKEMW-23564 --------- Co-authored-by: uganes412_comcast <Usha_Ganeshpandian@comcast.com>
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Unresolved critical and moderate findings remain in initialization failure handling, display routing, capability stubs, package installation, and dependency configuration.
Review effort: Lite
Findings: 7
Open (13)
Publish factory failure state and wake initialization waiters · New Make yaml-cpp dependency conditional across build configurations · New Unsynchronized shutdown flag causes a data race Restore installation of WPEFrameworkCOM package and target Invalidate socket after cleanup to prevent descriptor reuse closure Signal initialization failure to prevent waiters blocking forever Timer::cancel() detaches the worker thread when called from the timer thread itself. This avoids… Treat empty capability results as successful queries · New Preserve configured Wayland display for text-track sink This file callsfree(...)but does not include<cstdlib>(it currently relies on transitive…open("/dev/null", ...)can fail (returning -1). The current test unconditionally calls… getSupportedRobustnessLevels currently returns false when the underlying OpenCDM call succeeds but… Thefcntlwrapper comment says it returns “the new socket fd”, butfcntl()can return many…
| auto glibWrapper = firebolt::rialto::wrappers::IGlibWrapperFactory::getFactory()->getGlibWrapper(); | ||
| if (!glibWrapper) | ||
| { | ||
| RIALTO_SERVER_LOG_ERROR("Failed to create the glib wrapper"); | ||
| return; |
| ${WRAPPER_LIBS} | ||
| ${GStreamerApp_LIBRARIES} | ||
| yaml-cpp |
| OpenCDMError opencdm_system_supported_robustness(struct OpenCDMSystem *system, char ***robustness, uint16_t *count) | ||
| { | ||
| if (robustness) | ||
| *robustness = nullptr; | ||
| if (count) | ||
| *count = 0; | ||
| return ERROR_NONE; |



Summary: Performance improvements in play request and flush
Type: Fix
Test Plan: UT/CT, Fullstack
Jira: ENTDAI-1750 ENTDAI-1738 ENTDAI-485