audio: rewrite IHardwareOpusDecoder

This commit is contained in:
Liam 2024-02-20 22:15:28 -05:00
parent c575a85233
commit 5f90bd88da
2 changed files with 123 additions and 218 deletions

View file

@ -2,7 +2,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/audio/hardware_opus_decoder.h" #include "core/hle/service/audio/hardware_opus_decoder.h"
#include "core/hle/service/ipc_helpers.h" #include "core/hle/service/cmif_serialization.h"
namespace Service::Audio { namespace Service::Audio {
@ -13,16 +13,16 @@ IHardwareOpusDecoder::IHardwareOpusDecoder(Core::System& system_, HardwareOpus&
impl{std::make_unique<AudioCore::OpusDecoder::OpusDecoder>(system_, hardware_opus)} { impl{std::make_unique<AudioCore::OpusDecoder::OpusDecoder>(system_, hardware_opus)} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, &IHardwareOpusDecoder::DecodeInterleavedOld, "DecodeInterleavedOld"}, {0, D<&IHardwareOpusDecoder::DecodeInterleavedOld>, "DecodeInterleavedOld"},
{1, &IHardwareOpusDecoder::SetContext, "SetContext"}, {1, D<&IHardwareOpusDecoder::SetContext>, "SetContext"},
{2, &IHardwareOpusDecoder::DecodeInterleavedForMultiStreamOld, "DecodeInterleavedForMultiStreamOld"}, {2, D<&IHardwareOpusDecoder::DecodeInterleavedForMultiStreamOld>, "DecodeInterleavedForMultiStreamOld"},
{3, &IHardwareOpusDecoder::SetContextForMultiStream, "SetContextForMultiStream"}, {3, D<&IHardwareOpusDecoder::SetContextForMultiStream>, "SetContextForMultiStream"},
{4, &IHardwareOpusDecoder::DecodeInterleavedWithPerfOld, "DecodeInterleavedWithPerfOld"}, {4, D<&IHardwareOpusDecoder::DecodeInterleavedWithPerfOld>, "DecodeInterleavedWithPerfOld"},
{5, &IHardwareOpusDecoder::DecodeInterleavedForMultiStreamWithPerfOld, "DecodeInterleavedForMultiStreamWithPerfOld"}, {5, D<&IHardwareOpusDecoder::DecodeInterleavedForMultiStreamWithPerfOld>, "DecodeInterleavedForMultiStreamWithPerfOld"},
{6, &IHardwareOpusDecoder::DecodeInterleavedWithPerfAndResetOld, "DecodeInterleavedWithPerfAndResetOld"}, {6, D<&IHardwareOpusDecoder::DecodeInterleavedWithPerfAndResetOld>, "DecodeInterleavedWithPerfAndResetOld"},
{7, &IHardwareOpusDecoder::DecodeInterleavedForMultiStreamWithPerfAndResetOld, "DecodeInterleavedForMultiStreamWithPerfAndResetOld"}, {7, D<&IHardwareOpusDecoder::DecodeInterleavedForMultiStreamWithPerfAndResetOld>, "DecodeInterleavedForMultiStreamWithPerfAndResetOld"},
{8, &IHardwareOpusDecoder::DecodeInterleaved, "DecodeInterleaved"}, {8, D<&IHardwareOpusDecoder::DecodeInterleaved>, "DecodeInterleaved"},
{9, &IHardwareOpusDecoder::DecodeInterleavedForMultiStream, "DecodeInterleavedForMultiStream"}, {9, D<&IHardwareOpusDecoder::DecodeInterleavedForMultiStream>, "DecodeInterleavedForMultiStream"},
}; };
// clang-format on // clang-format on
@ -43,223 +43,103 @@ Result IHardwareOpusDecoder::Initialize(const OpusMultiStreamParametersEx& param
return impl->Initialize(params, transfer_memory, transfer_memory_size); return impl->Initialize(params, transfer_memory, transfer_memory_size);
} }
void IHardwareOpusDecoder::DecodeInterleavedOld(HLERequestContext& ctx) { Result IHardwareOpusDecoder::DecodeInterleavedOld(OutBuffer<BufferAttr_HipcMapAlias> out_pcm_data,
IPC::RequestParser rp{ctx}; Out<u32> out_data_size, Out<u32> out_sample_count,
InBuffer<BufferAttr_HipcMapAlias> opus_data) {
auto input_data{ctx.ReadBuffer(0)}; R_TRY(impl->DecodeInterleaved(out_data_size, nullptr, out_sample_count, opus_data, out_pcm_data,
output_data.resize_destructive(ctx.GetWriteBufferSize()); false));
LOG_DEBUG(Service_Audio, "bytes read {:#x} samples generated {}", *out_data_size,
u32 size{}; *out_sample_count);
u32 sample_count{}; R_SUCCEED();
auto result =
impl->DecodeInterleaved(&size, nullptr, &sample_count, input_data, output_data, false);
LOG_DEBUG(Service_Audio, "bytes read 0x{:X} samples generated {}", size, sample_count);
ctx.WriteBuffer(output_data);
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(result);
rb.Push(size);
rb.Push(sample_count);
} }
void IHardwareOpusDecoder::SetContext(HLERequestContext& ctx) { Result IHardwareOpusDecoder::SetContext(InBuffer<BufferAttr_HipcMapAlias> decoder_context) {
IPC::RequestParser rp{ctx};
LOG_DEBUG(Service_Audio, "called"); LOG_DEBUG(Service_Audio, "called");
R_RETURN(impl->SetContext(decoder_context));
auto input_data{ctx.ReadBuffer(0)};
auto result = impl->SetContext(input_data);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(result);
} }
void IHardwareOpusDecoder::DecodeInterleavedForMultiStreamOld(HLERequestContext& ctx) { Result IHardwareOpusDecoder::DecodeInterleavedForMultiStreamOld(
IPC::RequestParser rp{ctx}; OutBuffer<BufferAttr_HipcMapAlias> out_pcm_data, Out<u32> out_data_size,
Out<u32> out_sample_count, InBuffer<BufferAttr_HipcMapAlias> opus_data) {
auto input_data{ctx.ReadBuffer(0)}; R_TRY(impl->DecodeInterleavedForMultiStream(out_data_size, nullptr, out_sample_count, opus_data,
output_data.resize_destructive(ctx.GetWriteBufferSize()); out_pcm_data, false));
LOG_DEBUG(Service_Audio, "bytes read {:#x} samples generated {}", *out_data_size,
u32 size{}; *out_sample_count);
u32 sample_count{}; R_SUCCEED();
auto result = impl->DecodeInterleavedForMultiStream(&size, nullptr, &sample_count, input_data,
output_data, false);
LOG_DEBUG(Service_Audio, "bytes read 0x{:X} samples generated {}", size, sample_count);
ctx.WriteBuffer(output_data);
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(result);
rb.Push(size);
rb.Push(sample_count);
} }
void IHardwareOpusDecoder::SetContextForMultiStream(HLERequestContext& ctx) { Result IHardwareOpusDecoder::SetContextForMultiStream(
IPC::RequestParser rp{ctx}; InBuffer<BufferAttr_HipcMapAlias> decoder_context) {
LOG_DEBUG(Service_Audio, "called"); LOG_DEBUG(Service_Audio, "called");
R_RETURN(impl->SetContext(decoder_context));
auto input_data{ctx.ReadBuffer(0)};
auto result = impl->SetContext(input_data);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(result);
} }
void IHardwareOpusDecoder::DecodeInterleavedWithPerfOld(HLERequestContext& ctx) { Result IHardwareOpusDecoder::DecodeInterleavedWithPerfOld(
IPC::RequestParser rp{ctx}; OutBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_pcm_data,
Out<u32> out_data_size, Out<u32> out_sample_count, Out<u64> out_time_taken,
auto input_data{ctx.ReadBuffer(0)}; InBuffer<BufferAttr_HipcMapAlias> opus_data) {
output_data.resize_destructive(ctx.GetWriteBufferSize()); R_TRY(impl->DecodeInterleaved(out_data_size, out_time_taken, out_sample_count, opus_data,
out_pcm_data, false));
u32 size{}; LOG_DEBUG(Service_Audio, "bytes read {:#x} samples generated {} time taken {}", *out_data_size,
u32 sample_count{}; *out_sample_count, *out_time_taken);
u64 time_taken{}; R_SUCCEED();
auto result =
impl->DecodeInterleaved(&size, &time_taken, &sample_count, input_data, output_data, false);
LOG_DEBUG(Service_Audio, "bytes read 0x{:X} samples generated {} time taken {}", size,
sample_count, time_taken);
ctx.WriteBuffer(output_data);
IPC::ResponseBuilder rb{ctx, 6};
rb.Push(result);
rb.Push(size);
rb.Push(sample_count);
rb.Push(time_taken);
} }
void IHardwareOpusDecoder::DecodeInterleavedForMultiStreamWithPerfOld(HLERequestContext& ctx) { Result IHardwareOpusDecoder::DecodeInterleavedForMultiStreamWithPerfOld(
IPC::RequestParser rp{ctx}; OutBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_pcm_data,
Out<u32> out_data_size, Out<u32> out_sample_count, Out<u64> out_time_taken,
auto input_data{ctx.ReadBuffer(0)}; InBuffer<BufferAttr_HipcMapAlias> opus_data) {
output_data.resize_destructive(ctx.GetWriteBufferSize()); R_TRY(impl->DecodeInterleavedForMultiStream(out_data_size, out_time_taken, out_sample_count,
opus_data, out_pcm_data, false));
u32 size{}; LOG_DEBUG(Service_Audio, "bytes read {:#x} samples generated {} time taken {}", *out_data_size,
u32 sample_count{}; *out_sample_count, *out_time_taken);
u64 time_taken{}; R_SUCCEED();
auto result = impl->DecodeInterleavedForMultiStream(&size, &time_taken, &sample_count,
input_data, output_data, false);
LOG_DEBUG(Service_Audio, "bytes read 0x{:X} samples generated {} time taken {}", size,
sample_count, time_taken);
ctx.WriteBuffer(output_data);
IPC::ResponseBuilder rb{ctx, 6};
rb.Push(result);
rb.Push(size);
rb.Push(sample_count);
rb.Push(time_taken);
} }
void IHardwareOpusDecoder::DecodeInterleavedWithPerfAndResetOld(HLERequestContext& ctx) { Result IHardwareOpusDecoder::DecodeInterleavedWithPerfAndResetOld(
IPC::RequestParser rp{ctx}; OutBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_pcm_data,
Out<u32> out_data_size, Out<u32> out_sample_count, Out<u64> out_time_taken,
auto reset{rp.Pop<bool>()}; InBuffer<BufferAttr_HipcMapAlias> opus_data, bool reset) {
R_TRY(impl->DecodeInterleaved(out_data_size, out_time_taken, out_sample_count, opus_data,
auto input_data{ctx.ReadBuffer(0)}; out_pcm_data, reset));
output_data.resize_destructive(ctx.GetWriteBufferSize()); LOG_DEBUG(Service_Audio, "reset {} bytes read {:#x} samples generated {} time taken {}", reset,
*out_data_size, *out_sample_count, *out_time_taken);
u32 size{}; R_SUCCEED();
u32 sample_count{};
u64 time_taken{};
auto result =
impl->DecodeInterleaved(&size, &time_taken, &sample_count, input_data, output_data, reset);
LOG_DEBUG(Service_Audio, "reset {} bytes read 0x{:X} samples generated {} time taken {}", reset,
size, sample_count, time_taken);
ctx.WriteBuffer(output_data);
IPC::ResponseBuilder rb{ctx, 6};
rb.Push(result);
rb.Push(size);
rb.Push(sample_count);
rb.Push(time_taken);
} }
void IHardwareOpusDecoder::DecodeInterleavedForMultiStreamWithPerfAndResetOld( Result IHardwareOpusDecoder::DecodeInterleavedForMultiStreamWithPerfAndResetOld(
HLERequestContext& ctx) { OutBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_pcm_data,
IPC::RequestParser rp{ctx}; Out<u32> out_data_size, Out<u32> out_sample_count, Out<u64> out_time_taken,
InBuffer<BufferAttr_HipcMapAlias> opus_data, bool reset) {
auto reset{rp.Pop<bool>()}; R_TRY(impl->DecodeInterleavedForMultiStream(out_data_size, out_time_taken, out_sample_count,
opus_data, out_pcm_data, reset));
auto input_data{ctx.ReadBuffer(0)}; LOG_DEBUG(Service_Audio, "reset {} bytes read {:#x} samples generated {} time taken {}", reset,
output_data.resize_destructive(ctx.GetWriteBufferSize()); *out_data_size, *out_sample_count, *out_time_taken);
R_SUCCEED();
u32 size{};
u32 sample_count{};
u64 time_taken{};
auto result = impl->DecodeInterleavedForMultiStream(&size, &time_taken, &sample_count,
input_data, output_data, reset);
LOG_DEBUG(Service_Audio, "reset {} bytes read 0x{:X} samples generated {} time taken {}", reset,
size, sample_count, time_taken);
ctx.WriteBuffer(output_data);
IPC::ResponseBuilder rb{ctx, 6};
rb.Push(result);
rb.Push(size);
rb.Push(sample_count);
rb.Push(time_taken);
} }
void IHardwareOpusDecoder::DecodeInterleaved(HLERequestContext& ctx) { Result IHardwareOpusDecoder::DecodeInterleaved(
IPC::RequestParser rp{ctx}; OutBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_pcm_data,
Out<u32> out_data_size, Out<u32> out_sample_count, Out<u64> out_time_taken,
auto reset{rp.Pop<bool>()}; InBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> opus_data,
bool reset) {
auto input_data{ctx.ReadBuffer(0)}; R_TRY(impl->DecodeInterleaved(out_data_size, out_time_taken, out_sample_count, opus_data,
output_data.resize_destructive(ctx.GetWriteBufferSize()); out_pcm_data, reset));
LOG_DEBUG(Service_Audio, "reset {} bytes read {:#x} samples generated {} time taken {}", reset,
u32 size{}; *out_data_size, *out_sample_count, *out_time_taken);
u32 sample_count{}; R_SUCCEED();
u64 time_taken{};
auto result =
impl->DecodeInterleaved(&size, &time_taken, &sample_count, input_data, output_data, reset);
LOG_DEBUG(Service_Audio, "reset {} bytes read 0x{:X} samples generated {} time taken {}", reset,
size, sample_count, time_taken);
ctx.WriteBuffer(output_data);
IPC::ResponseBuilder rb{ctx, 6};
rb.Push(result);
rb.Push(size);
rb.Push(sample_count);
rb.Push(time_taken);
} }
void IHardwareOpusDecoder::DecodeInterleavedForMultiStream(HLERequestContext& ctx) { Result IHardwareOpusDecoder::DecodeInterleavedForMultiStream(
IPC::RequestParser rp{ctx}; OutBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_pcm_data,
Out<u32> out_data_size, Out<u32> out_sample_count, Out<u64> out_time_taken,
auto reset{rp.Pop<bool>()}; InBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> opus_data,
bool reset) {
auto input_data{ctx.ReadBuffer(0)}; R_TRY(impl->DecodeInterleavedForMultiStream(out_data_size, out_time_taken, out_sample_count,
output_data.resize_destructive(ctx.GetWriteBufferSize()); opus_data, out_pcm_data, reset));
LOG_DEBUG(Service_Audio, "reset {} bytes read {:#x} samples generated {} time taken {}", reset,
u32 size{}; *out_data_size, *out_sample_count, *out_time_taken);
u32 sample_count{}; R_SUCCEED();
u64 time_taken{};
auto result = impl->DecodeInterleavedForMultiStream(&size, &time_taken, &sample_count,
input_data, output_data, reset);
LOG_DEBUG(Service_Audio, "reset {} bytes read 0x{:X} samples generated {} time taken {}", reset,
size, sample_count, time_taken);
ctx.WriteBuffer(output_data);
IPC::ResponseBuilder rb{ctx, 6};
rb.Push(result);
rb.Push(size);
rb.Push(sample_count);
rb.Push(time_taken);
} }
} // namespace Service::Audio } // namespace Service::Audio

