[WebRTC] Boost Pulseaudio during audio playback 10/324910/3
authorJakub Gajownik <j.gajownik2@samsung.com>
Fri, 17 Jan 2025 15:56:49 +0000 (16:56 +0100)
committerBot Blink <blinkbot@samsung.com>
Thu, 29 May 2025 11:00:38 +0000 (11:00 +0000)
On Tizen TV pulseaudio standard priority is normal
(i.e non-realtime), so this can dramatically decrease audio
playback stability.
This CL fixes that by manually send appropriate message
using dbus interface when playback through audio stream
is started.

Bug: https://jira-eu.sec.samsung.net/browse/VDGAME-680
Change-Id: I6db125cf4081bc408d15dbfd29bddd58b8ae8c20
Signed-off-by: Jakub Gajownik <j.gajownik2@samsung.com>
tizen_src/chromium_impl/media/audio/tizen/capi_audio_output.cc
tizen_src/chromium_impl/media/audio/tizen/capi_audio_output.h
tizen_src/chromium_impl/media/audio/tizen/scoped_pulse_audio_booster.cc [new file with mode: 0644]
tizen_src/chromium_impl/media/audio/tizen/scoped_pulse_audio_booster.h [new file with mode: 0644]
tizen_src/chromium_impl/media/media_efl.gni

index 94d1a0cfe70d524dae318644d2406daa9b8e76fd..c7e3ad0f05520bb6ea1cb1092fd535a622045ae9 100644 (file)
@@ -5,6 +5,7 @@
 #include "media/audio/tizen/capi_audio_output.h"
 
 #include <audio_io.h>
+#include <memory>
 
 #include "base/functional/bind.h"
 #include "base/logging.h"
 #include "tizen_src/ewk/efl_integration/ewk_privilege_checker.h"
 #endif
 
