prx_mem memory leak fixed

CPUThread::ExecAsCallback (experimental)
This commit is contained in:
Nekotekina 2014-03-04 23:18:17 +04:00
parent b32a8e2e28
commit 384536ba4f
11 changed files with 133 additions and 39 deletions

View file

@ -145,15 +145,19 @@ public:
{ {
if (!tid) if (!tid)
{ {
ConLog.Error("SMutexLockerBase: thread id == 0"); if (!Emu.IsStopped())
Emu.Pause(); {
ConLog.Error("SMutexLockerBase: thread id == 0");
Emu.Pause();
}
return;
} }
sm.lock(tid); sm.lock(tid);
} }
~SMutexLockerBase() ~SMutexLockerBase()
{ {
sm.unlock(tid); if (tid) sm.unlock(tid);
} }
}; };

View file

@ -360,3 +360,44 @@ void CPUThread::Task()
if (Ini.HLELogging.GetValue()) ConLog.Write("%s leave", CPUThread::GetFName().wx_str()); if (Ini.HLELogging.GetValue()) ConLog.Write("%s leave", CPUThread::GetFName().wx_str());
} }
int CPUThread::ExecAsCallback(u64 pc, bool wait, u64 a1, u64 a2, u64 a3, u64 a4) // not multithread-safe
{
while (m_alive)
{
if (Emu.IsStopped())
{
ConLog.Warning("ExecAsCallback() aborted");
return CELL_ECANCELED; // doesn't mean anything
}
Sleep(1);
}
Stop();
Reset();
SetEntry(pc);
SetPrio(1001);
SetStackSize(0x10000);
SetExitStatus(CELL_OK);
SetArg(0, a1);
SetArg(1, a2);
SetArg(2, a3);
SetArg(3, a4);
Run();
Exec();
while (wait && m_alive)
{
if (Emu.IsStopped())
{
ConLog.Warning("ExecAsCallback() aborted");
return CELL_EABORT; // doesn't mean anything
}
Sleep(1);
}
return wait * m_exit_status;
}

View file

@ -234,6 +234,8 @@ public:
return pc + 4; return pc + 4;
} }
int ExecAsCallback(u64 pc, bool wait, u64 a1 = 0, u64 a2 = 0, u64 a3 = 0, u64 a4 = 0);
protected: protected:
virtual void DoReset()=0; virtual void DoReset()=0;
virtual void DoRun()=0; virtual void DoRun()=0;

View file

@ -118,14 +118,11 @@ void PPUThread::InitRegs()
GPR[6] = m_args[3]; GPR[6] = m_args[3];
} }
u32 prx_mem = Memory.PRXMem.AllocAlign(0x10000);
Memory.Write64(prx_mem, 0xDEADBEEFABADCAFE);
GPR[0] = pc; GPR[0] = pc;
GPR[8] = entry; GPR[8] = entry;
GPR[11] = 0x80; GPR[11] = 0x80;
GPR[12] = Emu.GetMallocPageSize(); GPR[12] = Emu.GetMallocPageSize();
GPR[13] = prx_mem + 0x7060; GPR[13] = Memory.PRXMem.GetStartAddr() + 0x7060;
GPR[28] = GPR[4]; GPR[28] = GPR[4];
GPR[29] = GPR[3]; GPR[29] = GPR[3];
GPR[31] = GPR[5]; GPR[31] = GPR[5];

View file

