From 81474be1035465d98558844c57aa118f5e711753 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Sat, 18 Oct 2014 21:00:21 +0400 Subject: [PATCH] AV decoding minor cleanup --- Utilities/SQueue.h | 24 ++----- rpcs3/Emu/SysCalls/Modules/cellAdec.cpp | 88 ++++++++++--------------- rpcs3/Emu/SysCalls/Modules/cellDmux.cpp | 21 ++++-- rpcs3/Emu/SysCalls/Modules/cellVdec.cpp | 84 ++++++++--------------- 4 files changed, 82 insertions(+), 135 deletions(-) diff --git a/Utilities/SQueue.h b/Utilities/SQueue.h index 4b2c615ae2..35abca4654 100644 --- a/Utilities/SQueue.h +++ b/Utilities/SQueue.h @@ -78,30 +78,13 @@ public: } } - u32 GetCount() - { - std::lock_guard lock(m_mutex); - return m_count; - } - - u32 GetCountUnsafe() - { - return m_count; - } - - bool IsEmpty() - { - std::lock_guard lock(m_mutex); - return !m_count; - } - void Clear() { std::lock_guard 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; } }; diff --git a/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp b/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp index 59fcd4b6a3..64774cc762 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp @@ -65,9 +65,9 @@ AudioDecoder::AudioDecoder(AudioCodecType type, u32 addr, u32 size, vm::ptrWarning("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 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 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::make(adec->memAddr + adec->memBias); diff --git a/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp b/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp index b3283aa4ce..dccb5c3d74 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp @@ -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::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::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 code; diff --git a/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp b/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp index d136591bfd..b2751d7561 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp @@ -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 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 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 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 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::make(vdec->memAddr + vdec->memBias);