sceMpegbase: delay the colour conversion, as the hardware does

sceMpegBaseCscAvc/CscAvcRange run on the DMACPLUS and take real time. A
psmfplayer game re-blits the current video frame every render frame while it
waits for the next, so an instant return here is a tight loop that never yields
and starves the audio thread the playback clock is paced by - the whole A/V
pipeline then deadlocks a few frames into the movie. SOCOM: Tactical Strike
hung exactly this way running the real mpeg.prx; with the delay it plays. Same
value and reason as our sceMpeg HLE's sceMpegAvcCsc.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Henrik RydgårdandClaude Opus 5 committed 2026-09-17 09:53:03 -06:00
1 parent 4079adf424
commit e784f8bccb
1 file changed
+8 -2
+8 -2
View File
@@ -340,8 +340,14 @@ static int MpegBaseCscRange(u32 bufferRGB, u32 cscAddr, int bufferWidth,
// last frame the GE drew - the same notification our sceMpegAvcCsc HLE does. The pixel mode
// numbering matches GEBufferFormat, as it does there.
gpu->PerformWriteFormattedFromMemory(bufferRGB, destSize, bufferWidth, (GEBufferFormat)g_mpegBasePixelMode);
return hleLogDebug(Log::Mpeg, 0, "%dx%d at %d,%d -> %08x stride %d",
rangeWidth, rangeHeight, rangeX, rangeY, bufferRGB, bufferWidth);
// This runs on the DMACPLUS hardware and takes real time, and a caller running the real
// mpeg.prx leans on that. A psmfplayer game blits the current video frame every render frame
// while it waits for the next one to be ready, so returning instantly turns that into a tight
// loop that never yields and starves the audio thread - which is what paces playback - so the
// whole A/V pipeline deadlocks a few frames in. (SOCOM: Tactical Strike hangs exactly here.)
// Our sceMpeg HLE delays the equivalent sceMpegAvcCsc by the same amount for the same reason.
return hleDelayResult(hleLogDebug(Log::Mpeg, 0, "%dx%d at %d,%d -> %08x stride %d",
rangeWidth, rangeHeight, rangeX, rangeY, bufferRGB, bufferWidth), "mpegbase csc", 4000);
}
static int sceMpegBaseCscInit(int bufferWidth) {