mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-02-01 11:08:34 +00:00
Fix sideband buffer order (#1454)
This commit is contained in:
parent
99a87c321f
commit
32f5dafaf7
|
@ -83,19 +83,19 @@ int PS4_SYSV_ABI sceAjmBatchErrorDump() {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ChunkType, class CursorType>
|
template <class ChunkType, class CursorType>
|
||||||
ChunkType& AjmGetChunk(CursorType& p_cursor) {
|
ChunkType& AjmBufferExtract(CursorType& p_cursor) {
|
||||||
auto* const result = reinterpret_cast<ChunkType*>(p_cursor);
|
auto* const result = reinterpret_cast<ChunkType*>(p_cursor);
|
||||||
p_cursor += sizeof(ChunkType);
|
p_cursor += sizeof(ChunkType);
|
||||||
return *result;
|
return *result;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ChunkType, class CursorType>
|
template <class ChunkType, class CursorType>
|
||||||
void AjmSkipChunk(CursorType& p_cursor) {
|
void AjmBufferSkip(CursorType& p_cursor) {
|
||||||
p_cursor += sizeof(ChunkType);
|
p_cursor += sizeof(ChunkType);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ChunkType, class CursorType>
|
template <class ChunkType, class CursorType>
|
||||||
ChunkType& AjmPeekChunk(CursorType p_cursor) {
|
ChunkType& AjmBufferPeek(CursorType p_cursor) {
|
||||||
return *reinterpret_cast<ChunkType*>(p_cursor);
|
return *reinterpret_cast<ChunkType*>(p_cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,21 +108,21 @@ void* PS4_SYSV_ABI sceAjmBatchJobControlBufferRa(void* p_buffer, u32 instance_id
|
||||||
|
|
||||||
u8* p_current = (u8*)p_buffer;
|
u8* p_current = (u8*)p_buffer;
|
||||||
|
|
||||||
auto& header = AjmGetChunk<AjmChunkHeader>(p_current);
|
auto& header = AjmBufferExtract<AjmChunkHeader>(p_current);
|
||||||
header.ident = AjmIdentJob;
|
header.ident = AjmIdentJob;
|
||||||
header.payload = instance_id;
|
header.payload = instance_id;
|
||||||
|
|
||||||
const u8* const p_begin = p_current;
|
const u8* const p_begin = p_current;
|
||||||
|
|
||||||
if (p_return_address != nullptr) {
|
if (p_return_address != nullptr) {
|
||||||
auto& chunk_ra = AjmGetChunk<AjmChunkBuffer>(p_current);
|
auto& chunk_ra = AjmBufferExtract<AjmChunkBuffer>(p_current);
|
||||||
chunk_ra.header.ident = AjmIdentReturnAddressBuf;
|
chunk_ra.header.ident = AjmIdentReturnAddressBuf;
|
||||||
chunk_ra.header.size = 0;
|
chunk_ra.header.size = 0;
|
||||||
chunk_ra.p_address = p_return_address;
|
chunk_ra.p_address = p_return_address;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto& chunk_input = AjmGetChunk<AjmChunkBuffer>(p_current);
|
auto& chunk_input = AjmBufferExtract<AjmChunkBuffer>(p_current);
|
||||||
chunk_input.header.ident = AjmIdentInputControlBuf;
|
chunk_input.header.ident = AjmIdentInputControlBuf;
|
||||||
chunk_input.header.size = sideband_input_size;
|
chunk_input.header.size = sideband_input_size;
|
||||||
chunk_input.p_address = p_sideband_input;
|
chunk_input.p_address = p_sideband_input;
|
||||||
|
@ -141,14 +141,14 @@ void* PS4_SYSV_ABI sceAjmBatchJobControlBufferRa(void* p_buffer, u32 instance_id
|
||||||
const bool is_statistics = instance_id == AJM_INSTANCE_STATISTICS;
|
const bool is_statistics = instance_id == AJM_INSTANCE_STATISTICS;
|
||||||
flags &= is_statistics ? 0x0000'0000'C001'8007 : 0x0000'6000'0000'E7FF;
|
flags &= is_statistics ? 0x0000'0000'C001'8007 : 0x0000'6000'0000'E7FF;
|
||||||
|
|
||||||
auto& chunk_flags = AjmGetChunk<AjmChunkHeader>(p_current);
|
auto& chunk_flags = AjmBufferExtract<AjmChunkHeader>(p_current);
|
||||||
chunk_flags.ident = AjmIdentControlFlags;
|
chunk_flags.ident = AjmIdentControlFlags;
|
||||||
chunk_flags.payload = u32(flags >> 32);
|
chunk_flags.payload = u32(flags >> 32);
|
||||||
chunk_flags.size = u32(flags);
|
chunk_flags.size = u32(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto& chunk_output = AjmGetChunk<AjmChunkBuffer>(p_current);
|
auto& chunk_output = AjmBufferExtract<AjmChunkBuffer>(p_current);
|
||||||
chunk_output.header.ident = AjmIdentOutputControlBuf;
|
chunk_output.header.ident = AjmIdentOutputControlBuf;
|
||||||
chunk_output.header.size = sideband_output_size;
|
chunk_output.header.size = sideband_output_size;
|
||||||
chunk_output.p_address = p_sideband_output;
|
chunk_output.p_address = p_sideband_output;
|
||||||
|
@ -165,7 +165,7 @@ void* PS4_SYSV_ABI sceAjmBatchJobInlineBuffer(void* p_buffer, const void* p_data
|
||||||
|
|
||||||
u8* p_current = (u8*)p_buffer;
|
u8* p_current = (u8*)p_buffer;
|
||||||
|
|
||||||
auto& header = AjmGetChunk<AjmChunkHeader>(p_current);
|
auto& header = AjmBufferExtract<AjmChunkHeader>(p_current);
|
||||||
header.ident = AjmIdentInlineBuf;
|
header.ident = AjmIdentInlineBuf;
|
||||||
header.size = Common::AlignUp(data_input_size, 8);
|
header.size = Common::AlignUp(data_input_size, 8);
|
||||||
*pp_batch_address = p_current;
|
*pp_batch_address = p_current;
|
||||||
|
@ -183,21 +183,21 @@ void* PS4_SYSV_ABI sceAjmBatchJobRunBufferRa(void* p_buffer, u32 instance_id, u6
|
||||||
|
|
||||||
u8* p_current = (u8*)p_buffer;
|
u8* p_current = (u8*)p_buffer;
|
||||||
|
|
||||||
auto& header = AjmGetChunk<AjmChunkHeader>(p_current);
|
auto& header = AjmBufferExtract<AjmChunkHeader>(p_current);
|
||||||
header.ident = AjmIdentJob;
|
header.ident = AjmIdentJob;
|
||||||
header.payload = instance_id;
|
header.payload = instance_id;
|
||||||
|
|
||||||
const u8* const p_begin = p_current;
|
const u8* const p_begin = p_current;
|
||||||
|
|
||||||
if (p_return_address != nullptr) {
|
if (p_return_address != nullptr) {
|
||||||
auto& chunk_ra = AjmGetChunk<AjmChunkBuffer>(p_current);
|
auto& chunk_ra = AjmBufferExtract<AjmChunkBuffer>(p_current);
|
||||||
chunk_ra.header.ident = AjmIdentReturnAddressBuf;
|
chunk_ra.header.ident = AjmIdentReturnAddressBuf;
|
||||||
chunk_ra.header.size = 0;
|
chunk_ra.header.size = 0;
|
||||||
chunk_ra.p_address = p_return_address;
|
chunk_ra.p_address = p_return_address;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto& chunk_input = AjmGetChunk<AjmChunkBuffer>(p_current);
|
auto& chunk_input = AjmBufferExtract<AjmChunkBuffer>(p_current);
|
||||||
chunk_input.header.ident = AjmIdentInputRunBuf;
|
chunk_input.header.ident = AjmIdentInputRunBuf;
|
||||||
chunk_input.header.size = data_input_size;
|
chunk_input.header.size = data_input_size;
|
||||||
chunk_input.p_address = p_data_input;
|
chunk_input.p_address = p_data_input;
|
||||||
|
@ -209,21 +209,21 @@ void* PS4_SYSV_ABI sceAjmBatchJobRunBufferRa(void* p_buffer, u32 instance_id, u6
|
||||||
// | 111 | 00000000000000000000000000000 | 000 | 11 | 11111111 | 111 |
|
// | 111 | 00000000000000000000000000000 | 000 | 11 | 11111111 | 111 |
|
||||||
flags &= 0x0000'E000'0000'1FFF;
|
flags &= 0x0000'E000'0000'1FFF;
|
||||||
|
|
||||||
auto& chunk_flags = AjmGetChunk<AjmChunkHeader>(p_current);
|
auto& chunk_flags = AjmBufferExtract<AjmChunkHeader>(p_current);
|
||||||
chunk_flags.ident = AjmIdentRunFlags;
|
chunk_flags.ident = AjmIdentRunFlags;
|
||||||
chunk_flags.payload = u32(flags >> 32);
|
chunk_flags.payload = u32(flags >> 32);
|
||||||
chunk_flags.size = u32(flags);
|
chunk_flags.size = u32(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto& chunk_output = AjmGetChunk<AjmChunkBuffer>(p_current);
|
auto& chunk_output = AjmBufferExtract<AjmChunkBuffer>(p_current);
|
||||||
chunk_output.header.ident = AjmIdentOutputRunBuf;
|
chunk_output.header.ident = AjmIdentOutputRunBuf;
|
||||||
chunk_output.header.size = data_output_size;
|
chunk_output.header.size = data_output_size;
|
||||||
chunk_output.p_address = p_data_output;
|
chunk_output.p_address = p_data_output;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto& chunk_output = AjmGetChunk<AjmChunkBuffer>(p_current);
|
auto& chunk_output = AjmBufferExtract<AjmChunkBuffer>(p_current);
|
||||||
chunk_output.header.ident = AjmIdentOutputControlBuf;
|
chunk_output.header.ident = AjmIdentOutputControlBuf;
|
||||||
chunk_output.header.size = sideband_output_size;
|
chunk_output.header.size = sideband_output_size;
|
||||||
chunk_output.p_address = p_sideband_output;
|
chunk_output.p_address = p_sideband_output;
|
||||||
|
@ -242,21 +242,21 @@ void* PS4_SYSV_ABI sceAjmBatchJobRunSplitBufferRa(
|
||||||
|
|
||||||
u8* p_current = (u8*)p_buffer;
|
u8* p_current = (u8*)p_buffer;
|
||||||
|
|
||||||
auto& header = AjmGetChunk<AjmChunkHeader>(p_current);
|
auto& header = AjmBufferExtract<AjmChunkHeader>(p_current);
|
||||||
header.ident = AjmIdentJob;
|
header.ident = AjmIdentJob;
|
||||||
header.payload = instance_id;
|
header.payload = instance_id;
|
||||||
|
|
||||||
const u8* const p_begin = p_current;
|
const u8* const p_begin = p_current;
|
||||||
|
|
||||||
if (p_return_address != nullptr) {
|
if (p_return_address != nullptr) {
|
||||||
auto& chunk_ra = AjmGetChunk<AjmChunkBuffer>(p_current);
|
auto& chunk_ra = AjmBufferExtract<AjmChunkBuffer>(p_current);
|
||||||
chunk_ra.header.ident = AjmIdentReturnAddressBuf;
|
chunk_ra.header.ident = AjmIdentReturnAddressBuf;
|
||||||
chunk_ra.header.size = 0;
|
chunk_ra.header.size = 0;
|
||||||
chunk_ra.p_address = p_return_address;
|
chunk_ra.p_address = p_return_address;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (s32 i = 0; i < num_data_input_buffers; i++) {
|
for (s32 i = 0; i < num_data_input_buffers; i++) {
|
||||||
auto& chunk_input = AjmGetChunk<AjmChunkBuffer>(p_current);
|
auto& chunk_input = AjmBufferExtract<AjmChunkBuffer>(p_current);
|
||||||
chunk_input.header.ident = AjmIdentInputRunBuf;
|
chunk_input.header.ident = AjmIdentInputRunBuf;
|
||||||
chunk_input.header.size = p_data_input_buffers[i].size;
|
chunk_input.header.size = p_data_input_buffers[i].size;
|
||||||
chunk_input.p_address = p_data_input_buffers[i].p_address;
|
chunk_input.p_address = p_data_input_buffers[i].p_address;
|
||||||
|
@ -268,21 +268,21 @@ void* PS4_SYSV_ABI sceAjmBatchJobRunSplitBufferRa(
|
||||||
// | 111 | 00000000000000000000000000000 | 000 | 11 | 11111111 | 111 |
|
// | 111 | 00000000000000000000000000000 | 000 | 11 | 11111111 | 111 |
|
||||||
flags &= 0x0000'E000'0000'1FFF;
|
flags &= 0x0000'E000'0000'1FFF;
|
||||||
|
|
||||||
auto& chunk_flags = AjmGetChunk<AjmChunkHeader>(p_current);
|
auto& chunk_flags = AjmBufferExtract<AjmChunkHeader>(p_current);
|
||||||
chunk_flags.ident = AjmIdentRunFlags;
|
chunk_flags.ident = AjmIdentRunFlags;
|
||||||
chunk_flags.payload = u32(flags >> 32);
|
chunk_flags.payload = u32(flags >> 32);
|
||||||
chunk_flags.size = u32(flags);
|
chunk_flags.size = u32(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (s32 i = 0; i < num_data_output_buffers; i++) {
|
for (s32 i = 0; i < num_data_output_buffers; i++) {
|
||||||
auto& chunk_output = AjmGetChunk<AjmChunkBuffer>(p_current);
|
auto& chunk_output = AjmBufferExtract<AjmChunkBuffer>(p_current);
|
||||||
chunk_output.header.ident = AjmIdentOutputRunBuf;
|
chunk_output.header.ident = AjmIdentOutputRunBuf;
|
||||||
chunk_output.header.size = p_data_output_buffers[i].size;
|
chunk_output.header.size = p_data_output_buffers[i].size;
|
||||||
chunk_output.p_address = p_data_output_buffers[i].p_address;
|
chunk_output.p_address = p_data_output_buffers[i].p_address;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto& chunk_output = AjmGetChunk<AjmChunkBuffer>(p_current);
|
auto& chunk_output = AjmBufferExtract<AjmChunkBuffer>(p_current);
|
||||||
chunk_output.header.ident = AjmIdentOutputControlBuf;
|
chunk_output.header.ident = AjmIdentOutputControlBuf;
|
||||||
chunk_output.header.size = sideband_output_size;
|
chunk_output.header.size = sideband_output_size;
|
||||||
chunk_output.p_address = p_sideband_output;
|
chunk_output.p_address = p_sideband_output;
|
||||||
|
@ -315,7 +315,7 @@ int PS4_SYSV_ABI sceAjmBatchStartBuffer(u32 context, const u8* batch, u32 batch_
|
||||||
const u8* p_batch_end = batch + batch_size;
|
const u8* p_batch_end = batch + batch_size;
|
||||||
|
|
||||||
while (p_current < p_batch_end) {
|
while (p_current < p_batch_end) {
|
||||||
auto& header = AjmGetChunk<const AjmChunkHeader>(p_current);
|
auto& header = AjmBufferExtract<const AjmChunkHeader>(p_current);
|
||||||
ASSERT(header.ident == AjmIdentJob);
|
ASSERT(header.ident == AjmIdentJob);
|
||||||
|
|
||||||
std::optional<AjmJobFlags> job_flags = {};
|
std::optional<AjmJobFlags> job_flags = {};
|
||||||
|
@ -327,23 +327,23 @@ int PS4_SYSV_ABI sceAjmBatchStartBuffer(u32 context, const u8* batch, u32 batch_
|
||||||
// Read parameters of a job
|
// Read parameters of a job
|
||||||
auto* const p_job_end = p_current + header.size;
|
auto* const p_job_end = p_current + header.size;
|
||||||
while (p_current < p_job_end) {
|
while (p_current < p_job_end) {
|
||||||
auto& header = AjmPeekChunk<const AjmChunkHeader>(p_current);
|
auto& header = AjmBufferPeek<const AjmChunkHeader>(p_current);
|
||||||
switch (header.ident) {
|
switch (header.ident) {
|
||||||
case Identifier::AjmIdentInputRunBuf: {
|
case Identifier::AjmIdentInputRunBuf: {
|
||||||
input_run_buffers.emplace_back(AjmGetChunk<const AjmChunkBuffer>(p_current));
|
input_run_buffers.emplace_back(AjmBufferExtract<const AjmChunkBuffer>(p_current));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Identifier::AjmIdentInputControlBuf: {
|
case Identifier::AjmIdentInputControlBuf: {
|
||||||
ASSERT_MSG(!input_control_buffer.has_value(),
|
ASSERT_MSG(!input_control_buffer.has_value(),
|
||||||
"Only one instance of input control buffer is allowed per job");
|
"Only one instance of input control buffer is allowed per job");
|
||||||
input_control_buffer = AjmGetChunk<const AjmChunkBuffer>(p_current);
|
input_control_buffer = AjmBufferExtract<const AjmChunkBuffer>(p_current);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Identifier::AjmIdentControlFlags:
|
case Identifier::AjmIdentControlFlags:
|
||||||
case Identifier::AjmIdentRunFlags: {
|
case Identifier::AjmIdentRunFlags: {
|
||||||
ASSERT_MSG(!job_flags.has_value(),
|
ASSERT_MSG(!job_flags.has_value(),
|
||||||
"Only one instance of job flags is allowed per job");
|
"Only one instance of job flags is allowed per job");
|
||||||
auto& flags_chunk = AjmGetChunk<const AjmChunkHeader>(p_current);
|
auto& flags_chunk = AjmBufferExtract<const AjmChunkHeader>(p_current);
|
||||||
job_flags = AjmJobFlags{
|
job_flags = AjmJobFlags{
|
||||||
.raw = (u64(flags_chunk.payload) << 32) + flags_chunk.size,
|
.raw = (u64(flags_chunk.payload) << 32) + flags_chunk.size,
|
||||||
};
|
};
|
||||||
|
@ -351,17 +351,17 @@ int PS4_SYSV_ABI sceAjmBatchStartBuffer(u32 context, const u8* batch, u32 batch_
|
||||||
}
|
}
|
||||||
case Identifier::AjmIdentReturnAddressBuf: {
|
case Identifier::AjmIdentReturnAddressBuf: {
|
||||||
// Ignore return address buffers.
|
// Ignore return address buffers.
|
||||||
AjmSkipChunk<const AjmChunkBuffer>(p_current);
|
AjmBufferSkip<const AjmChunkBuffer>(p_current);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Identifier::AjmIdentOutputRunBuf: {
|
case Identifier::AjmIdentOutputRunBuf: {
|
||||||
output_run_buffers.emplace_back(AjmGetChunk<const AjmChunkBuffer>(p_current));
|
output_run_buffers.emplace_back(AjmBufferExtract<const AjmChunkBuffer>(p_current));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Identifier::AjmIdentOutputControlBuf: {
|
case Identifier::AjmIdentOutputControlBuf: {
|
||||||
ASSERT_MSG(!output_control_buffer.has_value(),
|
ASSERT_MSG(!output_control_buffer.has_value(),
|
||||||
"Only one instance of output control buffer is allowed per job");
|
"Only one instance of output control buffer is allowed per job");
|
||||||
output_control_buffer = AjmGetChunk<const AjmChunkBuffer>(p_current);
|
output_control_buffer = AjmBufferExtract<const AjmChunkBuffer>(p_current);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -391,19 +391,48 @@ int PS4_SYSV_ABI sceAjmBatchStartBuffer(u32 context, const u8* batch, u32 batch_
|
||||||
LOG_ERROR(Lib_Ajm, "Unimplemented: Set resample params of instance {}", instance);
|
LOG_ERROR(Lib_Ajm, "Unimplemented: Set resample params of instance {}", instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write sideband structures.
|
AjmSidebandResult* p_result = nullptr;
|
||||||
auto* p_sideband = reinterpret_cast<u8*>(output_control_buffer.value().p_address);
|
AjmSidebandStream* p_stream = nullptr;
|
||||||
auto* result = reinterpret_cast<AjmSidebandResult*>(p_sideband);
|
AjmSidebandFormat* p_format = nullptr;
|
||||||
result->result = 0;
|
AjmSidebandGaplessDecode* p_gapless_decode = nullptr;
|
||||||
result->internal_result = 0;
|
AjmSidebandMFrame* p_mframe = nullptr;
|
||||||
p_sideband += sizeof(AjmSidebandResult);
|
u8* p_codec_info = nullptr;
|
||||||
|
|
||||||
|
// Initialize sideband structures.
|
||||||
|
if (output_control_buffer.has_value()) {
|
||||||
|
auto* p_sideband = reinterpret_cast<u8*>(output_control_buffer.value().p_address);
|
||||||
|
p_result = &AjmBufferExtract<AjmSidebandResult>(p_sideband);
|
||||||
|
*p_result = AjmSidebandResult{};
|
||||||
|
|
||||||
|
const auto sideband_flags = job_flags.value().sideband_flags;
|
||||||
|
if (True(sideband_flags & AjmJobSidebandFlags::Stream)) {
|
||||||
|
p_stream = &AjmBufferExtract<AjmSidebandStream>(p_sideband);
|
||||||
|
*p_stream = AjmSidebandStream{};
|
||||||
|
}
|
||||||
|
if (True(sideband_flags & AjmJobSidebandFlags::Format)) {
|
||||||
|
LOG_ERROR(Lib_Ajm, "SIDEBAND_FORMAT is not implemented");
|
||||||
|
p_format = &AjmBufferExtract<AjmSidebandFormat>(p_sideband);
|
||||||
|
*p_format = AjmSidebandFormat{};
|
||||||
|
}
|
||||||
|
if (True(sideband_flags & AjmJobSidebandFlags::GaplessDecode)) {
|
||||||
|
LOG_ERROR(Lib_Ajm, "SIDEBAND_GAPLESS_DECODE is not implemented");
|
||||||
|
p_gapless_decode = &AjmBufferExtract<AjmSidebandGaplessDecode>(p_sideband);
|
||||||
|
*p_gapless_decode = AjmSidebandGaplessDecode{};
|
||||||
|
}
|
||||||
|
const auto run_flags = job_flags.value().run_flags;
|
||||||
|
if (True(run_flags & AjmJobRunFlags::MultipleFrames)) {
|
||||||
|
p_mframe = &AjmBufferExtract<AjmSidebandMFrame>(p_sideband);
|
||||||
|
*p_mframe = AjmSidebandMFrame{};
|
||||||
|
}
|
||||||
|
if (True(run_flags & AjmJobRunFlags::GetCodecInfo)) {
|
||||||
|
p_codec_info = p_sideband;
|
||||||
|
p_sideband += p_instance->GetCodecInfoSize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Perform operation requested by run flags.
|
// Perform operation requested by run flags.
|
||||||
ASSERT_MSG(input_run_buffers.size() == output_run_buffers.size(),
|
ASSERT_MSG(input_run_buffers.size() == output_run_buffers.size(),
|
||||||
"Run operation with uneven input/output of buffers.");
|
"Run operation with uneven input/output buffers.");
|
||||||
|
|
||||||
const auto run_flags = job_flags.value().run_flags;
|
|
||||||
const auto sideband_flags = job_flags.value().sideband_flags;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < input_run_buffers.size(); ++i) {
|
for (size_t i = 0; i < input_run_buffers.size(); ++i) {
|
||||||
// Decode as much of the input bitstream as possible.
|
// Decode as much of the input bitstream as possible.
|
||||||
|
@ -414,24 +443,22 @@ int PS4_SYSV_ABI sceAjmBatchStartBuffer(u32 context, const u8* batch, u32 batch_
|
||||||
reinterpret_cast<u8*>(in_buffer.p_address), in_buffer.header.size,
|
reinterpret_cast<u8*>(in_buffer.p_address), in_buffer.header.size,
|
||||||
reinterpret_cast<u8*>(out_buffer.p_address), out_buffer.header.size);
|
reinterpret_cast<u8*>(out_buffer.p_address), out_buffer.header.size);
|
||||||
|
|
||||||
// Check sideband flags for decoding
|
if (p_stream != nullptr) {
|
||||||
if (True(sideband_flags & AjmJobSidebandFlags::Stream)) {
|
p_stream->input_consumed += in_buffer.header.size - in_remain;
|
||||||
auto* stream = reinterpret_cast<AjmSidebandStream*>(p_sideband);
|
p_stream->output_written += out_buffer.header.size - out_remain;
|
||||||
stream->input_consumed = in_buffer.header.size - in_remain;
|
p_stream->total_decoded_samples += p_instance->decoded_samples;
|
||||||
stream->output_written = out_buffer.header.size - out_remain;
|
|
||||||
stream->total_decoded_samples = p_instance->decoded_samples;
|
|
||||||
p_sideband += sizeof(AjmSidebandStream);
|
|
||||||
}
|
}
|
||||||
if (True(run_flags & AjmJobRunFlags::MultipleFrames)) {
|
if (p_mframe != nullptr) {
|
||||||
auto* mframe = reinterpret_cast<AjmSidebandMFrame*>(p_sideband);
|
p_mframe->num_frames += num_frames;
|
||||||
mframe->num_frames = num_frames;
|
|
||||||
p_sideband += sizeof(AjmSidebandMFrame);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (True(run_flags & AjmJobRunFlags::GetCodecInfo)) {
|
if (p_codec_info) {
|
||||||
p_instance->GetCodecInfo(p_sideband);
|
p_instance->GetCodecInfo(p_codec_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p_result->result = 0;
|
||||||
|
p_result->internal_result = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
batch_info->finished = true;
|
batch_info->finished = true;
|
||||||
|
|
|
@ -70,7 +70,7 @@ DECLARE_ENUM_FLAG_OPERATORS(AjmJobRunFlags)
|
||||||
|
|
||||||
enum class AjmJobSidebandFlags : u64 {
|
enum class AjmJobSidebandFlags : u64 {
|
||||||
GaplessDecode = 1 << 0,
|
GaplessDecode = 1 << 0,
|
||||||
GetInfo = 1 << 1,
|
Format = 1 << 1,
|
||||||
Stream = 1 << 2,
|
Stream = 1 << 2,
|
||||||
};
|
};
|
||||||
DECLARE_ENUM_FLAG_OPERATORS(AjmJobSidebandFlags)
|
DECLARE_ENUM_FLAG_OPERATORS(AjmJobSidebandFlags)
|
||||||
|
|
|
@ -31,9 +31,9 @@ void AjmAt9Decoder::Reset() {
|
||||||
void AjmAt9Decoder::Initialize(const void* buffer, u32 buffer_size) {
|
void AjmAt9Decoder::Initialize(const void* buffer, u32 buffer_size) {
|
||||||
Atrac9ReleaseHandle(handle);
|
Atrac9ReleaseHandle(handle);
|
||||||
handle = Atrac9GetHandle();
|
handle = Atrac9GetHandle();
|
||||||
ASSERT_MSG(buffer_size == sizeof(SceAjmDecAt9InitializeParameters),
|
ASSERT_MSG(buffer_size == sizeof(AjmDecAt9InitializeParameters),
|
||||||
"Incorrect At9 initialization buffer size {}", buffer_size);
|
"Incorrect At9 initialization buffer size {}", buffer_size);
|
||||||
const auto params = reinterpret_cast<const SceAjmDecAt9InitializeParameters*>(buffer);
|
const auto params = reinterpret_cast<const AjmDecAt9InitializeParameters*>(buffer);
|
||||||
std::memcpy(config_data, params->config_data, SCE_AT9_CONFIG_DATA_SIZE);
|
std::memcpy(config_data, params->config_data, SCE_AT9_CONFIG_DATA_SIZE);
|
||||||
Atrac9InitDecoder(handle, config_data);
|
Atrac9InitDecoder(handle, config_data);
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ void AjmAt9Decoder::GetCodecInfo(void* out_info) {
|
||||||
Atrac9CodecInfo decoder_codec_info;
|
Atrac9CodecInfo decoder_codec_info;
|
||||||
Atrac9GetCodecInfo(handle, &decoder_codec_info);
|
Atrac9GetCodecInfo(handle, &decoder_codec_info);
|
||||||
|
|
||||||
auto* codec_info = reinterpret_cast<SceAjmSidebandDecAt9CodecInfo*>(out_info);
|
auto* codec_info = reinterpret_cast<AjmSidebandDecAt9CodecInfo*>(out_info);
|
||||||
codec_info->uiFrameSamples = decoder_codec_info.frameSamples;
|
codec_info->uiFrameSamples = decoder_codec_info.frameSamples;
|
||||||
codec_info->uiFramesInSuperFrame = decoder_codec_info.framesInSuperframe;
|
codec_info->uiFramesInSuperFrame = decoder_codec_info.framesInSuperframe;
|
||||||
codec_info->uiNextFrameSize = static_cast<Atrac9Handle*>(handle)->Config.FrameBytes;
|
codec_info->uiNextFrameSize = static_cast<Atrac9Handle*>(handle)->Config.FrameBytes;
|
||||||
|
|
|
@ -18,12 +18,12 @@ namespace Libraries::Ajm {
|
||||||
constexpr u32 SCE_AT9_CONFIG_DATA_SIZE = 4;
|
constexpr u32 SCE_AT9_CONFIG_DATA_SIZE = 4;
|
||||||
constexpr s32 SCE_AJM_DEC_AT9_MAX_CHANNELS = 8;
|
constexpr s32 SCE_AJM_DEC_AT9_MAX_CHANNELS = 8;
|
||||||
|
|
||||||
struct SceAjmDecAt9InitializeParameters {
|
struct AjmDecAt9InitializeParameters {
|
||||||
u8 config_data[SCE_AT9_CONFIG_DATA_SIZE];
|
u8 config_data[SCE_AT9_CONFIG_DATA_SIZE];
|
||||||
u32 reserved;
|
u32 reserved;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SceAjmSidebandDecAt9CodecInfo {
|
struct AjmSidebandDecAt9CodecInfo {
|
||||||
u32 uiSuperFrameSize;
|
u32 uiSuperFrameSize;
|
||||||
u32 uiFramesInSuperFrame;
|
u32 uiFramesInSuperFrame;
|
||||||
u32 uiNextFrameSize;
|
u32 uiNextFrameSize;
|
||||||
|
@ -45,6 +45,9 @@ struct AjmAt9Decoder final : AjmInstance {
|
||||||
void Initialize(const void* buffer, u32 buffer_size) override;
|
void Initialize(const void* buffer, u32 buffer_size) override;
|
||||||
|
|
||||||
void GetCodecInfo(void* out_info) override;
|
void GetCodecInfo(void* out_info) override;
|
||||||
|
u32 GetCodecInfoSize() override {
|
||||||
|
return sizeof(AjmSidebandDecAt9CodecInfo);
|
||||||
|
}
|
||||||
|
|
||||||
std::tuple<u32, u32, u32> Decode(const u8* in_buf, u32 in_size, u8* out_buf,
|
std::tuple<u32, u32, u32> Decode(const u8* in_buf, u32 in_size, u8* out_buf,
|
||||||
u32 out_size) override;
|
u32 out_size) override;
|
||||||
|
|
|
@ -54,6 +54,12 @@ struct AjmSidebandFormat {
|
||||||
u32 reserved;
|
u32 reserved;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct AjmSidebandGaplessDecode {
|
||||||
|
u32 total_samples;
|
||||||
|
u16 skip_samples;
|
||||||
|
u16 skipped_samples;
|
||||||
|
};
|
||||||
|
|
||||||
struct AjmInstance {
|
struct AjmInstance {
|
||||||
AjmCodecType codec_type;
|
AjmCodecType codec_type;
|
||||||
u32 decoded_samples{};
|
u32 decoded_samples{};
|
||||||
|
@ -69,6 +75,7 @@ struct AjmInstance {
|
||||||
virtual void Initialize(const void* buffer, u32 buffer_size) = 0;
|
virtual void Initialize(const void* buffer, u32 buffer_size) = 0;
|
||||||
|
|
||||||
virtual void GetCodecInfo(void* out_info) = 0;
|
virtual void GetCodecInfo(void* out_info) = 0;
|
||||||
|
virtual u32 GetCodecInfoSize() = 0;
|
||||||
|
|
||||||
virtual std::tuple<u32, u32, u32> Decode(const u8* in_buf, u32 in_size, u8* out_buf,
|
virtual std::tuple<u32, u32, u32> Decode(const u8* in_buf, u32 in_size, u8* out_buf,
|
||||||
u32 out_size) = 0;
|
u32 out_size) = 0;
|
||||||
|
|
|
@ -70,6 +70,9 @@ struct AjmMp3Decoder : public AjmInstance {
|
||||||
void Initialize(const void* buffer, u32 buffer_size) override {}
|
void Initialize(const void* buffer, u32 buffer_size) override {}
|
||||||
|
|
||||||
void GetCodecInfo(void* out_info) override {}
|
void GetCodecInfo(void* out_info) override {}
|
||||||
|
u32 GetCodecInfoSize() override {
|
||||||
|
return sizeof(AjmSidebandDecMp3CodecInfo);
|
||||||
|
}
|
||||||
|
|
||||||
std::tuple<u32, u32, u32> Decode(const u8* in_buf, u32 in_size, u8* out_buf,
|
std::tuple<u32, u32, u32> Decode(const u8* in_buf, u32 in_size, u8* out_buf,
|
||||||
u32 out_size) override;
|
u32 out_size) override;
|
||||||
|
|
Loading…
Reference in a new issue