Files
ppsspp/Core/HLE/sceMpegbase.h
T
Henrik RydgårdandClaude Opus 5 b77e7c4e66 sceVideocodec: implement CopyYCbCr
This is what sceMpegAvcCopyYCbCr is built on, and a game that wants the raw
YCbCr rather than letting sceMpegbase convert to RGB uses it and nothing else.

mpeg.prx builds the descriptor on its own stack and avcodec.prx reads it back at
0x800015c4. Dimensions in pixels at 0x00/0x04, the eight frame buffers from 0x0c
but ordered 0,2,4,6 then 1,3,5,7, and from 0x2c the destination Y with Cb and Cr
following it contiguously - ordinary planar YUV420. Checked against what the
game passes: the eight addresses are exactly the buffers we handed out, and the
three destinations are spaced width*height and width*height/4 apart.

Un-tiling is the same operation the colour conversion already does, so that
moves out of sceMpegbase.cpp as ReadTiledYCbCr rather than being written twice.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-09-18 09:43:15 -06:00

44 lines
1.7 KiB
C++

// Copyright (c) 2026- PPSSPP Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0 or later versions.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#pragma once
#include <vector>
#include "Common/CommonTypes.h"
class PointerWrap;
void Register_sceMpegbase();
// Called per boot, from __MpegInit.
void __MpegBaseInit();
void __MpegBaseDoState(PointerWrap &p);
// 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);
// Un-tiles a decoded frame from the eight buffers the Media Engine lays it out in into three
// planes. The buffers are in sceVideocodec's order: four luma, then four chroma. cb and cr come
// out at half width and half height, as YUV420 does.
bool ReadTiledYCbCr(const u32 *buffers, int width, int height,
std::vector<u8> &luma, std::vector<u8> &cb, std::vector<u8> &cr);