mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 13:30:02 +00:00
Add save stating changes to mediaengine.
Also makes it compile again.
This commit is contained in:
parent
6f9f9e1c98
commit
ac2768640a
@ -168,7 +168,9 @@ void __KernelDoState(PointerWrap &p)
|
||||
__GeDoState(p);
|
||||
__ImposeDoState(p);
|
||||
__IoDoState(p);
|
||||
__MpegDoState(p);
|
||||
__PowerDoState(p);
|
||||
__PsmfDoState(p);
|
||||
__SasDoState(p);
|
||||
__SslDoState(p);
|
||||
__UmdDoState(p);
|
||||
|
@ -191,7 +191,6 @@ bool __KernelSwitchOffThread(const char *reason);
|
||||
|
||||
// A call into game code. These can be pending on a thread.
|
||||
// Similar to Callback-s (NOT CallbackInfos) in JPCSP.
|
||||
class Action;
|
||||
typedef Action *(*ActionCreator)();
|
||||
Action *__KernelCreateAction(int actionType);
|
||||
int __KernelRegisterActionType(ActionCreator creator);
|
||||
|
@ -87,7 +87,7 @@ struct StreamInfo
|
||||
};
|
||||
|
||||
// Internal structure
|
||||
struct MpegContext {
|
||||
struct MpegContextSimple {
|
||||
u32 defaultFrameWidth;
|
||||
int videoFrameCount;
|
||||
int audioFrameCount;
|
||||
@ -108,20 +108,31 @@ struct MpegContext {
|
||||
bool esBuffers[NUM_ES_BUFFERS];
|
||||
AvcContext avc;
|
||||
|
||||
std::map<int, StreamInfo> streamMap;
|
||||
|
||||
bool avcRegistered;
|
||||
bool atracRegistered;
|
||||
bool pcmRegistered;
|
||||
|
||||
bool isAnalyzed;
|
||||
};
|
||||
typedef std::map<u32, StreamInfo> StreamInfoMap;
|
||||
|
||||
struct MpegContext : public MpegContextSimple {
|
||||
void DoState(PointerWrap &p) {
|
||||
p.Do<MpegContextSimple>(*this);
|
||||
p.Do<StreamInfo>(streamMap);
|
||||
// Media engine has nothing exotic.
|
||||
p.Do<MediaEngine>(*mediaengine);
|
||||
p.DoMarker("MpegContext");
|
||||
}
|
||||
|
||||
StreamInfoMap streamMap;
|
||||
MediaEngine *mediaengine;
|
||||
};
|
||||
|
||||
static int streamIdGen;
|
||||
static u32 streamIdGen;
|
||||
static bool isCurrentMpegAnalyzed;
|
||||
static bool fakeMode;
|
||||
static int actionPostPut;
|
||||
static std::map<u32, MpegContext *> mpegMap;
|
||||
// TODO: Remove.
|
||||
static u32 lastMpegHandle = 0;
|
||||
@ -225,18 +236,65 @@ void AnalyzeMpeg(u32 buffer_addr, MpegContext *ctx) {
|
||||
INFO_LOG(ME, "First timestamp: %d, Last timestamp: %d", ctx->mpegFirstTimestamp, ctx->mpegLastTimestamp);
|
||||
}
|
||||
|
||||
class PostPutAction : public Action {
|
||||
public:
|
||||
PostPutAction() {}
|
||||
void setRingAddr(u32 ringAddr) { ringAddr_ = ringAddr; }
|
||||
static Action *Create() { return new PostPutAction; }
|
||||
void DoState(PointerWrap &p) { p.Do(ringAddr_); p.DoMarker("PostPutAction"); }
|
||||
void run();
|
||||
private:
|
||||
u32 ringAddr_;
|
||||
};
|
||||
|
||||
void __MpegInit(bool useMediaEngine_) {
|
||||
lastMpegHandle = 0;
|
||||
streamIdGen = 1;
|
||||
fakeMode = !useMediaEngine_;
|
||||
isCurrentMpegAnalyzed = false;
|
||||
actionPostPut = __KernelRegisterActionType(PostPutAction::Create);
|
||||
}
|
||||
|
||||
void __MpegDoState(PointerWrap &p) {
|
||||
p.Do(lastMpegHandle);
|
||||
p.Do(streamIdGen);
|
||||
p.Do(fakeMode);
|
||||
p.Do(isCurrentMpegAnalyzed);
|
||||
p.Do(actionPostPut);
|
||||
__KernelRestoreActionType(actionPostPut, PostPutAction::Create);
|
||||
|
||||
int n = (int) mpegMap.size();
|
||||
p.Do(n);
|
||||
if (p.mode == p.MODE_READ) {
|
||||
std::map<u32, MpegContext *>::iterator it, end;
|
||||
for (it = mpegMap.begin(), end = mpegMap.end(); it != end; ++it) {
|
||||
delete it->second->mediaengine;
|
||||
delete it->second;
|
||||
}
|
||||
mpegMap.clear();
|
||||
|
||||
for (int i = 0; i < n; ++i) {
|
||||
u32 key;
|
||||
p.Do(key);
|
||||
MpegContext *ctx = new MpegContext;
|
||||
ctx->mediaengine = new MediaEngine;
|
||||
ctx->DoState(p);
|
||||
mpegMap[key] = ctx;
|
||||
}
|
||||
} else {
|
||||
std::map<u32, MpegContext *>::iterator it, end;
|
||||
for (it = mpegMap.begin(), end = mpegMap.end(); it != end; ++it) {
|
||||
p.Do(it->first);
|
||||
it->second->DoState(p);
|
||||
}
|
||||
}
|
||||
|
||||
p.DoMarker("sceMpeg");
|
||||
}
|
||||
|
||||
void __MpegShutdown() {
|
||||
std::map<u32, MpegContext *>::iterator it, end;
|
||||
for (it = mpegMap.begin(), end = mpegMap.end(); it != end; ++it)
|
||||
{
|
||||
for (it = mpegMap.begin(), end = mpegMap.end(); it != end; ++it) {
|
||||
delete it->second->mediaengine;
|
||||
delete it->second;
|
||||
}
|
||||
@ -433,7 +491,7 @@ int sceMpegRegistStream(u32 mpeg, u32 streamType, u32 streamNum)
|
||||
break;
|
||||
}
|
||||
// ...
|
||||
int sid = streamIdGen++;
|
||||
u32 sid = streamIdGen++;
|
||||
StreamInfo info;
|
||||
info.type = streamType;
|
||||
info.num = streamNum;
|
||||
@ -703,13 +761,7 @@ int sceMpegRingbufferAvailableSize(u32 ringbufferAddr)
|
||||
}
|
||||
|
||||
|
||||
class PostPutAction : public Action {
|
||||
public:
|
||||
PostPutAction(u32 ringAddr) : ringAddr_(ringAddr) {}
|
||||
void run();
|
||||
private:
|
||||
u32 ringAddr_;
|
||||
};
|
||||
|
||||
|
||||
void PostPutAction::run() {
|
||||
SceMpegRingBuffer ringbuffer;
|
||||
@ -764,7 +816,8 @@ u32 sceMpegRingbufferPut(u32 ringbufferAddr, u32 numPackets, u32 available)
|
||||
|
||||
// Execute callback function as a direct MipsCall, no blocking here so no messing around with wait states etc
|
||||
if (ringbuffer.callback_addr) {
|
||||
PostPutAction *action = new PostPutAction(ringbufferAddr);
|
||||
PostPutAction *action = (PostPutAction *) __KernelCreateAction(actionPostPut);
|
||||
action->setRingAddr(ringbufferAddr);
|
||||
u32 args[3] = {ringbuffer.data, numPackets, ringbuffer.callback_args};
|
||||
__KernelDirectMipsCall(ringbuffer.callback_addr, action, false, args, 3, false);
|
||||
} else {
|
||||
|
@ -18,6 +18,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../Globals.h"
|
||||
#include "../../Common/ChunkFile.h"
|
||||
|
||||
enum {
|
||||
ERROR_MPEG_BAD_VERSION = 0x80610002,
|
||||
@ -77,6 +78,7 @@ struct SceMpegRingBuffer {
|
||||
};
|
||||
|
||||
void __MpegInit(bool useMediaEngine_);
|
||||
void __MpegDoState(PointerWrap &p);
|
||||
void __MpegShutdown();
|
||||
|
||||
void Register_sceMpeg();
|
||||
|
@ -56,11 +56,7 @@ class PsmfStream;
|
||||
// we read it manually.
|
||||
// TODO: Change to work directly with the data in RAM instead of this
|
||||
// JPSCP-esque class.
|
||||
class Psmf {
|
||||
public:
|
||||
Psmf(u32 data);
|
||||
u32 getNumStreams() { return 2; }
|
||||
|
||||
struct PsmfSimple {
|
||||
u32 magic;
|
||||
u32 version;
|
||||
u32 streamOffset;
|
||||
@ -86,8 +82,16 @@ public:
|
||||
int videoHeight;
|
||||
int audioChannels;
|
||||
int audioFrequency;
|
||||
};
|
||||
typedef std::map<int, PsmfStream *> PsmfStreamMap;
|
||||
class Psmf : public PsmfSimple {
|
||||
public:
|
||||
Psmf(u32 data);
|
||||
~Psmf();
|
||||
u32 getNumStreams() { return 2; }
|
||||
void DoState(PointerWrap &p);
|
||||
|
||||
std::map<int, PsmfStream *> streamMap;
|
||||
PsmfStreamMap streamMap;
|
||||
};
|
||||
|
||||
class PsmfStream {
|
||||
@ -120,6 +124,10 @@ public:
|
||||
streamId, privateStreamId, psmf->audioChannels, psmf->audioFrequency);
|
||||
}
|
||||
|
||||
void DoState(PointerWrap &p) {
|
||||
p.Do<PsmfStream>(*this);
|
||||
}
|
||||
|
||||
int type;
|
||||
int channel;
|
||||
};
|
||||
@ -162,6 +170,37 @@ Psmf::Psmf(u32 data) {
|
||||
}
|
||||
}
|
||||
|
||||
Psmf::~Psmf() {
|
||||
for (auto it = streamMap.begin(), end = streamMap.end(); it != end; ++it) {
|
||||
delete it->second;
|
||||
}
|
||||
streamMap.clear();
|
||||
}
|
||||
|
||||
void Psmf::DoState(PointerWrap &p) {
|
||||
p.Do<PsmfSimple>(*this);
|
||||
|
||||
int n = (int) streamMap.size();
|
||||
p.Do(n);
|
||||
if (p.mode == p.MODE_READ) {
|
||||
// Already empty, if we're reading this is brand new.
|
||||
for (int i = 0; i < n; ++i) {
|
||||
int key;
|
||||
p.Do(key);
|
||||
PsmfStream *stream = new PsmfStream(0, 0);
|
||||
stream->DoState(p);
|
||||
streamMap[key] = stream;
|
||||
}
|
||||
} else {
|
||||
for (auto it = streamMap.begin(), end = streamMap.end(); it != end; ++it) {
|
||||
p.Do(it->first);
|
||||
it->second->DoState(p);
|
||||
}
|
||||
}
|
||||
|
||||
p.DoMarker("Psmf");
|
||||
}
|
||||
|
||||
std::map<u32, Psmf *> psmfMap;
|
||||
|
||||
Psmf *getPsmf(u32 psmf)
|
||||
@ -177,6 +216,35 @@ void __PsmfInit()
|
||||
{
|
||||
}
|
||||
|
||||
void __PsmfDoState(PointerWrap &p)
|
||||
{
|
||||
int n = (int) psmfMap.size();
|
||||
p.Do(n);
|
||||
if (p.mode == p.MODE_READ) {
|
||||
std::map<u32, Psmf *>::iterator it, end;
|
||||
for (it = psmfMap.begin(), end = psmfMap.end(); it != end; ++it) {
|
||||
delete it->second;
|
||||
}
|
||||
psmfMap.clear();
|
||||
|
||||
for (int i = 0; i < n; ++i) {
|
||||
u32 key;
|
||||
p.Do(key);
|
||||
Psmf *psmf = new Psmf(0);
|
||||
psmf->DoState(p);
|
||||
psmfMap[key] = psmf;
|
||||
}
|
||||
} else {
|
||||
std::map<u32, Psmf *>::iterator it, end;
|
||||
for (it = psmfMap.begin(), end = psmfMap.end(); it != end; ++it) {
|
||||
p.Do(it->first);
|
||||
it->second->DoState(p);
|
||||
}
|
||||
}
|
||||
|
||||
p.DoMarker("scePsmf");
|
||||
}
|
||||
|
||||
void __PsmfShutdown()
|
||||
{
|
||||
for (auto it = psmfMap.begin(), end = psmfMap.end(); it != end; ++it)
|
||||
|
@ -21,4 +21,5 @@ void Register_scePsmf();
|
||||
void Register_scePsmfPlayer();
|
||||
|
||||
void __PsmfInit();
|
||||
void __PsmfDoState(PointerWrap &p);
|
||||
void __PsmfShutdown();
|
||||
|
Loading…
Reference in New Issue
Block a user