Compare commits

..

1 Commits

Author SHA1 Message Date
xbzk f744bcf9e1 [opus] proper limit and error of opus decoder instances 2026-09-09 23:28:23 -03:00
9 changed files with 59 additions and 28 deletions
+16
View File
@@ -8,6 +8,7 @@
#include "audio_core/opus/hardware_opus.h" #include "audio_core/opus/hardware_opus.h"
#include "audio_core/opus/parameters.h" #include "audio_core/opus/parameters.h"
#include "common/alignment.h" #include "common/alignment.h"
#include "common/scope_exit.h"
#include "common/swap.h" #include "common/swap.h"
#include "core/core.h" #include "core/core.h"
@@ -28,10 +29,18 @@ OpusDecoder::OpusDecoder(Core::System& system_, HardwareOpus& hardware_opus_)
OpusDecoder::~OpusDecoder() { OpusDecoder::~OpusDecoder() {
if (decode_object_initialized) { if (decode_object_initialized) {
hardware_opus.ShutdownDecodeObject(shared_buffer.data(), shared_buffer.size()); 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) { 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}; auto frame_size{params.use_large_frame_size ? 5760 : 1920};
shared_buffer.resize(transfer_memory_size); shared_buffer.resize(transfer_memory_size);
shared_memory_mapped = true; 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) { 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}; auto frame_size{params.use_large_frame_size ? 5760 : 1920};
shared_buffer.resize(transfer_memory_size, 0); shared_buffer.resize(transfer_memory_size, 0);
shared_memory_mapped = true; shared_memory_mapped = true;
+20
View File
@@ -4,6 +4,7 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include <algorithm>
#include <array> #include <array>
#include "audio_core/audio_core.h" #include "audio_core/audio_core.h"
@@ -45,6 +46,25 @@ HardwareOpus::HardwareOpus(Core::System& system_)
opus_decoder.SetSharedMemory(shared_memory); 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) { u32 HardwareOpus::GetWorkBufferSize(u32 channel) {
if (!opus_decoder.IsRunning()) { if (!opus_decoder.IsRunning()) {
return 0; return 0;
+5
View File
@@ -3,6 +3,7 @@
#pragma once #pragma once
#include <array>
#include <mutex> #include <mutex>
#include <opus.h> #include <opus.h>
@@ -12,9 +13,12 @@
#include "core/hle/service/audio/errors.h" #include "core/hle/service/audio/errors.h"
namespace AudioCore::OpusDecoder { namespace AudioCore::OpusDecoder {
class OpusDecoder;
class HardwareOpus { class HardwareOpus {
public: public:
HardwareOpus(Core::System& system); HardwareOpus(Core::System& system);
Result RegisterDecoder(OpusDecoder* decoder);
void UnregisterDecoder(OpusDecoder* decoder);
u32 GetWorkBufferSize(u32 channel); u32 GetWorkBufferSize(u32 channel);
u32 GetWorkBufferSizeForMultiStream(u32 total_stream_count, u32 stereo_stream_count); u32 GetWorkBufferSizeForMultiStream(u32 total_stream_count, u32 stereo_stream_count);
@@ -39,6 +43,7 @@ public:
private: private:
Core::System& system; Core::System& system;
std::mutex mutex; std::mutex mutex;
std::array<OpusDecoder*, 24> decoders{};
ADSP::OpusDecoder::OpusDecoder& opus_decoder; ADSP::OpusDecoder::OpusDecoder& opus_decoder;
ADSP::OpusDecoder::SharedMemory shared_memory; ADSP::OpusDecoder::SharedMemory shared_memory;
}; };
+1
View File
@@ -33,6 +33,7 @@ constexpr Result ResultLibOpusInternalError{ErrorModule::HwOpus, 4};
constexpr Result ResultBufferTooSmall{ErrorModule::HwOpus, 3}; constexpr Result ResultBufferTooSmall{ErrorModule::HwOpus, 3};
constexpr Result ResultLibOpusBadArg{ErrorModule::HwOpus, 2}; constexpr Result ResultLibOpusBadArg{ErrorModule::HwOpus, 2};
constexpr Result ResultInvalidOpusDSPReturnCode{ErrorModule::HwOpus, 259}; constexpr Result ResultInvalidOpusDSPReturnCode{ErrorModule::HwOpus, 259};
constexpr Result ResultOutOfOpusDecoders{ErrorModule::HwOpus, 385};
constexpr Result ResultInvalidOpusSampleRate{ErrorModule::HwOpus, 1001}; constexpr Result ResultInvalidOpusSampleRate{ErrorModule::HwOpus, 1001};
constexpr Result ResultInvalidOpusChannelCount{ErrorModule::HwOpus, 1002}; constexpr Result ResultInvalidOpusChannelCount{ErrorModule::HwOpus, 1002};
+8 -9
View File
@@ -4,16 +4,17 @@
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include <chrono> #include <thread>
#include <fmt/ranges.h> #include <fmt/ranges.h>
#include <math.h> #include <math.h>
#include "common/param_package.h" #include "common/param_package.h"
#include "common/settings.h" #include "common/settings.h"
#include "common/steady_clock.h" #include "common/thread.h"
#include "input_common/drivers/mouse.h" #include "input_common/drivers/mouse.h"
namespace InputCommon { namespace InputCommon {
constexpr int update_time = 10;
constexpr float default_panning_sensitivity = 0.0010f; constexpr float default_panning_sensitivity = 0.0010f;
constexpr float default_stick_sensitivity = 0.0006f; constexpr float default_stick_sensitivity = 0.0006f;
constexpr float default_deadzone_counterweight = 0.01f; constexpr float default_deadzone_counterweight = 0.01f;
@@ -73,7 +74,7 @@ Mouse::Mouse(std::string input_engine_) : InputEngine(std::move(input_engine_))
last_motion_change = {}; last_motion_change = {};
} }
void Mouse::UpdateStickInput(Common::SteadyClock::time_point timestamp) { void Mouse::UpdateStickInput() {
if (!IsMousePanningEnabled()) { if (!IsMousePanningEnabled()) {
return; return;
} }
@@ -99,7 +100,7 @@ void Mouse::UpdateStickInput(Common::SteadyClock::time_point timestamp) {
last_mouse_change *= clamped_decay; last_mouse_change *= clamped_decay;
} }
void Mouse::UpdateMotionInput(Common::SteadyClock::time_point timestamp) { void Mouse::UpdateMotionInput() {
const float sensitivity = const float sensitivity =
IsMousePanningEnabled() ? default_motion_panning_sensitivity : default_motion_sensitivity; IsMousePanningEnabled() ? default_motion_panning_sensitivity : default_motion_sensitivity;
@@ -120,7 +121,7 @@ void Mouse::UpdateMotionInput(Common::SteadyClock::time_point timestamp) {
.accel_x = 0, .accel_x = 0,
.accel_y = 0, .accel_y = 0,
.accel_z = 0, .accel_z = 0,
.delta_timestamp = u64(std::chrono::duration_cast<std::chrono::microseconds>(timestamp - last_notify_timestamp).count()), .delta_timestamp = update_time * 1000,
}; };
if (IsMousePanningEnabled()) { if (IsMousePanningEnabled()) {
@@ -169,10 +170,8 @@ void Mouse::Move(int x, int y, int center_x, int center_y) {
} }
void Mouse::NotifyChanged() { void Mouse::NotifyChanged() {
auto const timestamp = Common::SteadyClock::Now(); UpdateStickInput();
UpdateStickInput(timestamp); UpdateMotionInput();
UpdateMotionInput(timestamp);
last_notify_timestamp = Common::SteadyClock::Now();
} }
void Mouse::MouseMove(f32 touch_x, f32 touch_y) { void Mouse::MouseMove(f32 touch_x, f32 touch_y) {
+2 -5
View File
@@ -7,9 +7,7 @@
#pragma once #pragma once
#include <thread> #include <thread>
#include <chrono>
#include "common/steady_clock.h"
#include "common/polyfill_thread.h" #include "common/polyfill_thread.h"
#include "common/vector_math.h" #include "common/vector_math.h"
#include "input_common/input_engine.h" #include "input_common/input_engine.h"
@@ -103,8 +101,8 @@ public:
Common::Input::ButtonNames GetUIName(const Common::ParamPackage& params) const override; Common::Input::ButtonNames GetUIName(const Common::ParamPackage& params) const override;
private: private:
void UpdateStickInput(Common::SteadyClock::time_point timestamp); void UpdateStickInput();
void UpdateMotionInput(Common::SteadyClock::time_point timestamp); void UpdateMotionInput();
bool IsMousePanningEnabled(); bool IsMousePanningEnabled();
Common::Input::ButtonNames GetUIButtonName(const Common::ParamPackage& params) const; Common::Input::ButtonNames GetUIButtonName(const Common::ParamPackage& params) const;
@@ -114,7 +112,6 @@ private:
Common::Vec<float, 2> last_mouse_change; Common::Vec<float, 2> last_mouse_change;
Common::Vec<float, 3> last_motion_change; Common::Vec<float, 3> last_motion_change;
Common::Vec<int, 2> wheel_position; Common::Vec<int, 2> wheel_position;
Common::SteadyClock::time_point last_notify_timestamp{};
bool button_pressed = false; bool button_pressed = false;
}; };
+7 -5
View File
@@ -538,7 +538,6 @@ void GRenderWindow::mouseReleaseEvent(QMouseEvent* event) {
} }
void GRenderWindow::ConstrainMouse() { void GRenderWindow::ConstrainMouse() {
input_subsystem->GetMouse()->NotifyChanged(); // required to reset mouse once it's no longer moved
if (QtCommon::emu_thread == nullptr || !Settings::values.mouse_panning) { if (QtCommon::emu_thread == nullptr || !Settings::values.mouse_panning) {
mouse_constrain_timer.stop(); mouse_constrain_timer.stop();
return; return;
@@ -553,12 +552,15 @@ void GRenderWindow::ConstrainMouse() {
const auto pos = mapFromGlobal(QCursor::pos()); const auto pos = mapFromGlobal(QCursor::pos());
const int new_pos_x = std::clamp(pos.x(), 0, width()); const int new_pos_x = std::clamp(pos.x(), 0, width());
const int new_pos_y = std::clamp(pos.y(), 0, height()); const int new_pos_y = std::clamp(pos.y(), 0, height());
QCursor::setPos(mapToGlobal(QPoint{new_pos_x, new_pos_y})); QCursor::setPos(mapToGlobal(QPoint{new_pos_x, new_pos_y}));
} else { return;
const int center_x = width() / 2;
const int center_y = height() / 2;
QCursor::setPos(mapToGlobal(QPoint{center_x, center_y}));
} }
const int center_x = width() / 2;
const int center_y = height() / 2;
QCursor::setPos(mapToGlobal(QPoint{center_x, center_y}));
} }
void GRenderWindow::wheelEvent(QWheelEvent* event) { void GRenderWindow::wheelEvent(QWheelEvent* event) {
@@ -37,16 +37,10 @@ EmuWindow_SDL3::EmuWindow_SDL3(InputCommon::InputSubsystem* input_subsystem_, Co
SDL_SetWindowTitle(this_->render_window, title.c_str()); SDL_SetWindowTitle(this_->render_window, title.c_str());
return 2000; return 2000;
}, this); }, this);
mouse_timer = SDL_AddTimer(100, [](void *userdata, SDL_TimerID, Uint32) -> Uint32 {
auto* this_ = (EmuWindow_SDL3*)userdata;
this_->input_subsystem->GetMouse()->NotifyChanged();
return 100;
}, this);
} }
EmuWindow_SDL3::~EmuWindow_SDL3() { EmuWindow_SDL3::~EmuWindow_SDL3() {
SDL_RemoveTimer(titlebar_timer); SDL_RemoveTimer(titlebar_timer);
SDL_RemoveTimer(mouse_timer);
system.HIDCore().UnloadInputDevices(); system.HIDCore().UnloadInputDevices();
input_subsystem->Shutdown(); input_subsystem->Shutdown();
SDL_Quit(); SDL_Quit();
@@ -84,9 +84,6 @@ protected:
/// Periodic changer of titlebar (independent of event loop) /// Periodic changer of titlebar (independent of event loop)
SDL_TimerID titlebar_timer; SDL_TimerID titlebar_timer;
// Mouse resetter once it
SDL_TimerID mouse_timer;
/// Is the window still open? /// Is the window still open?
bool is_open = true; bool is_open = true;