feat(mpeg): host-fed CD-stream ES injection for the guest-driven decoder#178
Open
smmathews wants to merge 1 commit into
Open
feat(mpeg): host-fed CD-stream ES injection for the guest-driven decoder#178smmathews wants to merge 1 commit into
smmathews wants to merge 1 commit into
Conversation
Add feedMpegCdStreamBytes, a host-memory counterpart to the guest demux syscalls, so runtimes that service the movie stream host-side (an HLE'd IOP streamer and/or an on-disc stream transform) can push elementary-stream bytes into the existing guest-driven decoder. Routes to the playback state(s) on the current CD-stream generation, bracketed by notifyMpegCdStreamStart/Eof, and demuxes through the same PSS path as sceMpegDemuxPss. Stream callbacks are not dispatched on this guestless path (documented TODO for a follow-up queue). Pure addition: no existing call site or behavior changes.
smmathews
marked this pull request as ready for review
July 21, 2026 18:49
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Host-fed CD-stream ES injection for the guest-driven MPEG decoder
Problem
Upstream's guest-driven MPEG decoder ingests elementary stream only through
the guest's own demux syscalls, which read from guest RAM at a guest
pointer. Runtimes that HLE the movie stream's IOP-side delivery — an IOP
streamer that fills an EE ring the runtime does not model — hold a correct,
in-order ES in host memory with the guest's
sceMpegGetPictureconsumerlive, but have no supported seam to hand those bytes to the decoder. They
are forced to reimplement the guest ring protocol or carry a parallel
downstream decoder. The same gap also applies when a runtime applies an
on-disc stream transform host-side before decode.
Fix
Add
size_t feedMpegCdStreamBytes(const uint8_t *, size_t): the missingdata verb to go with the existing control verbs
notifyMpegCdStreamStart/notifyMpegCdStreamEof. It routes host bytesinto the playback state(s) on the current CD-stream generation and demuxes
them through the exact same PSS path as
sceMpegDemuxPss, fanning out toevery open decoder on that generation. No
mpegAddrargument — a hoststreamer does not know the guest handle; routing mirrors the existing
generation bookkeeping. Returns
sizeonce the active stream is routed tothe open decoder(s) — regardless of how many decoders receive it — and 0
when no CD stream is active.
Scope / why generic
No game knowledge: no file layout, no transform, no addresses. Symmetric
with and reusing the merged
notifyMpegCdStream*contract. Inert for everyexisting title (no call site invokes it; it early-outs when no CD stream is
active). Internally a pure addition: one header declaration, one new public
function, and a single defaulted parameter on the internal
appendPssBytesthat leaves all existing callers and the guest demux/callback path
unchanged.
No in-tree consumer
Nothing in
ps2xRuntimecalls this yet. It is an embedder seam for theruntime library — the missing data verb alongside the existing
notifyMpegCdStream*control verbs — so downstream embedders thatproduce the elementary stream host-side can feed the upstream decoder
instead of carrying a parallel one.
Maintainer-attention point (callback design)
A host feed has no calling guest thread, so guest stream callbacks cannot be
dispatched from it. This PR ships the drop-callbacks variant (documented
with
// TODO(host-feed callbacks)): host-fed data records no guestaddresses, so no callback event is ever queued. If a future title needs
stream callbacks on a host-fed stream, the follow-up is a small
per-
MpegPlaybackStateevent queue drained by the next guest MPEG syscall.Flagged for your call.
Testing
Full suite passes — run:
Three added tests: a start/feed/getPicture/eof round-trip that decodes a
host-fed program stream with no
sceMpegDemuxPss*call in the path, afeed-before-start no-op, and a two-decoder fan-out test that pins the input
range being reported once (not once per decoder) and that every open
decoder on the current generation receives the fed bytes. Each pinned
property has a one-line mutation that makes exactly one named test fail:
feedMpegCdStreamBytes, changereturn routedCount != 0u ? size : 0u;toreturn routedCount * size;— run the suite; exactly "host feed fans outto every open decoder and reports the input range once" fails.
feedMpegCdStreamBytes, add abreak;right after++routedCount;— run the suite; exactly "host feedfans out to every open decoder and reports the input range once" fails.
feedMpegCdStreamBytes, dropcdStreamGeneration != 0u &&from thecdStreamActiveexpression — run the suite; exactly "feedMpegCdStreamBytesbefore a CD stream start is a no-op" fails.
feedMpegCdStreamBytes,drop
&& !...currentCdStreamEofSeenfrom thecdStreamActiveexpression —run the suite; exactly "host-fed CD stream decodes without a guest demux
call" fails (the feed-after-EOF assertion).
appendPssBytes, change the defaultbool trackGuestAddrs = trueto= false— run the suite; exactly "sceMpegDemuxPssRing dispatchesregistered video and audio stream callbacks" fails.
Note on the return value: it is
size(the whole input range) once theactive stream is routed, or 0 otherwise — it is not a decoded-byte count
and does not scale with how many decoders are open.