mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-15 15:30:29 +02:00
The SAS mix estimate was a guess capped at 1200us. Measured on a PSP (pspautotests audio/timing/sastiming), a mix costs 110us plus 0.49us per grain sample, plus per voice and sample 0.445us + 0.0675us per unit of pitch ratio (VAG; PCM and noise slightly less), plus 0.64us per sample with a reverb type set. Linear to 1% across 64-2048 samples and 0-32 voices: 32 VAG voices at 512 samples take 8.7ms, not 1.2. The mix runs on the Media Engine, as do video and audio decoding, so they now queue behind each other there (MEScheduleJob). A game that keeps SAS running during a movie - Star Wars: Lethal Alliance - decodes more slowly for it, like on hardware. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
70 lines
2.8 KiB
C++
70 lines
2.8 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 __VideocodecInit();
|
|
void __VideocodecShutdown();
|
|
void __VideocodecDoState(PointerWrap &p);
|
|
|
|
void Register_sceVideocodec();
|
|
|
|
// The state of each open decoder, for the debugger. A game can have several - Silent Hill Origins
|
|
// runs one context for the EDRAM and another for the decoding.
|
|
struct VideocodecCtxInfo {
|
|
u32 ctxAddr;
|
|
int type;
|
|
bool hasDecoder;
|
|
int frameCount;
|
|
// The token sceVideocodecGetEDRAM handed back, and how much it stands for. Not an address -
|
|
// the block is ours, not the game's, the way the Media Engine's memory is on hardware.
|
|
u32 edramToken;
|
|
u32 edramSize;
|
|
u32 frameBuffers;
|
|
u32 frameBuffersSize;
|
|
int width;
|
|
int height;
|
|
};
|
|
void VideocodecGetCtxInfo(std::vector<VideocodecCtxInfo> *infos);
|
|
|
|
// The Media Engine's address space. Separate from Allegrex's memory.
|
|
bool MEIsValidRange(u32 addr, u32 size);
|
|
|
|
// Runs a job of the given length on the Media Engine, after whatever it's already busy with -
|
|
// video decode, audio decode and SAS mixing all share it. Returns how long the caller waits for it
|
|
// to finish, in microseconds.
|
|
int MEScheduleJob(int us);
|
|
u8 *MEGetPointerRange(u32 addr, u32 size);
|
|
|
|
// The eight buffers of the frame starting at `firstBuffer`, and its size. Returns false if that
|
|
// isn't the start of an allocation we handed out (the normal answer once sceMpegBaseYCrCbCopy has
|
|
// moved a frame into the game's memory).
|
|
bool VideocodecGetFrameBuffers(u32 firstBuffer, u32 buffers[8], int *width = nullptr, int *height = nullptr);
|
|
|
|
// How the eight buffers a frame is delivered in are sized and laid out, in the order the
|
|
// descriptor lists them: four luma (left/right half of a 32-pixel band, even/odd rows) then four
|
|
// chroma. Everything that writes, reads or allocates them has to agree, so it lives in one place.
|
|
// `offsets` is each buffer's start within a single allocation, 64-byte aligned; either array may
|
|
// be null. Returns the total allocation size.
|
|
u32 VideocodecFrameBufferLayout(int width, int height, int sizes[8], u32 offsets[8]);
|