+#if defined(TIZEN_TV_UPSTREAM_MULTIMEDIA)
+#include "media/audio/tizen/scoped_pulse_audio_booster.h"
+#include "media/base/media_switches.h"
+#endif
+
 namespace {
 
 #define ENUM_CASE(x) \
@@ -150,6 +156,12 @@ void CapiAudioOutputStream::Start(AudioSourceCallback* callback) {
   DCHECK(audio_out_);
   source_callback_ = callback;
 
+#if defined(TIZEN_TV_UPSTREAM_MULTIMEDIA)
+  if (IsUpstreamArchitectureEnabled()) {
+    scoped_audio_booster_ = std::make_unique<ScopedPulseAudioBooster>();
+  }
+#endif
+
   LOG(INFO) << __func__ << " : state_ : " << static_cast<InternalState>(state_);
 
   if (AUDIO_IO_ERROR_NONE !=
@@ -182,6 +194,12 @@ void CapiAudioOutputStream::Stop() {
     LOG(WARNING) << "Cannot unset audio output cb";
   }
 
+#if defined(TIZEN_TV_UPSTREAM_MULTIMEDIA)
+  if (IsUpstreamArchitectureEnabled()) {
+    scoped_audio_booster_.reset();
+  }
+#endif
+
   state_ = media::kIsStopped;
   source_callback_ = NULL;
 }
index ea889ea4d606f64e9c22a54c4d86bebfca09cb2b..d496fae423560cf2b296856bffc245384d941734 100644 (file)
@@ -8,6 +8,8 @@
 #ifndef MEDIA_AUDIO_TIZEN_CAPI_AUDIO_OUTPUT_H_
 #define MEDIA_AUDIO_TIZEN_CAPI_AUDIO_OUTPUT_H_
 
+#include <memory>
+
 #include <audio_io.h>
 #include <sound_manager.h>
 
 
 namespace media {
 
+#if defined(TIZEN_TV_UPSTREAM_MULTIMEDIA)
+class ScopedPulseAudioBooster;
+#endif
+
 class AudioManagerBase;
 
 class CapiAudioOutputStream : public AudioOutputStream {
@@ -66,6 +72,10 @@ class CapiAudioOutputStream : public AudioOutputStream {
   media::InternalState state_;
   AudioSourceCallback* source_callback_;
   std::unique_ptr<AudioBus> audio_bus_;
+
+#if defined(TIZEN_TV_UPSTREAM_MULTIMEDIA)
+  std::unique_ptr<ScopedPulseAudioBooster> scoped_audio_booster_;
+#endif
 };
 
 }  // namespace media
diff --git a/tizen_src/chromium_impl/media/audio/tizen/scoped_pulse_audio_booster.cc b/tizen_src/chromium_impl/media/audio/tizen/scoped_pulse_audio_booster.cc
new file mode 100644 (file)
index 0000000..d810f80
--- /dev/null
@@ -0,0 +1,93 @@
+// Copyright 2024 Samsung Electronics Inc. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "media/audio/tizen/scoped_pulse_audio_booster.h"
+
+#include <memory>
+#include <utility>
+
+#include "base/logging.h"
+#include "dbus/bus.h"
+#include "dbus/error.h"
+#include "dbus/message.h"
+#include "dbus/object_proxy.h"
+
+namespace media {
+namespace {
+
+constexpr const char kEnablePulseBoosting[] = "ApplyBoostingByCloudGame";
+constexpr const char kDisablePulseBoosting[] = "ClearBoostingByCloudGame";
+constexpr const char kBusName[] = "org.pulseaudio.Server";
+constexpr const char kObjectPath[] = "/org/pulseaudio/TizenTV";
+constexpr const char kInterfaceName[] = "org.pulseaudio.TizenTV";
+
+bool PulseAudioDbusCall(const char* function_name) {
+  // Sets up the D-Bus connection.
+  dbus::Bus::Options bus_options;
+  bus_options.bus_type = dbus::Bus::SYSTEM;
+  bus_options.connection_type = dbus::Bus::SHARED;
+  auto bus = base::MakeRefCounted<dbus::Bus>(bus_options);
+  auto* dbus_proxy =
+      bus->GetObjectProxy(kBusName, dbus::ObjectPath(kObjectPath));
+
+  dbus::MethodCall method{kInterfaceName, function_name};
+
+  std::unique_ptr<dbus::Response> response;
+  dbus::Error error;
+  auto result = dbus_proxy->CallMethodAndBlock(
+      &method, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT);
+  if (result.has_value()) {
+    response = std::move(result.value());
+  } else {
+    error = std::move(result.error());
+  }
+
+  if (!response) {
+    LOG(WARNING) << function_name << " failed. "
+                 << (error.IsValid() ? error.message() : "Unknown error");
+    return false;
+  }
+
+  return true;
+}
+
+}  // namespace
+
+std::atomic_size_t ScopedPulseAudioBooster::active_instances_{0};
+
+ScopedPulseAudioBooster::ScopedPulseAudioBooster() {
+  const auto prev_active = active_instances_.fetch_add(1);
+  if (prev_active == 0) {
+    StartBoosting();
+  }
+}
+
+ScopedPulseAudioBooster::~ScopedPulseAudioBooster() {
+  const auto prev_active = active_instances_.fetch_sub(1);
+  if (prev_active == 1) {
+    StopBoosting();
+  }
+}
+
+void ScopedPulseAudioBooster::StartBoosting() {
+  LOG(INFO) << "PulseAudio start boosting requested";
+  auto result = PulseAudioDbusCall(kEnablePulseBoosting);
+  if (result) {
+    LOG(INFO) << "Successfully requested to boost PulseAudio";
+  } else {
+    LOG(WARNING) << "Failed to request to boost PulseAudio";
+  }
+}
+
+void ScopedPulseAudioBooster::StopBoosting() {
+  LOG(INFO) << "PulseAudio stop boosting requested";
+  auto result = PulseAudioDbusCall(kDisablePulseBoosting);
+  if (result) {
+    LOG(INFO) << "Successfully requested to stop boosting PulseAudio";
+  } else {
+    LOG(WARNING) << "Failed to request to stop boosting PulseAudio";
+  }
+}
+
+}  // namespace media
diff --git a/tizen_src/chromium_impl/media/audio/tizen/scoped_pulse_audio_booster.h b/tizen_src/chromium_impl/media/audio/tizen/scoped_pulse_audio_booster.h
new file mode 100644 (file)
index 0000000..bd6b9f1
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright 2024 Samsung Electronics Inc. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef TIZEN_SRC_CHROMIUM_IMPL_MEDIA_AUDIO_TIZEN_SCOPED_PULSE_AUDIO_BOOSTER_H_
+#define TIZEN_SRC_CHROMIUM_IMPL_MEDIA_AUDIO_TIZEN_SCOPED_PULSE_AUDIO_BOOSTER_H_
+
+#include <atomic>
+
+namespace media {
+
+class ScopedPulseAudioBooster {
+ public:
+  ScopedPulseAudioBooster();
+  ~ScopedPulseAudioBooster();
+
+  ScopedPulseAudioBooster(const ScopedPulseAudioBooster&) = delete;
+  ScopedPulseAudioBooster& operator=(const ScopedPulseAudioBooster&) = delete;
+
+ private:
+  void StartBoosting();
+  void StopBoosting();
+
+  static std::atomic_size_t active_instances_;
+};
+
+}  // namespace media
+
+#endif  // TIZEN_SRC_CHROMIUM_IMPL_MEDIA_AUDIO_TIZEN_SCOPED_PULSE_AUDIO_BOOSTER_H_
index bb235c7019c04c746583cf55e88407e84361035e..fa3ce4868106cd5620b90ccbf9feddaa2a6c5d72 100644 (file)
@@ -216,6 +216,16 @@ if (tizen_audio_io) {
     ]
   }
 
+  if (tizen_tv_upstream_multimedia) {
+    external_media_efl_audio_io_sources += [
+      "//tizen_src/chromium_impl/media/audio/tizen/scoped_pulse_audio_booster.h",
+      "//tizen_src/chromium_impl/media/audio/tizen/scoped_pulse_audio_booster.cc",
+    ]
+    external_media_efl_audio_io_deps += [
+      "//dbus",
+    ]
+  }
+
   if (tizen_tv_use_mch_pcm) {
     external_media_efl_audio_io_config += [
       "//tizen_src/build:tizen-tv-resource-manager-config",