AV decoding minor cleanup

This commit is contained in:
Nekotekina 2014-10-18 21:00:21 +04:00
parent 318d06efda
commit 81474be103
4 changed files with 82 additions and 135 deletions

View file

@ -78,30 +78,13 @@ public:
} }
} }
u32 GetCount()
{
std::lock_guard<std::mutex> lock(m_mutex);
return m_count;
}
u32 GetCountUnsafe()
{
return m_count;
}
bool IsEmpty()
{
std::lock_guard<std::mutex> lock(m_mutex);
return !m_count;
}
void Clear() void Clear()
{ {
std::lock_guard<std::mutex> lock(m_mutex); std::lock_guard<std::mutex> lock(m_mutex);
m_count = 0; m_count = 0;
} }
T& Peek(const volatile bool* do_exit, u32 pos = 0) bool Peek(T& data, const volatile bool* do_exit, u32 pos = 0)
{ {
while (true) while (true)
{ {
@ -109,7 +92,7 @@ public:
{ {
if (Emu.IsStopped() || do_exit && *do_exit) if (Emu.IsStopped() || do_exit && *do_exit)
{ {
break; return false;
} }
std::this_thread::sleep_for(std::chrono::milliseconds(1)); std::this_thread::sleep_for(std::chrono::milliseconds(1));
@ -124,6 +107,7 @@ public:
} }
} }
} }
return m_data[(m_pos + pos) % SQSize]; data = m_data[(m_pos + pos) % SQSize];
return true;
} }
}; };

View file

