From 9e11b23f0b5da39b06c6554fd0234c2b6d69b4e0 Mon Sep 17 00:00:00 2001 From: Nejuma28 Date: Wed, 7 Jan 2026 20:05:05 +0530 Subject: [PATCH 01/19] RDKEMW-11877 : Metrics Collection for Player Interface Public APIs Reason for change : Integrating code for metrics collection Test Procedure : Enable info logs to see metrics related logs Priority : P1 Risks : None Signed-off-by : nejumathoppil_nazar@comcast.com --- CMakeLists.txt | 3 +++ InterfacePlayerRDK.cpp | 47 +++++++++++++++++++++++++++++++++++++++++- PerfProfiler.cpp | 16 ++++++++++++++ PerfProfiler.h | 20 ++++++++++++++++++ 4 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 PerfProfiler.cpp create mode 100644 PerfProfiler.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 12649c98..0af4fc9f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -160,6 +160,7 @@ set(LIBPLAYERGSTINTERFACE_HEADERS vendor/default/DefaultSocInterface.h subtitle/vttCue.h ProcessHandler.h + PerfProfiler.h ) install(FILES closedcaptions/CCTrackInfo.h @@ -197,6 +198,7 @@ install(FILES closedcaptions/CCTrackInfo.h subtec/libsubtec/SubtecPacket.hpp playerisobmff/playerisobmffbuffer.h playerisobmff/playerisobmffbox.h + PerfProfiler.h DESTINATION include) set(SOURCES @@ -211,6 +213,7 @@ set(SOURCES vendor/default/DefaultSocInterface.cpp drm/processProtectionHls.cpp ProcessHandler.cpp + PerfProfiler.cpp ) if(NOT (CMAKE_PLATFORM_UBUNTU OR CMAKE_SYSTEM_NAME STREQUAL "Darwin")) diff --git a/InterfacePlayerRDK.cpp b/InterfacePlayerRDK.cpp index 1e8c4393..8da0c8a1 100644 --- a/InterfacePlayerRDK.cpp +++ b/InterfacePlayerRDK.cpp @@ -35,6 +35,7 @@ #include "player-xternal-stats.h" #endif #include "PlayerUtils.h" +#include "PerfProfiler.h" #define DEFAULT_BUFFERING_TO_MS 10 /**< TimeOut interval to check buffer fullness */ #define DEFAULT_BUFFERING_MAX_MS (1000) /**< max buffering time */ @@ -261,6 +262,7 @@ void InterfacePlayerRDK::ConfigurePipeline(int format, int audioFormat, int subF bool bESChangeStatus, bool setReadyAfterPipelineCreation, bool isSubEnable, int32_t trackId, gint rate, const char *pipelineName, int PipelinePriority, bool FirstFrameFlag, std::string manifestUrl) { + MW_PROFILE_FUNCTION(); mFirstFrameRequired = FirstFrameFlag; GstStreamOutputFormat gstFormat = static_cast(format); GstStreamOutputFormat gstAudioFormat = static_cast(audioFormat); @@ -506,6 +508,7 @@ static GstBusSyncReply bus_sync_handler(GstBus * bus, GstMessage * msg, Interfac void InterfacePlayerRDK::SetPauseOnStartPlayback(bool enable) { + MW_PROFILE_FUNCTION(); interfacePlayerPriv->gstPrivateContext->pauseOnStartPlayback = enable; } @@ -553,6 +556,7 @@ static void GstPlayer_OnFirstVideoFrameCallback(GstElement* object, guint arg0, */ const MonitorAVState& InterfacePlayerRDK::GetMonitorAVState() { + MW_PROFILE_FUNCTION(); return interfacePlayerPriv->gstPrivateContext->monitorAVstate; } @@ -799,6 +803,7 @@ bool gst_StartsWith( const char *inputStr, const char *prefix ); */ void InterfacePlayerRDK::setEncryption(void *Encrypt, void *DRMSessionManager) { + MW_PROFILE_FUNCTION(); mEncrypt = Encrypt; mDRMSessionManager = DRMSessionManager; } @@ -809,6 +814,7 @@ void InterfacePlayerRDK::setEncryption(void *Encrypt, void *DRMSessionManager) */ void InterfacePlayerRDK::SetPreferredDRM(const char *drmID) { + MW_PROFILE_FUNCTION(); if (drmID != NULL) { if (mDrmSystem != NULL) @@ -1036,6 +1042,7 @@ void InterfacePlayerRDK::RemoveProbe(int type) */ void InterfacePlayerRDK::DestroyPipeline() { + MW_PROFILE_FUNCTION(); if (interfacePlayerPriv->gstPrivateContext->pipeline) { /*"Destroying gstreamer pipeline" should only be logged when there is a pipeline to destroy @@ -1358,6 +1365,7 @@ void InterfacePlayerRDK::TearDownStream(int type) void InterfacePlayerRDK::Stop(bool keepLastFrame) { + MW_PROFILE_FUNCTION(); std::lock_guard lock(mMutex); /* make the execution of this function more deterministic and * reduce scope for potential pipeline lockups*/ @@ -1526,6 +1534,7 @@ bool InterfacePlayerRDK::IsUsingRialtoSink() */ bool InterfacePlayerRDK::Flush(double position, int rate, bool shouldTearDown, bool isAppSeek) { + MW_PROFILE_FUNCTION(); GstState aud_current; GstState aud_pending; GstState current; @@ -2518,11 +2527,13 @@ gboolean InterfacePlayerPriv::SendQtDemuxOverrideEvent(int mediaType, GstClockTi */ std::string InterfacePlayerRDK::GetVideoRectangle() { + MW_PROFILE_FUNCTION(); return std::string(interfacePlayerPriv->gstPrivateContext->videoRectangle); } void InterfacePlayerRDK::SetSubtitlePtsOffset(std::uint64_t pts_offset) { + MW_PROFILE_FUNCTION(); if (interfacePlayerPriv->gstPrivateContext->usingRialtoSink) { if(interfacePlayerPriv->gstPrivateContext->stream[eGST_MEDIATYPE_SUBTITLE].source) @@ -2557,6 +2568,7 @@ void InterfacePlayerRDK::ResetFirstFrame(void) GstPlaybackQualityStruct* InterfacePlayerRDK::GetVideoPlaybackQuality(void) { + MW_PROFILE_FUNCTION(); GstStructure *stats= 0; GstElement *element; if((interfacePlayerPriv->socInterface->IsPlaybackQualityFromSink())) @@ -2600,6 +2612,7 @@ GstPlaybackQualityStruct* InterfacePlayerRDK::GetVideoPlaybackQuality(void) */ long long InterfacePlayerRDK::GetPositionMilliseconds(void) { + MW_PROFILE_FUNCTION(); long long rc = 0; if (interfacePlayerPriv->gstPrivateContext->pipeline == NULL) { @@ -2672,6 +2685,7 @@ long long InterfacePlayerRDK::GetPositionMilliseconds(void) */ long InterfacePlayerRDK::GetDurationMilliseconds(void) { + MW_PROFILE_FUNCTION(); long rc = 0; if( interfacePlayerPriv->gstPrivateContext->pipeline ) { @@ -2716,6 +2730,7 @@ long InterfacePlayerRDK::GetDurationMilliseconds(void) */ void InterfacePlayerRDK::GetVideoSize(int &width, int &height) { + MW_PROFILE_FUNCTION(); int x; int y; int w = 0; @@ -2729,6 +2744,7 @@ void InterfacePlayerRDK::GetVideoSize(int &width, int &height) void InterfacePlayerRDK::SetSubtitleMute(bool muted) { + MW_PROFILE_FUNCTION(); interfacePlayerPriv->gstPrivateContext->subtitleMuted = muted; if (interfacePlayerPriv->gstPrivateContext->subtitle_sink) { @@ -2744,6 +2760,7 @@ void InterfacePlayerRDK::SetSubtitleMute(bool muted) */ void InterfacePlayerRDK::SetVideoRectangle(int x, int y, int w, int h) { + MW_PROFILE_FUNCTION(); int currentX = 0, currentY = 0, currentW = 0, currentH = 0; if (strcmp(interfacePlayerPriv->gstPrivateContext->videoRectangle, "") != 0) { @@ -2781,6 +2798,7 @@ void InterfacePlayerRDK::SetVideoRectangle(int x, int y, int w, int h) */ bool InterfacePlayerRDK::StopBuffering(bool forceStop, bool &isPlaying) { + MW_PROFILE_FUNCTION(); bool sendEndEvent = false; if (interfacePlayerPriv->gstPrivateContext->video_dec) { @@ -2832,6 +2850,7 @@ bool InterfacePlayerRDK::StopBuffering(bool forceStop, bool &isPlaying) */ unsigned long InterfacePlayerRDK::GetCCDecoderHandle() { + MW_PROFILE_FUNCTION(); gpointer dec_handle = NULL; if (interfacePlayerPriv->gstPrivateContext->usingClosedCaptionsControl) @@ -2899,6 +2918,7 @@ bool InterfacePlayerRDK::WaitForSourceSetup(int mediaType) bool InterfacePlayerRDK::HandleVideoBufferSent() { + MW_PROFILE_FUNCTION(); bool isFirstBuffer = (interfacePlayerPriv->gstPrivateContext->numberOfVideoBuffersSent == 0); interfacePlayerPriv->gstPrivateContext->numberOfVideoBuffersSent++; return isFirstBuffer; @@ -2906,6 +2926,7 @@ bool InterfacePlayerRDK::HandleVideoBufferSent() void InterfacePlayerRDK::SetPlayerName(std::string name) { + MW_PROFILE_FUNCTION(); interfacePlayerPriv->mPlayerName = name; } @@ -2914,6 +2935,7 @@ void InterfacePlayerRDK::SetPlayerName(std::string name) */ bool InterfacePlayerRDK::SendHelper(int type, const void *ptr, size_t len, double fpts, double fdts, double fDuration, double fragmentPTSoffset, bool copy, bool initFragment, bool &discontinuity, bool ¬ifyFirstBufferProcessed, bool &sendNewSegmentEvent, bool &resetTrickUTC, bool &firstBufferPushed) { + MW_PROFILE_FUNCTION(); GstMediaType mediaType = static_cast(type); GstClockTime pts = (GstClockTime)(fpts * GST_SECOND); GstClockTime dts = (GstClockTime)(fdts * GST_SECOND); @@ -3146,12 +3168,14 @@ bool InterfacePlayerRDK::SendHelper(int type, const void *ptr, size_t len, doubl void InterfacePlayerRDK::PauseInjector() { + MW_PROFILE_FUNCTION(); std::unique_lock lock(mSourceSetupMutex); mPauseInjector = true; } void InterfacePlayerRDK::ResumeInjector() { + MW_PROFILE_FUNCTION(); std::unique_lock lock(mSourceSetupMutex); mPauseInjector = false; mSourceSetupCV.notify_all(); @@ -3223,6 +3247,7 @@ void InterfacePlayerPriv::SendNewSegmentEvent(int type, GstClockTime startPts ,G */ void InterfacePlayerRDK::QueueProtectionEvent(const std::string& formatType, const char *protSystemId, const void *initData, size_t initDataSize, int mediaType) { + MW_PROFILE_FUNCTION(); /* There is a possibility that only single protection event is queued for multiple type since they are encrypted using same id. * Don't worry if you see only one protection event queued here. */ @@ -3257,6 +3282,7 @@ void InterfacePlayerRDK::QueueProtectionEvent(const std::string& formatType, con */ void InterfacePlayerRDK::ClearProtectionEvent() { + MW_PROFILE_FUNCTION(); pthread_mutex_lock(&mProtectionLock); for (int i = 0; i < GST_TRACK_COUNT; i++) { @@ -3309,6 +3335,7 @@ static GstState validateStateWithMsTimeout( InterfacePlayerRDK *pInterfacePlayer */ bool InterfacePlayerRDK::Pause(bool pause , bool forceStopGstreamerPreBuffering) { + MW_PROFILE_FUNCTION(); bool retValue = true; if (interfacePlayerPriv->gstPrivateContext->pipeline != NULL) { @@ -3360,6 +3387,7 @@ bool InterfacePlayerRDK::Pause(bool pause , bool forceStopGstreamerPreBuffering) */ bool InterfacePlayerRDK::CheckForPTSChangeWithTimeout(long timeout) { + MW_PROFILE_FUNCTION(); bool ret = true; gint64 currentPTS = GetVideoPTS(); /* Gets the currentPTS from the 'video-pts' property of the element */ if (currentPTS != 0) @@ -3393,6 +3421,7 @@ bool InterfacePlayerRDK::CheckForPTSChangeWithTimeout(long timeout) */ bool InterfacePlayerRDK::IsCacheEmpty(int Type) { + MW_PROFILE_FUNCTION(); GstMediaType mediaType = (GstMediaType)Type; bool ret = true; gst_media_stream *stream = &interfacePlayerPriv->gstPrivateContext->stream[mediaType]; @@ -3447,6 +3476,7 @@ void InterfacePlayerRDK::ResetEOSSignalledFlag() */ bool InterfacePlayerRDK::PipelineConfiguredForMedia(int type) { + MW_PROFILE_FUNCTION(); bool pipelineConfigured = true; gst_media_stream *stream = &interfacePlayerPriv->gstPrivateContext->stream[type]; @@ -3459,6 +3489,7 @@ bool InterfacePlayerRDK::PipelineConfiguredForMedia(int type) bool InterfacePlayerRDK::GetBufferControlData(int iMediaType) { + MW_PROFILE_FUNCTION(); bool GstWaitingForData = false; GstState current; GstState pending; @@ -3482,6 +3513,7 @@ bool InterfacePlayerRDK::GetBufferControlData(int iMediaType) } bool InterfacePlayerRDK::IsStreamReady(int mediaType) { + MW_PROFILE_FUNCTION(); bool StreamReady = false; const gst_media_stream *stream = &interfacePlayerPriv->gstPrivateContext->stream[mediaType]; @@ -3494,7 +3526,7 @@ bool InterfacePlayerRDK::IsStreamReady(int mediaType) */ void InterfacePlayerRDK::SignalTrickModeDiscontinuity() { - + MW_PROFILE_FUNCTION(); gst_media_stream* stream = &interfacePlayerPriv->gstPrivateContext->stream[eGST_MEDIATYPE_VIDEO]; if (stream && (interfacePlayerPriv->gstPrivateContext->rate != GST_NORMAL_PLAY_RATE) ) { @@ -3515,6 +3547,7 @@ void InterfacePlayerRDK::SignalTrickModeDiscontinuity() void InterfacePlayerRDK::EnableGstDebugLogging(std::string debugLevel) { + MW_PROFILE_FUNCTION(); if (!debugLevel.empty()) { gst_debug_set_threshold_from_string(debugLevel.c_str(), 1); @@ -3526,6 +3559,7 @@ void InterfacePlayerRDK::EnableGstDebugLogging(std::string debugLevel) */ bool InterfacePlayerRDK::CheckDiscontinuity(int mediaType, int streamFormat , bool codecChange, bool &unblockDiscProcess, bool &shouldHaltBuffering) { + MW_PROFILE_FUNCTION(); bool ret = false; GstMediaType type = (GstMediaType)mediaType; gst_media_stream *stream = &interfacePlayerPriv->gstPrivateContext->stream[type]; @@ -3929,6 +3963,7 @@ bool InterfacePlayerRDK::CreatePipeline(const char *pipelineName, int PipelinePr */ long long InterfacePlayerRDK::GetVideoPTS(void) { + MW_PROFILE_FUNCTION(); gint64 currentPTS = 0; currentPTS = interfacePlayerPriv->socInterface->GetVideoPts(interfacePlayerPriv->gstPrivateContext->video_sink, interfacePlayerPriv->gstPrivateContext->video_dec, interfacePlayerPriv->gstPrivateContext->using_westerossink); return (long long)currentPTS; @@ -4433,6 +4468,7 @@ static gboolean bus_message(GstBus * bus, GstMessage * msg, InterfacePlayerRDK * bool InterfacePlayerRDK::SetPlayBackRate(double rate) { + MW_PROFILE_FUNCTION(); bool ret = false; std::vector sources; MW_LOG_TRACE("InterfacePlayerRDK: gst_event_new_instant_rate_change: %f ...V6", rate); @@ -4452,6 +4488,7 @@ bool InterfacePlayerRDK::SetPlayBackRate(double rate) */ void InterfacePlayerRDK::SetAudioVolume(int volume) { + MW_PROFILE_FUNCTION(); interfacePlayerPriv->gstPrivateContext->audioVolume = static_cast(volume) / 100.0; } @@ -4460,6 +4497,7 @@ void InterfacePlayerRDK::SetAudioVolume(int volume) */ void InterfacePlayerRDK::SetVolumeOrMuteUnMute(void) { + MW_PROFILE_FUNCTION(); const std::lock_guard lock(interfacePlayerPriv->gstPrivateContext->volumeMuteMutex); GstElement *gSource = nullptr; const char *mutePropertyName = nullptr; @@ -4596,6 +4634,7 @@ static gboolean buffering_timeout (gpointer data) */ void InterfacePlayerRDK::SetVideoZoom(int zoom_mode) { + MW_PROFILE_FUNCTION(); MW_LOG_MIL(" SetVideoZoom :: ZoomMode %d, video_sink =%p",zoom_mode, interfacePlayerPriv->gstPrivateContext->video_sink); interfacePlayerPriv->gstPrivateContext->zoom = static_cast(zoom_mode); @@ -4614,6 +4653,7 @@ void InterfacePlayerRDK::SetVideoZoom(int zoom_mode) */ void InterfacePlayerRDK::SetVideoMute(bool muted) { + MW_PROFILE_FUNCTION(); MW_LOG_INFO("muted=%d video_sink =%p", muted, interfacePlayerPriv->gstPrivateContext->video_sink); interfacePlayerPriv->gstPrivateContext->videoMuted = muted; if (interfacePlayerPriv->gstPrivateContext->video_sink) @@ -4631,6 +4671,7 @@ void InterfacePlayerRDK::SetVideoMute(bool muted) */ bool InterfacePlayerRDK::SetTextStyle(const std::string &options) { + MW_PROFILE_FUNCTION(); bool ret = false; if (interfacePlayerPriv->gstPrivateContext->subtitle_sink) { @@ -4955,6 +4996,7 @@ void InterfacePlayerRDK::NotifyEOS() */ void InterfacePlayerRDK::NotifyFragmentCachingComplete() { + MW_PROFILE_FUNCTION(); if(interfacePlayerPriv->gstPrivateContext->pendingPlayState) { MW_LOG_MIL("InterfacePlayer: Setting pipeline to PLAYING state "); @@ -4976,6 +5018,7 @@ void InterfacePlayerRDK::NotifyFragmentCachingComplete() */ void InterfacePlayerRDK::EndOfStreamReached(int mediaType, bool &shouldHaltBuffering) { + MW_PROFILE_FUNCTION(); MW_LOG_MIL("entering InterfacePlayer_EndOfStreamReached type %d", mediaType); GstMediaType type = static_cast(mediaType); @@ -5034,6 +5077,7 @@ int InterfacePlayerRDK::InterfacePlayer_SetupStream(int streamId, std::string ma void InterfacePlayerRDK::DisableDecoderHandleNotified() { + MW_PROFILE_FUNCTION(); interfacePlayerPriv->gstPrivateContext->decoderHandleNotified = false; } @@ -5221,6 +5265,7 @@ void InterfacePlayerRDK::InitializePlayerGstreamerPlugins() */ double InterfacePlayerRDK::FlushTrack(int mediaType, double pos, double audioDelta, double subDelta) { + MW_PROFILE_FUNCTION(); double startPosition = 0; GstMediaType type = static_cast(mediaType); diff --git a/PerfProfiler.cpp b/PerfProfiler.cpp new file mode 100644 index 00000000..c9bd6694 --- /dev/null +++ b/PerfProfiler.cpp @@ -0,0 +1,16 @@ +#include "PerfProfiler.h" +#include +#include + +ScopedTimer::ScopedTimer(const std::string& funcName, const std::string& fileName, int line) + : name(funcName + " [" + fileName + ":" + std::to_string(line) + "]"), + start(std::chrono::high_resolution_clock::now()) {} + +ScopedTimer::~ScopedTimer() { + auto end = std::chrono::high_resolution_clock::now(); + long long duration = std::chrono::duration_cast(end - start).count(); + MW_LOG_INFO( "[PERF] %s (Thread %zu) took %lld us", + name.c_str(), + std::hash{}(std::this_thread::get_id()), + duration); +} diff --git a/PerfProfiler.h b/PerfProfiler.h new file mode 100644 index 00000000..f9b62488 --- /dev/null +++ b/PerfProfiler.h @@ -0,0 +1,20 @@ +#ifndef PERF_PROFILER_H +#define PERF_PROFILER_H + +#include +#include + +class ScopedTimer { +public: + ScopedTimer(const std::string& funcName, const std::string& fileName, int line); + ~ScopedTimer(); + +private: + std::string name; + std::chrono::high_resolution_clock::time_point start; +}; + +// Macro for easy integration +#define MW_PROFILE_FUNCTION() ScopedTimer timer(__FUNCTION__, __FILE__, __LINE__) + +#endif // PERF_PROFILER_H \ No newline at end of file From 32ae2d8d5ee33dd424eb770105adfbc454b99896 Mon Sep 17 00:00:00 2001 From: Nejuma28 Date: Wed, 7 Jan 2026 20:17:10 +0530 Subject: [PATCH 02/19] Adding necessary headers --- PerfProfiler.h | 1 + 1 file changed, 1 insertion(+) diff --git a/PerfProfiler.h b/PerfProfiler.h index f9b62488..590d2610 100644 --- a/PerfProfiler.h +++ b/PerfProfiler.h @@ -3,6 +3,7 @@ #include #include +#include "PlayerLogManager.h" class ScopedTimer { public: From fdbddc06755f401e1810233a8d49b2102587373b Mon Sep 17 00:00:00 2001 From: Nejuma28 Date: Wed, 7 Jan 2026 20:39:13 +0530 Subject: [PATCH 03/19] Adding option for conditional compilation --- CMakeLists.txt | 15 +++++++++++++++ PerfProfiler.cpp | 2 +- PerfProfiler.h | 7 +++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0af4fc9f..992ebb71 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,6 +26,12 @@ if(DISABLE_SECURITY_TOKEN) add_definitions(-DDISABLE_SECURITY_TOKEN) endif() +option(ENABLE_MW_PROFILING "Enable middleware profiling" ON) + +if(ENABLE_MW_PROFILING) + add_definitions(-DENABLE_MW_PROFILING) +endif() + # Option for building pi-cli option(BUILD_PICLI "Build the pi-cli test project" OFF) @@ -162,6 +168,9 @@ set(LIBPLAYERGSTINTERFACE_HEADERS ProcessHandler.h PerfProfiler.h ) +if(ENABLE_MW_PROFILING) + list(APPEND LIBPLAYERGSTINTERFACE_HEADERS PerfProfiler.h) +endif() install(FILES closedcaptions/CCTrackInfo.h PlayerScheduler.h @@ -200,6 +209,9 @@ install(FILES closedcaptions/CCTrackInfo.h playerisobmff/playerisobmffbox.h PerfProfiler.h DESTINATION include) +if(ENABLE_MW_PROFILING) + install(FILES PerfProfiler.h DESTINATION include) +endif() set(SOURCES InterfacePlayerRDK.cpp @@ -215,6 +227,9 @@ set(SOURCES ProcessHandler.cpp PerfProfiler.cpp ) +if(ENABLE_MW_PROFILING) + list(APPEND SOURCES PerfProfiler.cpp) +endif() if(NOT (CMAKE_PLATFORM_UBUNTU OR CMAKE_SYSTEM_NAME STREQUAL "Darwin")) list(APPEND SOURCES diff --git a/PerfProfiler.cpp b/PerfProfiler.cpp index c9bd6694..35e57470 100644 --- a/PerfProfiler.cpp +++ b/PerfProfiler.cpp @@ -12,5 +12,5 @@ ScopedTimer::~ScopedTimer() { MW_LOG_INFO( "[PERF] %s (Thread %zu) took %lld us", name.c_str(), std::hash{}(std::this_thread::get_id()), - duration); + duration) } diff --git a/PerfProfiler.h b/PerfProfiler.h index 590d2610..b1ca30a8 100644 --- a/PerfProfiler.h +++ b/PerfProfiler.h @@ -5,6 +5,8 @@ #include #include "PlayerLogManager.h" +#ifdef ENABLE_MW_PROFILING + class ScopedTimer { public: ScopedTimer(const std::string& funcName, const std::string& fileName, int line); @@ -18,4 +20,9 @@ class ScopedTimer { // Macro for easy integration #define MW_PROFILE_FUNCTION() ScopedTimer timer(__FUNCTION__, __FILE__, __LINE__) +#else + +#define MW_PROFILE_FUNCTION() //profiling disabled + +#endif //ENABLE_MW_PROFILING #endif // PERF_PROFILER_H \ No newline at end of file From 965ee324ccd928c017fa10b9d4eb77e351eb3e1e Mon Sep 17 00:00:00 2001 From: Nejuma28 Date: Thu, 8 Jan 2026 12:27:09 +0530 Subject: [PATCH 04/19] Fixing compilation issues --- PerfProfiler.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/PerfProfiler.cpp b/PerfProfiler.cpp index 35e57470..5127d6e0 100644 --- a/PerfProfiler.cpp +++ b/PerfProfiler.cpp @@ -2,6 +2,8 @@ #include #include +#ifdef ENABLE_MW_PROFILING + ScopedTimer::ScopedTimer(const std::string& funcName, const std::string& fileName, int line) : name(funcName + " [" + fileName + ":" + std::to_string(line) + "]"), start(std::chrono::high_resolution_clock::now()) {} @@ -12,5 +14,7 @@ ScopedTimer::~ScopedTimer() { MW_LOG_INFO( "[PERF] %s (Thread %zu) took %lld us", name.c_str(), std::hash{}(std::this_thread::get_id()), - duration) + duration); } + +#endif // ENABLE_MW_PROFILING From 3bc06c80c7bf019feca45dc88ef25a1b902ac489 Mon Sep 17 00:00:00 2001 From: Nejuma28 Date: Mon, 12 Jan 2026 17:15:21 +0530 Subject: [PATCH 05/19] Adding profiling function to public APIs --- InterfacePlayerRDK.cpp | 2 ++ externals/PlayerExternalsInterface.cpp | 11 +++++++++++ .../ContentSecurityManager.cpp | 12 ++++++++++++ 3 files changed, 25 insertions(+) diff --git a/InterfacePlayerRDK.cpp b/InterfacePlayerRDK.cpp index 8da0c8a1..e9fe98e5 100644 --- a/InterfacePlayerRDK.cpp +++ b/InterfacePlayerRDK.cpp @@ -2562,6 +2562,7 @@ void InterfacePlayerRDK::SetSubtitlePtsOffset(std::uint64_t pts_offset) */ void InterfacePlayerRDK::ResetFirstFrame(void) { + MW_PROFILE_FUNCTION(); MW_LOG_WARN("Reset first frame"); interfacePlayerPriv->gstPrivateContext->firstFrameReceived = false; } @@ -3468,6 +3469,7 @@ bool InterfacePlayerRDK::IsCacheEmpty(int Type) */ void InterfacePlayerRDK::ResetEOSSignalledFlag() { + MW_PROFILE_FUNCTION(); interfacePlayerPriv->gstPrivateContext->eosSignalled = false; } diff --git a/externals/PlayerExternalsInterface.cpp b/externals/PlayerExternalsInterface.cpp index ebb6d263..e9b94475 100644 --- a/externals/PlayerExternalsInterface.cpp +++ b/externals/PlayerExternalsInterface.cpp @@ -37,6 +37,7 @@ std::shared_ptr PlayerExternalsInterface::s_pPlayerOP */ PlayerExternalsInterface::PlayerExternalsInterface() { + MW_PROFILE_FUNCTION(); #ifdef IARM_MGR MW_PRE_LOGGER_LOG("Device API IARM/Firebolt\n"); m_pIarmInterface = PlayerExternalsRdkInterface::GetPlayerExternalsRdkInterfaceInstance(); @@ -52,12 +53,14 @@ PlayerExternalsInterface::PlayerExternalsInterface() */ PlayerExternalsInterface::~PlayerExternalsInterface() { + MW_PROFILE_FUNCTION(); m_pIarmInterface = nullptr; s_pPlayerOP = NULL; } void PlayerExternalsInterface::Initialize() { + MW_PROFILE_FUNCTION(); if(s_pPlayerOP != NULL) { MW_PRE_LOGGER_LOG("PlayerExternalsInterface::Initialize\n"); @@ -74,6 +77,7 @@ void PlayerExternalsInterface::Initialize() */ bool PlayerExternalsInterface::IsSourceUHD() { + MW_PROFILE_FUNCTION(); return m_pIarmInterface->IsSourceUHD(); } @@ -82,6 +86,7 @@ bool PlayerExternalsInterface::IsSourceUHD() */ void PlayerExternalsInterface::GetDisplayResolution(int &width, int &height) { + MW_PROFILE_FUNCTION(); m_pIarmInterface->GetDisplayResolution(width, height); } @@ -90,6 +95,7 @@ void PlayerExternalsInterface::GetDisplayResolution(int &width, int &height) */ bool PlayerExternalsInterface::IsPlayerExternalsInterfaceInstanceActive() { + MW_PROFILE_FUNCTION(); bool retval = false; if(s_pPlayerOP != NULL) { @@ -103,6 +109,7 @@ bool PlayerExternalsInterface::IsPlayerExternalsInterfaceInstanceActive() */ std::shared_ptr PlayerExternalsInterface::GetPlayerExternalsInterfaceInstance() { + MW_PROFILE_FUNCTION(); if(s_pPlayerOP == NULL) { s_pPlayerOP = std::shared_ptr(new PlayerExternalsInterface()); } @@ -115,6 +122,7 @@ std::shared_ptr PlayerExternalsInterface::GetPlayerExt */ char * PlayerExternalsInterface::GetTR181PlayerConfig(const char * paramName, size_t & iConfigLen) { + MW_PROFILE_FUNCTION(); char * sRet = nullptr; sRet = m_pIarmInterface->GetTR181Config(paramName, iConfigLen); return sRet; @@ -125,6 +133,7 @@ char * PlayerExternalsInterface::GetTR181PlayerConfig(const char * paramName, si */ bool PlayerExternalsInterface::GetActiveInterface() { + MW_PROFILE_FUNCTION(); bool bRet = false; bRet = m_pIarmInterface->GetActiveInterface(); return bRet; @@ -135,6 +144,7 @@ bool PlayerExternalsInterface::GetActiveInterface() */ bool PlayerExternalsInterface::IsConfigWifiCurlHeader() { + MW_PROFILE_FUNCTION(); bool bRet = false; #ifdef IARM_MGR bRet = true; @@ -146,5 +156,6 @@ bool PlayerExternalsInterface::IsConfigWifiCurlHeader() void PlayerExternalsInterface::SetUseFireBoltSDK(bool t_use_firebolt_sdk) { + MW_PROFILE_FUNCTION(); m_pIarmInterface->SetUseFireBoltSDK(t_use_firebolt_sdk); } diff --git a/externals/contentsecuritymanager/ContentSecurityManager.cpp b/externals/contentsecuritymanager/ContentSecurityManager.cpp index cfd10811..878ed165 100755 --- a/externals/contentsecuritymanager/ContentSecurityManager.cpp +++ b/externals/contentsecuritymanager/ContentSecurityManager.cpp @@ -53,6 +53,7 @@ static bool mUseFireboltSDK = false; */ ContentSecurityManager* ContentSecurityManager::GetInstance() { + MW_PROFILE_FUNCTION(); std::lock_guard lock{InstanceMutex}; if(Instance == nullptr) { @@ -80,6 +81,7 @@ ContentSecurityManager* ContentSecurityManager::GetInstance() */ void ContentSecurityManager::DestroyInstance() { + MW_PROFILE_FUNCTION(); std::lock_guard lock{InstanceMutex}; if (Instance) { @@ -93,6 +95,7 @@ void ContentSecurityManager::DestroyInstance() */ bool ContentSecurityManager::getSessionToken(std::string &token) { + MW_PROFILE_FUNCTION(); return false; } @@ -101,6 +104,7 @@ bool ContentSecurityManager::getSessionToken(std::string &token) */ void ContentSecurityManager::UseFireboltSDK(bool status) { + MW_PROFILE_FUNCTION(); MW_LOG_INFO("Set Use Firebolt SDK as %d",status); mUseFireboltSDK = status; } @@ -109,6 +113,7 @@ std::size_t ContentSecurityManager::getInputSummaryHash(const char* moneyTraceMe size_t contMetaLen, const char* licenseRequest, const char* keySystemId, const char* mediaUsage, const char* accessToken, bool isVideoMuted) { + MW_PROFILE_FUNCTION(); std::stringstream ss; ss<< moneyTraceMetadata[0][1]<(playback_speed), static_cast(playback_position)); return rpcResult; @@ -207,6 +217,7 @@ bool ContentSecurityManager::setPlaybackSpeedState(int64_t sessionId, int64_t pl */ void ContentSecurityManager::setWatermarkSessionEvent_CB(const std::function& callback) { + MW_PROFILE_FUNCTION(); SendWatermarkSessionEvent_CB = callback; return; } @@ -216,6 +227,7 @@ void ContentSecurityManager::setWatermarkSessionEvent_CB(const std::function& ContentSecurityManager::getWatermarkSessionEvent_CB( ) { + MW_PROFILE_FUNCTION(); return SendWatermarkSessionEvent_CB; } From c35d40da7bc6736afceaeeba7a55bd63f1bbca11 Mon Sep 17 00:00:00 2001 From: nejuma1 Date: Thu, 29 Jan 2026 16:44:27 +0530 Subject: [PATCH 06/19] Update PlayerExternalsInterface.cpp to include PerfProfiler.h --- externals/PlayerExternalsInterface.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/externals/PlayerExternalsInterface.cpp b/externals/PlayerExternalsInterface.cpp index e9b94475..a71db0e8 100644 --- a/externals/PlayerExternalsInterface.cpp +++ b/externals/PlayerExternalsInterface.cpp @@ -24,6 +24,7 @@ #include "PlayerExternalsInterface.h" #include "PlayerExternalUtils.h" +#include "PerfProfiler.h" #ifdef IARM_MGR #include "PlayerExternalsRdkInterface.h" From 6fcdd6a0c06fbe970533ca993d2e3a80199fd5fc Mon Sep 17 00:00:00 2001 From: nejuma1 Date: Thu, 29 Jan 2026 16:45:42 +0530 Subject: [PATCH 07/19] Update ContentSecurityManager.cpp to include PerfProfiler.h --- externals/contentsecuritymanager/ContentSecurityManager.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/externals/contentsecuritymanager/ContentSecurityManager.cpp b/externals/contentsecuritymanager/ContentSecurityManager.cpp index 878ed165..cdc95d9b 100755 --- a/externals/contentsecuritymanager/ContentSecurityManager.cpp +++ b/externals/contentsecuritymanager/ContentSecurityManager.cpp @@ -25,6 +25,7 @@ #include "ContentProtectionFirebolt.h" #include "ContentSecurityManager.h" #include "PlayerLogManager.h" +#include "PerfProfiler.h" #include #include "_base64.h" #include // For PRId64 From 297873ae20c03a2d59c9edf1a89fd9829161afe6 Mon Sep 17 00:00:00 2001 From: nejuma1 Date: Tue, 17 Feb 2026 14:44:24 +0530 Subject: [PATCH 08/19] RDKEMW-11877: adding function for profiling --- InterfacePlayerRDK.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/InterfacePlayerRDK.cpp b/InterfacePlayerRDK.cpp index e9fe98e5..823852db 100644 --- a/InterfacePlayerRDK.cpp +++ b/InterfacePlayerRDK.cpp @@ -184,6 +184,7 @@ static GstFlowReturn InterfacePlayerRDK_OnVideoSample(GstElement *object, void * InterfacePlayerPriv* InterfacePlayerRDK::GetPrivatePlayer() { + MW_PROFILE_FUNCTION(); return interfacePlayerPriv; } @@ -195,6 +196,7 @@ InterfacePlayerPriv* InterfacePlayerRDK::GetPrivatePlayer() */ bool InterfacePlayerRDK::IsPipelinePaused() { + MW_PROFILE_FUNCTION(); return interfacePlayerPriv->gstPrivateContext->paused; } @@ -203,6 +205,7 @@ bool InterfacePlayerRDK::IsPipelinePaused() */ void InterfacePlayerRDK::EnablePendingPlayState() { + MW_PROFILE_FUNCTION(); interfacePlayerPriv->gstPrivateContext->pendingPlayState = true; } @@ -898,6 +901,7 @@ static void GstPlayer_SignalEOS(GstPlayerPriv* gstPrivateContext) */ void InterfacePlayerRDK::SetSeekPosition(double positionSecs) { + MW_PROFILE_FUNCTION(); interfacePlayerPriv->gstPrivateContext->seekPosition = positionSecs; for (int i = 0; i < GST_TRACK_COUNT; i++) { @@ -953,6 +957,7 @@ static std::set GetElementPointers(gpointer pElementOrBin) void InterfacePlayerRDK::DisconnectSignals() { + MW_PROFILE_FUNCTION(); const std::lock_guard lock(interfacePlayerPriv->gstPrivateContext->mSignalVectorAccessMutex); if(m_gstConfigParam->enableDisconnectSignals) { @@ -995,6 +1000,7 @@ void InterfacePlayerRDK::DisconnectSignals() */ void InterfacePlayerRDK::TimerRemove(guint& taskId, const char* timerName) { + MW_PROFILE_FUNCTION(); std::lock_guard lock(interfacePlayerPriv->gstPrivateContext->TaskControlMutex); if ( 0 != taskId ) { @@ -1013,6 +1019,7 @@ void InterfacePlayerRDK::TimerRemove(guint& taskId, const char* timerName) */ void InterfacePlayerRDK::RemoveProbes() { + MW_PROFILE_FUNCTION(); for (int i = 0; i < GST_TRACK_COUNT; i++) { RemoveProbe((int)i); @@ -1300,6 +1307,7 @@ static GstStateChangeReturn SetStateWithWarnings(GstElement *element, GstState t void InterfacePlayerRDK::TearDownStream(int type) { + MW_PROFILE_FUNCTION(); tearDownCb(true, type); gst_media_stream* stream = &interfacePlayerPriv->gstPrivateContext->stream[type]; RemoveProbe(type); @@ -1468,6 +1476,7 @@ void InterfacePlayerRDK::Stop(bool keepLastFrame) void InterfacePlayerRDK::ResetGstEvents() { + MW_PROFILE_FUNCTION(); for (int i = 0; i < GST_TRACK_COUNT; i++) { interfacePlayerPriv->gstPrivateContext->stream[i].resetPosition = true; @@ -1481,6 +1490,7 @@ void InterfacePlayerRDK::ResetGstEvents() void InterfacePlayerRDK::SetPendingSeek(bool state) { + MW_PROFILE_FUNCTION(); for (int i = 0; i < GST_TRACK_COUNT; i++) { interfacePlayerPriv->gstPrivateContext->stream[i].pendingSeek = state; @@ -1494,6 +1504,7 @@ bool InterfacePlayerRDK::GetTrickTeardown() void InterfacePlayerRDK::SetTrickTearDown(bool state) { + MW_PROFILE_FUNCTION(); trickTeardown = state; } @@ -1502,6 +1513,7 @@ void InterfacePlayerRDK::SetTrickTearDown(bool state) */ bool InterfacePlayerRDK::IdleTaskRemove(GstTaskControlData& taskDetails) { + MW_PROFILE_FUNCTION(); bool ret = false; std::lock_guard lock(interfacePlayerPriv->gstPrivateContext->TaskControlMutex); @@ -1783,6 +1795,7 @@ static void gst_enough_data(GstElement *source, void *_this) } void InterfacePlayerRDK::InitializeSourceForPlayer(void *PlayerInstance, void * source, int type) { + MW_PROFILE_FUNCTION(); InterfacePlayerRDK* _this = (InterfacePlayerRDK*)PlayerInstance; InterfacePlayerPriv* privatePlayer = _this->GetPrivatePlayer(); GstCaps * caps = NULL; @@ -2121,6 +2134,7 @@ GstFlowReturn InterfacePlayerRDK_OnVideoSample(GstElement* object, void *_this) */ void InterfacePlayerRDK::SetupClosedCaptionControlStream() { + MW_PROFILE_FUNCTION(); GstElement *subtitlebin = nullptr, *appsrc = nullptr, *textsink = nullptr; InterfacePlayerRDK* pInterfacePlayerRDK = (InterfacePlayerRDK*)this; @@ -3608,6 +3622,7 @@ bool InterfacePlayerRDK::CheckDiscontinuity(int mediaType, int streamFormat , bo */ void InterfacePlayerRDK::TimerAdd(GSourceFunc funcPtr, int repeatTimeout, guint& taskId, gpointer user_data, const char* timerName) { + MW_PROFILE_FUNCTION(); std::lock_guard lock(interfacePlayerPriv->gstPrivateContext->TaskControlMutex); if (funcPtr && user_data) { @@ -3644,6 +3659,7 @@ bool InterfacePlayerRDK::TimerIsRunning(guint& taskId) */ void InterfacePlayerRDK::IdleTaskClearFlags(GstTaskControlData& taskDetails) { + MW_PROFILE_FUNCTION(); std::lock_guard lock(interfacePlayerPriv->gstPrivateContext->TaskControlMutex); if ( 0 != taskDetails.taskID ) { @@ -3662,6 +3678,7 @@ void InterfacePlayerRDK::IdleTaskClearFlags(GstTaskControlData& taskDetails) */ bool InterfacePlayerRDK::IdleTaskAdd(GstTaskControlData& taskDetails, BackgroundTask funcPtr) { + MW_PROFILE_FUNCTION(); bool ret = false; std::lock_guard lock(interfacePlayerPriv->gstPrivateContext->TaskControlMutex); @@ -3708,6 +3725,7 @@ void InterfacePlayerRDK::TearDownCallback(std::function callbac */ void InterfacePlayerRDK::NotifyFirstFrame(int mediaType) { + MW_PROFILE_FUNCTION(); bool notifyFirstBuffer = false; bool audioOnly = false; bool requireFirstVideoFrameDisplay = false; @@ -3774,6 +3792,7 @@ void InterfacePlayerRDK::NotifyFirstFrame(int mediaType) void InterfacePlayerRDK::TriggerEvent(InterfaceCB event) { + MW_PROFILE_FUNCTION(); auto it = callbackMap.find(event); if (it != callbackMap.end()) { @@ -3909,6 +3928,7 @@ bool GstPlayer_isVideoSink(const char* name, InterfacePlayerRDK* pInterfacePlaye */ bool InterfacePlayerRDK::CreatePipeline(const char *pipelineName, int PipelinePriority) { + MW_PROFILE_FUNCTION(); bool ret = false; /* Destroy any existing pipeline before creating a new one */ if (interfacePlayerPriv->gstPrivateContext->pipeline || interfacePlayerPriv->gstPrivateContext->bus) @@ -4956,6 +4976,7 @@ static GstBusSyncReply bus_sync_handler(GstBus * bus, GstMessage * msg, Interfac */ void InterfacePlayerRDK::NotifyEOS() { + MW_PROFILE_FUNCTION(); if (!interfacePlayerPriv->gstPrivateContext->eosSignalled) { if (!interfacePlayerPriv->gstPrivateContext->eosCallbackIdleTaskPending) @@ -5069,6 +5090,7 @@ void InterfacePlayerRDK::EndOfStreamReached(int mediaType, bool &shouldHaltBuffe */ int InterfacePlayerRDK::InterfacePlayer_SetupStream(int streamId, std::string manifestUrl) { + MW_PROFILE_FUNCTION(); int retvalue = 0; GstMediaType mediaType = static_cast(streamId); this->TriggerEvent(InterfaceCB::startNewSubtitleStream, mediaType); From a95131214c0fab06a8bdb6ecdb8c2aaa6625dba3 Mon Sep 17 00:00:00 2001 From: nejuma1 Date: Wed, 18 Feb 2026 11:31:11 +0530 Subject: [PATCH 09/19] changed the default option to collect metrics to "off" --- CMakeLists.txt | 2 +- InterfacePlayerRDK.cpp | 1 + externals/rdk/PlayerExternalsRdkInterface.cpp | 1 + playerLogManager/PlayerLogManager.cpp | 2 ++ playerLogManager/PlayerLogManager.h | 27 +++++++++++-------- 5 files changed, 21 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 992ebb71..d6215d01 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,7 +26,7 @@ if(DISABLE_SECURITY_TOKEN) add_definitions(-DDISABLE_SECURITY_TOKEN) endif() -option(ENABLE_MW_PROFILING "Enable middleware profiling" ON) +option(ENABLE_MW_PROFILING "Enable middleware profiling" OFF) if(ENABLE_MW_PROFILING) add_definitions(-DENABLE_MW_PROFILING) diff --git a/InterfacePlayerRDK.cpp b/InterfacePlayerRDK.cpp index 823852db..9a5ad5c2 100644 --- a/InterfacePlayerRDK.cpp +++ b/InterfacePlayerRDK.cpp @@ -2889,6 +2889,7 @@ unsigned long InterfacePlayerRDK::GetCCDecoderHandle() */ bool InterfacePlayerRDK::WaitForSourceSetup(int mediaType) { + MW_PROFILE_FUNCTION(); bool ret = false; GstMediaType type = static_cast(mediaType); gst_media_stream* stream = &interfacePlayerPriv->gstPrivateContext->stream[type]; diff --git a/externals/rdk/PlayerExternalsRdkInterface.cpp b/externals/rdk/PlayerExternalsRdkInterface.cpp index 339995c0..c21ae624 100644 --- a/externals/rdk/PlayerExternalsRdkInterface.cpp +++ b/externals/rdk/PlayerExternalsRdkInterface.cpp @@ -131,6 +131,7 @@ void PlayerExternalsRdkInterface::Initialize() PlayerExternalsRdkInterface::~PlayerExternalsRdkInterface() { + MW_PROFILE_FUNCTION(); m_pDeviceInterfaceBase = nullptr; s_pPlayerIarmRdkOP = nullptr; } diff --git a/playerLogManager/PlayerLogManager.cpp b/playerLogManager/PlayerLogManager.cpp index 213ec1e1..21b4a102 100644 --- a/playerLogManager/PlayerLogManager.cpp +++ b/playerLogManager/PlayerLogManager.cpp @@ -94,6 +94,7 @@ std::size_t GetPlayerPrintableThreadID( void ) */ void logprintf(MW_LogLevel logLevelIndex, const char* func, int line, const char *format, ...) { + MW_PROFILE_FUNCTION(); // Increment log counter for each log line, wrap at 1000 for consistent 3-digit formatting uint32_t logSeqNum = gMwLogCounter.fetch_add(1, std::memory_order_relaxed) % 1000; @@ -175,6 +176,7 @@ void logprintf(MW_LogLevel logLevelIndex, const char* func, int line, const char */ void DumpBinaryBlob(const unsigned char *ptr, size_t len) { + MW_PROFILE_FUNCTION(); #define FIT_CHARS 64 char buf[FIT_CHARS + 1]; // pad for NUL char *dst = buf; diff --git a/playerLogManager/PlayerLogManager.h b/playerLogManager/PlayerLogManager.h index 3dae3c98..9d5457e3 100644 --- a/playerLogManager/PlayerLogManager.h +++ b/playerLogManager/PlayerLogManager.h @@ -66,6 +66,7 @@ public : */ static void SetLoggerInfo(bool logRedirectStatus, bool ethanLogStatus, int level, bool lock) { + MW_PROFILE_FUNCTION(); PlayerLogManager::disableLogRedirection = logRedirectStatus; PlayerLogManager::enableEthanLogRedirection = ethanLogStatus; PlayerLogManager::setLogLevel(MW_LogLevel(level)); @@ -80,6 +81,7 @@ public : */ static bool isLogLevelAllowed(MW_LogLevel chkLevel) { + MW_PROFILE_FUNCTION(); return (chkLevel>=mwLoglevel); } /** @@ -90,6 +92,7 @@ public : */ static void setLogLevel(MW_LogLevel newLevel) { + MW_PROFILE_FUNCTION(); if( !locked ) { mwLoglevel = newLevel; @@ -102,19 +105,21 @@ public : */ static void lockLogLevel( bool lock ) { + MW_PROFILE_FUNCTION(); locked = lock; } - /** - * @fn getHexDebugStr - */ - static std::string getHexDebugStr(const std::vector& data) - { - std::ostringstream hexSs; - hexSs << "0x"; - hexSs << std::hex << std::uppercase << std::setfill('0'); - std::for_each(data.cbegin(), data.cend(), [&](int c) { hexSs << std::setw(2) << c; }); - return hexSs.str(); - } + /** + * @fn getHexDebugStr + */ + static std::string getHexDebugStr(const std::vector& data) + { + MW_PROFILE_FUNCTION(); + std::ostringstream hexSs; + hexSs << "0x"; + hexSs << std::hex << std::uppercase << std::setfill('0'); + std::for_each(data.cbegin(), data.cend(), [&](int c) { hexSs << std::setw(2) << c; }); + return hexSs.str(); + } }; /** From b910d40b23b76fbb24862fc0686a6832c2c559f0 Mon Sep 17 00:00:00 2001 From: nejuma1 Date: Fri, 6 Mar 2026 14:18:12 +0530 Subject: [PATCH 10/19] Update PlayerLogManager.h --- playerLogManager/PlayerLogManager.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/playerLogManager/PlayerLogManager.h b/playerLogManager/PlayerLogManager.h index 9d5457e3..846b2b4d 100644 --- a/playerLogManager/PlayerLogManager.h +++ b/playerLogManager/PlayerLogManager.h @@ -31,6 +31,9 @@ #include #include #include + +#include "PerfProfiler.h" + /** * @brief Log level's of Middleware */ From 6365e6829ca30d2e4f6ef1abd42b72cb187c4d56 Mon Sep 17 00:00:00 2001 From: Nejuma28 Date: Mon, 9 Mar 2026 21:30:12 +0530 Subject: [PATCH 11/19] Mitigating compilation errors --- PerfProfiler.cpp | 1 + PerfProfiler.h | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/PerfProfiler.cpp b/PerfProfiler.cpp index 5127d6e0..95df9533 100644 --- a/PerfProfiler.cpp +++ b/PerfProfiler.cpp @@ -1,6 +1,7 @@ #include "PerfProfiler.h" #include #include +#include "PlayerLogManager.h" #ifdef ENABLE_MW_PROFILING diff --git a/PerfProfiler.h b/PerfProfiler.h index b1ca30a8..dc914b3a 100644 --- a/PerfProfiler.h +++ b/PerfProfiler.h @@ -3,7 +3,6 @@ #include #include -#include "PlayerLogManager.h" #ifdef ENABLE_MW_PROFILING From 01521d7bfe85a0ed097381e7360b8520aa9465a4 Mon Sep 17 00:00:00 2001 From: nejuma1 Date: Tue, 24 Mar 2026 12:16:48 +0530 Subject: [PATCH 12/19] Modified cmakelists to optionally add the profiling related files --- CMakeLists.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fec9dc9d..3cef104c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -172,7 +172,6 @@ set(LIBPLAYERGSTINTERFACE_HEADERS vendor/mtk/MtkSocInterface.h subtitle/vttCue.h ProcessHandler.h - PerfProfiler.h ) if(ENABLE_MW_PROFILING) list(APPEND LIBPLAYERGSTINTERFACE_HEADERS PerfProfiler.h) @@ -214,7 +213,6 @@ install(FILES closedcaptions/CCTrackInfo.h subtec/libsubtec/SubtecPacket.hpp playerisobmff/playerisobmffbuffer.h playerisobmff/playerisobmffbox.h - PerfProfiler.h DESTINATION include) if(ENABLE_MW_PROFILING) install(FILES PerfProfiler.h DESTINATION include) @@ -232,7 +230,6 @@ set(SOURCES vendor/default/DefaultSocInterface.cpp drm/processProtectionHls.cpp ProcessHandler.cpp - PerfProfiler.cpp ) if(ENABLE_MW_PROFILING) list(APPEND SOURCES PerfProfiler.cpp) From 62c3fbbad0447eed86dbf11f0f3fb338336d5e6e Mon Sep 17 00:00:00 2001 From: nejuma1 Date: Tue, 24 Mar 2026 12:24:00 +0530 Subject: [PATCH 13/19] Disabling optional compilaton since the builds don't show metrics --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3cef104c..ec9d1cf3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,7 +31,7 @@ if(DISABLE_SECURITY_TOKEN) add_definitions(-DDISABLE_SECURITY_TOKEN) endif() -option(ENABLE_MW_PROFILING "Enable middleware profiling" OFF) +option(ENABLE_MW_PROFILING "Enable middleware profiling" ON) if(ENABLE_MW_PROFILING) add_definitions(-DENABLE_MW_PROFILING) From b1a061d43fa173b72428a8a7114cefdaacfbe29a Mon Sep 17 00:00:00 2001 From: nejuma1 Date: Wed, 25 Mar 2026 10:56:21 +0530 Subject: [PATCH 14/19] Adding debug lines --- CMakeLists.txt | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ec9d1cf3..8c8d9a38 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,9 +33,14 @@ endif() option(ENABLE_MW_PROFILING "Enable middleware profiling" ON) +message(STATUS "ENABLE_MW_PROFILING = ${ENABLE_MW_PROFILING}") + if(ENABLE_MW_PROFILING) - add_definitions(-DENABLE_MW_PROFILING) -endif() + message(STATUS "Middleware profiling is ENABLED") + add_definitions(-DENABLE_MW_PROFILING) +else() + message(STATUS "Middleware profiling is DISABLED") + endif() # Option for building pi-cli option(BUILD_PICLI "Build the pi-cli test project" OFF) From 43de1ed5b31557e2003eb38e8898610a1c7a78f8 Mon Sep 17 00:00:00 2001 From: nejuma1 Date: Thu, 26 Mar 2026 10:52:31 +0530 Subject: [PATCH 15/19] Remove space and add tab which was causing build failures --- CMakeLists.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8c8d9a38..2e4c2ea7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,11 +36,11 @@ option(ENABLE_MW_PROFILING "Enable middleware profiling" ON) message(STATUS "ENABLE_MW_PROFILING = ${ENABLE_MW_PROFILING}") if(ENABLE_MW_PROFILING) - message(STATUS "Middleware profiling is ENABLED") - add_definitions(-DENABLE_MW_PROFILING) + message(STATUS "Middleware profiling is ENABLED") + add_definitions(-DENABLE_MW_PROFILING) else() - message(STATUS "Middleware profiling is DISABLED") - endif() + message(STATUS "Middleware profiling is DISABLED") +endif() # Option for building pi-cli option(BUILD_PICLI "Build the pi-cli test project" OFF) From bc7cf5622cfc58d94b9d8aaa392a2ca04905803d Mon Sep 17 00:00:00 2001 From: Nejuma28 Date: Thu, 26 Mar 2026 21:37:22 +0530 Subject: [PATCH 16/19] Eliminating the profiling function from logprintf --- playerLogManager/PlayerLogManager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/playerLogManager/PlayerLogManager.cpp b/playerLogManager/PlayerLogManager.cpp index 21b4a102..8bad34a9 100644 --- a/playerLogManager/PlayerLogManager.cpp +++ b/playerLogManager/PlayerLogManager.cpp @@ -94,7 +94,7 @@ std::size_t GetPlayerPrintableThreadID( void ) */ void logprintf(MW_LogLevel logLevelIndex, const char* func, int line, const char *format, ...) { - MW_PROFILE_FUNCTION(); + //MW_PROFILE_FUNCTION(); // Increment log counter for each log line, wrap at 1000 for consistent 3-digit formatting uint32_t logSeqNum = gMwLogCounter.fetch_add(1, std::memory_order_relaxed) % 1000; @@ -176,7 +176,7 @@ void logprintf(MW_LogLevel logLevelIndex, const char* func, int line, const char */ void DumpBinaryBlob(const unsigned char *ptr, size_t len) { - MW_PROFILE_FUNCTION(); + //MW_PROFILE_FUNCTION(); #define FIT_CHARS 64 char buf[FIT_CHARS + 1]; // pad for NUL char *dst = buf; From 47dd663652fe4ea274a092ca43ab34cc96c6310b Mon Sep 17 00:00:00 2001 From: Nejuma28 Date: Mon, 30 Mar 2026 16:16:34 +0530 Subject: [PATCH 17/19] adding profiling function to setstreamcaps function --- InterfacePlayerRDK.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/InterfacePlayerRDK.cpp b/InterfacePlayerRDK.cpp index d0ecbe49..a4dee0a5 100644 --- a/InterfacePlayerRDK.cpp +++ b/InterfacePlayerRDK.cpp @@ -5367,6 +5367,7 @@ void AddBufferFieldToStructure(GstStructure *structure, const char *fieldName, c */ void InterfacePlayerRDK::SetStreamCaps(GstMediaType type, MediaCodecInfo&& codecInfo) { + MW_PROFILE_FUNCTION(); GstCaps *caps = GetCaps(codecInfo.mCodecFormat); gst_media_stream *stream = &interfacePlayerPriv->gstPrivateContext->stream[type]; stream->format = codecInfo.mCodecFormat; From 81469d0389791aabcddfbd503225eca0a625e16c Mon Sep 17 00:00:00 2001 From: Nejuma28 Date: Mon, 30 Mar 2026 16:21:52 +0530 Subject: [PATCH 18/19] Adding 5 second delay between profile logs --- PerfProfiler.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/PerfProfiler.cpp b/PerfProfiler.cpp index 95df9533..92b10c24 100644 --- a/PerfProfiler.cpp +++ b/PerfProfiler.cpp @@ -1,6 +1,8 @@ #include "PerfProfiler.h" #include #include +#include +#include #include "PlayerLogManager.h" #ifdef ENABLE_MW_PROFILING @@ -12,6 +14,22 @@ ScopedTimer::ScopedTimer(const std::string& funcName, const std::string& fileNam ScopedTimer::~ScopedTimer() { auto end = std::chrono::high_resolution_clock::now(); long long duration = std::chrono::duration_cast(end - start).count(); + + // Throttle profiling logs to at most once every 5 seconds per API signature. + static std::mutex sRateLimitMutex; + static std::unordered_map sLastLogTime; + static constexpr auto kProfileLogInterval = std::chrono::seconds(5); + + const auto now = std::chrono::steady_clock::now(); + { + std::lock_guard lock(sRateLimitMutex); + auto it = sLastLogTime.find(name); + if (it != sLastLogTime.end() && (now - it->second) < kProfileLogInterval) { + return; + } + sLastLogTime[name] = now; + } + MW_LOG_INFO( "[PERF] %s (Thread %zu) took %lld us", name.c_str(), std::hash{}(std::this_thread::get_id()), From 39ec01ffe35c0bb4c0cd13e0338e98cf6d8eed1d Mon Sep 17 00:00:00 2001 From: nejuma1 Date: Fri, 10 Apr 2026 10:00:54 +0530 Subject: [PATCH 19/19] Addressing copilot review comments --- CMakeLists.txt | 2 +- PerfProfiler.cpp | 1 - PerfProfiler.h | 9 +++++---- playerLogManager/PlayerLogManager.cpp | 2 -- playerLogManager/PlayerLogManager.h | 7 ------- 5 files changed, 6 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2e4c2ea7..dc80aaf3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,7 +31,7 @@ if(DISABLE_SECURITY_TOKEN) add_definitions(-DDISABLE_SECURITY_TOKEN) endif() -option(ENABLE_MW_PROFILING "Enable middleware profiling" ON) +option(ENABLE_MW_PROFILING "Enable middleware profiling" OFF) message(STATUS "ENABLE_MW_PROFILING = ${ENABLE_MW_PROFILING}") diff --git a/PerfProfiler.cpp b/PerfProfiler.cpp index 92b10c24..b0755174 100644 --- a/PerfProfiler.cpp +++ b/PerfProfiler.cpp @@ -1,5 +1,4 @@ #include "PerfProfiler.h" -#include #include #include #include diff --git a/PerfProfiler.h b/PerfProfiler.h index dc914b3a..8c825ca9 100644 --- a/PerfProfiler.h +++ b/PerfProfiler.h @@ -16,12 +16,13 @@ class ScopedTimer { std::chrono::high_resolution_clock::time_point start; }; +// Macro helpers for generating a unique variable name per expansion +#define MW_PROFILE_CONCAT_IMPL(x, y) x##y +#define MW_PROFILE_CONCAT(x, y) MW_PROFILE_CONCAT_IMPL(x, y) // Macro for easy integration -#define MW_PROFILE_FUNCTION() ScopedTimer timer(__FUNCTION__, __FILE__, __LINE__) - +#define MW_PROFILE_FUNCTION() ScopedTimer MW_PROFILE_CONCAT(timer_, __LINE__)(__FUNCTION__, __FILE__, __LINE__) #else - -#define MW_PROFILE_FUNCTION() //profiling disabled +#define MW_PROFILE_FUNCTION() do { } while (0) #endif //ENABLE_MW_PROFILING #endif // PERF_PROFILER_H \ No newline at end of file diff --git a/playerLogManager/PlayerLogManager.cpp b/playerLogManager/PlayerLogManager.cpp index 8bad34a9..213ec1e1 100644 --- a/playerLogManager/PlayerLogManager.cpp +++ b/playerLogManager/PlayerLogManager.cpp @@ -94,7 +94,6 @@ std::size_t GetPlayerPrintableThreadID( void ) */ void logprintf(MW_LogLevel logLevelIndex, const char* func, int line, const char *format, ...) { - //MW_PROFILE_FUNCTION(); // Increment log counter for each log line, wrap at 1000 for consistent 3-digit formatting uint32_t logSeqNum = gMwLogCounter.fetch_add(1, std::memory_order_relaxed) % 1000; @@ -176,7 +175,6 @@ void logprintf(MW_LogLevel logLevelIndex, const char* func, int line, const char */ void DumpBinaryBlob(const unsigned char *ptr, size_t len) { - //MW_PROFILE_FUNCTION(); #define FIT_CHARS 64 char buf[FIT_CHARS + 1]; // pad for NUL char *dst = buf; diff --git a/playerLogManager/PlayerLogManager.h b/playerLogManager/PlayerLogManager.h index 846b2b4d..f7c5fbbf 100644 --- a/playerLogManager/PlayerLogManager.h +++ b/playerLogManager/PlayerLogManager.h @@ -32,8 +32,6 @@ #include #include -#include "PerfProfiler.h" - /** * @brief Log level's of Middleware */ @@ -69,7 +67,6 @@ public : */ static void SetLoggerInfo(bool logRedirectStatus, bool ethanLogStatus, int level, bool lock) { - MW_PROFILE_FUNCTION(); PlayerLogManager::disableLogRedirection = logRedirectStatus; PlayerLogManager::enableEthanLogRedirection = ethanLogStatus; PlayerLogManager::setLogLevel(MW_LogLevel(level)); @@ -84,7 +81,6 @@ public : */ static bool isLogLevelAllowed(MW_LogLevel chkLevel) { - MW_PROFILE_FUNCTION(); return (chkLevel>=mwLoglevel); } /** @@ -95,7 +91,6 @@ public : */ static void setLogLevel(MW_LogLevel newLevel) { - MW_PROFILE_FUNCTION(); if( !locked ) { mwLoglevel = newLevel; @@ -108,7 +103,6 @@ public : */ static void lockLogLevel( bool lock ) { - MW_PROFILE_FUNCTION(); locked = lock; } /** @@ -116,7 +110,6 @@ public : */ static std::string getHexDebugStr(const std::vector& data) { - MW_PROFILE_FUNCTION(); std::ostringstream hexSs; hexSs << "0x"; hexSs << std::hex << std::uppercase << std::setfill('0');