From f744bcf9e1c366d274c297a603af9fd8f6b78b96 Mon Sep 17 00:00:00 2001 From: xbzk Date: Wed, 9 Sep 2026 23:22:54 -0300 Subject: [PATCH] [opus] proper limit and error of opus decoder instances --- src/audio_core/opus/decoder.cpp | 16 ++++++++++++++++ src/audio_core/opus/hardware_opus.cpp | 20 ++++++++++++++++++++ src/audio_core/opus/hardware_opus.h | 5 +++++ src/core/hle/service/audio/errors.h | 1 + 4 files changed, 42 insertions(+) diff --git a/src/audio_core/opus/decoder.cpp b/src/audio_core/opus/decoder.cpp index e3a8fe1bfa..1c13cb60e9 100644 --- a/src/audio_core/opus/decoder.cpp +++ b/src/audio_core/opus/decoder.cpp @@ -8,6 +8,7 @@ #include "audio_core/opus/hardware_opus.h" #include "audio_core/opus/parameters.h" #include "common/alignment.h" +#include "common/scope_exit.h" #include "common/swap.h" #include "core/core.h" @@ -28,10 +29,18 @@ OpusDecoder::OpusDecoder(Core::System& system_, HardwareOpus& hardware_opus_) OpusDecoder::~OpusDecoder() { if (decode_object_initialized) { hardware_opus.ShutdownDecodeObject(shared_buffer.data(), shared_buffer.size()); + hardware_opus.UnregisterDecoder(this); } } Result OpusDecoder::Initialize(const OpusParametersEx& params, Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size) { + R_TRY(hardware_opus.RegisterDecoder(this)); + SCOPE_EXIT { + if (!decode_object_initialized) { + hardware_opus.UnregisterDecoder(this); + } + }; + auto frame_size{params.use_large_frame_size ? 5760 : 1920}; shared_buffer.resize(transfer_memory_size); shared_memory_mapped = true; @@ -61,6 +70,13 @@ Result OpusDecoder::Initialize(const OpusParametersEx& params, Kernel::KTransfer } Result OpusDecoder::Initialize(const OpusMultiStreamParametersEx& params, Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size) { + R_TRY(hardware_opus.RegisterDecoder(this)); + SCOPE_EXIT { + if (!decode_object_initialized) { + hardware_opus.UnregisterDecoder(this); + } + }; + auto frame_size{params.use_large_frame_size ? 5760 : 1920}; shared_buffer.resize(transfer_memory_size, 0); shared_memory_mapped = true; diff --git a/src/audio_core/opus/hardware_opus.cpp b/src/audio_core/opus/hardware_opus.cpp index 0037a3e503..04591c10b6 100644 --- a/src/audio_core/opus/hardware_opus.cpp +++ b/src/audio_core/opus/hardware_opus.cpp @@ -4,6 +4,7 @@ // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include #include #include "audio_core/audio_core.h" @@ -45,6 +46,25 @@ HardwareOpus::HardwareOpus(Core::System& system_) opus_decoder.SetSharedMemory(shared_memory); } +Result HardwareOpus::RegisterDecoder(OpusDecoder* decoder) { + std::scoped_lock l{mutex}; + const auto slot = std::ranges::find(decoders, nullptr); + if (slot == decoders.end()) { + R_THROW(ResultOutOfOpusDecoders); + } + *slot = decoder; + R_SUCCEED(); +} + +void HardwareOpus::UnregisterDecoder(OpusDecoder* decoder) { + std::scoped_lock l{mutex}; + const auto slot = std::ranges::find(decoders, decoder); + if (slot == decoders.end()) { + return; + } + *slot = nullptr; +} + u32 HardwareOpus::GetWorkBufferSize(u32 channel) { if (!opus_decoder.IsRunning()) { return 0; diff --git a/src/audio_core/opus/hardware_opus.h b/src/audio_core/opus/hardware_opus.h index caa7468401..f8d0d67a5f 100644 --- a/src/audio_core/opus/hardware_opus.h +++ b/src/audio_core/opus/hardware_opus.h @@ -3,6 +3,7 @@ #pragma once +#include #include #include @@ -12,9 +13,12 @@ #include "core/hle/service/audio/errors.h" namespace AudioCore::OpusDecoder { +class OpusDecoder; class HardwareOpus { public: HardwareOpus(Core::System& system); + Result RegisterDecoder(OpusDecoder* decoder); + void UnregisterDecoder(OpusDecoder* decoder); u32 GetWorkBufferSize(u32 channel); u32 GetWorkBufferSizeForMultiStream(u32 total_stream_count, u32 stereo_stream_count); @@ -39,6 +43,7 @@ public: private: Core::System& system; std::mutex mutex; + std::array decoders{}; ADSP::OpusDecoder::OpusDecoder& opus_decoder; ADSP::OpusDecoder::SharedMemory shared_memory; }; diff --git a/src/core/hle/service/audio/errors.h b/src/core/hle/service/audio/errors.h index 8062820de3..c23244c63f 100644 --- a/src/core/hle/service/audio/errors.h +++ b/src/core/hle/service/audio/errors.h @@ -33,6 +33,7 @@ constexpr Result ResultLibOpusInternalError{ErrorModule::HwOpus, 4}; constexpr Result ResultBufferTooSmall{ErrorModule::HwOpus, 3}; constexpr Result ResultLibOpusBadArg{ErrorModule::HwOpus, 2}; constexpr Result ResultInvalidOpusDSPReturnCode{ErrorModule::HwOpus, 259}; +constexpr Result ResultOutOfOpusDecoders{ErrorModule::HwOpus, 385}; constexpr Result ResultInvalidOpusSampleRate{ErrorModule::HwOpus, 1001}; constexpr Result ResultInvalidOpusChannelCount{ErrorModule::HwOpus, 1002};