@ -65,9 +65,9 @@ AudioDecoder::AudioDecoder(AudioCodecType type, u32 addr, u32 size, vm::ptr<Cell
AudioDecoder::~AudioDecoder() AudioDecoder::~AudioDecoder()
{ {
// TODO: check finalization // TODO: check finalization
for (u32 i = frames.GetCount() - 1; ~i; i--) AdecFrame af;
while (frames.Pop(af, &sq_no_wait))
{ {
AdecFrame& af = frames.Peek(nullptr, i);
av_frame_unref(af.data); av_frame_unref(af.data);
av_frame_free(&af.data); av_frame_free(&af.data);
} }
@ -96,17 +96,14 @@ int adecRawRead(void* opaque, u8* buf, int buf_size)
next: next:
if (adec.reader.size < (u32)buf_size /*&& !adec.just_started*/) if (adec.reader.size < (u32)buf_size /*&& !adec.just_started*/)
{ {
while (!adec.job.GetCountUnsafe()) AdecTask task;
if (!adec.job.Peek(task, &adec.is_closed))
{ {
if (Emu.IsStopped() || adec.is_closed) if (Emu.IsStopped()) cellAdec->Warning("adecRawRead() aborted");
{ return 0;
if (Emu.IsStopped()) cellAdec->Warning("adecRawRead(): aborted");
return 0;
}
std::this_thread::sleep_for(std::chrono::milliseconds(1));
} }
switch (auto jtype = adec.job.Peek(nullptr).type) switch (task.type)
{ {
case adecEndSeq: case adecEndSeq:
case adecClose: case adecClose:
@ -135,7 +132,7 @@ next:
default: default:
{ {
cellAdec->Error("adecRawRead(): unknown task (%d)", jtype); cellAdec->Error("adecRawRead(): unknown task (%d)", task.type);
Emu.Pause(); Emu.Pause();
return -1; return -1;
} }
@ -275,17 +272,11 @@ u32 adecOpen(AudioDecoder* data)
break; break;
} }
if (!adec.job.GetCountUnsafe() && adec.is_running) //if (!adec.job.GetCountUnsafe() && adec.is_running)
{ //{
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // std::this_thread::sleep_for(std::chrono::milliseconds(1));
continue; // continue;
} //}
/*if (adec.frames.GetCount() >= 50)
{
std::this_thread::sleep_for(std::chrono::milliseconds(1));
continue;
}*/
if (!adec.job.Pop(task, &adec.is_closed)) if (!adec.job.Pop(task, &adec.is_closed))
{ {
@ -667,7 +658,7 @@ int cellAdecClose(u32 handle)
int cellAdecStartSeq(u32 handle, u32 param_addr) int cellAdecStartSeq(u32 handle, u32 param_addr)
{ {
cellAdec->Log("cellAdecStartSeq(handle=%d, param_addr=0x%x)", handle, param_addr); cellAdec->Todo("cellAdecStartSeq(handle=%d, param_addr=0x%x)", handle, param_addr);
AudioDecoder* adec; AudioDecoder* adec;
if (!Emu.GetIdManager().GetIDData(handle, adec)) if (!Emu.GetIdManager().GetIDData(handle, adec))
@ -676,14 +667,8 @@ int cellAdecStartSeq(u32 handle, u32 param_addr)
} }
AdecTask task(adecStartSeq); AdecTask task(adecStartSeq);
/*if (adec->type == CELL_ADEC_TYPE_ATRACX_2CH)
{
} // TODO: using parameters
else*/
{
cellAdec->Todo("cellAdecStartSeq(): initialization");
}
adec->job.Push(task, &adec->is_closed); adec->job.Push(task, &adec->is_closed);
return CELL_OK; return CELL_OK;
@ -734,38 +719,36 @@ int cellAdecGetPcm(u32 handle, vm::ptr<float> outBuffer)
return CELL_ADEC_ERROR_ARG; return CELL_ADEC_ERROR_ARG;
} }
if (adec->frames.IsEmpty()) AdecFrame af;
if (!adec->frames.Pop(af, &sq_no_wait))
{ {
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack
return CELL_ADEC_ERROR_EMPTY; return CELL_ADEC_ERROR_EMPTY;
} }
AdecFrame af;
if (!adec->frames.Pop(af, &adec->is_closed))
{
return CELL_ADEC_ERROR_EMPTY;
}
AVFrame* frame = af.data; AVFrame* frame = af.data;
if (!af.data) // fake: empty data if (!af.data)
{ {
// hack
return CELL_OK; return CELL_OK;
} }
// reverse byte order, extract data: if (outBuffer)
float* in_f[2];
in_f[0] = (float*)frame->extended_data[0];
in_f[1] = (float*)frame->extended_data[1];
for (u32 i = 0; i < af.size / 8; i++)
{ {
outBuffer[i * 2 + 0] = in_f[0][i]; // reverse byte order, extract data:
outBuffer[i * 2 + 1] = in_f[1][i]; float* in_f[2];
in_f[0] = (float*)frame->extended_data[0];
in_f[1] = (float*)frame->extended_data[1];
for (u32 i = 0; i < af.size / 8; i++)
{
outBuffer[i * 2 + 0] = in_f[0][i];
outBuffer[i * 2 + 1] = in_f[1][i];
}
} }
if (af.data) av_frame_unref(af.data);
{ av_frame_free(&af.data);
av_frame_unref(af.data);
av_frame_free(&af.data);
}
return CELL_OK; return CELL_OK;
} }
@ -779,14 +762,13 @@ int cellAdecGetPcmItem(u32 handle, vm::ptr<u32> pcmItem_ptr)
return CELL_ADEC_ERROR_ARG; return CELL_ADEC_ERROR_ARG;
} }
if (adec->frames.IsEmpty()) AdecFrame af;
if (!adec->frames.Peek(af, &sq_no_wait))
{ {
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack
return CELL_ADEC_ERROR_EMPTY; return CELL_ADEC_ERROR_EMPTY;
} }
AdecFrame& af = adec->frames.Peek(nullptr);
AVFrame* frame = af.data; AVFrame* frame = af.data;
auto pcm = vm::ptr<CellAdecPcmItem>::make(adec->memAddr + adec->memBias); auto pcm = vm::ptr<CellAdecPcmItem>::make(adec->memAddr + adec->memBias);

View file

@ -62,7 +62,11 @@ bool ElementaryStream::is_full()
{ {
if (released < put_count) if (released < put_count)
{ {
u32 first = entries.Peek(&dmux->is_closed); u32 first;
if (!entries.Peek(first, &dmux->is_closed))
{
return false;
}
if (first >= put) if (first >= put)
{ {
return (first - put) < GetMaxAU(); return (first - put) < GetMaxAU();
@ -201,7 +205,11 @@ bool ElementaryStream::release()
return false; return false;
} }
u32 addr = entries.Peek(&dmux->is_closed); u32 addr;
if (!entries.Peek(addr, &dmux->is_closed))
{
return false; // ???
}
auto info = vm::ptr<CellDmuxAuInfo>::make(addr); auto info = vm::ptr<CellDmuxAuInfo>::make(addr);
//if (fidMajor != 0xbd) LOG_WARNING(HLE, "es::release(): (%s) size = 0x%x, info = 0x%x, pts = 0x%x", //if (fidMajor != 0xbd) LOG_WARNING(HLE, "es::release(): (%s) size = 0x%x, info = 0x%x, pts = 0x%x",
@ -239,7 +247,12 @@ bool ElementaryStream::peek(u32& out_data, bool no_ex, u32& out_spec, bool updat
return false; return false;
} }
u32 addr = entries.Peek(&dmux->is_closed, peek_count - released); u32 addr;
if (!entries.Peek(addr, &dmux->is_closed, peek_count - released))
{
return false; // ???
}
auto info = vm::ptr<CellDmuxAuInfo>::make(addr); auto info = vm::ptr<CellDmuxAuInfo>::make(addr);
//if (fidMajor != 0xbd) LOG_WARNING(HLE, "es::peek(%sAu(Ex)): (%s) size = 0x%x, info = 0x%x, pts = 0x%x", //if (fidMajor != 0xbd) LOG_WARNING(HLE, "es::peek(%sAu(Ex)): (%s) size = 0x%x, info = 0x%x, pts = 0x%x",
//wxString(update_index ? "Get" : "Peek").wx_str(), //wxString(update_index ? "Get" : "Peek").wx_str(),
@ -334,7 +347,7 @@ u32 dmuxOpen(Demuxer* data)
break; break;
} }
if (!dmux.job.GetCountUnsafe() && dmux.is_running) if (!dmux.job.Peek(task, &sq_no_wait) && dmux.is_running)
{ {
// default task (demuxing) (if there is no other work) // default task (demuxing) (if there is no other work)
be_t<u32> code; be_t<u32> code;

View file

@ -65,9 +65,9 @@ VideoDecoder::VideoDecoder(CellVdecCodecType type, u32 profile, u32 addr, u32 si
VideoDecoder::~VideoDecoder() VideoDecoder::~VideoDecoder()
{ {
// TODO: check finalization // TODO: check finalization
for (u32 i = frames.GetCount() - 1; ~i; i--) VdecFrame vf;
while (frames.Pop(vf, &sq_no_wait))
{ {
VdecFrame& vf = frames.Peek(nullptr, i);
av_frame_unref(vf.data); av_frame_unref(vf.data);
av_frame_free(&vf.data); av_frame_free(&vf.data);
} }
@ -96,17 +96,14 @@ int vdecRead(void* opaque, u8* buf, int buf_size)
next: next:
if (vdec.reader.size < (u32)buf_size /*&& !vdec.just_started*/) if (vdec.reader.size < (u32)buf_size /*&& !vdec.just_started*/)
{ {
while (!vdec.job.GetCountUnsafe()) VdecTask task;
if (!vdec.job.Peek(task, &vdec.is_closed))
{ {
if (Emu.IsStopped() || vdec.is_closed) if (Emu.IsStopped()) cellVdec->Warning("vdecRead() aborted");
{ return 0;
if (Emu.IsStopped()) cellVdec->Warning("vdecRead(): aborted");
return 0;
}
std::this_thread::sleep_for(std::chrono::milliseconds(1));
} }
switch (auto jtype = vdec.job.Peek(nullptr).type) switch (task.type)
{ {
case vdecEndSeq: case vdecEndSeq:
case vdecClose: case vdecClose:
@ -135,7 +132,7 @@ next:
default: default:
{ {
cellVdec->Error("vdecRead(): unknown task (%d)", jtype); cellVdec->Error("vdecRead(): unknown task (%d)", task.type);
Emu.Pause(); Emu.Pause();
return -1; return -1;
} }
@ -210,17 +207,11 @@ u32 vdecOpen(VideoDecoder* data)
break; break;
} }
if (!vdec.job.GetCountUnsafe() && vdec.is_running) //if (!vdec.job.GetCountUnsafe() && vdec.is_running)
{ //{
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // std::this_thread::sleep_for(std::chrono::milliseconds(1));
continue; // continue;
} //}
if (vdec.frames.GetCount() >= 50)
{
std::this_thread::sleep_for(std::chrono::milliseconds(1));
continue;
}
if (!vdec.job.Pop(task, &vdec.is_closed)) if (!vdec.job.Pop(task, &vdec.is_closed))
{ {
@ -563,28 +554,6 @@ int cellVdecEndSeq(u32 handle)
return CELL_VDEC_ERROR_ARG; return CELL_VDEC_ERROR_ARG;
} }
/*if (!vdec->job.IsEmpty())
{
std::this_thread::sleep_for(std::chrono::milliseconds(1));
return CELL_VDEC_ERROR_BUSY; // ???
}
if (!vdec->frames.IsEmpty())
{
std::this_thread::sleep_for(std::chrono::milliseconds(1));
return CELL_VDEC_ERROR_BUSY; // ???
}*/
while (!vdec->job.IsEmpty() || !vdec->frames.IsEmpty())
{
if (Emu.IsStopped())
{
cellVdec->Warning("cellVdecEndSeq(%d) aborted", handle);
return CELL_OK;
}
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
vdec->job.Push(VdecTask(vdecEndSeq), &vdec->is_closed); vdec->job.Push(VdecTask(vdecEndSeq), &vdec->is_closed);
return CELL_OK; return CELL_OK;
} }
@ -623,11 +592,19 @@ int cellVdecGetPicture(u32 handle, vm::ptr<const CellVdecPicFormat> format, vm::
return CELL_VDEC_ERROR_ARG; return CELL_VDEC_ERROR_ARG;
} }
if (vdec->frames.IsEmpty()) VdecFrame vf;
if (!vdec->frames.Pop(vf, &sq_no_wait))
{ {
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack
return CELL_VDEC_ERROR_EMPTY; return CELL_VDEC_ERROR_EMPTY;
} }
if (!vf.data)
{
// hack
return CELL_OK;
}
if (outBuff) if (outBuff)
{ {
u32 buf_size = a128(av_image_get_buffer_size(vdec->ctx->pix_fmt, vdec->ctx->width, vdec->ctx->height, 1)); u32 buf_size = a128(av_image_get_buffer_size(vdec->ctx->pix_fmt, vdec->ctx->width, vdec->ctx->height, 1));
@ -644,13 +621,6 @@ int cellVdecGetPicture(u32 handle, vm::ptr<const CellVdecPicFormat> format, vm::
return CELL_OK; return CELL_OK;
} }
VdecFrame vf;
if (!vdec->frames.Pop(vf, &vdec->is_closed))
{
return CELL_VDEC_ERROR_EMPTY;
}
AVFrame& frame = *vf.data; AVFrame& frame = *vf.data;
// TODO: zero padding bytes // TODO: zero padding bytes
@ -661,11 +631,10 @@ int cellVdecGetPicture(u32 handle, vm::ptr<const CellVdecPicFormat> format, vm::
cellVdec->Error("cellVdecGetPicture: av_image_copy_to_buffer failed(%d)", err); cellVdec->Error("cellVdecGetPicture: av_image_copy_to_buffer failed(%d)", err);
Emu.Pause(); Emu.Pause();
} }
av_frame_unref(vf.data);
av_frame_free(&vf.data);
} }
av_frame_unref(vf.data);
av_frame_free(&vf.data);
return CELL_OK; return CELL_OK;
} }
@ -679,14 +648,13 @@ int cellVdecGetPicItem(u32 handle, vm::ptr<u32> picItem_ptr)
return CELL_VDEC_ERROR_ARG; return CELL_VDEC_ERROR_ARG;
} }
if (vdec->frames.IsEmpty()) VdecFrame vf;
if (!vdec->frames.Peek(vf, &sq_no_wait))
{ {
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack
return CELL_VDEC_ERROR_EMPTY; return CELL_VDEC_ERROR_EMPTY;
} }
VdecFrame& vf = vdec->frames.Peek(nullptr);
AVFrame& frame = *vf.data; AVFrame& frame = *vf.data;
auto info = vm::ptr<CellVdecPicItem>::make(vdec->memAddr + vdec->memBias); auto info = vm::ptr<CellVdecPicItem>::make(vdec->memAddr + vdec->memBias);