Skip to content

Fix tune time stuck: serialize Pause() state changes and add recovery for failed async transitions#1465

Draft
Copilot wants to merge 4 commits into
feature/RDKEMW-16484from
copilot/rdkemw-16484-fix-tune-time-stuck-issue
Draft

Fix tune time stuck: serialize Pause() state changes and add recovery for failed async transitions#1465
Copilot wants to merge 4 commits into
feature/RDKEMW-16484from
copilot/rdkemw-16484-fix-tune-time-stuck-issue

Conversation

Copilot AI commented May 19, 2026

Copy link
Copy Markdown
Contributor

Two race conditions in InterfacePlayerRDK::Pause() cause the player to get stuck during tune when rapid PLAY→PAUSE→PLAY sequences (within ~400ms) confuse GStreamer's state machine, or when an async pipeline transition stalls indefinitely.

Changes

Serialize state change requests (InterfacePlayerRDK::Pause())

Before issuing any new PLAY/PAUSE state change, block on gst_element_get_state with a 500ms timeout. This drains any in-flight PAUSED→PLAYING async transition before the next contradictory request is sent — preventing GStreamer from receiving back-to-back conflicting state changes.

// Wait for any pending async transition to complete before issuing a new one
GstState current, pending;
GstStateChangeReturn pendingRc = gst_element_get_state(
    pipeline, &current, &pending, 500 * GST_MSECOND);
if (GST_STATE_CHANGE_ASYNC == pendingRc)
    MW_LOG_WARN("async state change still in progress, proceeding with %d", nextState);

Recovery logic after validateStateWithMsTimeout failure (InterfacePlayerRDK::Pause())

Previously, a timed-out async state transition only logged an error, leaving the pipeline stuck. Now:

  1. Retry the state change once via SetStateWithWarnings
  2. If the retry also stalls (returns ASYNC), re-validate with validateStateWithMsTimeout
  3. If recovery fails, report MESSAGE_ERROR to the application via busMessageCallback

A local lambda eliminates the duplicated error-reporting code across the two failure branches.

Test updates (InterfacePlayerFunctionTests.cpp)

  • Pause_Success — fixed mock to set the current-state output parameter via SetArgPointee<1>(GST_STATE_PAUSED) so validateStateWithMsTimeout succeeds without triggering the new retry path.
  • Pause_SerializesStateChange_WaitsForPendingAsync — new: serialization check detects in-flight async and waits before proceeding.
  • Pause_AsyncStateChange_ValidationFails_RecoverySuccess — new: retry resolves the stuck transition; no error is reported.
  • Pause_AsyncStateChange_ValidationFails_ErrorReported — new: both initial and retry validations fail; busMessageCallback receives MESSAGE_ERROR.
Original prompt

Fix the tune time stuck issue on branch feature/RDKEMW-16484 with the following two changes:

1. Add recovery logic after validateStateWithMsTimeout failure

If the GStreamer pipeline cannot transition to PLAYING within the timeout period, the code should:

  • Retry the state change, OR tear down and recreate the pipeline
  • Report an error to the application if recovery fails

This prevents the player from getting stuck indefinitely when a state transition hangs.

2. Serialize state change requests to prevent conflicting async transitions

Prevent Pause(1) from being called while a PAUSED→PLAYING async state change is still pending. The rapid PLAY→PAUSE→PLAY sequence within 400ms confuses the GStreamer state machine.

The fix should:

  • Serialize state change requests (PLAY, PAUSE) so that a new request waits for the previous async state change to complete before issuing the next one
  • Prevent conflicting state transitions from being queued while one is in progress
  • Ensure the GStreamer state machine is not confused by rapid back-to-back contradictory state changes

The following is the prior conversation context from the user's chat exploration (may be truncated):

User: https://github.com/rdkcentral/aamp/tree/feature/RDKEMW-16484
for tune time stuck issue provide the below code changes

Add recovery logic after validateStateWithMsTimeout failure. If the pipeline cannot transition to PLAYING within timeout, retry the state change or tear down and recreate the pipeline. Report an error to the application if recovery fails.
Prevent Pause(1) from being called while a PAUSED→PLAYING async state change is still pending. The rapid PLAY→PAUSE→PLAY within 400ms confuses the GStreamer state machine. Serialize state change requests and wait for async completion.

Assistant: I've initiated the coding agent to create a pull request on the feature/RDKEMW-16484 branch with the two fixes for the tune time stuck issue. We're waiting for your confirmation to proceed with the deep research and code changes.

This pull request was created from Copilot chat.

Copilot AI and others added 3 commits May 19, 2026 07:01
…ization in Pause()

Agent-Logs-Url: https://github.com/rdkcentral/aamp/sessions/1efbe83f-b635-4efb-bf93-992574859a04

Co-authored-by: rekhap2kandhavelan <217911244+rekhap2kandhavelan@users.noreply.github.com>
Agent-Logs-Url: https://github.com/rdkcentral/aamp/sessions/1efbe83f-b635-4efb-bf93-992574859a04

Co-authored-by: rekhap2kandhavelan <217911244+rekhap2kandhavelan@users.noreply.github.com>
Agent-Logs-Url: https://github.com/rdkcentral/aamp/sessions/1efbe83f-b635-4efb-bf93-992574859a04

Co-authored-by: rekhap2kandhavelan <217911244+rekhap2kandhavelan@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix tune time stuck issue with recovery logic and serialization Fix tune time stuck: serialize Pause() state changes and add recovery for failed async transitions May 19, 2026
Copilot AI requested a review from rekhap2kandhavelan May 19, 2026 07:06
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.

2 participants