Skip to content

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

Open
intrepidsilence wants to merge 1 commit into
tvlabs: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 into
tvlabs:masterfrom
intrepidsilence:fix/single-thread-ready-tasks

Conversation

@intrepidsilence

Copy link
Copy Markdown
Contributor

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.
jens-duttke referenced this pull request in jens-duttke/edge264-mvc Jun 25, 2026
The "What's fixed vs upstream master" table only listed the MVC-correctness
patches. Group it and add every fix that had since landed - the sample-audit
decode-robustness sweep and the MinGW / wasm build fixes. Describe each
robustness fix by its generic failure mode; keep private sample filenames,
frame counts and volatile source line numbers out of this public doc.

Move the single-threaded decode hang (PR #25) out of the MVC table - it is a
general single-thread fix, not MVC-specific - into the single-thread lead
note. Remove the now-redundant Status section, keeping only its non-redundant
facts (single-thread requirement, +4 POC API fields, upstream-match result,
and a "Deliberately not included" note for PR #26 and unsupported NAL types).
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