Skip to content

Comments

Fix single-threaded decode hang when ready_tasks is zero#25

Open
intrepidsilence wants to merge 1 commit intotvlabs:masterfrom
intrepidsilence:fix/single-thread-ready-tasks
Open

Fix single-threaded decode hang when ready_tasks is zero#25
intrepidsilence wants to merge 1 commit intotvlabs:masterfrom
intrepidsilence:fix/single-thread-ready-tasks

Conversation

@intrepidsilence
Copy link

Summary

In single-threaded mode (n_threads == 0), after initializing a task, ready_tasks can be zero because the dependency calculation may not account for the current frame being in a transitional state. The code then calls worker_loop directly, but no task is selected because ready_tasks is empty, causing the decoder to hang.

In multithreaded mode, worker threads recalculate ready_tasks after completing each task (line ~572), providing a second chance. In single-threaded mode there is no such recalculation.

Fix

Add a safety net that force-sets the task bit when ready_tasks is unexpectedly zero in single-threaded mode:

if (dec->n_threads) {
    pthread_cond_signal(&dec->task_ready);
} else if (!dec->ready_tasks) {
    // Safety net: force-set task bit when dependency calc yields 0
    dec->ready_tasks |= 1 << task_id;
    dec->worker_loop(dec);
} else {
    dec->worker_loop(dec);
}

Symptom

Decoder hangs indefinitely with 0% CPU on certain MVC streams. The task is initialized but never executed.

Verification

  • Tested on commercial 3D Blu-ray MVC streams (130,000+ frame pairs)
  • Before fix: decoder hangs after variable number of frames
  • After fix: decoder completes all frames successfully
  • 85/85 JVT conformance streams continue to pass

In single-threaded mode (n_threads == 0), after initializing a task,
the code directly calls worker_loop. However, ready_tasks can be zero
at this point because the dependency calculation at line 1256 may not
account for the current frame being in a transitional state during
single-threaded execution.

In multithreaded mode, worker threads recalculate ready_tasks after
completing each task (line 572), providing a second chance. In
single-threaded mode there is no such recalculation, so the task is
never executed and the decoder hangs.

Add a safety net that force-sets the task bit when ready_tasks is
unexpectedly zero in single-threaded mode, allowing the worker loop
to proceed.

Symptom: decoder hangs indefinitely with 0% CPU on certain MVC
streams. Verified on commercial 3D Blu-ray content.
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.

1 participant