View file

@ -4,6 +4,7 @@
#pragma once #pragma once
#include "audio_core/opus/decoder.h" #include "audio_core/opus/decoder.h"
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/service.h" #include "core/hle/service/service.h"
namespace Service::Audio { namespace Service::Audio {
@ -20,16 +21,40 @@ public:
Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size); Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size);
private: private:
void DecodeInterleavedOld(HLERequestContext& ctx); Result DecodeInterleavedOld(OutBuffer<BufferAttr_HipcMapAlias> out_pcm_data,
void SetContext(HLERequestContext& ctx); Out<u32> out_data_size, Out<u32> out_sample_count,
void DecodeInterleavedForMultiStreamOld(HLERequestContext& ctx); InBuffer<BufferAttr_HipcMapAlias> opus_data);
void SetContextForMultiStream(HLERequestContext& ctx); Result SetContext(InBuffer<BufferAttr_HipcMapAlias> decoder_context);
void DecodeInterleavedWithPerfOld(HLERequestContext& ctx); Result DecodeInterleavedForMultiStreamOld(OutBuffer<BufferAttr_HipcMapAlias> out_pcm_data,
void DecodeInterleavedForMultiStreamWithPerfOld(HLERequestContext& ctx); Out<u32> out_data_size, Out<u32> out_sample_count,
void DecodeInterleavedWithPerfAndResetOld(HLERequestContext& ctx); InBuffer<BufferAttr_HipcMapAlias> opus_data);
void DecodeInterleavedForMultiStreamWithPerfAndResetOld(HLERequestContext& ctx); Result SetContextForMultiStream(InBuffer<BufferAttr_HipcMapAlias> decoder_context);
void DecodeInterleaved(HLERequestContext& ctx); Result DecodeInterleavedWithPerfOld(
void DecodeInterleavedForMultiStream(HLERequestContext& ctx); OutBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_pcm_data,
Out<u32> out_data_size, Out<u32> out_sample_count, Out<u64> out_time_taken,
InBuffer<BufferAttr_HipcMapAlias> opus_data);
Result DecodeInterleavedForMultiStreamWithPerfOld(
OutBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_pcm_data,
Out<u32> out_data_size, Out<u32> out_sample_count, Out<u64> out_time_taken,
InBuffer<BufferAttr_HipcMapAlias> opus_data);
Result DecodeInterleavedWithPerfAndResetOld(
OutBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_pcm_data,
Out<u32> out_data_size, Out<u32> out_sample_count, Out<u64> out_time_taken,
InBuffer<BufferAttr_HipcMapAlias> opus_data, bool reset);
Result DecodeInterleavedForMultiStreamWithPerfAndResetOld(
OutBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_pcm_data,
Out<u32> out_data_size, Out<u32> out_sample_count, Out<u64> out_time_taken,
InBuffer<BufferAttr_HipcMapAlias> opus_data, bool reset);
Result DecodeInterleaved(
OutBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_pcm_data,
Out<u32> out_data_size, Out<u32> out_sample_count, Out<u64> out_time_taken,
InBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> opus_data,
bool reset);
Result DecodeInterleavedForMultiStream(
OutBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_pcm_data,
Out<u32> out_data_size, Out<u32> out_sample_count, Out<u64> out_time_taken,
InBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> opus_data,
bool reset);
std::unique_ptr<AudioCore::OpusDecoder::OpusDecoder> impl; std::unique_ptr<AudioCore::OpusDecoder::OpusDecoder> impl;
Common::ScratchBuffer<u8> output_data; Common::ScratchBuffer<u8> output_data;