@ -47,6 +47,8 @@ u32 adecOpen(AudioDecoder* data)
{ {
AudioDecoder& adec = *data; AudioDecoder& adec = *data;
adec.adecCb = &Emu.GetCPU().AddThread(CPU_THREAD_PPU);
u32 adec_id = cellAdec.GetNewId(data); u32 adec_id = cellAdec.GetNewId(data);
adec.id = adec_id; adec.id = adec_id;
@ -70,11 +72,11 @@ u32 adecOpen(AudioDecoder* data)
continue; continue;
} }
if (adec.frames.GetCount() >= 50) /*if (adec.frames.GetCount() >= 50)
{ {
Sleep(1); Sleep(1);
continue; continue;
} }*/
if (!adec.job.Pop(task)) if (!adec.job.Pop(task))
{ {
@ -100,10 +102,11 @@ u32 adecOpen(AudioDecoder* data)
// TODO: finalize // TODO: finalize
ConLog.Warning("adecEndSeq:"); ConLog.Warning("adecEndSeq:");
Callback cb; /*Callback cb;
cb.SetAddr(adec.cbFunc); cb.SetAddr(adec.cbFunc);
cb.Handle(adec.id, CELL_ADEC_MSG_TYPE_SEQDONE, CELL_OK, adec.cbArg); cb.Handle(adec.id, CELL_ADEC_MSG_TYPE_SEQDONE, CELL_OK, adec.cbArg);
cb.Branch(true); // ??? cb.Branch(true); // ???*/
adec.adecCb->ExecAsCallback(adec.cbFunc, true, adec.id, CELL_ADEC_MSG_TYPE_SEQDONE, CELL_OK, adec.cbArg);
avcodec_close(adec.ctx); avcodec_close(adec.ctx);
avformat_close_input(&adec.fmt); avformat_close_input(&adec.fmt);
@ -214,14 +217,15 @@ u32 adecOpen(AudioDecoder* data)
frame.auAddr = task.au.addr; frame.auAddr = task.au.addr;
frame.auSize = task.au.size; frame.auSize = task.au.size;
frame.userdata = task.au.userdata; frame.userdata = task.au.userdata;
frame.size = 2048; frame.size = 4096;
frame.data = nullptr; frame.data = nullptr;
adec.frames.Push(frame); adec.frames.Push(frame);
Callback cb; /*Callback cb;
cb.SetAddr(adec.cbFunc); cb.SetAddr(adec.cbFunc);
cb.Handle(adec.id, CELL_ADEC_MSG_TYPE_PCMOUT, CELL_OK, adec.cbArg); cb.Handle(adec.id, CELL_ADEC_MSG_TYPE_PCMOUT, CELL_OK, adec.cbArg);
cb.Branch(false); cb.Branch(false);*/
adec.adecCb->ExecAsCallback(adec.cbFunc, false, adec.id, CELL_ADEC_MSG_TYPE_PCMOUT, CELL_OK, adec.cbArg);
break; break;
} }
@ -273,17 +277,19 @@ u32 adecOpen(AudioDecoder* data)
adec.frames.Push(frame); adec.frames.Push(frame);
frame.data = nullptr; // to prevent destruction frame.data = nullptr; // to prevent destruction
Callback cb; /*Callback cb;
cb.SetAddr(adec.cbFunc); cb.SetAddr(adec.cbFunc);
cb.Handle(adec.id, CELL_ADEC_MSG_TYPE_PCMOUT, CELL_OK, adec.cbArg); cb.Handle(adec.id, CELL_ADEC_MSG_TYPE_PCMOUT, CELL_OK, adec.cbArg);
cb.Branch(false); cb.Branch(false);*/
adec.adecCb->ExecAsCallback(adec.cbFunc, false, adec.id, CELL_ADEC_MSG_TYPE_PCMOUT, CELL_OK, adec.cbArg);
} }
} }
Callback cb; /*Callback cb;
cb.SetAddr(adec.cbFunc); cb.SetAddr(adec.cbFunc);
cb.Handle(adec.id, CELL_ADEC_MSG_TYPE_AUDONE, task.au.auInfo_addr, adec.cbArg); cb.Handle(adec.id, CELL_ADEC_MSG_TYPE_AUDONE, task.au.auInfo_addr, adec.cbArg);
cb.Branch(false); cb.Branch(false);*/
adec.adecCb->ExecAsCallback(adec.cbFunc, false, adec.id, CELL_ADEC_MSG_TYPE_AUDONE, task.au.auInfo_addr, adec.cbArg);
} }
break; break;
@ -408,6 +414,7 @@ int cellAdecClose(u32 handle)
Sleep(1); Sleep(1);
} }
if (adec->adecCb) Emu.GetCPU().RemoveThread(adec->adecCb->GetId());
Emu.GetIdManager().RemoveID(handle); Emu.GetIdManager().RemoveID(handle);
return CELL_OK; return CELL_OK;
} }
@ -506,6 +513,10 @@ int cellAdecGetPcm(u32 handle, u32 outBuffer_addr)
// copy data // copy data
if (!af.data) // fake: empty data if (!af.data) // fake: empty data
{ {
u8* buf = (u8*)malloc(4096);
memset(buf, 0, 4096);
Memory.CopyFromReal(outBuffer_addr, buf, 4096);
free(buf);
return CELL_OK; return CELL_OK;
} }
} }
@ -546,7 +557,9 @@ int cellAdecGetPcmItem(u32 handle, mem32_t pcmItem_ptr)
adec->memBias += 512; adec->memBias += 512;
if (adec->memBias + 512 > adec->memSize) if (adec->memBias + 512 > adec->memSize)
{
adec->memBias = 0; adec->memBias = 0;
}
pcm->pcmHandle = 0; // ??? pcm->pcmHandle = 0; // ???
pcm->pcmAttr.bsiInfo_addr = pcm.GetAddr() + sizeof(CellAdecPcmItem); pcm->pcmAttr.bsiInfo_addr = pcm.GetAddr() + sizeof(CellAdecPcmItem);

