Skip to content

RDKEMW-21923 : [LLAMA /Cello]Observed the message "Sorry, fast forward isn't available for this programme followed by techanical fault error" while performing fast scrubbing by long-pressing the Right and Left navigation keys. - #216

Open
rekhap2kandhavelan wants to merge 3 commits into
support/0.2.0_8.6from
feature/RDKEMW-21923
Open

RDKEMW-21923 : [LLAMA /Cello]Observed the message "Sorry, fast forward isn't available for this programme followed by techanical fault error" while performing fast scrubbing by long-pressing the Right and Left navigation keys.#216
rekhap2kandhavelan wants to merge 3 commits into
support/0.2.0_8.6from
feature/RDKEMW-21923

Conversation

@rekhap2kandhavelan

Copy link
Copy Markdown
Contributor

Handling race conditions

Copilot AI review requested due to automatic review settings July 28, 2026 13:23
@rekhap2kandhavelan
rekhap2kandhavelan requested a review from a team as a code owner July 28, 2026 13:23

Copilot AI left a comment

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.

Pull request overview

This PR aims to reduce race-condition fallout during rapid scrubbing by adding a recovery path when the GStreamer pipeline appears “wedged” around PAUSED state transitions.

Changes:

  • Add a fallback in validateStateWithMsTimeout() to force a pipeline reset via GST_STATE_NULL when the pipeline appears stuck in a PAUSED/PAUSED state.

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

Comment thread InterfacePlayerRDK.cpp Outdated
Comment on lines +3475 to +3482
if (gst_current == GST_STATE_PAUSED && gst_pending == GST_STATE_PAUSED)

{
// Pipeline wedged in PAUSED->PAUSED transition Force state reset by going through NULL state
MW_LOG_INFO("validateStateWithMsTimeout: PAUSED->PAUSED wedged, forcing reset");
SetStateWithWarnings(privatePlayer->gstPrivateContext->pipeline, GST_STATE_NULL);
SetStateWithWarnings(privatePlayer->gstPrivateContext->pipeline, GST_STATE_PAUSED);
}
Comment thread InterfacePlayerRDK.cpp Outdated
Comment on lines +3478 to +3482
// Pipeline wedged in PAUSED->PAUSED transition Force state reset by going through NULL state
MW_LOG_INFO("validateStateWithMsTimeout: PAUSED->PAUSED wedged, forcing reset");
SetStateWithWarnings(privatePlayer->gstPrivateContext->pipeline, GST_STATE_NULL);
SetStateWithWarnings(privatePlayer->gstPrivateContext->pipeline, GST_STATE_PAUSED);
}
Copilot AI review requested due to automatic review settings July 31, 2026 09:40

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

Suppressed comments (3)

InterfacePlayerRDK.cpp:3456

  • gst_current and gst_pending are read in the loop condition and in logs but are never initialized before the first gst_element_get_state() call. If gst_element_get_state() doesn’t write these outputs (e.g., in some failure paths or in unit tests where the mock only returns a value), this becomes undefined behavior and can cause flaky results.
	GstState gst_pending;
	float timeout = 100.0;
	InterfacePlayerPriv* privatePlayer = pInterfacePlayerRDK->GetPrivatePlayer();
	gint gstGetStateCnt = GST_ELEMENT_GET_STATE_RETRY_CNT_MAX;
	GstStateChangeReturn ret = GST_STATE_CHANGE_FAILURE;

InterfacePlayerRDK.cpp:3479

  • This introduces a new failure path (returning GST_STATE_VOID_PENDING as an error sentinel) when gst_element_get_state() reports GST_STATE_CHANGE_ASYNC with PAUSED/PAUSED. There doesn’t appear to be a unit test covering this wedged-state detection via InterfacePlayerRDK::Pause() (existing Pause tests only cover SUCCESS/FAILURE paths). Adding a test will help prevent regressions and confirm AAMP recovery behavior.
	if (ret == GST_STATE_CHANGE_ASYNC && gst_current == GST_STATE_PAUSED && gst_pending == GST_STATE_PAUSED)
	{
		MW_LOG_WARN("validateStateWithMsTimeout: PAUSED->PAUSED wedged detected, returning error to let AAMP recover");
		return GST_STATE_VOID_PENDING;
	}

InterfacePlayerRDK.cpp:3477

  • The warning string has a grammatical issue: “wedged detected” is awkward; consider “wedge detected” or “wedged state detected” to make logs clearer for triage.
		MW_LOG_WARN("validateStateWithMsTimeout: PAUSED->PAUSED wedged detected, returning error to let AAMP recover");

Copilot AI review requested due to automatic review settings August 3, 2026 10:01

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

Suppressed comments (2)

InterfacePlayerRDK.cpp:517

  • The new non-blocking gst_element_get_state() call in ConfigurePipeline adds an extra pipeline state query before the existing SetStateWithWarnings() call (which itself calls gst_element_get_state()). Several gmock unit tests currently expect only one gst_element_get_state(&gst_element_pipeline, ...) during ConfigurePipeline (e.g., test/utests/tests/GstPlayer/PauseOnPlaybackTests.cpp:126-130), so this change will cause test failures unless expectations are updated (e.g., Times(2)/WillRepeatedly or an additional WillOnce for the new call).
		GstState cur = GST_STATE_NULL, pend = GST_STATE_NULL;
		gst_element_get_state(interfacePlayerPriv->gstPrivateContext->pipeline,
		                       &cur, &pend, 0 /* non-blocking */);
		if (cur == GST_STATE_PAUSED && pend == GST_STATE_PAUSED)
		{

InterfacePlayerRDK.cpp:3508

  • validateStateWithMsTimeout() always logs MW_LOG_ERR("... FAILURE") before checking for the newly-handled ASYNC wedge cases; this will still emit an error log even when you intentionally return GST_STATE_VOID_PENDING to trigger recovery. If this error log feeds user-facing "technical fault" reporting/telemetry, it undermines the goal of treating these cases as recoverable timeouts.
	MW_LOG_ERR("validateStateWithMsTimeout - PIPELINE gst_element_get_state - FAILURE : State = %d, Pending = %d",
			   gst_current, gst_pending);
	
	if (ret == GST_STATE_CHANGE_ASYNC && gst_current == GST_STATE_PAUSED && gst_pending == GST_STATE_PAUSED)

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.

3 participants