Feature/vplay 12261 8.4 fake#1149
Conversation
… applicable to Sky UK Stream Boxes (#797) RDKEMW-8209: Fake tune integrated with IARM Reason for Change: RCA : Trigger the fake tune only when the device transitions from DEEPSLEEP to ON/STANDBY, we can make sure that HDMI is in the expected state and the playback should work as expected. This pull request implements a decoder pre-initialization feature for Sky UK Stream Boxes to improve tune time. The solution uses a "fake tune" mechanism that pre-warms the decoder when the device transitions from deep sleep to active power states (ON or STANDBY). The implementation integrates with the WPEFramework PowerController to monitor power state changes and trigger the fake tune at appropriate times. Key changes: Integration of PowerController to monitor power state transitions via Thunder/WPEFramework Implementation of a fake tune mechanism using a dummy manifest URL to initialize decoder resources Addition of special handling throughout the codebase to suppress errors and metrics for fake tune operations Test Guidance: refer ticket Risk: Low (has been patched to releases) --------- Signed-off-by: Alsameema <alsameema_ahmedansar@comcast.com> Signed-off-by: Anurag Krishnan <akrish513@cable.comcast.com> Co-authored-by: aahmed878 <Alsameema_Ahmedansar@comcast.com> Co-authored-by: nrames759 <Naren_Ramesh@comcast.com> Co-authored-by: narenr94 <51772499+narenr94@users.noreply.github.com> Co-authored-by: pstroffolino <Philip_Stroffolino@cable.comcast.com>
…#797) RDKEMW-8209: Fake tune integrated with IARM Reason for Change: RCA : Trigger the fake tune only when the device transitions from DEEPSLEEP to ON/STANDBY, we can make sure that HDMI is in the expected state and the playback should work as expected. This pull request implements a decoder pre-initialization feature to improve tune time. The solution uses a "fake tune" mechanism that pre-warms the decoder when the device transitions from deep sleep to active power states (ON or STANDBY). The implementation integrates with the WPEFramework PowerController to monitor power state changes and trigger the fake tune at appropriate times. Key changes: Integration of PowerController to monitor power state transitions via Thunder/WPEFramework Implementation of a fake tune mechanism using a dummy manifest URL to initialize decoder resources Addition of special handling throughout the codebase to suppress errors and metrics for fake tune operations Test Guidance: refer ticket Risk: Low (has been patched to releases) --------- Signed-off-by: Alsameema <alsameema_ahmedansar@comcast.com> Signed-off-by: Anurag Krishnan <akrish513@cable.comcast.com> Co-authored-by: aahmed878 <Alsameema_Ahmedansar@comcast.com> Co-authored-by: nrames759 <Naren_Ramesh@comcast.com> Co-authored-by: narenr94 <51772499+narenr94@users.noreply.github.com> Co-authored-by: pstroffolino <Philip_Stroffolino@cable.comcast.com>
…#797) RDKEMW-8209: Fake tune integrated with IARM Reason for Change: RCA : Trigger the fake tune only when the device transitions from DEEPSLEEP to ON/STANDBY, we can make sure that HDMI is in the expected state and the playback should work as expected. This pull request implements a decoder pre-initialization feature to improve tune time. The solution uses a "fake tune" mechanism that pre-warms the decoder when the device transitions from deep sleep to active power states (ON or STANDBY). The implementation integrates with the WPEFramework PowerController to monitor power state changes and trigger the fake tune at appropriate times. Key changes: Integration of PowerController to monitor power state transitions via Thunder/WPEFramework Implementation of a fake tune mechanism using a dummy manifest URL to initialize decoder resources Addition of special handling throughout the codebase to suppress errors and metrics for fake tune operations Test Guidance: refer ticket Risk: Low (has been patched to releases)
There was a problem hiding this comment.
Pull request overview
Implements a “decoder pre-initialization” (fake tune) flow intended to improve tune time by pre-warming decoder resources, primarily driven by power-state transitions (deep sleep → ON/STANDBY) via WPEFramework PowerController, and suppresses error/metrics noise for those fake-tune operations.
Changes:
- Adds PowerController integration (via IARM path) and a callback mechanism to trigger fake tune on specific power transitions.
- Introduces
doFakeTune()and wires it through the externals interface (plus JS bindings), along with fake-tune-specific suppression in error/metrics/DRM paths. - Adds build-time enablement (
CMAKE_PREINIT_DECODER/USE_PREINIT_DECODING) and updates unit-test fakes for new interfaces/signatures.
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| test/utests/fakes/FakePlayerInstanceAamp.cpp | Updates fake PlayerInstanceAAMP ctor signature to match new parameter list. |
| test/utests/fakes/FakePlayerExternalsInterface.cpp | Adds stub implementations for newly introduced externals methods used by preinit flow. |
| priv_aamp.cpp | Suppresses error and tune-metrics profiling for fake-tune URL. |
| middleware/externals/rdk/PlayerExternalsRdkInterface.h | Adds power-event flag and fake-tune callback plumbing to RDK externals implementation. |
| middleware/externals/rdk/PlayerExternalsRdkInterface.cpp | Implements power-event + fake-tune callback setters/getters. |
| middleware/externals/rdk/IIarm/DeviceIARMInterface.cpp | Integrates PowerController client lifecycle + power-change callback to trigger fake tune. |
| middleware/externals/PlayerExternalsInterfaceBase.h | Extends externals base interface with power-event + fake-tune callback APIs. |
| middleware/externals/PlayerExternalsInterface.h | Adds stubbed implementations in Fake externals and new wrapper methods. |
| middleware/externals/PlayerExternalsInterface.cpp | Implements wrapper methods and adds IsDevicePropertiesPresent() helper. |
| middleware/externals/CMakeLists.txt | Adds build flag and link dependency for WPEFramework PowerController when enabled. |
| main_aamp.h | Declares doFakeTune() and adds powerEvt parameter to PlayerInstanceAAMP ctor. |
| main_aamp.cpp | Implements doFakeTune() and wires callback/power-event enablement into externals init. |
| jsbindings/jsmediaplayer.cpp | Triggers doFakeTune() during JS load when preinit decoding is enabled. |
| jsbindings/jsbindings.cpp | Constructs JS singleton PlayerInstanceAAMP with power events enabled. |
| drm/AampDRMLicManager.cpp | Short-circuits license acquisition for fake tune URL. |
| CMakeLists.txt | Adds top-level USE_PREINIT_DECODING defines when CMAKE_PREINIT_DECODER is set. |
| AampDefine.h | Defines FAKE_TUNE_URL constant used to identify fake tune. |
| AampDRMLicPreFetcher.cpp | Skips DRM failure error event emission when mIsFakeTune is set. |
Comments suppressed due to low confidence (2)
priv_aamp.cpp:3509
- When
mManifestUrl == FAKE_TUNE_URL,profiler.TuneEnd(...)is skipped, butSendTuneMetricsEvent(tuneData)is still executed if the listener is available. SincetuneDataremains the empty string in that case, this will emit an empty/invalid tune-metrics event. If fake tune should suppress tune-time metrics, gate theSendTuneMetricsEventcall the same way (or only send whenTuneEndpopulatedtuneData).
if(mManifestUrl != FAKE_TUNE_URL)
{
profiler.TuneEnd(mTuneMetrics, mAppName,(mbPlayEnabled?STRFGPLAYER:STRBGPLAYER), mPlayerId, mPlayerPreBuffered, durationSeconds, activeInterfaceWifi, mFailureReason, eventAvailStatus ? &tuneData : NULL);
}
if(eventAvailStatus)
{
SendTuneMetricsEvent(tuneData);
}
priv_aamp.cpp:3540
- Same as
TuneFail(): whenmManifestUrl == FAKE_TUNE_URL,profiler.TuneEnd(...)is skipped butSendTuneMetricsEvent(tuneData)may still run withtuneDataleft as an empty string. Gate the event emission on the same fake-tune condition (or ensuretuneDatais populated) to avoid sending empty metrics.
if(mManifestUrl != FAKE_TUNE_URL)
{
profiler.TuneEnd(mTuneMetrics,mAppName,(mbPlayEnabled?STRFGPLAYER:STRBGPLAYER), mPlayerId, mPlayerPreBuffered, durationSeconds, activeInterfaceWifi, mFailureReason, eventAvailStatus ? &tuneData : NULL);
}
if(eventAvailStatus)
{
SendTuneMetricsEvent(tuneData);
}
| #ifdef USE_PREINIT_DECODING | ||
| if(mManifestUrl.compare(FAKE_TUNE_URL) == 0) | ||
| { | ||
| AAMPLOG_WARN("PrivateInstanceAAMP: Ignore error for fake tune"); | ||
| return; | ||
| } | ||
| #endif |
There was a problem hiding this comment.
SendErrorEvent() checks mManifestUrl for fake-tune before acquiring mLock. Since mManifestUrl is written during Tune(), reading it without holding the same lock can introduce a data race/UB. Move the fake-tune check to after mLock is acquired (or use an existing fake-tune flag that is safe to read here) so the early-return is thread-safe.
| if(pInstance->GetDoFakeTuneCallBack()) | ||
| { | ||
| MW_LOG_INFO("Calling Fake tune callback"); | ||
| pInstance->GetDoFakeTuneCallBack()(); |
There was a problem hiding this comment.
In triggerFakeTune(), GetDoFakeTuneCallBack() is called twice (once in the if and again to invoke), which creates an avoidable race window and redundant copies of the std::function. Read it once into a local variable (e.g., auto cb = ...) and invoke that local copy if it is set.
| if(pInstance->GetDoFakeTuneCallBack()) | |
| { | |
| MW_LOG_INFO("Calling Fake tune callback"); | |
| pInstance->GetDoFakeTuneCallBack()(); | |
| auto cb = pInstance->GetDoFakeTuneCallBack(); | |
| if (cb) | |
| { | |
| MW_LOG_INFO("Calling Fake tune callback"); | |
| cb(); |
| std::shared_ptr<PlayerInstanceAAMP> fakeTuneInstance = std::make_shared<PlayerInstanceAAMP>(nullptr, nullptr); | ||
| std::string jsonStr = R"({ | ||
| "preferredDrm": 1, | ||
| "licenseServerUrl": "https://dummy.com" | ||
| })"; | ||
| fakeTuneInstance->InitAAMPConfig(jsonStr.c_str()); | ||
| fakeTuneInstance->Tune( | ||
| FAKE_TUNE_URL, | ||
| true, // autoPlay | ||
| "VOD", // contentType | ||
| true, // bFirstAttempt | ||
| false, // bFinalAttempt |
There was a problem hiding this comment.
doFakeTune() tunes to FAKE_TUNE_URL without the existing fakeTune=true marker. In PrivateInstanceAAMP::Tune() the mIsFakeTune flag is currently derived from strcasestr(mainManifestUrl, "fakeTune=true"), so this new fake-tune path will not set mIsFakeTune and may still emit events/metrics in code paths that key off that flag. Consider appending ?fakeTune=true to the fake-tune URL (or otherwise setting mIsFakeTune explicitly for this path) so existing fake-tune suppression logic is consistently applied.
| #include "PlayerExternalUtils.h" | ||
|
|
||
| constexpr int POWER_CONTROLLER_CONNECT_MAX_RETRIES = 50; // ~15 seconds total | ||
| constexpr useconds_t POWER_CONTROLLER_RETRY_SLEEP_MICROSECONDS = 300000; // 300 ms |
There was a problem hiding this comment.
POWER_CONTROLLER_RETRY_SLEEP_MICROSECONDS uses useconds_t but this file doesn't include the header that defines it (typically <unistd.h>/<sys/types.h>). Also these constexpr declarations are outside #ifdef USE_PREINIT_DECODING, so builds without USE_PREINIT_DECODING may fail due to the unknown type. Wrap these constants in the #ifdef block or use a standard integer type and include the proper header.
| constexpr useconds_t POWER_CONTROLLER_RETRY_SLEEP_MICROSECONDS = 300000; // 300 ms | |
| constexpr unsigned int POWER_CONTROLLER_RETRY_SLEEP_MICROSECONDS = 300000; // 300 ms |
| void DeviceIARMInterface::Initialize() | ||
| { | ||
| if(s_pDeviceIARMInterface) | ||
| { | ||
| #ifdef USE_PREINIT_DECODING | ||
| if(!IsContainerEnvironment()) | ||
| { | ||
| MW_LOG_INFO("\nCalling terminatePowerController()"); | ||
| terminatePowerController(); | ||
| } |
There was a problem hiding this comment.
DeviceIARMInterface::Initialize() unconditionally calls terminatePowerController() (when not in container). Since Initialize() is invoked from PlayerExternalsRdkInterface::Initialize() and can be called multiple times (including during the fake-tune instance construction), this will unregister the power callback and tear down the PowerController client, preventing subsequent power-transition triggers and potentially racing with the connect thread. Only terminate during shutdown/destruction, or guard with an "initialized/registered" flag (and avoid tearing down while the connect thread may be running).
| #ifdef USE_PREINIT_DECODING | ||
| doFakeTune(); | ||
| #endif |
There was a problem hiding this comment.
Calling doFakeTune() directly from AAMPPlayer_LoadJS() triggers a fake tune on every JS bindings load (and does so synchronously on the load path). This doesn't align with the stated goal of triggering fake tune only on deep-sleep -> ON/STANDBY transitions, and it risks adding startup latency or side effects during plugin initialization. Gate this call on the intended power-transition logic (or dispatch it asynchronously / remove it from JS load).
| * | ||
| * This function initiates a fake tune using a predefined manifest URL, | ||
| * primarily used for testing and validation scenarios. | ||
| * |
There was a problem hiding this comment.
The doc comment for doFakeTune() says it's "primarily used for testing and validation scenarios", but in this change it is part of a production pre-init decoder workflow triggered by power transitions. Updating the comment to reflect its real purpose (decoder pre-warm on wake) will avoid confusing API consumers/maintainers.
| * | |
| * This function initiates a fake tune using a predefined manifest URL, | |
| * primarily used for testing and validation scenarios. | |
| * | |
| * | |
| * This function initiates a fake tune using a predefined manifest URL in order | |
| * to pre-initialize (pre-warm) the decoder pipeline, for example as part of | |
| * the pre-init decoder workflow triggered by power transitions (wake from | |
| * low-power/sleep). It can also be used in testing and validation scenarios. | |
| * |
VPLAY-12261: Tune time improvement with preinit Decoder Functionality (#797)