mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-06 00:40:11 +00:00
cellAdec: make AdecContext and AdecFrame trivial classes
This commit is contained in:
parent
108247dccc
commit
8778e69f9d
@ -696,12 +696,12 @@ error_code adecNotifyPcmOut(ppu_thread& ppu, s32 pcmHandle, vm::ptr<void> pcmAdd
|
||||
return CELL_ADEC_ERROR_FATAL;
|
||||
}
|
||||
|
||||
if (handle->pcm_queue.push(pcm_item, pcmHandle) != CELL_OK)
|
||||
if (handle->pcm_queue.push(ppu, pcm_item, pcmHandle) != CELL_OK)
|
||||
{
|
||||
return CELL_ADEC_ERROR_FATAL;
|
||||
}
|
||||
|
||||
if (handle->pcm_item_queue.push(pcm_item, pcmHandle) != CELL_OK)
|
||||
if (handle->pcm_item_queue.push(ppu, pcm_item, pcmHandle) != CELL_OK)
|
||||
{
|
||||
return CELL_ADEC_ERROR_FATAL;
|
||||
}
|
||||
@ -804,7 +804,6 @@ error_code adecOpen(ppu_thread& ppu, vm::ptr<CellAdecType> type, vm::cptr<CellAd
|
||||
const u32 bitstream_info_size = core_ops->getBsiInfoSize(ppu);
|
||||
|
||||
const auto _this = vm::ptr<AdecContext>::make(utils::align(+res->startAddr, 0x80));
|
||||
const u32 this_size = sizeof(AdecContext) + (bitstream_info_size + sizeof(AdecFrame)) * pcm_handle_num;
|
||||
const auto frames = vm::ptr<AdecFrame>::make(_this.addr() + sizeof(AdecContext));
|
||||
const u32 bitstream_infos_addr = frames.addr() + pcm_handle_num * sizeof(AdecFrame);
|
||||
const auto core_handle = vm::ptr<void>::make(utils::align(bitstream_infos_addr + bitstream_info_size * pcm_handle_num, 0x80));
|
||||
@ -818,7 +817,43 @@ error_code adecOpen(ppu_thread& ppu, vm::ptr<CellAdecType> type, vm::cptr<CellAd
|
||||
// TODO
|
||||
}
|
||||
|
||||
new (_this.get_ptr()) AdecContext(ppu, _this, this_size, *type, *res, *cb, core_handle, core_ops, pcm_handle_num, frames, bitstream_info_size, bitstream_infos_addr);
|
||||
_this->_this = _this;
|
||||
_this->this_size = sizeof(AdecContext) + (bitstream_info_size + sizeof(AdecFrame)) * pcm_handle_num;
|
||||
_this->unk = 0;
|
||||
_this->sequence_state = AdecSequenceState::dormant;
|
||||
_this->type = *type;
|
||||
_this->res = *res;
|
||||
_this->callback = *cb;
|
||||
_this->core_handle = core_handle;
|
||||
_this->core_ops = core_ops;
|
||||
_this->previous_pts = { CODEC_TS_INVALID, CODEC_TS_INVALID };
|
||||
_this->frames_num = pcm_handle_num;
|
||||
_this->reserved1 = 0;
|
||||
_this->frames_head = -1;
|
||||
_this->frames_tail = -1;
|
||||
_this->frames = frames;
|
||||
_this->bitstream_info_size = bitstream_info_size;
|
||||
_this->mutex_attribute = { SYS_SYNC_PRIORITY, SYS_SYNC_NOT_RECURSIVE, SYS_SYNC_NOT_PROCESS_SHARED, SYS_SYNC_NOT_ADAPTIVE, 0, 0, 0, { "_adem03"_u64 } };
|
||||
|
||||
_this->pcm_queue.init(ppu, _this.ptr(&AdecContext::pcm_queue));
|
||||
_this->pcm_item_queue.init(ppu, _this.ptr(&AdecContext::pcm_item_queue));
|
||||
|
||||
for (s32 i = 0; i < pcm_handle_num; i++)
|
||||
{
|
||||
frames[i].in_use = false;
|
||||
frames[i].this_index = i;
|
||||
frames[i].au_done = false;
|
||||
frames[i].unk1 = false;
|
||||
frames[i].pcm_out = false;
|
||||
frames[i].unk2 = false;
|
||||
frames[i].pcm_item.pcmAttr.bsiInfo.set(bitstream_infos_addr + bitstream_info_size * i);
|
||||
frames[i].reserved1 = 0;
|
||||
frames[i].reserved2 = 0;
|
||||
frames[i].next = 0;
|
||||
frames[i].prev = 0;
|
||||
}
|
||||
|
||||
ensure(sys_mutex_create(ppu, _this.ptr(&AdecContext::mutex), _this.ptr(&AdecContext::mutex_attribute)) == CELL_OK); // Error code isn't checked on LLE
|
||||
|
||||
*handle = _this;
|
||||
|
||||
@ -901,6 +936,16 @@ error_code cellAdecClose(ppu_thread& ppu, vm::ptr<AdecContext> handle)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (error_code ret = handle->pcm_queue.finalize(ppu); ret != CELL_OK)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (error_code ret = handle->pcm_item_queue.finalize(ppu); ret != CELL_OK)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
handle->_this = vm::null;
|
||||
handle->sequence_state = AdecSequenceState::closed;
|
||||
|
||||
@ -1038,12 +1083,12 @@ error_code cellAdecGetPcm(ppu_thread& ppu, vm::ptr<AdecContext> handle, vm::ptr<
|
||||
}
|
||||
|
||||
// If the pcm_handles are equal, then cellAdecGetPcmItem() was not called before cellAdecGetPcm(). We need to pop pcm_item_queue as well
|
||||
if (handle->pcm_item_queue.peek().pcm_handle == handle->pcm_queue.peek().pcm_handle)
|
||||
if (handle->pcm_item_queue.peek(ppu).pcm_handle == handle->pcm_queue.peek(ppu).pcm_handle)
|
||||
{
|
||||
handle->pcm_item_queue.pop();
|
||||
handle->pcm_item_queue.pop(ppu);
|
||||
}
|
||||
|
||||
const auto pcm_queue_entry = handle->pcm_queue.pop();
|
||||
const auto pcm_queue_entry = handle->pcm_queue.pop(ppu);
|
||||
|
||||
if (!pcm_queue_entry)
|
||||
{
|
||||
@ -1082,7 +1127,7 @@ error_code cellAdecGetPcm(ppu_thread& ppu, vm::ptr<AdecContext> handle, vm::ptr<
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellAdecGetPcmItem(vm::ptr<AdecContext> handle, vm::pptr<CellAdecPcmItem> pcmItem)
|
||||
error_code cellAdecGetPcmItem(ppu_thread& ppu, vm::ptr<AdecContext> handle, vm::pptr<CellAdecPcmItem> pcmItem)
|
||||
{
|
||||
cellAdec.trace("cellAdecGetPcmItem(handle=*0x%x, pcmItem=**0x%x)", handle, pcmItem);
|
||||
|
||||
@ -1096,7 +1141,12 @@ error_code cellAdecGetPcmItem(vm::ptr<AdecContext> handle, vm::pptr<CellAdecPcmI
|
||||
return CELL_ADEC_ERROR_FATAL;
|
||||
}
|
||||
|
||||
const auto pcm_item_entry = handle->pcm_item_queue.pop();
|
||||
const auto pcm_item_entry = handle->pcm_item_queue.pop(ppu);
|
||||
|
||||
if (ppu.state & cpu_flag::again) // Savestate was created while waiting on the queue mutex
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!pcm_item_entry)
|
||||
{
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include "cellPamf.h" // CellCodecTimeStamp
|
||||
#include "../lv2/sys_mutex.h"
|
||||
#include "../lv2/sys_cond.h"
|
||||
|
||||
// Error Codes
|
||||
enum CellAdecError : u32
|
||||
@ -461,31 +462,25 @@ struct AdecCmdQueue
|
||||
|
||||
struct AdecFrame
|
||||
{
|
||||
b8 in_use = false; // True after issuing a decode command until the frame is consumed
|
||||
b8 in_use; // True after issuing a decode command until the frame is consumed
|
||||
|
||||
const be_t<s32> this_index; // Set when initialized in cellAdecOpen(), unused afterward
|
||||
be_t<s32> this_index; // Set when initialized in cellAdecOpen(), unused afterward
|
||||
|
||||
// Set when the corresponding callback is received, unused afterward
|
||||
b8 au_done = false;
|
||||
const b8 unk1 = false;
|
||||
b8 pcm_out = false;
|
||||
const b8 unk2 = false;
|
||||
b8 au_done;
|
||||
b8 unk1;
|
||||
b8 pcm_out;
|
||||
b8 unk2;
|
||||
|
||||
CellAdecAuInfo au_info;
|
||||
CellAdecPcmItem pcm_item;
|
||||
|
||||
const u32 reserved1 = 0;
|
||||
const u32 reserved2 = 0;
|
||||
u32 reserved1;
|
||||
u32 reserved2;
|
||||
|
||||
// Frames that are ready to be consumed form a linked list. However, this list is not used (AdecOutputQueue is used instead)
|
||||
be_t<s32> next = 0; // Index of the next frame that can be consumed
|
||||
be_t<s32> prev = 0; // Index of the previous frame that can be consumed
|
||||
|
||||
AdecFrame(s32 index, u32 bitstream_info_addr)
|
||||
: this_index(index)
|
||||
{
|
||||
pcm_item.pcmAttr.bsiInfo.set(bitstream_info_addr);
|
||||
}
|
||||
be_t<s32> next; // Index of the next frame that can be consumed
|
||||
be_t<s32> prev; // Index of the previous frame that can be consumed
|
||||
};
|
||||
|
||||
CHECK_SIZE(AdecFrame, 0x68);
|
||||
@ -494,27 +489,61 @@ class AdecOutputQueue
|
||||
{
|
||||
struct entry
|
||||
{
|
||||
const be_t<s32> this_index; // Unused
|
||||
be_t<s32> state = 0xff; // 0xff = empty, 0x10 = filled
|
||||
vm::bptr<CellAdecPcmItem> pcm_item = vm::null;
|
||||
be_t<s32> pcm_handle = -1;
|
||||
be_t<s32> this_index; // Unused
|
||||
be_t<s32> state; // 0xff = empty, 0x10 = filled
|
||||
vm::bptr<CellAdecPcmItem> pcm_item;
|
||||
be_t<s32> pcm_handle;
|
||||
}
|
||||
entries[4]{ {0}, {1}, {2}, {3} };
|
||||
entries[4];
|
||||
|
||||
be_t<s32> front = 0;
|
||||
be_t<s32> back = 0;
|
||||
be_t<s32> size = 0;
|
||||
be_t<s32> front;
|
||||
be_t<s32> back;
|
||||
be_t<s32> size;
|
||||
|
||||
shared_mutex mutex; // sys_mutex_t
|
||||
be_t<u32> cond{}; // sys_cond_t, unused
|
||||
be_t<u32> mutex; // sys_mutex_t
|
||||
be_t<u32> cond; // sys_cond_t, unused
|
||||
|
||||
public:
|
||||
error_code push(vm::ptr<CellAdecPcmItem> pcm_item, s32 pcm_handle)
|
||||
void init(ppu_thread& ppu, vm::ptr<AdecOutputQueue> _this)
|
||||
{
|
||||
std::lock_guard lock{mutex};
|
||||
this->front = 0;
|
||||
this->back = 0;
|
||||
this->size = 0;
|
||||
|
||||
const vm::var<sys_mutex_attribute_t> mutex_attr = {{ SYS_SYNC_PRIORITY, SYS_SYNC_NOT_RECURSIVE, SYS_SYNC_NOT_PROCESS_SHARED, SYS_SYNC_NOT_ADAPTIVE, 0, 0, 0, { "_adem07"_u64 } }};
|
||||
ensure(sys_mutex_create(ppu, _this.ptr(&AdecOutputQueue::mutex), mutex_attr) == CELL_OK); // Error code isn't checked on LLE
|
||||
|
||||
const vm::var<sys_cond_attribute_t> cond_attr = {{ SYS_SYNC_NOT_PROCESS_SHARED, 0, 0, { "_adec05"_u64 } }};
|
||||
ensure(sys_cond_create(ppu, _this.ptr(&AdecOutputQueue::cond), mutex, cond_attr) == CELL_OK); // Error code isn't checked on LLE
|
||||
|
||||
for (s32 i = 0; i < 4; i++)
|
||||
{
|
||||
entries[i] = { i, 0xff, vm::null, -1 };
|
||||
}
|
||||
}
|
||||
|
||||
error_code finalize(ppu_thread& ppu) const
|
||||
{
|
||||
if (error_code ret = sys_cond_destroy(ppu, cond); ret != CELL_OK)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (error_code ret = sys_mutex_destroy(ppu, mutex); ret != CELL_OK)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code push(ppu_thread& ppu, vm::ptr<CellAdecPcmItem> pcm_item, s32 pcm_handle)
|
||||
{
|
||||
ensure(sys_mutex_lock(ppu, mutex, 0) == CELL_OK); // Error code isn't checked on LLE
|
||||
|
||||
if (entries[back].state != 0xff)
|
||||
{
|
||||
ensure(sys_mutex_unlock(ppu, mutex) == CELL_OK); // Error code isn't checked on LLE
|
||||
return true; // LLE returns the result of the comparison above
|
||||
}
|
||||
|
||||
@ -525,15 +554,17 @@ public:
|
||||
back = (back + 1) & 3;
|
||||
size++;
|
||||
|
||||
ensure(sys_mutex_unlock(ppu, mutex) == CELL_OK); // Error code isn't checked on LLE
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
const entry* pop()
|
||||
const entry* pop(ppu_thread& ppu)
|
||||
{
|
||||
std::lock_guard lock{mutex};
|
||||
ensure(sys_mutex_lock(ppu, mutex, 0) == CELL_OK); // Error code isn't checked on LLE
|
||||
|
||||
if (entries[front].state == 0xff)
|
||||
{
|
||||
ensure(sys_mutex_unlock(ppu, mutex) == CELL_OK); // Error code isn't checked on LLE
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -545,13 +576,16 @@ public:
|
||||
front = (front + 1) & 3;
|
||||
size--;
|
||||
|
||||
ensure(sys_mutex_unlock(ppu, mutex) == CELL_OK); // Error code isn't checked on LLE
|
||||
return ret;
|
||||
}
|
||||
|
||||
const entry& peek()
|
||||
const entry& peek(ppu_thread& ppu) const
|
||||
{
|
||||
std::lock_guard lock{mutex};
|
||||
return entries[front];
|
||||
ensure(sys_mutex_lock(ppu, mutex, 0) == CELL_OK); // Error code isn't checked on LLE
|
||||
const entry& ret = entries[front];
|
||||
ensure(sys_mutex_unlock(ppu, mutex) == CELL_OK); // Error code isn't checked on LLE
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
@ -567,30 +601,30 @@ enum class AdecSequenceState : u32
|
||||
struct AdecContext // CellAdecHandle = AdecContext*
|
||||
{
|
||||
vm::bptr<AdecContext> _this;
|
||||
const be_t<u32> this_size; // Size of this struct + AdecFrames + bitstream info structs
|
||||
be_t<u32> this_size; // Size of this struct + AdecFrames + bitstream info structs
|
||||
|
||||
const u32 unk = 0; // Unused
|
||||
u32 unk; // Unused
|
||||
|
||||
be_t<AdecSequenceState> sequence_state = AdecSequenceState::dormant;
|
||||
be_t<AdecSequenceState> sequence_state;
|
||||
|
||||
const CellAdecType type;
|
||||
const CellAdecResource res;
|
||||
const CellAdecCb callback;
|
||||
CellAdecType type;
|
||||
CellAdecResource res;
|
||||
CellAdecCb callback;
|
||||
|
||||
const vm::bptr<void> core_handle;
|
||||
const vm::bcptr<CellAdecCoreOps> core_ops;
|
||||
vm::bptr<void> core_handle;
|
||||
vm::bcptr<CellAdecCoreOps> core_ops;
|
||||
|
||||
CellCodecTimeStamp previous_pts{ CODEC_TS_INVALID, CODEC_TS_INVALID };
|
||||
CellCodecTimeStamp previous_pts;
|
||||
|
||||
const be_t<s32> frames_num;
|
||||
const u32 reserved1 = 0;
|
||||
be_t<s32> frames_head = -1; // Index of the oldest frame that can be consumed
|
||||
be_t<s32> frames_tail = -1; // Index of the most recent frame that can be consumed
|
||||
const vm::bptr<AdecFrame> frames; // Array of AdecFrames, number of elements is return value of CellAdecCoreOps::getPcmHandleNum
|
||||
be_t<s32> frames_num;
|
||||
u32 reserved1;
|
||||
be_t<s32> frames_head; // Index of the oldest frame that can be consumed
|
||||
be_t<s32> frames_tail; // Index of the most recent frame that can be consumed
|
||||
vm::bptr<AdecFrame> frames; // Array of AdecFrames, number of elements is return value of CellAdecCoreOps::getPcmHandleNum
|
||||
|
||||
const be_t<u32> bitstream_info_size;
|
||||
be_t<u32> bitstream_info_size;
|
||||
|
||||
sys_mutex_attribute_t mutex_attribute{ 2, 0x20, 0x200, 0x2000, 0, 0, 0, { "_adem03"_u64 } };
|
||||
sys_mutex_attribute_t mutex_attribute;
|
||||
be_t<u32> mutex; // sys_mutex_t
|
||||
|
||||
AdecOutputQueue pcm_queue; // Output queue for cellAdecGetPcm()
|
||||
@ -598,20 +632,6 @@ struct AdecContext // CellAdecHandle = AdecContext*
|
||||
|
||||
u8 reserved2[1028];
|
||||
|
||||
AdecContext(ppu_thread& ppu, vm::bptr<AdecContext> _this, u32 this_size, const CellAdecType& type, const CellAdecResource& res, const CellAdecCb& callback, vm::bptr<void> core_handle,
|
||||
vm::bcptr<CellAdecCoreOps> core_ops, s32 frames_num, vm::bptr<AdecFrame> frames, u32 bitstream_info_size, u32 bitstream_infos_addr)
|
||||
: _this(_this), this_size(this_size), type(type), res(res), callback(callback), core_handle(core_handle), core_ops(core_ops), frames_num(frames_num), frames(frames), bitstream_info_size(bitstream_info_size)
|
||||
{
|
||||
ensure(this == _this.get_ptr());
|
||||
|
||||
for (s32 i = 0; i < frames_num; i++)
|
||||
{
|
||||
new (&frames[i]) AdecFrame(i, bitstream_infos_addr + bitstream_info_size * i);
|
||||
}
|
||||
|
||||
ensure(sys_mutex_create(ppu, _this.ptr(&AdecContext::mutex), _this.ptr(&AdecContext::mutex_attribute)) == CELL_OK); // Error code isn't checked on LLE
|
||||
}
|
||||
|
||||
[[nodiscard]] error_code get_new_pcm_handle(vm::ptr<CellAdecAuInfo> au_info) const;
|
||||
error_code verify_pcm_handle(s32 pcm_handle) const;
|
||||
vm::ptr<CellAdecAuInfo> get_au_info(s32 pcm_handle) const;
|
||||
@ -624,7 +644,7 @@ struct AdecContext // CellAdecHandle = AdecContext*
|
||||
error_code correct_pts_value(ppu_thread& ppu, s32 pcm_handle, s8 correct_pts_type);
|
||||
};
|
||||
|
||||
static_assert(std::is_standard_layout_v<AdecContext>);
|
||||
static_assert(std::is_standard_layout_v<AdecContext> && std::is_trivial_v<AdecContext>);
|
||||
CHECK_SIZE_ALIGN(AdecContext, 0x530, 8);
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user