From c596bdf9a488eb24acbffcef31f2051ddf1c710b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 17 Sep 2026 11:01:09 -0600 Subject: [PATCH] sceAudiocodec/sceVideocodec: fill an AAC gap and name two ME functions sceAudiocodecCheckNeedMem set neededMem for every codec except AAC, where it was left at whatever was in the context. Set it to 0x18f20 like the others; our faked ME memory meant this never blocked, but a game that validates it could. Also name the two hash-named sceVideocodec exports from their firmware behaviour: 0x893B32B1 configures the codec during sceMpegCreate in mode 1 (SetMode), and 0xD95C24D5 copies a decoded YCbCr frame between buffers via the ME (CopyYCbCr), the videocodec-level counterpart of sceMpegBaseYCrCbCopy. Both are still stubs - only mpeg.prx calls them, on paths nothing we run reaches - but they are now documented for whoever implements them. Co-Authored-By: Claude Opus 5 (1M context) --- Core/HLE/sceAudiocodec.cpp | 1 + Core/HLE/sceVideocodec.cpp | 15 +++++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Core/HLE/sceAudiocodec.cpp b/Core/HLE/sceAudiocodec.cpp index 1950e09821..29b0449b34 100644 --- a/Core/HLE/sceAudiocodec.cpp +++ b/Core/HLE/sceAudiocodec.cpp @@ -460,6 +460,7 @@ static int sceAudiocodecCheckNeedMem(u32 ctxPtr, int codec) { break; case 0x1003: // Kosmodrones uses sceAudiocodec directly (no intermediate library). + ctx->neededMem = 0x18f20; INFO_LOG(Log::ME, "CheckNeedMem for codec %04x: format %02x %02x", codec, ctx->fmt.at3.formatByte1, ctx->fmt.at3.formatByte2); break; } diff --git a/Core/HLE/sceVideocodec.cpp b/Core/HLE/sceVideocodec.cpp index faf1e70661..b9489ce120 100644 --- a/Core/HLE/sceVideocodec.cpp +++ b/Core/HLE/sceVideocodec.cpp @@ -635,11 +635,18 @@ static int sceVideocodecSetMemory(u32 ctxAddr, int type) { return hleLogDebug(Log::ME, 0); } -static int sceVideocodec_893B32B1(u32 ctxAddr, int type) { +// 0x893B32B1. mpeg.prx runs this from sceMpegCreate, only in mode 1 (the path where the game reads +// raw YCbCr out rather than letting sceMpegbase convert to RGB). On hardware it writes back the +// 0x28-byte output descriptor at ctx+0x10 and issues ME video op 0x6D68B223 to configure the codec. +// Nothing we run reaches it, so it stays a stub - implement it if a mode-1 game needs it. +static int sceVideocodecSetMode(u32 ctxAddr, int type) { return hleLogWarning(Log::ME, 0, "UNIMPL"); } -static int sceVideocodec_D95C24D5(u32 ctxAddr, int type) { +// 0xD95C24D5. Copies a decoded YCbCr frame between two sets of buffers through the ME (op +// 0x21521BE5) - the videocodec-level counterpart of sceMpegBaseYCrCbCopy. mpeg.prx calls it on the +// sceMpegAvcCopyYCbCr path. Nothing we run reaches it, so it stays a stub for now. +static int sceVideocodecCopyYCbCr(u32 ctxAddr, int type) { return hleLogWarning(Log::ME, 0, "UNIMPL"); } @@ -656,8 +663,8 @@ const HLEFunction sceVideocodec[] = { {0X17CF7D2C, &WrapI_UI, "sceVideocodecGetFrameCrop", 'i', "xi"}, {0X26927D19, &WrapI_UI, "sceVideocodecGetVersion", 'i', "xi"}, {0X627B7D42, &WrapI_UI, "sceVideocodecGetSEI", 'i', "xi"}, - {0X893B32B1, &WrapI_UI, "sceVideocodec_893B32B1", 'i', "xi"}, - {0XD95C24D5, &WrapI_UI, "sceVideocodec_D95C24D5", 'i', "xi"}, + {0X893B32B1, &WrapI_UI, "sceVideocodecSetMode", 'i', "xi"}, + {0XD95C24D5, &WrapI_UI, "sceVideocodecCopyYCbCr", 'i', "xi"}, }; void Register_sceVideocodec() {