__MpegBaseInit was called by __MpegInit rather than by __KernelInit, and
__MpegBaseShutdown had just been added the same way. Every other module is
started and stopped directly by the kernel - __MpegBaseDoState already was -
so do the same here and let sceMpeg.cpp mind only its own state.
The order is unchanged: __MpegBaseInit ran first inside __MpegInit and now sits
just before it, __MpegBaseShutdown ran last and now sits just after.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
__MpegBaseShutdown, hanging off __MpegShutdown the way __MpegBaseInit hangs off
__MpegInit, so the de-tiling scratch and the swscale context go back when the
game stops rather than only when the next one starts. Between them they are a
few hundred kilobytes that a game which played one video early on has no further
use for.
Also name the swscale flags rather than passing SWS_POINT inline, and say next
to it what the choice actually decides - with equal sizes in and out it is only
how chroma gets to full resolution, and SWS_BILINEAR (what the HLE uses) is a
one-line swap. Worth a real option one day; not adding one now.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
sceMpeg and sceAudiocodec only cleared their context maps on shutdown, while
sceMpegbase and sceVideocodec clear theirs on init. Both maps are keyed on an
address the game chooses, and getMpegCtx reads its key straight out of game
memory, so anything left behind can be handed to the next game we run in the
same session. Clear them on init as well. sceVideocodec's init cleared its map
without deleting the decoders in it; use ClearContexts for that.
Headless never loads a config file, so every g_Config field it doesn't set
keeps the zero-initialized value rather than the ConfigSetting default.
bFuncReplacements is one of those, so headless was the only build running games
without function replacements - which is why a crash in Jak and Daxter's
memcpy_jak wouldn't reproduce there.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Four places were each computing the same sizes and 64-byte-aligned offsets:
the allocation, the recovery sceMpegbase uses, and the readers on both sides.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Add flash0:/kd/mpeg.prx to the sceUtility module swap, hung off av_mpegbase,
so it loads when DisableHLEFlags::sceMpeg is set. Games that ship their own
sceMpeg_library on the disc never get here and just use theirs.
The piece that was missing to make it work: the access unit address mpeg.prx
passes to sceVideocodecDecode is in Media Engine space, which we can't read.
On hardware sceMpegBasePESpacketCopy DMA'd the payload there first. That copy
is ours, so it now gathers the blocks and sceVideocodec decodes from those,
falling back to main memory for any caller that points at it directly. The
gather is keyed by destination, because that call carries the audio payload
too - video to an ME address, audio to main memory - and handing an ATRAC
packet to the H.264 decoder gets you nothing.
With that, video/mpeg/basic gets a 144x80 frame out of real Sony code driving
our sceVideocodec through ffmpeg. The test still fails overall, as it did
before this branch - it is in tests_next.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Five of the six functions in this module were registered as nullptr, so any
caller reaching them got nothing. mpeg.prx needs all of them, and this is the
first of the pieces required before the real module can run in place of our
sceMpeg HLE.
The module gets its own file at the same time. It was a tail of sceMpeg.cpp,
which is long enough already, and everything below is new code for it.
sceMpegBaseCscAvc and sceMpegBaseCscAvcRange convert the ME's decoded output to
RGB. The 48-byte descriptor holds the frame size in macroblocks at 0x10 and
0x14 - it appears at 0x00/0x04 too, but scaled differently depending on which
path built it, so the second pair is the one every caller agrees on - and the
four luma buffers at 0x20. What they point at is not planar: luma arrives as
16-pixel-wide vertical strips alternating between buffers on every other line,
and chroma as Cb/Cr pairs interleaved across four more. All eight are untangled
into planes once per frame before converting, which keeps the pixel loop
readable.
sceMpegBaseCscInit carries the default buffer width for callers that pass zero.
sceMpegBaseCscSetPixelMode (0x0530BE4E - the official name isn't known) carries
the output format, in mpegbase's own numbering rather than the GE's: mpeg.prx
gets it by indexing a table of {1, 2, 3, 0} with the pixel mode the game gave
sceMpegAvcDecodeMode, making 0 ABGR8888 and 2 ABGR5551. Read as a GE mode it
turned Thrillville's black into blue.
sceMpegBaseYCrCbCopy copies the descriptor but not the buffers it points at,
and says so in its log - nothing seen so far needs more, and inventing the
buffer copy without something to test it against seemed worse than a note.
Behaviour is cross-checked against JPCSP, which implements all of these.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* Rename LogType to Log
* Explicitly use the Log:: enum when logging. Allows for autocomplete when editing.
* Mac/ARM64 buildfix
* Do the same with the hle result log macros
* Rename the log names to mixed case while at it.
* iOS buildfix
* Qt buildfix attempt, ARM32 buildfix