View file

@ -1064,6 +1064,8 @@ public:
const u32 cbArg; const u32 cbArg;
u32 memBias; u32 memBias;
CPUThread* adecCb;
AudioDecoder(AudioCodecType type, u32 addr, u32 size, u32 func, u32 arg) AudioDecoder(AudioCodecType type, u32 addr, u32 size, u32 func, u32 arg)
: type(type) : type(type)
, memAddr(addr) , memAddr(addr)
@ -1071,6 +1073,7 @@ public:
, memBias(0) , memBias(0)
, cbFunc(func) , cbFunc(func)
, cbArg(arg) , cbArg(arg)
, adecCb(nullptr)
, is_running(false) , is_running(false)
, is_finished(false) , is_finished(false)
, just_started(false) , just_started(false)

View file

@ -20,7 +20,7 @@ void dmuxQueryEsAttr(u32 info_addr /* may be 0 */, const mem_ptr_t<CellCodecEsFi
if (esFilterId->filterIdMajor >= 0xe0) if (esFilterId->filterIdMajor >= 0xe0)
attr->memSize = 0x2000000; // 0x45fa49 from ps3 attr->memSize = 0x2000000; // 0x45fa49 from ps3
else else
attr->memSize = 0x400000; // 0x73d9 from ps3 attr->memSize = 0x100000; // 0x73d9 from ps3
cellDmux.Warning("*** filter(0x%x, 0x%x, 0x%x, 0x%x)", (u32)esFilterId->filterIdMajor, (u32)esFilterId->filterIdMinor, cellDmux.Warning("*** filter(0x%x, 0x%x, 0x%x, 0x%x)", (u32)esFilterId->filterIdMajor, (u32)esFilterId->filterIdMinor,
(u32)esFilterId->supplementalInfo1, (u32)esFilterId->supplementalInfo2); (u32)esFilterId->supplementalInfo1, (u32)esFilterId->supplementalInfo2);
@ -30,6 +30,8 @@ u32 dmuxOpen(Demuxer* data)
{ {
Demuxer& dmux = *data; Demuxer& dmux = *data;
dmux.dmuxCb = &Emu.GetCPU().AddThread(CPU_THREAD_PPU);
u32 dmux_id = cellDmux.GetNewId(data); u32 dmux_id = cellDmux.GetNewId(data);
dmux.id = dmux_id; dmux.id = dmux_id;
@ -138,10 +140,11 @@ u32 dmuxOpen(Demuxer* data)
mem_ptr_t<CellDmuxEsMsg> esMsg(a128(dmux.memAddr) + (cb_add ^= 16)); mem_ptr_t<CellDmuxEsMsg> esMsg(a128(dmux.memAddr) + (cb_add ^= 16));
esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_AU_FOUND; esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_AU_FOUND;
esMsg->supplementalInfo = stream.userdata; esMsg->supplementalInfo = stream.userdata;
Callback cb; /*Callback cb;
cb.SetAddr(es.cbFunc); cb.SetAddr(es.cbFunc);
cb.Handle(dmux.id, es.id, esMsg.GetAddr(), es.cbArg); cb.Handle(dmux.id, es.id, esMsg.GetAddr(), es.cbArg);
cb.Branch(false); cb.Branch(false);*/
dmux.dmuxCb->ExecAsCallback(es.cbFunc, false, dmux.id, es.id, esMsg.GetAddr(), es.cbArg);
} }
else else
{ {
@ -184,10 +187,11 @@ u32 dmuxOpen(Demuxer* data)
mem_ptr_t<CellDmuxEsMsg> esMsg(a128(dmux.memAddr) + (cb_add ^= 16)); mem_ptr_t<CellDmuxEsMsg> esMsg(a128(dmux.memAddr) + (cb_add ^= 16));
esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_AU_FOUND; esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_AU_FOUND;
esMsg->supplementalInfo = stream.userdata; esMsg->supplementalInfo = stream.userdata;
Callback cb; /*Callback cb;
cb.SetAddr(es.cbFunc); cb.SetAddr(es.cbFunc);
cb.Handle(dmux.id, es.id, esMsg.GetAddr(), es.cbArg); cb.Handle(dmux.id, es.id, esMsg.GetAddr(), es.cbArg);
cb.Branch(false); cb.Branch(false);*/
dmux.dmuxCb->ExecAsCallback(es.cbFunc, false, dmux.id, es.id, esMsg.GetAddr(), es.cbArg);
} }
if (pes.new_au) if (pes.new_au)
@ -292,10 +296,12 @@ task:
mem_ptr_t<CellDmuxMsg> dmuxMsg(a128(dmux.memAddr) + (cb_add ^= 16)); mem_ptr_t<CellDmuxMsg> dmuxMsg(a128(dmux.memAddr) + (cb_add ^= 16));
dmuxMsg->msgType = CELL_DMUX_MSG_TYPE_DEMUX_DONE; dmuxMsg->msgType = CELL_DMUX_MSG_TYPE_DEMUX_DONE;
dmuxMsg->supplementalInfo = stream.userdata; dmuxMsg->supplementalInfo = stream.userdata;
Callback cb; /*Callback cb;
cb.SetAddr(dmux.cbFunc); cb.SetAddr(dmux.cbFunc);
cb.Handle(dmux.id, dmuxMsg.GetAddr(), dmux.cbArg); cb.Handle(dmux.id, dmuxMsg.GetAddr(), dmux.cbArg);
cb.Branch(task.type == dmuxResetStreamAndWaitDone); cb.Branch(task.type == dmuxResetStreamAndWaitDone);*/
dmux.dmuxCb->ExecAsCallback(dmux.cbFunc, task.type == dmuxResetStreamAndWaitDone,
dmux.id, dmuxMsg.GetAddr(), dmux.cbArg);
dmux.is_running = false; dmux.is_running = false;
} }
break; break;
@ -370,20 +376,22 @@ task:
mem_ptr_t<CellDmuxEsMsg> esMsg(a128(dmux.memAddr) + (cb_add ^= 16)); mem_ptr_t<CellDmuxEsMsg> esMsg(a128(dmux.memAddr) + (cb_add ^= 16));
esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_AU_FOUND; esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_AU_FOUND;
esMsg->supplementalInfo = stream.userdata; esMsg->supplementalInfo = stream.userdata;
Callback cb; /*Callback cb;
cb.SetAddr(es.cbFunc); cb.SetAddr(es.cbFunc);
cb.Handle(dmux.id, es.id, esMsg.GetAddr(), es.cbArg); cb.Handle(dmux.id, es.id, esMsg.GetAddr(), es.cbArg);
cb.Branch(false); cb.Branch(false);*/
dmux.dmuxCb->ExecAsCallback(es.cbFunc, false, dmux.id, es.id, esMsg.GetAddr(), es.cbArg);
} }
// callback // callback
mem_ptr_t<CellDmuxEsMsg> esMsg(a128(dmux.memAddr) + (cb_add ^= 16)); mem_ptr_t<CellDmuxEsMsg> esMsg(a128(dmux.memAddr) + (cb_add ^= 16));
esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_FLUSH_DONE; esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_FLUSH_DONE;
esMsg->supplementalInfo = stream.userdata; esMsg->supplementalInfo = stream.userdata;
Callback cb; /*Callback cb;
cb.SetAddr(es.cbFunc); cb.SetAddr(es.cbFunc);
cb.Handle(dmux.id, es.id, esMsg.GetAddr(), es.cbArg); cb.Handle(dmux.id, es.id, esMsg.GetAddr(), es.cbArg);
cb.Branch(false); cb.Branch(false);*/
dmux.dmuxCb->ExecAsCallback(es.cbFunc, false, dmux.id, es.id, esMsg.GetAddr(), es.cbArg);
} }
break; break;
@ -549,6 +557,7 @@ int cellDmuxClose(u32 demuxerHandle)
Sleep(1); Sleep(1);
} }
if (dmux->dmuxCb) Emu.GetCPU().RemoveThread(dmux->dmuxCb->GetId());
Emu.GetIdManager().RemoveID(demuxerHandle); Emu.GetIdManager().RemoveID(demuxerHandle);
return CELL_OK; return CELL_OK;
} }

