shadPS4/src/core/libraries/ajm/ajm.h
Vladislav Mikhalin 46ac48c311
AJM: Added some missing features (#1489)
* AJM: Added support for different PCM formats

* updated libatrac9 ref

* remove log

* Add support for non-interleaved flag

* Added support for output sideband format query
2024-11-06 22:39:43 +02:00

188 lines
5.5 KiB
C++

// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "common/bit_field.h"
#include "common/enum.h"
#include "common/types.h"
namespace Core::Loader {
class SymbolsResolver;
}
namespace Libraries::Ajm {
constexpr u32 ORBIS_AT9_CONFIG_DATA_SIZE = 4;
constexpr u32 AJM_INSTANCE_STATISTICS = 0x80000;
enum class AjmCodecType : u32 {
Mp3Dec = 0,
At9Dec = 1,
M4aacDec = 2,
Max = 23,
};
DECLARE_ENUM_FLAG_OPERATORS(AjmCodecType);
struct AjmBatchInfo {
void* pBuffer;
u64 offset;
u64 size;
};
struct AjmBatchError {
int error_code;
const void* job_addr;
u32 cmd_offset;
const void* job_ra;
};
struct AjmBuffer {
u8* p_address;
u64 size;
};
enum class AjmJobControlFlags : u64 {
Reset = 1 << 0,
Initialize = 1 << 1,
Resample = 1 << 2,
};
DECLARE_ENUM_FLAG_OPERATORS(AjmJobControlFlags)
enum class AjmJobRunFlags : u64 {
GetCodecInfo = 1 << 0,
MultipleFrames = 1 << 1,
};
DECLARE_ENUM_FLAG_OPERATORS(AjmJobRunFlags)
enum class AjmJobSidebandFlags : u64 {
GaplessDecode = 1 << 0,
Format = 1 << 1,
Stream = 1 << 2,
};
DECLARE_ENUM_FLAG_OPERATORS(AjmJobSidebandFlags)
union AjmJobFlags {
u64 raw;
struct {
u64 version : 3;
u64 codec : 8;
AjmJobRunFlags run_flags : 2;
AjmJobControlFlags control_flags : 3;
u64 reserved : 29;
AjmJobSidebandFlags sideband_flags : 3;
};
};
struct AjmSidebandResult {
s32 result;
s32 internal_result;
};
struct AjmSidebandMFrame {
u32 num_frames;
u32 reserved;
};
struct AjmSidebandStream {
s32 input_consumed;
s32 output_written;
u64 total_decoded_samples;
};
enum class AjmFormatEncoding : u32 {
S16 = 0,
S32 = 1,
Float = 2,
};
struct AjmSidebandFormat {
u32 num_channels;
u32 channel_mask;
u32 sampl_freq;
AjmFormatEncoding sample_encoding;
u32 bitrate;
u32 reserved;
};
struct AjmSidebandGaplessDecode {
u32 total_samples;
u16 skip_samples;
u16 skipped_samples;
};
struct AjmSidebandResampleParameters {
float ratio;
uint32_t flags;
};
struct AjmDecAt9InitializeParameters {
u8 config_data[ORBIS_AT9_CONFIG_DATA_SIZE];
u32 reserved;
};
union AjmSidebandInitParameters {
AjmDecAt9InitializeParameters at9;
u8 reserved[8];
};
union AjmInstanceFlags {
u64 raw;
struct {
u64 version : 3;
u64 channels : 4;
u64 format : 3;
u64 gapless_loop : 1;
u64 : 21;
u64 codec : 28;
};
};
static_assert(sizeof(AjmInstanceFlags) == 8);
struct AjmDecMp3ParseFrame;
u32 GetChannelMask(u32 num_channels);
int PS4_SYSV_ABI sceAjmBatchCancel(const u32 context_id, const u32 batch_id);
int PS4_SYSV_ABI sceAjmBatchErrorDump();
void* PS4_SYSV_ABI sceAjmBatchJobControlBufferRa(void* p_buffer, u32 instance_id, u64 flags,
void* p_sideband_input, size_t sideband_input_size,
void* p_sideband_output,
size_t sideband_output_size,
void* p_return_address);
void* PS4_SYSV_ABI sceAjmBatchJobInlineBuffer(void* p_buffer, const void* p_data_input,
size_t data_input_size,
const void** pp_batch_address);
void* PS4_SYSV_ABI sceAjmBatchJobRunBufferRa(void* p_buffer, u32 instance_id, u64 flags,
void* p_data_input, size_t data_input_size,
void* p_data_output, size_t data_output_size,
void* p_sideband_output, size_t sideband_output_size,
void* p_return_address);
void* PS4_SYSV_ABI sceAjmBatchJobRunSplitBufferRa(
void* p_buffer, u32 instance_id, u64 flags, const AjmBuffer* p_data_input_buffers,
size_t num_data_input_buffers, const AjmBuffer* p_data_output_buffers,
size_t num_data_output_buffers, void* p_sideband_output, size_t sideband_output_size,
void* p_return_address);
int PS4_SYSV_ABI sceAjmBatchStartBuffer(u32 context, u8* batch, u32 batch_size, const int priority,
AjmBatchError* batch_error, u32* out_batch_id);
int PS4_SYSV_ABI sceAjmBatchWait(const u32 context, const u32 batch_id, const u32 timeout,
AjmBatchError* const batch_error);
int PS4_SYSV_ABI sceAjmDecAt9ParseConfigData();
int PS4_SYSV_ABI sceAjmDecMp3ParseFrame(const u8* stream, u32 stream_size, int parse_ofl,
AjmDecMp3ParseFrame* frame);
int PS4_SYSV_ABI sceAjmFinalize();
int PS4_SYSV_ABI sceAjmInitialize(s64 reserved, u32* out_context);
int PS4_SYSV_ABI sceAjmInstanceCodecType();
int PS4_SYSV_ABI sceAjmInstanceCreate(u32 context, AjmCodecType codec_type, AjmInstanceFlags flags,
u32* instance);
int PS4_SYSV_ABI sceAjmInstanceDestroy(u32 context, u32 instance);
int PS4_SYSV_ABI sceAjmInstanceExtend();
int PS4_SYSV_ABI sceAjmInstanceSwitch();
int PS4_SYSV_ABI sceAjmMemoryRegister();
int PS4_SYSV_ABI sceAjmMemoryUnregister();
int PS4_SYSV_ABI sceAjmModuleRegister(u32 context, AjmCodecType codec_type, s64 reserved);
int PS4_SYSV_ABI sceAjmModuleUnregister();
int PS4_SYSV_ABI sceAjmStrError();
void RegisterlibSceAjm(Core::Loader::SymbolsResolver* sym);
} // namespace Libraries::Ajm