@@ -174,6 +174,8 @@ bool XmaContextNew::Work() {
174174 data.output_buffer_valid , data.subframe_decode_count ,
175175 data.output_buffer_padding );
176176
177+ const uint32_t pre_decode_offset = data.input_buffer_read_offset ;
178+
177179 Decode (&data);
178180 Consume (&output_rb, &data);
179181
@@ -183,6 +185,18 @@ bool XmaContextNew::Work() {
183185 id (), data.IsAnyInputBufferValid (), data.error_status );
184186 break ;
185187 }
188+
189+ // If Decode didn't advance the read offset and produced no frame, we can't
190+ // make progress (e.g. split frame waiting for next buffer).
191+ // Break to avoid spinning.
192+ if (data.input_buffer_read_offset == pre_decode_offset &&
193+ current_frame_remaining_subframes_ == 0 ) {
194+ XELOGAPU (
195+ " XmaContext {}: Decode stalled at offset {} (no progress), "
196+ " waiting for next buffer" ,
197+ id (), pre_decode_offset);
198+ break ;
199+ }
186200 }
187201
188202 data.output_buffer_write_offset =
@@ -461,8 +475,15 @@ void XmaContextNew::Decode(XMA_CONTEXT_DATA* data) {
461475 const uint8_t * next_packet =
462476 GetNextPacket (data, next_packet_index, current_input_packet_count);
463477 if (!next_packet) {
464- // Matching split-body error handling below; correct error code unknown.
465- data->error_status = 4 ;
478+ // Next buffer not available yet. We can't resolve the split header
479+ // without it, so consume (swap) the current buffer and move on.
480+ // This loses one frame but avoids a deadlock where the game waits
481+ // for us to finish this buffer before providing the next one.
482+ XELOGAPU (
483+ " XmaContext {}: Split frame header at packet {}, next buffer "
484+ " unavailable — swapping input buffer" ,
485+ id (), packet_index);
486+ SwapInputBuffer (data);
466487 return ;
467488 }
468489 std::memcpy (input_buffer_.data (), packet + kBytesPerPacketHeader ,
@@ -507,10 +528,13 @@ void XmaContextNew::Decode(XMA_CONTEXT_DATA* data) {
507528 GetNextPacket (data, next_packet_index, current_input_packet_count);
508529
509530 if (!next_packet) {
510- // Error path
511- // Decoder probably should return error here
512- // Not sure what error code should be returned
513- data->error_status = 4 ;
531+ // Next buffer not available yet. We can't decode the split frame
532+ // without it, so consume (swap) the current buffer and move on.
533+ XELOGAPU (
534+ " XmaContext {}: Split frame body at packet {}, next buffer "
535+ " unavailable — swapping input buffer (need packet {}/{})" ,
536+ id (), packet_index, next_packet_index, current_input_packet_count);
537+ SwapInputBuffer (data);
514538 return ;
515539 }
516540 // Copy next packet to buffer
0 commit comments