View file

@ -470,6 +470,7 @@ public:
volatile bool is_finished; volatile bool is_finished;
volatile bool is_running; volatile bool is_running;
CPUThread* dmuxCb;
Demuxer(u32 addr, u32 size, u32 func, u32 arg) Demuxer(u32 addr, u32 size, u32 func, u32 arg)
: is_finished(false) : is_finished(false)
@ -478,6 +479,7 @@ public:
, memSize(size) , memSize(size)
, cbFunc(func) , cbFunc(func)
, cbArg(arg) , cbArg(arg)
, dmuxCb(nullptr)
{ {
} }
}; };

View file

@ -55,10 +55,11 @@ int vdecRead(void* opaque, u8* buf, int buf_size)
buf_size -= vdec.reader.size; buf_size -= vdec.reader.size;
res += vdec.reader.size; res += vdec.reader.size;
Callback cb; /*Callback cb;
cb.SetAddr(vdec.cbFunc); cb.SetAddr(vdec.cbFunc);
cb.Handle(vdec.id, CELL_VDEC_MSG_TYPE_AUDONE, CELL_OK, vdec.cbArg); cb.Handle(vdec.id, CELL_VDEC_MSG_TYPE_AUDONE, CELL_OK, vdec.cbArg);
cb.Branch(false); cb.Branch(false);*/
vdec.vdecCb->ExecAsCallback(vdec.cbFunc, false, vdec.id, CELL_VDEC_MSG_TYPE_AUDONE, CELL_OK, vdec.cbArg);
vdec.job.Pop(vdec.task); vdec.job.Pop(vdec.task);
@ -73,6 +74,7 @@ int vdecRead(void* opaque, u8* buf, int buf_size)
ConLog.Error("vdecRead(): sequence error (task %d)", vdec.job.Peek().type); ConLog.Error("vdecRead(): sequence error (task %d)", vdec.job.Peek().type);
return 0; return 0;
} }
//buf_size = vdec.reader.size;
} }
if (!buf_size) if (!buf_size)
@ -115,6 +117,8 @@ u32 vdecOpen(VideoDecoder* data)
{ {
VideoDecoder& vdec = *data; VideoDecoder& vdec = *data;
vdec.vdecCb = &Emu.GetCPU().AddThread(CPU_THREAD_PPU);
u32 vdec_id = cellVdec.GetNewId(data); u32 vdec_id = cellVdec.GetNewId(data);
vdec.id = vdec_id; vdec.id = vdec_id;
@ -168,10 +172,11 @@ u32 vdecOpen(VideoDecoder* data)
// TODO: finalize // TODO: finalize
ConLog.Warning("vdecEndSeq:"); ConLog.Warning("vdecEndSeq:");
Callback cb; vdec.vdecCb->ExecAsCallback(vdec.cbFunc, false, vdec.id, CELL_VDEC_MSG_TYPE_SEQDONE, CELL_OK, vdec.cbArg);
/*Callback cb;
cb.SetAddr(vdec.cbFunc); cb.SetAddr(vdec.cbFunc);
cb.Handle(vdec.id, CELL_VDEC_MSG_TYPE_SEQDONE, CELL_OK, vdec.cbArg); cb.Handle(vdec.id, CELL_VDEC_MSG_TYPE_SEQDONE, CELL_OK, vdec.cbArg);
cb.Branch(true); // ??? cb.Branch(true); // ???*/
avcodec_close(vdec.ctx); avcodec_close(vdec.ctx);
avformat_close_input(&vdec.fmt); avformat_close_input(&vdec.fmt);
@ -268,6 +273,8 @@ u32 vdecOpen(VideoDecoder* data)
Emu.Pause(); Emu.Pause();
break; break;
} }
//vdec.ctx->flags |= CODEC_FLAG_TRUNCATED;
//vdec.ctx->flags2 |= CODEC_FLAG2_CHUNKS;
vdec.just_started = false; vdec.just_started = false;
} }
@ -275,9 +282,15 @@ u32 vdecOpen(VideoDecoder* data)
while (true) while (true)
{ {
if (Emu.IsStopped())
{
ConLog.Warning("vdecDecodeAu aborted");
return;
}
last_frame = av_read_frame(vdec.fmt, &au) < 0; last_frame = av_read_frame(vdec.fmt, &au) < 0;
if (last_frame) if (last_frame)
{ {
//break;
av_free(au.data); av_free(au.data);
au.data = NULL; au.data = NULL;
au.size = 0; au.size = 0;
@ -329,20 +342,22 @@ u32 vdecOpen(VideoDecoder* data)
frame.dts = vdec.last_dts; vdec.last_dts += 3003; // + duration??? frame.dts = vdec.last_dts; vdec.last_dts += 3003; // + duration???
frame.pts = vdec.last_pts; vdec.last_pts += 3003; frame.pts = vdec.last_pts; vdec.last_pts += 3003;
frame.userdata = task.userData; frame.userdata = task.userData;
vdec.frames.Push(frame); vdec.frames.Push(frame); // !!!!!!!!
frame.data = nullptr; // to prevent destruction frame.data = nullptr; // to prevent destruction
Callback cb; vdec.vdecCb->ExecAsCallback(vdec.cbFunc, false, vdec.id, CELL_VDEC_MSG_TYPE_PICOUT, CELL_OK, vdec.cbArg);
/*Callback cb;
cb.SetAddr(vdec.cbFunc); cb.SetAddr(vdec.cbFunc);
cb.Handle(vdec.id, CELL_VDEC_MSG_TYPE_PICOUT, CELL_OK, vdec.cbArg); cb.Handle(vdec.id, CELL_VDEC_MSG_TYPE_PICOUT, CELL_OK, vdec.cbArg);
cb.Branch(false); cb.Branch(false);*/
} }
} }
Callback cb; vdec.vdecCb->ExecAsCallback(vdec.cbFunc, false, vdec.id, CELL_VDEC_MSG_TYPE_AUDONE, CELL_OK, vdec.cbArg);
/*Callback cb;
cb.SetAddr(vdec.cbFunc); cb.SetAddr(vdec.cbFunc);
cb.Handle(vdec.id, CELL_VDEC_MSG_TYPE_AUDONE, CELL_OK, vdec.cbArg); cb.Handle(vdec.id, CELL_VDEC_MSG_TYPE_AUDONE, CELL_OK, vdec.cbArg);
cb.Branch(false); cb.Branch(false);*/
} }
break; break;
@ -459,6 +474,7 @@ int cellVdecClose(u32 handle)
Sleep(1); Sleep(1);
} }
if (vdec->vdecCb) Emu.GetCPU().RemoveThread(vdec->vdecCb->GetId());
Emu.GetIdManager().RemoveID(handle); Emu.GetIdManager().RemoveID(handle);
return CELL_OK; return CELL_OK;
} }
@ -638,7 +654,9 @@ int cellVdecGetPicItem(u32 handle, mem32_t picItem_ptr)
vdec->memBias += 512; vdec->memBias += 512;
if (vdec->memBias + 512 > vdec->memSize) if (vdec->memBias + 512 > vdec->memSize)
{
vdec->memBias = 0; vdec->memBias = 0;
}
info->codecType = vdec->type; info->codecType = vdec->type;
info->startAddr = 0x00000123; // invalid value (no address for picture) info->startAddr = 0x00000123; // invalid value (no address for picture)

