mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
sceVideocodec/sceMpegbase: stop holding on to contexts and payloads that are done
Decode looked its context up with operator[], so a game that never opened one would still get an entry and a decoder, and only Delete ever removes those. Require the context to exist instead. The gathered PES payloads were likewise kept for the whole boot, so the first decode of a movie could be handed the last packet of the previous one if the address came round again. Hand each payload out once. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
1 parent
779f9eb811
commit
435d446c37
3 files changed
+22
-13
No files matched your search
@@ -36,7 +36,6 @@
|
||||
// copied to. It carries audio as well as video - the destination is what tells them apart - so
|
||||
// sceVideocodec has to ask for the one matching the address it was handed.
|
||||
static std::map<u32, std::vector<u8>> g_pesPackets;
|
||||
|
||||
// Set by sceMpegBaseCscInit / sceMpegBaseCscSetPixelMode, and used when the caller passes 0.
|
||||
static int g_mpegBaseBufferWidth = 512;
|
||||
static int g_mpegBasePixelMode = GE_CMODE_32BIT_ABGR8888;
|
||||
@@ -66,7 +65,7 @@ static u32 sceMpegBasePESpacketCopy(u32 p)
|
||||
// On hardware this is the DMA that moves the PES payload into the Media Engine's own memory,
|
||||
// after which mpeg.prx hands sceVideocodecDecode an ME-side address we have no way to read.
|
||||
// Since the copy is ours, gather the blocks here instead and let sceVideocodec decode from
|
||||
// this - see MpegBaseGetPESPacket.
|
||||
// this - see MpegBaseTakePESPacket.
|
||||
lli = PSPPointer<SceMpegLLI>::Create(p);
|
||||
u32 dest = 0;
|
||||
std::vector<u8> gathered;
|
||||
@@ -100,9 +99,16 @@ static u32 sceMpegBasePESpacketCopy(u32 p)
|
||||
return 0;
|
||||
}
|
||||
|
||||
const std::vector<u8> *MpegBaseGetPESPacket(u32 dest) {
|
||||
std::vector<u8> MpegBaseTakePESPacket(u32 dest) {
|
||||
auto it = g_pesPackets.find(dest);
|
||||
return it == g_pesPackets.end() ? nullptr : &it->second;
|
||||
if (it == g_pesPackets.end()) {
|
||||
return std::vector<u8>();
|
||||
}
|
||||
// Handed over, not lent: leaving it behind meant the first decode of the next movie could pick
|
||||
// up the last packet of the previous one, if the address came round again.
|
||||
std::vector<u8> packet = std::move(it->second);
|
||||
g_pesPackets.erase(it);
|
||||
return packet;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -26,7 +26,8 @@ void Register_sceMpegbase();
|
||||
// Called per boot, from __MpegInit.
|
||||
void __MpegBaseInit();
|
||||
|
||||
// The PES payload sceMpegBasePESpacketCopy gathered for a given destination. On hardware that copy
|
||||
// lands in Media Engine memory, which sceVideocodec would then read back; we keep it here instead.
|
||||
// Returns nullptr if nothing was copied to that address.
|
||||
const std::vector<u8> *MpegBaseGetPESPacket(u32 dest);
|
||||
// Takes the PES payload sceMpegBasePESpacketCopy gathered for a given destination. On hardware that
|
||||
// copy lands in Media Engine memory, which sceVideocodec would then read back; we keep it here
|
||||
// instead. The payload is moved out and dropped from the table, so each one is decoded once.
|
||||
// Empty if nothing was copied to that address.
|
||||
std::vector<u8> MpegBaseTakePESPacket(u32 dest);
|
||||
@@ -500,15 +500,17 @@ static int sceVideocodecDecode(u32 ctxAddr, int type) {
|
||||
bool gotFrame = false;
|
||||
const u8 *au = nullptr;
|
||||
int auBytes = 0;
|
||||
// Owns the gathered payload for as long as au points into it.
|
||||
std::vector<u8> pes;
|
||||
if (auSize > 0 && Memory::IsValidRange(auAddr, auSize)) {
|
||||
au = Memory::GetTypedPointerRange<u8>(auAddr, auSize);
|
||||
auBytes = auSize;
|
||||
} else {
|
||||
// Ask for the payload copied to this exact address - the same call carries audio too.
|
||||
const std::vector<u8> *pes = MpegBaseGetPESPacket(auAddr);
|
||||
if (pes && !pes->empty()) {
|
||||
au = pes->data();
|
||||
auBytes = (int)pes->size();
|
||||
// Take the payload copied to this exact address - the same call carries audio too.
|
||||
pes = MpegBaseTakePESPacket(auAddr);
|
||||
if (!pes.empty()) {
|
||||
au = pes.data();
|
||||
auBytes = (int)pes.size();
|
||||
}
|
||||
}
|
||||
if (au && auBytes > 0) {
|
||||
|
||||
Reference in new issue
Block a user