[XMA] Fix stall detection false positive in Work loop

Stall detection was triggering during multi-pass subframe consumption
(e.g. stereo with subframe_decode_count < total subframes), breaking
audio looping in games like Tomb Raider. Now only detects a stall when
no subframes were pending, so Consume-only iterations aren't mistaken
for no-progress cycles. Fixes Halo 4 without regressing Tomb Raider.
This commit is contained in:
Herman S.
2026-04-06 09:06:53 +09:00
parent 8a49c0380f
commit ade7e610bb

View File

@@ -176,6 +176,9 @@ bool XmaContextNew::Work() {
data.output_buffer_valid, data.subframe_decode_count, data.output_buffer_valid, data.subframe_decode_count,
data.output_buffer_padding); data.output_buffer_padding);
const uint32_t pre_decode_offset = data.input_buffer_read_offset;
const uint8_t pre_remaining_subframes = current_frame_remaining_subframes_;
Decode(&data); Decode(&data);
Consume(&output_rb, &data); Consume(&output_rb, &data);
@@ -185,6 +188,21 @@ bool XmaContextNew::Work() {
id(), data.IsAnyInputBufferValid(), data.error_status); id(), data.IsAnyInputBufferValid(), data.error_status);
break; break;
} }
// If Decode didn't advance the read offset and produced no new frame,
// we can't make progress. Break to avoid spinning.
// Only check when there were no pending subframes — if we entered this
// iteration with subframes remaining, Decode() intentionally skipped
// (offset unchanged) while Consume() drained the frame.
if (pre_remaining_subframes == 0 &&
data.input_buffer_read_offset == pre_decode_offset &&
current_frame_remaining_subframes_ == 0) {
XELOGAPU(
"XmaContext {}: Decode stalled at offset {} (no progress), "
"waiting for next buffer",
id(), pre_decode_offset);
break;
}
} }
data.output_buffer_write_offset = data.output_buffer_write_offset =