View file

@ -718,9 +718,11 @@ public:
const u32 cbArg; const u32 cbArg;
u32 memBias; u32 memBias;
VdecTask task; // reference to current task variable VdecTask task; // current task variable
u64 last_pts, last_dts; u64 last_pts, last_dts;
CPUThread* vdecCb;
VideoDecoder(CellVdecCodecType type, u32 profile, u32 addr, u32 size, u32 func, u32 arg) VideoDecoder(CellVdecCodecType type, u32 profile, u32 addr, u32 size, u32 func, u32 arg)
: type(type) : type(type)
, profile(profile) , profile(profile)
@ -733,6 +735,7 @@ public:
, is_running(false) , is_running(false)
, just_started(false) , just_started(false)
, ctx(nullptr) , ctx(nullptr)
, vdecCb(nullptr)
{ {
AVCodec* codec = avcodec_find_decoder(AV_CODEC_ID_H264); AVCodec* codec = avcodec_find_decoder(AV_CODEC_ID_H264);
if (!codec) if (!codec)

View file

@ -267,6 +267,8 @@ void Emulator::Load()
ppu_thr_exit_data += ADDI(11, 0, 41); ppu_thr_exit_data += ADDI(11, 0, 41);
ppu_thr_exit_data += SC(2); ppu_thr_exit_data += SC(2);
ppu_thr_exit_data += BCLR(0x10 | 0x04, 0, 0, 0); ppu_thr_exit_data += BCLR(0x10 | 0x04, 0, 0, 0);
Memory.Write64(Memory.PRXMem.AllocAlign(0x10000), 0xDEADBEEFABADCAFE);
} }
break; break;