mirror of
https://github.com/RPCSX/rpcsx.git
synced 2025-12-06 07:12:14 +01:00
ajm: rewrite using new ioctl handling api
Some checks failed
Formatting check / formatting-check (push) Has been cancelled
Build RPCSX / build-linux (push) Has been cancelled
Build RPCSX / build-android (arm64-v8a, armv8-a) (push) Has been cancelled
Build RPCSX / build-android (arm64-v8a, armv8.1-a) (push) Has been cancelled
Build RPCSX / build-android (arm64-v8a, armv8.2-a) (push) Has been cancelled
Build RPCSX / build-android (arm64-v8a, armv8.4-a) (push) Has been cancelled
Build RPCSX / build-android (arm64-v8a, armv8.5-a) (push) Has been cancelled
Build RPCSX / build-android (arm64-v8a, armv9-a) (push) Has been cancelled
Build RPCSX / build-android (arm64-v8a, armv9.1-a) (push) Has been cancelled
Build RPCSX / build-android (x86_64, x86-64) (push) Has been cancelled
Some checks failed
Formatting check / formatting-check (push) Has been cancelled
Build RPCSX / build-linux (push) Has been cancelled
Build RPCSX / build-android (arm64-v8a, armv8-a) (push) Has been cancelled
Build RPCSX / build-android (arm64-v8a, armv8.1-a) (push) Has been cancelled
Build RPCSX / build-android (arm64-v8a, armv8.2-a) (push) Has been cancelled
Build RPCSX / build-android (arm64-v8a, armv8.4-a) (push) Has been cancelled
Build RPCSX / build-android (arm64-v8a, armv8.5-a) (push) Has been cancelled
Build RPCSX / build-android (arm64-v8a, armv9-a) (push) Has been cancelled
Build RPCSX / build-android (arm64-v8a, armv9.1-a) (push) Has been cancelled
Build RPCSX / build-android (x86_64, x86-64) (push) Has been cancelled
This commit is contained in:
parent
8cfb4e8d16
commit
e27926d629
|
|
@ -1,6 +1,7 @@
|
||||||
#include "ajm.hpp"
|
#include "ajm.hpp"
|
||||||
#include "io-device.hpp"
|
#include "io-device.hpp"
|
||||||
#include "orbis-config.hpp"
|
#include "orbis-config.hpp"
|
||||||
|
#include "orbis/IoDevice.hpp"
|
||||||
#include "orbis/KernelAllocator.hpp"
|
#include "orbis/KernelAllocator.hpp"
|
||||||
#include "orbis/file.hpp"
|
#include "orbis/file.hpp"
|
||||||
#include "orbis/thread/Thread.hpp"
|
#include "orbis/thread/Thread.hpp"
|
||||||
|
|
@ -40,7 +41,20 @@ enum {
|
||||||
AJM_RESULT_CODEC_ERROR = 0x40000000,
|
AJM_RESULT_CODEC_ERROR = 0x40000000,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AjmDevice : orbis::IoDevice {
|
enum {
|
||||||
|
AJM_IOCTL_FINALIZE = 0xc0288900,
|
||||||
|
AJM_IOCTL_MODULE_REGISTER = 0xc0288903,
|
||||||
|
AJM_IOCTL_MODULE_UNREGISTER = 0xc0288904,
|
||||||
|
AJM_IOCTL_INSTANCE_CREATE = 0xc0288905,
|
||||||
|
AJM_IOCTL_INSTANCE_DESTROY = 0xc0288906,
|
||||||
|
AJM_IOCTL_START_BATCH_BUFFER = 0xc0288907,
|
||||||
|
AJM_IOCTL_WAIT_BATCH_BUFFER = 0xc0288908,
|
||||||
|
AJM_IOCTL_INSTANCE_EXTEND = 0xc028890a,
|
||||||
|
AJM_IOCTL_INSTANCE_SWITCH = 0xc028890b,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AjmDevice
|
||||||
|
: orbis::IoDeviceWithIoctl<orbis::ioctl::group(AJM_IOCTL_FINALIZE)> {
|
||||||
rx::shared_mutex mtx;
|
rx::shared_mutex mtx;
|
||||||
orbis::uint32_t batchId = 1; // temp
|
orbis::uint32_t batchId = 1; // temp
|
||||||
|
|
||||||
|
|
@ -50,6 +64,8 @@ struct AjmDevice : orbis::IoDevice {
|
||||||
orbis::ErrorCode open(rx::Ref<orbis::File> *file, const char *path,
|
orbis::ErrorCode open(rx::Ref<orbis::File> *file, const char *path,
|
||||||
std::uint32_t flags, std::uint32_t mode,
|
std::uint32_t flags, std::uint32_t mode,
|
||||||
orbis::Thread *thread) override;
|
orbis::Thread *thread) override;
|
||||||
|
|
||||||
|
AjmDevice();
|
||||||
};
|
};
|
||||||
|
|
||||||
AVSampleFormat ajmToAvFormat(AJMFormat ajmFormat) {
|
AVSampleFormat ajmToAvFormat(AJMFormat ajmFormat) {
|
||||||
|
|
@ -105,70 +121,83 @@ void resetAt9(Instance *instance) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static orbis::ErrorCode ajm_ioctl(orbis::File *file, std::uint64_t request,
|
struct AjmIoctlInstanceFinalize {
|
||||||
void *argp, orbis::Thread *thread) {
|
|
||||||
|
|
||||||
auto device = static_cast<AjmDevice *>(file->device.get());
|
|
||||||
// 0xc0288900 - finalize
|
|
||||||
// 0xc0288903 - module register
|
|
||||||
// 0xc0288904 - module unregister
|
|
||||||
// 0xc0288905 - instance create
|
|
||||||
// 0xc0288906 - instance destroy
|
|
||||||
// 0xc028890a - instance extend
|
|
||||||
// 0xc028890b - intasnce switch
|
|
||||||
// 0xc0288907 - start batch buffer
|
|
||||||
// 0xc0288908 - wait batch buffer
|
|
||||||
// 0xc0288900 - unregister context
|
|
||||||
if (request == 0xc0288906) {
|
|
||||||
struct InstanceDestroyArgs {
|
|
||||||
orbis::uint32_t result;
|
orbis::uint32_t result;
|
||||||
orbis::uint32_t unk0;
|
orbis::uint32_t unk0;
|
||||||
orbis::uint32_t instanceId;
|
orbis::uint32_t instanceId;
|
||||||
|
orbis::uint32_t unk[7];
|
||||||
};
|
};
|
||||||
auto args = reinterpret_cast<InstanceDestroyArgs *>(argp);
|
|
||||||
if (device->instanceMap.erase(args->instanceId) == 0) {
|
|
||||||
return orbis::ErrorCode::INVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
args->result = 0;
|
static orbis::ErrorCode ajm_ioctl_finalize(orbis::Thread *, AjmDevice *device,
|
||||||
|
AjmIoctlInstanceFinalize &args) {
|
||||||
|
ORBIS_LOG_ERROR(__FUNCTION__, args.instanceId);
|
||||||
|
args.result = 0;
|
||||||
|
args.unk0 = 0;
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request == 0xc0288903 || request == 0xc0288904 || request == 0xc0288900) {
|
struct AjmIoctlModuleRegister {
|
||||||
auto arg = reinterpret_cast<std::uint32_t *>(argp)[2];
|
orbis::uint32_t result;
|
||||||
ORBIS_LOG_ERROR(__FUNCTION__, request, arg);
|
orbis::uint32_t unk0;
|
||||||
*reinterpret_cast<std::uint64_t *>(argp) = 0;
|
orbis::uint32_t instanceId;
|
||||||
|
orbis::uint32_t unk[7];
|
||||||
|
};
|
||||||
|
|
||||||
|
static orbis::ErrorCode
|
||||||
|
ajm_ioctl_module_register(orbis::Thread *, AjmDevice *device,
|
||||||
|
AjmIoctlModuleRegister &args) {
|
||||||
|
ORBIS_LOG_ERROR(__FUNCTION__, args.instanceId);
|
||||||
|
args.result = 0;
|
||||||
|
args.unk0 = 0;
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request == 0xc0288905) {
|
struct AjmIoctlModuleUnregister {
|
||||||
struct InstanceCreateArgs {
|
orbis::uint32_t result;
|
||||||
|
orbis::uint32_t unk0;
|
||||||
|
orbis::uint32_t instanceId;
|
||||||
|
orbis::uint32_t unk[7];
|
||||||
|
};
|
||||||
|
static orbis::ErrorCode
|
||||||
|
ajm_ioctl_module_unregister(orbis::Thread *, AjmDevice *device,
|
||||||
|
AjmIoctlModuleUnregister &args) {
|
||||||
|
ORBIS_LOG_ERROR(__FUNCTION__, args.instanceId);
|
||||||
|
args.result = 0;
|
||||||
|
args.unk0 = 0;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
struct AjmIoctlInstanceCreate {
|
||||||
orbis::uint32_t result;
|
orbis::uint32_t result;
|
||||||
orbis::uint32_t unk0;
|
orbis::uint32_t unk0;
|
||||||
orbis::uint64_t flags;
|
orbis::uint64_t flags;
|
||||||
orbis::uint32_t codec;
|
orbis::uint32_t codec;
|
||||||
orbis::uint32_t instanceId;
|
orbis::uint32_t instanceId;
|
||||||
|
orbis::uint32_t unk[4];
|
||||||
};
|
};
|
||||||
|
static orbis::ErrorCode
|
||||||
|
ajm_ioctl_instance_create(orbis::Thread *, AjmDevice *device,
|
||||||
|
AjmIoctlInstanceCreate &args) {
|
||||||
|
ORBIS_LOG_WARNING(__FUNCTION__, args.flags, args.codec);
|
||||||
|
std::lock_guard lock(device->mtx);
|
||||||
|
|
||||||
auto args = reinterpret_cast<InstanceCreateArgs *>(argp);
|
auto codecId = AJMCodecs(args.codec);
|
||||||
auto codecId = AJMCodecs(args->codec);
|
|
||||||
auto codecOffset = codecId << 0xe;
|
auto codecOffset = codecId << 0xe;
|
||||||
|
args.result = 0;
|
||||||
if (codecId < AJM_CODEC_COUNT) {
|
if (codecId < AJM_CODEC_COUNT) {
|
||||||
args->result = 0;
|
args.instanceId = codecOffset + device->instanceIds[codecId]++;
|
||||||
args->instanceId = codecOffset + device->instanceIds[codecId]++;
|
|
||||||
|
|
||||||
auto [it, inserted] = device->instanceMap.try_emplace(args->instanceId);
|
auto [it, inserted] = device->instanceMap.try_emplace(args.instanceId);
|
||||||
|
|
||||||
assert(inserted);
|
assert(inserted);
|
||||||
auto &instance = it->second;
|
auto &instance = it->second;
|
||||||
instance.codec = codecId;
|
instance.codec = codecId;
|
||||||
instance.maxChannels =
|
instance.maxChannels =
|
||||||
AJMChannels(((args->flags & ~7) & (0xFF & ~0b11)) >> 3);
|
AJMChannels(((args.flags & ~7) & (0xFF & ~0b11)) >> 3);
|
||||||
instance.outputFormat = AJMFormat((args->flags & ~7) & 0b11);
|
instance.outputFormat = AJMFormat((args.flags & ~7) & 0b11);
|
||||||
if (codecId == AJM_CODEC_AAC) {
|
if (codecId == AJM_CODEC_AAC) {
|
||||||
instance.aac.isHeaac = ((args->flags & ~7) & 0x100000000) != 0;
|
instance.aac.isHeaac = ((args.flags & ~7) & 0x100000000) != 0;
|
||||||
instance.aac.isFrameSkipEnabled =
|
instance.aac.isFrameSkipEnabled = ((args.flags & ~7) & 0x200000000) == 0;
|
||||||
((args->flags & ~7) & 0x200000000) == 0;
|
|
||||||
}
|
}
|
||||||
if (codecId == AJM_CODEC_At9) {
|
if (codecId == AJM_CODEC_At9) {
|
||||||
instance.at9.handle = Atrac9GetHandle();
|
instance.at9.handle = Atrac9GetHandle();
|
||||||
|
|
@ -207,41 +236,91 @@ static orbis::ErrorCode ajm_ioctl(orbis::File *file, std::uint64_t request,
|
||||||
instance.codecCtx = codecCtx;
|
instance.codecCtx = codecCtx;
|
||||||
}
|
}
|
||||||
|
|
||||||
ORBIS_LOG_ERROR(__FUNCTION__, request, args->result, args->unk0,
|
ORBIS_LOG_ERROR(__FUNCTION__, args.result, args.unk0, args.flags,
|
||||||
args->flags, args->codec, args->instanceId,
|
args.codec, args.instanceId,
|
||||||
(std::uint16_t)instance.outputFormat,
|
(std::uint16_t)instance.outputFormat,
|
||||||
(std::uint16_t)instance.maxChannels);
|
(std::uint16_t)instance.maxChannels);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
args->instanceId = codecOffset + device->unimplementedInstanceId++;
|
args.instanceId = codecOffset + device->unimplementedInstanceId++;
|
||||||
ORBIS_LOG_ERROR(__FUNCTION__, request, "unimplemented codec",
|
ORBIS_LOG_ERROR(__FUNCTION__, "unimplemented codec", args.result, args.unk0,
|
||||||
args->result, args->unk0, args->flags, args->codec,
|
args.flags, args.codec, args.instanceId);
|
||||||
args->instanceId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request == 0xc0288907) {
|
struct AjmIoctlInstanceDestroy {
|
||||||
struct StartBatchBufferArgs {
|
|
||||||
orbis::uint32_t result;
|
orbis::uint32_t result;
|
||||||
orbis::uint32_t unk0;
|
orbis::uint32_t unk0;
|
||||||
std::byte *pBatch;
|
orbis::uint32_t instanceId;
|
||||||
|
orbis::uint32_t unk[7];
|
||||||
|
};
|
||||||
|
static orbis::ErrorCode
|
||||||
|
ajm_ioctl_instance_destroy(orbis::Thread *, AjmDevice *device,
|
||||||
|
AjmIoctlInstanceDestroy &args) {
|
||||||
|
ORBIS_LOG_ERROR(__FUNCTION__, args.instanceId);
|
||||||
|
std::lock_guard lock(device->mtx);
|
||||||
|
if (device->instanceMap.erase(args.instanceId) == 0) {
|
||||||
|
return orbis::ErrorCode::INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
args.result = 0;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
struct AjmIoctlInstanceExtend {
|
||||||
|
orbis::uint32_t result;
|
||||||
|
orbis::uint32_t unk0;
|
||||||
|
orbis::uint32_t instanceId;
|
||||||
|
orbis::uint32_t unk[7];
|
||||||
|
};
|
||||||
|
static orbis::ErrorCode
|
||||||
|
ajm_ioctl_instance_extend(orbis::Thread *thread, AjmDevice *device,
|
||||||
|
AjmIoctlInstanceExtend &args) {
|
||||||
|
ORBIS_LOG_ERROR(__FUNCTION__);
|
||||||
|
thread->where();
|
||||||
|
args.result = 0;
|
||||||
|
args.unk0 = 0;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
struct AjmIoctlInstanceSwitch {
|
||||||
|
orbis::uint32_t result;
|
||||||
|
orbis::uint32_t unk0;
|
||||||
|
orbis::uint32_t instanceId;
|
||||||
|
orbis::uint32_t unk[7];
|
||||||
|
};
|
||||||
|
static orbis::ErrorCode
|
||||||
|
ajm_ioctl_instance_switch(orbis::Thread *thread, AjmDevice *device,
|
||||||
|
AjmIoctlInstanceSwitch &args) {
|
||||||
|
ORBIS_LOG_ERROR(__FUNCTION__);
|
||||||
|
thread->where();
|
||||||
|
args.result = 0;
|
||||||
|
args.unk0 = 0;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
struct AjmIoctlStartBatchBuffer {
|
||||||
|
orbis::uint32_t result;
|
||||||
|
orbis::uint32_t unk0;
|
||||||
|
orbis::ptr<std::byte> pBatch;
|
||||||
orbis::uint32_t batchSize;
|
orbis::uint32_t batchSize;
|
||||||
orbis::uint32_t priority;
|
orbis::uint32_t priority;
|
||||||
orbis::uint64_t batchError;
|
orbis::uint64_t batchError;
|
||||||
orbis::uint32_t batchId;
|
orbis::uint32_t batchId;
|
||||||
};
|
};
|
||||||
auto args = reinterpret_cast<StartBatchBufferArgs *>(argp);
|
static orbis::ErrorCode
|
||||||
args->result = 0;
|
ajm_ioctl_start_batch_buffer(orbis::Thread *, AjmDevice *device,
|
||||||
args->batchId = device->batchId++;
|
AjmIoctlStartBatchBuffer &args) {
|
||||||
// ORBIS_LOG_ERROR(__FUNCTION__, request, args->result, args->unk0,
|
args.result = 0;
|
||||||
// args->pBatch, args->batchSize, args->priority,
|
args.batchId = device->batchId++;
|
||||||
// args->batchError, args->batchId);
|
// ORBIS_LOG_ERROR(__FUNCTION__, args.result, args.unk0, args.pBatch,
|
||||||
|
// args.batchSize, args.priority, args.batchError, args.batchId);
|
||||||
// thread->where();
|
// thread->where();
|
||||||
|
|
||||||
auto ptr = args->pBatch;
|
auto ptr = args.pBatch;
|
||||||
auto endPtr = args->pBatch + args->batchSize;
|
auto endPtr = args.pBatch + args.batchSize;
|
||||||
|
|
||||||
while (ptr < endPtr) {
|
while (ptr < endPtr) {
|
||||||
auto header = (InstructionHeader *)ptr;
|
auto header = (InstructionHeader *)ptr;
|
||||||
|
|
@ -271,7 +350,7 @@ static orbis::ErrorCode ajm_ioctl(orbis::File *file, std::uint64_t request,
|
||||||
reinterpret_cast<AJMSidebandResult *>(ctrl->pSidebandOutput);
|
reinterpret_cast<AJMSidebandResult *>(ctrl->pSidebandOutput);
|
||||||
*result = {};
|
*result = {};
|
||||||
|
|
||||||
ORBIS_LOG_ERROR(__FUNCTION__, request, "control buffer", ctrl->opcode,
|
ORBIS_LOG_ERROR(__FUNCTION__, "control buffer", ctrl->opcode,
|
||||||
ctrl->commandId, ctrl->flagsHi, ctrl->flagsLo,
|
ctrl->commandId, ctrl->flagsHi, ctrl->flagsLo,
|
||||||
ctrl->sidebandInputSize, ctrl->sidebandOutputSize);
|
ctrl->sidebandInputSize, ctrl->sidebandOutputSize);
|
||||||
if (ctrl->getFlags() & CONTROL_RESET) {
|
if (ctrl->getFlags() & CONTROL_RESET) {
|
||||||
|
|
@ -301,8 +380,7 @@ static orbis::ErrorCode ajm_ioctl(orbis::File *file, std::uint64_t request,
|
||||||
? maxChannels
|
? maxChannels
|
||||||
: instance.at9.inputChannels;
|
: instance.at9.inputChannels;
|
||||||
// TODO: check max channels
|
// TODO: check max channels
|
||||||
ORBIS_LOG_TODO("CONTROL_INITIALIZE AT9",
|
ORBIS_LOG_TODO("CONTROL_INITIALIZE AT9", instance.at9.inputChannels,
|
||||||
instance.at9.inputChannels,
|
|
||||||
instance.at9.sampleRate, instance.at9.frameSamples,
|
instance.at9.sampleRate, instance.at9.frameSamples,
|
||||||
instance.at9.superFrameSize, maxChannels,
|
instance.at9.superFrameSize, maxChannels,
|
||||||
outputChannels, initializeBuffer->configData,
|
outputChannels, initializeBuffer->configData,
|
||||||
|
|
@ -323,8 +401,7 @@ static orbis::ErrorCode ajm_ioctl(orbis::File *file, std::uint64_t request,
|
||||||
AVCodecContext *codecCtx =
|
AVCodecContext *codecCtx =
|
||||||
avcodec_alloc_context3(instance.avCodec);
|
avcodec_alloc_context3(instance.avCodec);
|
||||||
if (!codecCtx) {
|
if (!codecCtx) {
|
||||||
ORBIS_LOG_FATAL(
|
ORBIS_LOG_FATAL("Failed to allocate codec context for raw aac");
|
||||||
"Failed to allocate codec context for raw aac");
|
|
||||||
std::abort();
|
std::abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -338,8 +415,7 @@ static orbis::ErrorCode ajm_ioctl(orbis::File *file, std::uint64_t request,
|
||||||
codecCtx->ch_layout = chLayout;
|
codecCtx->ch_layout = chLayout;
|
||||||
codecCtx->sample_rate = instance.aac.sampleRate;
|
codecCtx->sample_rate = instance.aac.sampleRate;
|
||||||
|
|
||||||
if (int err =
|
if (int err = avcodec_open2(codecCtx, instance.avCodec, nullptr);
|
||||||
avcodec_open2(codecCtx, instance.avCodec, nullptr);
|
|
||||||
err < 0) {
|
err < 0) {
|
||||||
ORBIS_LOG_FATAL("Could not open codec for raw aac", err);
|
ORBIS_LOG_FATAL("Could not open codec for raw aac", err);
|
||||||
std::abort();
|
std::abort();
|
||||||
|
|
@ -347,10 +423,9 @@ static orbis::ErrorCode ajm_ioctl(orbis::File *file, std::uint64_t request,
|
||||||
|
|
||||||
instance.codecCtx = codecCtx;
|
instance.codecCtx = codecCtx;
|
||||||
}
|
}
|
||||||
ORBIS_LOG_TODO("CONTROL_INITIALIZE AAC",
|
ORBIS_LOG_TODO(
|
||||||
(std::int16_t)instance.aac.headerType,
|
"CONTROL_INITIALIZE AAC", (std::int16_t)instance.aac.headerType,
|
||||||
instance.aac.sampleRate,
|
instance.aac.sampleRate, (std::int16_t)instance.maxChannels,
|
||||||
(std::int16_t)instance.maxChannels,
|
|
||||||
(orbis::uint32_t)instance.outputFormat);
|
(orbis::uint32_t)instance.outputFormat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -471,8 +546,7 @@ static orbis::ErrorCode ajm_ioctl(orbis::File *file, std::uint64_t request,
|
||||||
if (instance.codec == AJM_CODEC_At9) {
|
if (instance.codec == AJM_CODEC_At9) {
|
||||||
inputFrameSize = 4;
|
inputFrameSize = 4;
|
||||||
outputBufferSize = av_samples_get_buffer_size(
|
outputBufferSize = av_samples_get_buffer_size(
|
||||||
nullptr, instance.at9.inputChannels,
|
nullptr, instance.at9.inputChannels, instance.at9.frameSamples,
|
||||||
instance.at9.frameSamples,
|
|
||||||
ajmToAvFormat(instance.outputFormat), 0);
|
ajmToAvFormat(instance.outputFormat), 0);
|
||||||
} else if (instance.codec == AJM_CODEC_MP3) {
|
} else if (instance.codec == AJM_CODEC_MP3) {
|
||||||
if (instance.inputBuffer.size() - totalDecodedBytes < 4) {
|
if (instance.inputBuffer.size() - totalDecodedBytes < 4) {
|
||||||
|
|
@ -533,8 +607,7 @@ static orbis::ErrorCode ajm_ioctl(orbis::File *file, std::uint64_t request,
|
||||||
instance.at9.superFrameDataIdx++;
|
instance.at9.superFrameDataIdx++;
|
||||||
if (instance.at9.superFrameDataIdx ==
|
if (instance.at9.superFrameDataIdx ==
|
||||||
instance.at9.framesInSuperframe) {
|
instance.at9.framesInSuperframe) {
|
||||||
instance.at9.estimatedSizeUsed +=
|
instance.at9.estimatedSizeUsed += instance.at9.superFrameDataLeft;
|
||||||
instance.at9.superFrameDataLeft;
|
|
||||||
instance.at9.superFrameDataIdx = 0;
|
instance.at9.superFrameDataIdx = 0;
|
||||||
instance.at9.superFrameDataLeft = instance.at9.superFrameSize;
|
instance.at9.superFrameDataLeft = instance.at9.superFrameSize;
|
||||||
}
|
}
|
||||||
|
|
@ -573,8 +646,7 @@ static orbis::ErrorCode ajm_ioctl(orbis::File *file, std::uint64_t request,
|
||||||
// we simply call this method directly (but it can be very
|
// we simply call this method directly (but it can be very
|
||||||
// unstable)
|
// unstable)
|
||||||
int gotFrame;
|
int gotFrame;
|
||||||
int len =
|
int len = ffcodec(instance.codecCtx->codec)
|
||||||
ffcodec(instance.codecCtx->codec)
|
|
||||||
->cb.decode(instance.codecCtx, frame, &gotFrame, pkt);
|
->cb.decode(instance.codecCtx, frame, &gotFrame, pkt);
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
ORBIS_LOG_FATAL("Error during decoding AAC");
|
ORBIS_LOG_FATAL("Error during decoding AAC");
|
||||||
|
|
@ -634,8 +706,7 @@ static orbis::ErrorCode ajm_ioctl(orbis::File *file, std::uint64_t request,
|
||||||
av_opt_set_sample_fmt(resampler, "out_sample_fmt",
|
av_opt_set_sample_fmt(resampler, "out_sample_fmt",
|
||||||
ajmToAvFormat(instance.outputFormat), 0);
|
ajmToAvFormat(instance.outputFormat), 0);
|
||||||
if (swr_init(resampler) < 0) {
|
if (swr_init(resampler) < 0) {
|
||||||
ORBIS_LOG_FATAL(
|
ORBIS_LOG_FATAL("Failed to initialize the resampling context");
|
||||||
"Failed to initialize the resampling context");
|
|
||||||
std::abort();
|
std::abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -657,9 +728,9 @@ static orbis::ErrorCode ajm_ioctl(orbis::File *file, std::uint64_t request,
|
||||||
if (bufferOffset <= outputWritten &&
|
if (bufferOffset <= outputWritten &&
|
||||||
bufferOffset + buffer.size > outputWritten) {
|
bufferOffset + buffer.size > outputWritten) {
|
||||||
auto byteOffset = outputWritten - bufferOffset;
|
auto byteOffset = outputWritten - bufferOffset;
|
||||||
auto size = std::min(buffer.size - byteOffset,
|
auto size =
|
||||||
instance.outputBuffer.size() -
|
std::min(buffer.size - byteOffset,
|
||||||
bufferOutputWritten);
|
instance.outputBuffer.size() - bufferOutputWritten);
|
||||||
ORBIS_RET_ON_ERROR(orbis::uwrite(
|
ORBIS_RET_ON_ERROR(orbis::uwrite(
|
||||||
buffer.pOutput + byteOffset,
|
buffer.pOutput + byteOffset,
|
||||||
instance.outputBuffer.data() + bufferOutputWritten, size));
|
instance.outputBuffer.data() + bufferOutputWritten, size));
|
||||||
|
|
@ -684,8 +755,8 @@ static orbis::ErrorCode ajm_ioctl(orbis::File *file, std::uint64_t request,
|
||||||
if (runJob.flags & SIDEBAND_STREAM) {
|
if (runJob.flags & SIDEBAND_STREAM) {
|
||||||
// ORBIS_LOG_TODO("SIDEBAND_STREAM", currentSize, outputWritten,
|
// ORBIS_LOG_TODO("SIDEBAND_STREAM", currentSize, outputWritten,
|
||||||
// instance.processedSamples);
|
// instance.processedSamples);
|
||||||
auto *stream = reinterpret_cast<AJMSidebandStream *>(
|
auto *stream = reinterpret_cast<AJMSidebandStream *>(runJob.pSideband +
|
||||||
runJob.pSideband + currentSize);
|
currentSize);
|
||||||
stream->inputSize = totalDecodedBytes;
|
stream->inputSize = totalDecodedBytes;
|
||||||
stream->outputSize = outputWritten;
|
stream->outputSize = outputWritten;
|
||||||
stream->decodedSamples = instance.processedSamples;
|
stream->decodedSamples = instance.processedSamples;
|
||||||
|
|
@ -697,8 +768,8 @@ static orbis::ErrorCode ajm_ioctl(orbis::File *file, std::uint64_t request,
|
||||||
// (std::uint16_t)instance.lastDecode.channels,
|
// (std::uint16_t)instance.lastDecode.channels,
|
||||||
// (std::uint16_t)instance.outputFormat,
|
// (std::uint16_t)instance.outputFormat,
|
||||||
// instance.lastDecode.sampleRate);
|
// instance.lastDecode.sampleRate);
|
||||||
auto *format = reinterpret_cast<AJMSidebandFormat *>(
|
auto *format = reinterpret_cast<AJMSidebandFormat *>(runJob.pSideband +
|
||||||
runJob.pSideband + currentSize);
|
currentSize);
|
||||||
format->channels = AJMChannels(instance.lastDecode.channels);
|
format->channels = AJMChannels(instance.lastDecode.channels);
|
||||||
format->sampleRate = instance.lastDecode.sampleRate;
|
format->sampleRate = instance.lastDecode.sampleRate;
|
||||||
format->sampleFormat = instance.outputFormat;
|
format->sampleFormat = instance.outputFormat;
|
||||||
|
|
@ -753,30 +824,37 @@ static orbis::ErrorCode ajm_ioctl(orbis::File *file, std::uint64_t request,
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request == 0xc0288908) {
|
struct AjmIoctlWaitBatchBuffer {
|
||||||
struct Args {
|
orbis::uint32_t result;
|
||||||
orbis::uint32_t unk0;
|
orbis::uint32_t unk0;
|
||||||
orbis::uint32_t unk1;
|
|
||||||
orbis::uint32_t batchId;
|
orbis::uint32_t batchId;
|
||||||
orbis::uint32_t timeout;
|
orbis::uint32_t timeout;
|
||||||
orbis::uint64_t batchError;
|
orbis::uint64_t batchError;
|
||||||
|
orbis::uint32_t unk[4];
|
||||||
};
|
};
|
||||||
auto args = reinterpret_cast<Args *>(argp);
|
static orbis::ErrorCode
|
||||||
args->unk0 = 0;
|
ajm_ioctl_wait_batch_buffer(orbis::Thread *thread, AjmDevice *device,
|
||||||
// ORBIS_LOG_ERROR(__FUNCTION__, request, args->unk0, args->unk1,
|
AjmIoctlWaitBatchBuffer &args) {
|
||||||
// args->batchId, args->timeout, args->batchError);
|
args.result = 0;
|
||||||
|
// ORBIS_LOG_ERROR(__FUNCTION__, request, args.result, args.unk0,
|
||||||
|
// args.batchId, args.timeout, args.batchError);
|
||||||
// thread->where();
|
// thread->where();
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
ORBIS_LOG_FATAL("Unhandled AJM ioctl", request);
|
static const orbis::FileOps fileOps = {};
|
||||||
thread->where();
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
static const orbis::FileOps fileOps = {
|
AjmDevice::AjmDevice() {
|
||||||
.ioctl = ajm_ioctl,
|
addIoctl<AJM_IOCTL_FINALIZE>(ajm_ioctl_finalize);
|
||||||
};
|
addIoctl<AJM_IOCTL_MODULE_REGISTER>(ajm_ioctl_module_register);
|
||||||
|
addIoctl<AJM_IOCTL_MODULE_UNREGISTER>(ajm_ioctl_module_unregister);
|
||||||
|
addIoctl<AJM_IOCTL_INSTANCE_CREATE>(ajm_ioctl_instance_create);
|
||||||
|
addIoctl<AJM_IOCTL_INSTANCE_DESTROY>(ajm_ioctl_instance_destroy);
|
||||||
|
addIoctl<AJM_IOCTL_START_BATCH_BUFFER>(ajm_ioctl_start_batch_buffer);
|
||||||
|
addIoctl<AJM_IOCTL_WAIT_BATCH_BUFFER>(ajm_ioctl_wait_batch_buffer);
|
||||||
|
addIoctl<AJM_IOCTL_INSTANCE_EXTEND>(ajm_ioctl_instance_extend);
|
||||||
|
addIoctl<AJM_IOCTL_INSTANCE_SWITCH>(ajm_ioctl_instance_switch);
|
||||||
|
}
|
||||||
|
|
||||||
orbis::ErrorCode AjmDevice::open(rx::Ref<orbis::File> *file, const char *path,
|
orbis::ErrorCode AjmDevice::open(rx::Ref<orbis::File> *file, const char *path,
|
||||||
std::uint32_t flags, std::uint32_t mode,
|
std::uint32_t flags, std::uint32_t mode,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue