[XMA] Fixed min output space gating to match Consume() write granularity

The decoder gate required a full frame of free blocks (4 mono / 8 stereo +
padding) before allowing a decode pass, but Consume() only writes
subframe_decode_count blocks per call. Games like TGM Ace with
subframe_decode_count=2 on a small ring buffer could never meet the old
threshold, causing a permanent decoder stall.
This commit is contained in:
AllanCat
2026-03-07 01:11:38 +08:00
committed by Herman S.
parent e8263d3672
commit 10cecae4c2

View File

@@ -142,9 +142,17 @@ bool XmaContextNew::Work() {
return true;
}
// Minimum free blocks needed before attempting a decode.
// Use the number of subframes Consume() will actually write per iteration
// (= subframe_decode_count, clamped to 1) plus any headroom requested by
// output_buffer_padding. Using a full-frame worth of space (the old
// formula) was far too restrictive: games like TGM Ace use
// subframe_decode_count=2 on a small ring buffer and never had 8 free
// blocks available, causing the decoder to permanently stall.
const uint32_t effective_sdc =
std::max(static_cast<uint32_t>(1), data.subframe_decode_count);
const int32_t minimum_subframe_decode_count =
((kBytesPerFrameChannel / kOutputBytesPerBlock) << data.is_stereo) +
data.output_buffer_padding;
static_cast<int32_t>(effective_sdc) + data.output_buffer_padding;
// We don't have enough space to even make one pass
// Waiting for decoder to return more space.