Add save stating changes to mediaengine.

Also makes it compile again.
This commit is contained in:
Unknown W. Brackets 2012-12-28 23:29:24 -08:00
parent 6f9f9e1c98
commit ac2768640a
6 changed files with 147 additions and 22 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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 {

View File

@ -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();

View File

@ -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)

View File

@ -21,4 +21,5 @@ void Register_scePsmf();
void Register_scePsmfPlayer();
void __PsmfInit();
void __PsmfDoState(PointerWrap &p);
void __PsmfShutdown();