Files
ppsspp/android
Henrik RydgårdandClaude Opus 5 184c2cb4ea Implement sceVideocodec, the ME's H.264 decoding interface
The last piece mpeg.prx needs from us. It decodes through AvcDecoder and writes
the result where sceMpegbase expects to read it: for type 0, the eight-buffer
tiled layout, produced here as the exact inverse of the reader added with the
colour conversion. Type 1 hands back plain planar YUV instead.

The descriptor mpeg.prx passes in is empty - on hardware the Media Engine owns
the frame buffers and reports back where it put them - so they are allocated
here and their addresses filled in, and sceMpegbase can recover the full set
from that allocation afterwards. The list is only read as addresses once it
holds addresses: a caller that leaves small integers there used to take us
straight into a memory exception.

Both those buffers and the block sceVideocodecGetEDRAM hands out live in a
model of the ME's own 2MB of embedded DRAM rather than in either PSP partition,
with a BlockAllocator carving it up. The CPU can't reach ME memory on hardware:
mpeg.prx keeps the EDRAM value and hands it back without ever dereferencing it,
and it has no way to say where the frame buffers should go - sceVideocodecSetMemory
is given a frame size and a buffer count, 480, 272 and 2 for a full-screen movie.
Taking either from the game would push its own allocations around or spend memory
a real PSP never spends, so sceMpegbase reads the frame through a host pointer
into that block instead of through Memory::.

A game can hold several contexts at once - Silent Hill Origins runs two, one
that owns the EDRAM and one that does every decode - so the decoder, the frame
buffers and the EDRAM address are per context, keyed by context address the way
sceAudiocodec keys its decoders. The EDRAM itself the firmware tracks in the
caller's context struct and nowhere else, including refusing a second request
rather than replacing the first, as videocodec_260.prx shows, so we do the same.

Registered at the end of RegisterAllModules, since a savestate stores the
syscall opcode encoding that order.

GetSEI, ScanHeader, GetFrameCrop and the two unnamed NIDs return 0 and log -
mpeg.prx calls them but nothing yet shows what they need to return, and
guessing seemed worse than being loud about it.

Untested: nothing calls this until mpeg.prx is loaded, which is the next step.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-12 12:53:13 -06:00
..
2026-08-31 11:02:32 +02:00
2026-08-03 18:55:33 +02:00
2026-06-15 09:17:13 +02:00

================================================================

NOTE: These are legacy instructions for building using ndk-build.

We mostly only use this on CI because it's faster than gradle.
There might also be some holdouts around still using eclipse.

================================================================

First, build the C++ static library:

> cd android
> ./ab.sh
Or
> ./ab.cmd

as appropriate.

Start Eclipse, import the android directory as an existing project
You need to also load the "native" project into your eclipse workspace
Build and run. 

If you modify the C++ code, you need to rebuild the static library, of
course. To get Eclipse to understand that you have in fact changed something
if you haven't also changed any Java code, just add a space character to 
PPSSPPActivity.java, or right click the project and choose Refresh, and then
relaunch the app on the device.

A real Android device is strongly recommended for testing. Don't trust
the emulator.