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()
{
std::lock_guard<std::mutex> lock(m_mutex);
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)
{
@ -109,7 +92,7 @@ public:
{
if (Emu.IsStopped() || do_exit && *do_exit)
{
break;
return false;
}
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()
{
// 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_free(&af.data);
}
@ -96,17 +96,14 @@ int adecRawRead(void* opaque, u8* buf, int buf_size)
next:
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;
}
std::this_thread::sleep_for(std::chrono::milliseconds(1));
if (Emu.IsStopped()) cellAdec->Warning("adecRawRead() aborted");
return 0;
}
switch (auto jtype = adec.job.Peek(nullptr).type)
switch (task.type)
{
case adecEndSeq:
case adecClose:
@ -135,7 +132,7 @@ next:
default:
{
cellAdec->Error("adecRawRead(): unknown task (%d)", jtype);
cellAdec->Error("adecRawRead(): unknown task (%d)", task.type);
Emu.Pause();
return -1;
}
@ -275,17 +272,11 @@ u32 adecOpen(AudioDecoder* data)
break;
}
if (!adec.job.GetCountUnsafe() && adec.is_running)
{
std::this_thread::sleep_for(std::chrono::milliseconds(1));
continue;
}
/*if (adec.frames.GetCount() >= 50)
{
std::this_thread::sleep_for(std::chrono::milliseconds(1));
continue;
}*/
//if (!adec.job.GetCountUnsafe() && adec.is_running)
//{
// std::this_thread::sleep_for(std::chrono::milliseconds(1));
// continue;
//}
if (!adec.job.Pop(task, &adec.is_closed))
{
@ -667,7 +658,7 @@ int cellAdecClose(u32 handle)
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;
if (!Emu.GetIdManager().GetIDData(handle, adec))
@ -676,15 +667,9 @@ int cellAdecStartSeq(u32 handle, u32 param_addr)
}
AdecTask task(adecStartSeq);
/*if (adec->type == CELL_ADEC_TYPE_ATRACX_2CH)
{
}
else*/
{
cellAdec->Todo("cellAdecStartSeq(): initialization");
}
// TODO: using parameters
adec->job.Push(task, &adec->is_closed);
return CELL_OK;
}
@ -734,38 +719,36 @@ int cellAdecGetPcm(u32 handle, vm::ptr<float> outBuffer)
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;
}
AdecFrame af;
if (!adec->frames.Pop(af, &adec->is_closed))
{
return CELL_ADEC_ERROR_EMPTY;
}
AVFrame* frame = af.data;
if (!af.data) // fake: empty data
if (!af.data)
{
// hack
return CELL_OK;
}
// reverse byte order, extract data:
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++)
if (outBuffer)
{
outBuffer[i * 2 + 0] = in_f[0][i];
outBuffer[i * 2 + 1] = in_f[1][i];
// reverse byte order, extract data:
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;
}
@ -779,14 +762,13 @@ int cellAdecGetPcmItem(u32 handle, vm::ptr<u32> pcmItem_ptr)
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
return CELL_ADEC_ERROR_EMPTY;
}
AdecFrame& af = adec->frames.Peek(nullptr);
AVFrame* frame = af.data;
auto pcm = vm::ptr<CellAdecPcmItem>::make(adec->memAddr + adec->memBias);

View file

@ -62,7 +62,11 @@ bool ElementaryStream::is_full()
{
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)
{
return (first - put) < GetMaxAU();
@ -201,7 +205,11 @@ bool ElementaryStream::release()
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);
//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;
}
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);
//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(),
@ -334,7 +347,7 @@ u32 dmuxOpen(Demuxer* data)
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)
be_t<u32> code;

View file

@ -65,9 +65,9 @@ VideoDecoder::VideoDecoder(CellVdecCodecType type, u32 profile, u32 addr, u32 si
VideoDecoder::~VideoDecoder()
{
// 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_free(&vf.data);
}
@ -96,17 +96,14 @@ int vdecRead(void* opaque, u8* buf, int buf_size)
next:
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;
}
std::this_thread::sleep_for(std::chrono::milliseconds(1));
if (Emu.IsStopped()) cellVdec->Warning("vdecRead() aborted");
return 0;
}
switch (auto jtype = vdec.job.Peek(nullptr).type)
switch (task.type)
{
case vdecEndSeq:
case vdecClose:
@ -135,7 +132,7 @@ next:
default:
{
cellVdec->Error("vdecRead(): unknown task (%d)", jtype);
cellVdec->Error("vdecRead(): unknown task (%d)", task.type);
Emu.Pause();
return -1;
}
@ -210,17 +207,11 @@ u32 vdecOpen(VideoDecoder* data)
break;
}
if (!vdec.job.GetCountUnsafe() && vdec.is_running)
{
std::this_thread::sleep_for(std::chrono::milliseconds(1));
continue;
}
if (vdec.frames.GetCount() >= 50)
{
std::this_thread::sleep_for(std::chrono::milliseconds(1));
continue;
}
//if (!vdec.job.GetCountUnsafe() && vdec.is_running)
//{
// std::this_thread::sleep_for(std::chrono::milliseconds(1));
// continue;
//}
if (!vdec.job.Pop(task, &vdec.is_closed))
{
@ -563,28 +554,6 @@ int cellVdecEndSeq(u32 handle)
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);
return CELL_OK;
}
@ -623,11 +592,19 @@ int cellVdecGetPicture(u32 handle, vm::ptr<const CellVdecPicFormat> format, vm::
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;
}
if (!vf.data)
{
// hack
return CELL_OK;
}
if (outBuff)
{
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;
}
VdecFrame vf;
if (!vdec->frames.Pop(vf, &vdec->is_closed))
{
return CELL_VDEC_ERROR_EMPTY;
}
AVFrame& frame = *vf.data;
// 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);
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;
}
@ -679,14 +648,13 @@ int cellVdecGetPicItem(u32 handle, vm::ptr<u32> picItem_ptr)
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
return CELL_VDEC_ERROR_EMPTY;
}
VdecFrame& vf = vdec->frames.Peek(nullptr);
AVFrame& frame = *vf.data;
auto info = vm::ptr<CellVdecPicItem>::make(vdec->memAddr + vdec->memBias);