From 41f5b77e10c1b66d537c8ac0288c4b477a199f86 Mon Sep 17 00:00:00 2001 From: Niek van der Maas Date: Thu, 3 Dec 2020 11:18:32 +0100 Subject: [PATCH] Apply PR 1034 --- android/audio/audio_hw.cpp | 8 ++++++++ src/anbox/audio/server.cpp | 9 ++++++--- src/anbox/platform/base_platform.h | 3 ++- src/anbox/platform/null/platform.cpp | 3 ++- src/anbox/platform/null/platform.h | 2 +- src/anbox/platform/sdl/audio_sink.cpp | 22 +++++++++++++++++++--- src/anbox/platform/sdl/audio_sink.h | 4 +++- src/anbox/platform/sdl/platform.cpp | 4 ++-- src/anbox/platform/sdl/platform.h | 2 +- 9 files changed, 44 insertions(+), 13 deletions(-) diff --git a/android/audio/audio_hw.cpp b/android/audio/audio_hw.cpp index f44e73826..39b845669 100644 --- a/android/audio/audio_hw.cpp +++ b/android/audio/audio_hw.cpp @@ -180,6 +180,14 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer, pthread_mutex_lock(&adev->lock); if (out->fd >= 0) bytes = write(out->fd, buffer, bytes); + + // wait until session writes the data we sent, + // this will block if sink queue is full, + // acting as synchronization to time audio + int64_t arrived_us; + read(out->fd, &arrived_us, sizeof(arrived_us)); + (void) arrived_us; + pthread_mutex_unlock(&adev->lock); return bytes; } diff --git a/src/anbox/audio/server.cpp b/src/anbox/audio/server.cpp index 716c9e651..72e8f4ead 100644 --- a/src/anbox/audio/server.cpp +++ b/src/anbox/audio/server.cpp @@ -31,8 +31,10 @@ using namespace std::placeholders; namespace { class AudioForwarder : public anbox::network::MessageProcessor { public: - AudioForwarder(const std::shared_ptr &sink) : - sink_(sink) { + AudioForwarder(const std::shared_ptr &sink, + const std::shared_ptr &messenger) : + sink_(sink), + messenger_(messenger) { } bool process_data(const std::vector &data) override { @@ -42,6 +44,7 @@ class AudioForwarder : public anbox::network::MessageProcessor { private: std::shared_ptr sink_; + std::shared_ptr messenger_; }; } @@ -80,7 +83,7 @@ void Server::create_connection_for(std::shared_ptr(platform_->create_audio_sink()); + processor = std::make_shared(platform_->create_audio_sink(messenger), messenger); break; case ClientInfo::Type::Recording: break; diff --git a/src/anbox/platform/base_platform.h b/src/anbox/platform/base_platform.h index 91ea36c93..7ecdd86cc 100644 --- a/src/anbox/platform/base_platform.h +++ b/src/anbox/platform/base_platform.h @@ -20,6 +20,7 @@ #include "anbox/graphics/rect.h" #include "anbox/wm/window_state.h" +#include "anbox/network/local_socket_messenger.h" #include @@ -53,7 +54,7 @@ class BasePlatform { virtual void set_clipboard_data(const ClipboardData &data) = 0; virtual ClipboardData get_clipboard_data() = 0; - virtual std::shared_ptr create_audio_sink() = 0; + virtual std::shared_ptr create_audio_sink(const std::shared_ptr &messenger) = 0; virtual std::shared_ptr create_audio_source() = 0; virtual void set_renderer(const std::shared_ptr &renderer) = 0; diff --git a/src/anbox/platform/null/platform.cpp b/src/anbox/platform/null/platform.cpp index c89480640..27a97e3d8 100644 --- a/src/anbox/platform/null/platform.cpp +++ b/src/anbox/platform/null/platform.cpp @@ -48,7 +48,8 @@ NullPlatform::ClipboardData NullPlatform::get_clipboard_data() { return ClipboardData{}; } -std::shared_ptr NullPlatform::create_audio_sink() { +std::shared_ptr NullPlatform::create_audio_sink(const std::shared_ptr &messenger) { + (void) messenger; ERROR("Not implemented"); return nullptr; } diff --git a/src/anbox/platform/null/platform.h b/src/anbox/platform/null/platform.h index 24ad341e2..c0da52b08 100644 --- a/src/anbox/platform/null/platform.h +++ b/src/anbox/platform/null/platform.h @@ -31,7 +31,7 @@ class NullPlatform : public BasePlatform { const std::string &title) override; void set_clipboard_data(const ClipboardData &data) override; ClipboardData get_clipboard_data() override; - std::shared_ptr create_audio_sink() override; + std::shared_ptr create_audio_sink(const std::shared_ptr &messenger) override; std::shared_ptr create_audio_source() override; void set_renderer(const std::shared_ptr &renderer) override; void set_window_manager(const std::shared_ptr &window_manager) override; diff --git a/src/anbox/platform/sdl/audio_sink.cpp b/src/anbox/platform/sdl/audio_sink.cpp index 66510a328..7cb9b9362 100644 --- a/src/anbox/platform/sdl/audio_sink.cpp +++ b/src/anbox/platform/sdl/audio_sink.cpp @@ -19,15 +19,17 @@ #include "anbox/logger.h" #include +#include #include namespace { -const constexpr size_t max_queue_size{16}; +const constexpr size_t max_queue_size{1}; } namespace anbox::platform::sdl { -AudioSink::AudioSink() : +AudioSink::AudioSink(const std::shared_ptr &messenger) : + messenger_(messenger), device_id_(0), queue_(max_queue_size) { } @@ -111,5 +113,19 @@ void AudioSink::write_data(const std::vector &data) { } graphics::Buffer buffer{data.data(), data.data() + data.size()}; queue_.push_locked(std::move(buffer), l); + + // Android side is waiting for "confirmation" that data arrived, + // if sink queue is full, Android audio thread will be blocked + // untill there's space available in the queue + // + // this acts as sychronization to time audio + // + // at the time of implementation, + // the data we send to Android is not actually used + timespec t; + clock_gettime(CLOCK_MONOTONIC, &t); + int64_t now_us = (t.tv_sec * 1000000000LL + t.tv_nsec) / 1000; + + messenger_->send(reinterpret_cast(&now_us), sizeof(now_us)); +} } -} \ No newline at end of file diff --git a/src/anbox/platform/sdl/audio_sink.h b/src/anbox/platform/sdl/audio_sink.h index 2f8df13ba..d357a7312 100644 --- a/src/anbox/platform/sdl/audio_sink.h +++ b/src/anbox/platform/sdl/audio_sink.h @@ -21,13 +21,14 @@ #include "anbox/audio/sink.h" #include "anbox/graphics/buffer_queue.h" #include "anbox/platform/sdl/sdl_wrapper.h" +#include "anbox/network/local_socket_messenger.h" #include namespace anbox::platform::sdl { class AudioSink : public audio::Sink { public: - AudioSink(); + AudioSink(const std::shared_ptr &messenger); ~AudioSink(); void write_data(const std::vector &data) override; @@ -39,6 +40,7 @@ class AudioSink : public audio::Sink { static void on_data_requested(void *user_data, std::uint8_t *buffer, int size); + std::shared_ptr messenger_; std::mutex lock_; SDL_AudioSpec spec_; SDL_AudioDeviceID device_id_; diff --git a/src/anbox/platform/sdl/platform.cpp b/src/anbox/platform/sdl/platform.cpp index 734d3f5dc..09bcdffdc 100644 --- a/src/anbox/platform/sdl/platform.cpp +++ b/src/anbox/platform/sdl/platform.cpp @@ -500,8 +500,8 @@ Platform::ClipboardData Platform::get_clipboard_data() { return data; } -std::shared_ptr Platform::create_audio_sink() { - return std::make_shared(); +std::shared_ptr Platform::create_audio_sink(const std::shared_ptr &messenger) { + return std::make_shared(messenger); } std::shared_ptr Platform::create_audio_source() { diff --git a/src/anbox/platform/sdl/platform.h b/src/anbox/platform/sdl/platform.h index 9633e0038..d96a99b6f 100644 --- a/src/anbox/platform/sdl/platform.h +++ b/src/anbox/platform/sdl/platform.h @@ -65,7 +65,7 @@ class Platform : public std::enable_shared_from_this, void set_clipboard_data(const ClipboardData &data) override; ClipboardData get_clipboard_data() override; - std::shared_ptr create_audio_sink() override; + std::shared_ptr create_audio_sink(const std::shared_ptr &messenger) override; std::shared_ptr create_audio_source() override; bool supports_multi_window() const override;