#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) \
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 !=
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;
}
#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 {
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
--- /dev/null
+// 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
--- /dev/null
+// 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_