Commit 36818434 authored by Peng Huang's avatar Peng Huang Committed by Commit Bot

Revert "Fork AudioInputController to the audio service."

This reverts commit 040f2ad0.

Reason for revert: <INSERT REASONING HERE>

Original change's description:
> Fork AudioInputController to the audio service.
> 
> Also migrate the audio service to it. We want to add audio processing
> capabilities to the audio service, and the media/ code cannot depend
> on services/audio/, so we need the AudioInputController code in the
> audio service. There's a very sketched design doc for processing in the
> audio service at
> https://docs.google.com/document/d/1HJnii4kuBXshVM202TVPJt_9iDmlaCX-VhatjRxRbC4/edit#.
> 
> Bug: 851959
> Change-Id: Icabef727e6d309f86472d2fb401d7383051fa0ae
> Reviewed-on: https://chromium-review.googlesource.com/1104464
> Commit-Queue: Max Morin <maxmorin@chromium.org>
> Reviewed-by: Olga Sharonova <olka@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#570014}

TBR=olka@chromium.org,maxmorin@chromium.org

Change-Id: I3727f7454ec28718e327335baec3960365afbe93
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: 851959,856215
Reviewed-on: https://chromium-review.googlesource.com/1113837Reviewed-by: default avatarPeng Huang <penghuang@chromium.org>
Commit-Queue: Peng Huang <penghuang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#570050}
parent 26dcff34
...@@ -41,12 +41,8 @@ source_set("lib") { ...@@ -41,12 +41,8 @@ source_set("lib") {
"group_member.h", "group_member.h",
"in_process_audio_manager_accessor.cc", "in_process_audio_manager_accessor.cc",
"in_process_audio_manager_accessor.h", "in_process_audio_manager_accessor.h",
"input_controller.cc",
"input_controller.h",
"input_stream.cc", "input_stream.cc",
"input_stream.h", "input_stream.h",
"input_sync_writer.cc",
"input_sync_writer.h",
"local_muter.cc", "local_muter.cc",
"local_muter.h", "local_muter.h",
"loopback_stream.cc", "loopback_stream.cc",
...@@ -93,9 +89,7 @@ source_set("tests") { ...@@ -93,9 +89,7 @@ source_set("tests") {
"delay_buffer_unittest.cc", "delay_buffer_unittest.cc",
"device_notifier_unittest.cc", "device_notifier_unittest.cc",
"group_coordinator_unittest.cc", "group_coordinator_unittest.cc",
"input_controller_unittest.cc",
"input_stream_unittest.cc", "input_stream_unittest.cc",
"input_sync_writer_unittest.cc",
"local_muter_unittest.cc", "local_muter_unittest.cc",
"loopback_stream_unittest.cc", "loopback_stream_unittest.cc",
"output_controller_unittest.cc", "output_controller_unittest.cc",
......
This diff is collapsed.
This diff is collapsed.
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "services/audio/input_controller.h"
#include <memory>
#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "media/audio/audio_manager.h"
#include "media/audio/fake_audio_input_stream.h"
#include "media/audio/fake_audio_log_factory.h"
#include "media/audio/fake_audio_manager.h"
#include "media/audio/test_audio_thread.h"
#include "media/base/user_input_monitor.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using ::testing::_;
using ::testing::AtLeast;
using ::testing::Exactly;
using ::testing::InvokeWithoutArgs;
using ::testing::NotNull;
using base::WaitableEvent;
namespace audio {
namespace {
const int kSampleRate = media::AudioParameters::kAudioCDSampleRate;
const media::ChannelLayout kChannelLayout = media::CHANNEL_LAYOUT_STEREO;
const int kSamplesPerPacket = kSampleRate / 10;
const double kMaxVolume = 1.0;
// InputController will poll once every second, so wait at most a bit
// more than that for the callbacks.
constexpr base::TimeDelta kOnMuteWaitTimeout =
base::TimeDelta::FromMilliseconds(1500);
// Posts run_loop->QuitClosure() on specified
// message loop after a certain number of calls given by |limit|.
ACTION_P4(CheckCountAndPostQuitTask, count, limit, loop_or_proxy, run_loop) {
if (++*count >= limit) {
loop_or_proxy->PostTask(FROM_HERE, run_loop->QuitWhenIdleClosure());
}
}
void RunLoopWithTimeout(base::RunLoop* run_loop, base::TimeDelta timeout) {
base::OneShotTimer timeout_timer;
timeout_timer.Start(FROM_HERE, timeout, run_loop->QuitClosure());
run_loop->Run();
}
} // namespace
class MockInputControllerEventHandler : public InputController::EventHandler {
public:
MockInputControllerEventHandler() = default;
void OnLog(base::StringPiece) override {}
MOCK_METHOD1(OnCreated, void(bool initially_muted));
MOCK_METHOD1(OnError, void(InputController::ErrorCode error_code));
MOCK_METHOD1(OnMuted, void(bool is_muted));
private:
DISALLOW_COPY_AND_ASSIGN(MockInputControllerEventHandler);
};
class MockSyncWriter : public InputController::SyncWriter {
public:
MockSyncWriter() = default;
MOCK_METHOD4(Write,
void(const media::AudioBus* data,
double volume,
bool key_pressed,
base::TimeTicks capture_time));
MOCK_METHOD0(Close, void());
};
class MockUserInputMonitor : public media::UserInputMonitor {
public:
MockUserInputMonitor() = default;
uint32_t GetKeyPressCount() const override { return 0; }
MOCK_METHOD0(EnableKeyPressMonitoring, void());
MOCK_METHOD0(DisableKeyPressMonitoring, void());
};
class MockAudioInputStream : public media::AudioInputStream {
public:
MockAudioInputStream() {}
~MockAudioInputStream() override {}
void Start(AudioInputCallback*) override {}
void Stop() override {}
void Close() override {}
double GetMaxVolume() override { return kMaxVolume; }
double GetVolume() override { return 0; }
bool SetAutomaticGainControl(bool) override { return false; }
bool GetAutomaticGainControl() override { return false; }
bool IsMuted() override { return false; }
void SetOutputDeviceForAec(const std::string&) override {}
MOCK_METHOD0(Open, bool());
MOCK_METHOD1(SetVolume, void(double));
};
class InputControllerTest : public testing::TestWithParam<bool> {
public:
InputControllerTest()
: run_on_audio_thread_(GetParam()),
audio_manager_(std::make_unique<media::FakeAudioManager>(
std::make_unique<media::TestAudioThread>(!run_on_audio_thread_),
&log_factory_)),
params_(media::AudioParameters::AUDIO_FAKE,
kChannelLayout,
kSampleRate,
kSamplesPerPacket) {}
~InputControllerTest() override {
audio_manager_->Shutdown();
base::RunLoop().RunUntilIdle();
}
protected:
void CreateAudioController() {
controller_ = InputController::Create(
audio_manager_.get(), &event_handler_, &sync_writer_,
&user_input_monitor_, params_,
media::AudioDeviceDescription::kDefaultDeviceId, false);
}
void CloseAudioController() {
if (run_on_audio_thread_) {
controller_->Close(base::OnceClosure());
return;
}
base::RunLoop loop;
controller_->Close(loop.QuitWhenIdleClosure());
loop.Run();
}
base::MessageLoop message_loop_;
// Parameterize tests to run InputController either on audio thread
// (synchronously), or on a different thread (non-blocking).
bool run_on_audio_thread_;
scoped_refptr<InputController> controller_;
media::FakeAudioLogFactory log_factory_;
std::unique_ptr<media::AudioManager> audio_manager_;
MockInputControllerEventHandler event_handler_;
MockSyncWriter sync_writer_;
MockUserInputMonitor user_input_monitor_;
media::AudioParameters params_;
MockAudioInputStream stream_;
private:
DISALLOW_COPY_AND_ASSIGN(InputControllerTest);
};
TEST_P(InputControllerTest, CreateAndCloseWithoutRecording) {
EXPECT_CALL(event_handler_, OnCreated(_));
CreateAudioController();
base::RunLoop().RunUntilIdle();
ASSERT_TRUE(controller_.get());
EXPECT_CALL(sync_writer_, Close());
CloseAudioController();
}
// Test a normal call sequence of create, record and close.
TEST_P(InputControllerTest, CreateRecordAndClose) {
int count = 0;
EXPECT_CALL(event_handler_, OnCreated(_));
CreateAudioController();
ASSERT_TRUE(controller_.get());
base::RunLoop loop;
// Write() should be called ten times.
EXPECT_CALL(sync_writer_, Write(NotNull(), _, _, _))
.Times(AtLeast(10))
.WillRepeatedly(CheckCountAndPostQuitTask(
&count, 10, message_loop_.task_runner(), &loop));
EXPECT_CALL(user_input_monitor_, EnableKeyPressMonitoring());
controller_->Record();
// Record and wait until ten Write() callbacks are received.
loop.Run();
EXPECT_CALL(user_input_monitor_, DisableKeyPressMonitoring());
EXPECT_CALL(sync_writer_, Close());
CloseAudioController();
}
// Test that InputController rejects insanely large packet sizes.
TEST_P(InputControllerTest, SamplesPerPacketTooLarge) {
// Create an audio device with a very large packet size.
params_.set_frames_per_buffer(kSamplesPerPacket * 1000);
// OnCreated() shall not be called in this test.
EXPECT_CALL(event_handler_, OnCreated(_)).Times(Exactly(0));
CreateAudioController();
ASSERT_FALSE(controller_.get());
}
TEST_P(InputControllerTest, CloseTwice) {
EXPECT_CALL(event_handler_, OnCreated(_));
CreateAudioController();
ASSERT_TRUE(controller_.get());
EXPECT_CALL(user_input_monitor_, EnableKeyPressMonitoring());
controller_->Record();
EXPECT_CALL(user_input_monitor_, DisableKeyPressMonitoring());
EXPECT_CALL(sync_writer_, Close());
CloseAudioController();
CloseAudioController();
}
// Test that InputController sends OnMute callbacks properly.
TEST_P(InputControllerTest, TestOnmutedCallbackInitiallyUnmuted) {
const auto timeout = kOnMuteWaitTimeout;
WaitableEvent callback_event(WaitableEvent::ResetPolicy::AUTOMATIC,
WaitableEvent::InitialState::NOT_SIGNALED);
base::RunLoop unmute_run_loop;
base::RunLoop mute_run_loop;
base::RunLoop setup_run_loop;
EXPECT_CALL(event_handler_, OnCreated(false)).WillOnce(InvokeWithoutArgs([&] {
setup_run_loop.QuitWhenIdle();
}));
EXPECT_CALL(sync_writer_, Close());
EXPECT_CALL(event_handler_, OnMuted(true)).WillOnce(InvokeWithoutArgs([&] {
mute_run_loop.Quit();
}));
EXPECT_CALL(event_handler_, OnMuted(false)).WillOnce(InvokeWithoutArgs([&] {
unmute_run_loop.Quit();
}));
media::FakeAudioInputStream::SetGlobalMutedState(false);
CreateAudioController();
ASSERT_TRUE(controller_.get());
RunLoopWithTimeout(&setup_run_loop, timeout);
media::FakeAudioInputStream::SetGlobalMutedState(true);
RunLoopWithTimeout(&mute_run_loop, timeout);
media::FakeAudioInputStream::SetGlobalMutedState(false);
RunLoopWithTimeout(&unmute_run_loop, timeout);
CloseAudioController();
}
TEST_P(InputControllerTest, TestOnmutedCallbackInitiallyMuted) {
const auto timeout = kOnMuteWaitTimeout;
WaitableEvent callback_event(WaitableEvent::ResetPolicy::AUTOMATIC,
WaitableEvent::InitialState::NOT_SIGNALED);
base::RunLoop unmute_run_loop;
base::RunLoop setup_run_loop;
EXPECT_CALL(event_handler_, OnCreated(true)).WillOnce(InvokeWithoutArgs([&] {
setup_run_loop.QuitWhenIdle();
}));
EXPECT_CALL(sync_writer_, Close());
EXPECT_CALL(event_handler_, OnMuted(false)).WillOnce(InvokeWithoutArgs([&] {
unmute_run_loop.Quit();
}));
media::FakeAudioInputStream::SetGlobalMutedState(true);
CreateAudioController();
ASSERT_TRUE(controller_.get());
RunLoopWithTimeout(&setup_run_loop, timeout);
media::FakeAudioInputStream::SetGlobalMutedState(false);
RunLoopWithTimeout(&unmute_run_loop, timeout);
CloseAudioController();
}
INSTANTIATE_TEST_CASE_P(SyncAsync, InputControllerTest, testing::Bool());
} // namespace audio
...@@ -9,13 +9,13 @@ ...@@ -9,13 +9,13 @@
#include "base/bind_helpers.h" #include "base/bind_helpers.h"
#include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event.h"
#include "media/audio/audio_input_sync_writer.h"
#include "media/audio/audio_manager.h" #include "media/audio/audio_manager.h"
#include "media/base/audio_parameters.h" #include "media/base/audio_parameters.h"
#include "media/base/user_input_monitor.h" #include "media/base/user_input_monitor.h"
#include "mojo/public/cpp/system/buffer.h" #include "mojo/public/cpp/system/buffer.h"
#include "mojo/public/cpp/system/handle.h" #include "mojo/public/cpp/system/handle.h"
#include "mojo/public/cpp/system/platform_handle.h" #include "mojo/public/cpp/system/platform_handle.h"
#include "services/audio/input_sync_writer.h"
#include "services/audio/user_input_monitor.h" #include "services/audio/user_input_monitor.h"
namespace audio { namespace audio {
...@@ -45,7 +45,7 @@ InputStream::InputStream(CreatedCallback created_callback, ...@@ -45,7 +45,7 @@ InputStream::InputStream(CreatedCallback created_callback,
created_callback_(std::move(created_callback)), created_callback_(std::move(created_callback)),
delete_callback_(std::move(delete_callback)), delete_callback_(std::move(delete_callback)),
foreign_socket_(), foreign_socket_(),
writer_(InputSyncWriter::Create( writer_(media::AudioInputSyncWriter::Create(
log_ ? base::BindRepeating(&media::mojom::AudioLog::OnLogMessage, log_ ? base::BindRepeating(&media::mojom::AudioLog::OnLogMessage,
base::Unretained(log_->get())) base::Unretained(log_->get()))
: base::DoNothing(), : base::DoNothing(),
...@@ -88,9 +88,9 @@ InputStream::InputStream(CreatedCallback created_callback, ...@@ -88,9 +88,9 @@ InputStream::InputStream(CreatedCallback created_callback,
return; return;
} }
controller_ = InputController::Create(audio_manager, this, writer_.get(), controller_ = media::AudioInputController::Create(
user_input_monitor_.get(), params, audio_manager, this, writer_.get(), user_input_monitor_.get(), params,
device_id, enable_agc); device_id, enable_agc);
} }
InputStream::~InputStream() { InputStream::~InputStream() {
...@@ -116,7 +116,7 @@ InputStream::~InputStream() { ...@@ -116,7 +116,7 @@ InputStream::~InputStream() {
return; return;
} }
// TODO(https://crbug.com/803102): remove InputController::Close() after // TODO(https://crbug.com/803102): remove AudioInputController::Close() after
// content/ streams are removed, destructor should suffice. // content/ streams are removed, destructor should suffice.
controller_->Close(base::OnceClosure()); controller_->Close(base::OnceClosure());
...@@ -183,7 +183,7 @@ void InputStream::OnCreated(bool initially_muted) { ...@@ -183,7 +183,7 @@ void InputStream::OnCreated(bool initially_muted) {
initially_muted, id_); initially_muted, id_);
} }
void InputStream::OnError(InputController::ErrorCode error_code) { void InputStream::OnError(media::AudioInputController::ErrorCode error_code) {
DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_); DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_);
TRACE_EVENT_NESTABLE_ASYNC_INSTANT0("audio", "Error", this); TRACE_EVENT_NESTABLE_ASYNC_INSTANT0("audio", "Error", this);
......
...@@ -11,14 +11,15 @@ ...@@ -11,14 +11,15 @@
#include "base/memory/scoped_refptr.h" #include "base/memory/scoped_refptr.h"
#include "base/sync_socket.h" #include "base/sync_socket.h"
#include "base/unguessable_token.h" #include "base/unguessable_token.h"
#include "media/audio/audio_input_controller.h"
#include "media/mojo/interfaces/audio_data_pipe.mojom.h" #include "media/mojo/interfaces/audio_data_pipe.mojom.h"
#include "media/mojo/interfaces/audio_input_stream.mojom.h" #include "media/mojo/interfaces/audio_input_stream.mojom.h"
#include "media/mojo/interfaces/audio_logging.mojom.h" #include "media/mojo/interfaces/audio_logging.mojom.h"
#include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/binding.h"
#include "services/audio/input_controller.h"
namespace media { namespace media {
class AudioInputSyncWriter;
class AudioManager; class AudioManager;
class AudioParameters; class AudioParameters;
...@@ -26,11 +27,10 @@ class AudioParameters; ...@@ -26,11 +27,10 @@ class AudioParameters;
namespace audio { namespace audio {
class InputSyncWriter;
class UserInputMonitor; class UserInputMonitor;
class InputStream final : public media::mojom::AudioInputStream, class InputStream final : public media::mojom::AudioInputStream,
public InputController::EventHandler { public media::AudioInputController::EventHandler {
public: public:
using CreatedCallback = using CreatedCallback =
base::OnceCallback<void(media::mojom::ReadOnlyAudioDataPipePtr, base::OnceCallback<void(media::mojom::ReadOnlyAudioDataPipePtr,
...@@ -59,9 +59,9 @@ class InputStream final : public media::mojom::AudioInputStream, ...@@ -59,9 +59,9 @@ class InputStream final : public media::mojom::AudioInputStream,
void Record() override; void Record() override;
void SetVolume(double volume) override; void SetVolume(double volume) override;
// InputController::EventHandler implementation. // media::AudioInputController::EventHandler implementation.
void OnCreated(bool initially_muted) override; void OnCreated(bool initially_muted) override;
void OnError(InputController::ErrorCode error_code) override; void OnError(media::AudioInputController::ErrorCode error_code) override;
void OnLog(base::StringPiece) override; void OnLog(base::StringPiece) override;
void OnMuted(bool is_muted) override; void OnMuted(bool is_muted) override;
...@@ -83,8 +83,8 @@ class InputStream final : public media::mojom::AudioInputStream, ...@@ -83,8 +83,8 @@ class InputStream final : public media::mojom::AudioInputStream,
DeleteCallback delete_callback_; DeleteCallback delete_callback_;
base::CancelableSyncSocket foreign_socket_; base::CancelableSyncSocket foreign_socket_;
const std::unique_ptr<InputSyncWriter> writer_; const std::unique_ptr<media::AudioInputSyncWriter> writer_;
scoped_refptr<InputController> controller_; scoped_refptr<media::AudioInputController> controller_;
const std::unique_ptr<UserInputMonitor> user_input_monitor_; const std::unique_ptr<UserInputMonitor> user_input_monitor_;
SEQUENCE_CHECKER(owning_sequence_); SEQUENCE_CHECKER(owning_sequence_);
......
This diff is collapsed.
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SERVICES_AUDIO_INPUT_SYNC_WRITER_H_
#define SERVICES_AUDIO_INPUT_SYNC_WRITER_H_
#include <stddef.h>
#include <stdint.h>
#include <memory>
#include <string>
#include <vector>
#include "base/containers/circular_deque.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/memory/read_only_shared_memory_region.h"
#include "base/sync_socket.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "media/base/audio_bus.h"
#include "media/base/audio_parameters.h"
#include "services/audio/input_controller.h"
#if defined(OS_POSIX)
#include "base/file_descriptor_posix.h"
#endif
namespace audio {
// A InputController::SyncWriter implementation using SyncSocket. This
// is used by InputController to provide a low latency data source for
// transmitting audio packets between the browser process and the renderer
// process.
class InputSyncWriter : public InputController::SyncWriter {
public:
// Maximum fifo size (|overflow_buses_| and |overflow_params_|) in number of
// media::AudioBuses.
enum { kMaxOverflowBusesSize = 100 };
// Create() automatically initializes the InputSyncWriter correctly,
// and should be strongly preferred over calling the constructor directly!
InputSyncWriter(
base::RepeatingCallback<void(const std::string&)> log_callback,
base::MappedReadOnlyRegion shared_memory,
std::unique_ptr<base::CancelableSyncSocket> socket,
uint32_t shared_memory_segment_count,
const media::AudioParameters& params);
~InputSyncWriter() override;
static std::unique_ptr<InputSyncWriter> Create(
base::RepeatingCallback<void(const std::string&)> log_callback,
uint32_t shared_memory_segment_count,
const media::AudioParameters& params,
base::CancelableSyncSocket* foreign_socket);
// Transfers shared memory region ownership to a caller. It shouldn't be
// called more than once.
base::ReadOnlySharedMemoryRegion TakeSharedMemoryRegion();
size_t shared_memory_segment_count() const { return audio_buses_.size(); }
// InputController::SyncWriter implementation.
void Write(const media::AudioBus* data,
double volume,
bool key_pressed,
base::TimeTicks capture_time) override;
void Close() override;
private:
friend class InputSyncWriterTest;
// Called by Write(). Checks the time since last called and if larger than a
// threshold logs info about that.
void CheckTimeSinceLastWrite();
// Push |data| and metadata to |audio_buffer_fifo_|. Returns true if
// successful. Logs error and returns false if the fifo already reached the
// maximum size.
bool PushDataToFifo(const media::AudioBus* data,
double volume,
bool key_pressed,
base::TimeTicks capture_time);
// Writes as much data as possible from the fifo (|overflow_buses_|) to the
// shared memory ring buffer. Returns true if all operations were successful,
// otherwise false.
bool WriteDataFromFifoToSharedMemory();
// Write audio parameters to current segment in shared memory.
void WriteParametersToCurrentSegment(double volume,
bool key_pressed,
base::TimeTicks capture_time);
// Signals over the socket that data has been written to the current segment.
// Updates counters and returns true if successful. Logs error and returns
// false if failure.
bool SignalDataWrittenAndUpdateCounters();
const base::RepeatingCallback<void(const std::string&)> log_callback_;
// Socket used to signal that audio data is ready.
const std::unique_ptr<base::CancelableSyncSocket> socket_;
// Shared memory for audio data and associated metadata.
base::ReadOnlySharedMemoryRegion shared_memory_region_;
const base::WritableSharedMemoryMapping shared_memory_mapping_;
// The size in bytes of a single audio segment in the shared memory.
const uint32_t shared_memory_segment_size_;
// Index of next segment to write.
uint32_t current_segment_id_ = 0;
// The time of the creation of this object.
base::TimeTicks creation_time_;
// The time of the last Write call.
base::TimeTicks last_write_time_;
// Size in bytes of each audio bus.
const int audio_bus_memory_size_;
// Increasing ID used for checking audio buffers are in correct sequence at
// read side.
uint32_t next_buffer_id_ = 0;
// Next expected audio buffer index to have been read at the other side. We
// will get the index read at the other side over the socket. Note that this
// index does not correspond to |next_buffer_id_|, it's two separate counters.
uint32_t next_read_buffer_index_ = 0;
// Keeps track of number of filled buffer segments in the ring buffer to
// ensure the we don't overwrite data that hasn't been read yet.
size_t number_of_filled_segments_ = 0;
// Counts the total number of calls to Write().
size_t write_count_ = 0;
// Counts the number of writes to the fifo instead of to the shared memory.
size_t write_to_fifo_count_ = 0;
// Counts the number of errors that causes data to be dropped, due to either
// the fifo or the socket buffer being full.
size_t write_error_count_ = 0;
// Denotes that the most recent socket error has been logged. Used to avoid
// log spam.
bool had_socket_error_ = false;
// Counts the fifo writes and errors we get during renderer process teardown
// so that we can account for that (subtract) when we calculate the overall
// counts.
size_t trailing_write_to_fifo_count_ = 0;
size_t trailing_write_error_count_ = 0;
// Vector of audio buses allocated during construction and deleted in the
// destructor.
std::vector<std::unique_ptr<media::AudioBus>> audio_buses_;
// Fifo for audio that is used in case there isn't room in the shared memory.
// This can for example happen under load when the consumer side is starved.
// It should ideally be rare, but we need to guarantee that the data arrives
// since audio processing such as echo cancelling requires that to perform
// properly.
struct OverflowData {
OverflowData(double volume,
bool key_pressed,
base::TimeTicks capture_time,
std::unique_ptr<media::AudioBus> audio_bus);
~OverflowData();
OverflowData(OverflowData&&);
OverflowData& operator=(OverflowData&& other);
double volume_;
bool key_pressed_;
base::TimeTicks capture_time_;
std::unique_ptr<media::AudioBus> audio_bus_;
private:
DISALLOW_COPY_AND_ASSIGN(OverflowData);
};
std::vector<OverflowData> overflow_data_;
DISALLOW_IMPLICIT_CONSTRUCTORS(InputSyncWriter);
};
} // namespace audio
#endif // SERVICES_AUDIO_INPUT_SYNC_WRITER_H_
This diff is collapsed.
...@@ -68,10 +68,11 @@ LoopbackStream::LoopbackStream( ...@@ -68,10 +68,11 @@ LoopbackStream::LoopbackStream(
// the consumer. If successful, create the FlowNetwork too. // the consumer. If successful, create the FlowNetwork too.
if (base::TimeTicks::IsHighResolution()) { if (base::TimeTicks::IsHighResolution()) {
base::CancelableSyncSocket foreign_socket; base::CancelableSyncSocket foreign_socket;
std::unique_ptr<InputSyncWriter> writer = InputSyncWriter::Create( std::unique_ptr<media::AudioInputSyncWriter> writer =
base::BindRepeating( media::AudioInputSyncWriter::Create(
[](const std::string& message) { VLOG(1) << message; }), base::BindRepeating(
shared_memory_count, params, &foreign_socket); [](const std::string& message) { VLOG(1) << message; }),
shared_memory_count, params, &foreign_socket);
if (writer) { if (writer) {
base::ReadOnlySharedMemoryRegion shared_memory_region = base::ReadOnlySharedMemoryRegion shared_memory_region =
writer->TakeSharedMemoryRegion(); writer->TakeSharedMemoryRegion();
...@@ -231,7 +232,7 @@ void LoopbackStream::OnError() { ...@@ -231,7 +232,7 @@ void LoopbackStream::OnError() {
LoopbackStream::FlowNetwork::FlowNetwork( LoopbackStream::FlowNetwork::FlowNetwork(
scoped_refptr<base::SequencedTaskRunner> flow_task_runner, scoped_refptr<base::SequencedTaskRunner> flow_task_runner,
const media::AudioParameters& output_params, const media::AudioParameters& output_params,
std::unique_ptr<InputSyncWriter> writer) std::unique_ptr<media::AudioInputSyncWriter> writer)
: clock_(base::DefaultTickClock::GetInstance()), : clock_(base::DefaultTickClock::GetInstance()),
flow_task_runner_(flow_task_runner), flow_task_runner_(flow_task_runner),
output_params_(output_params), output_params_(output_params),
......
...@@ -21,14 +21,14 @@ ...@@ -21,14 +21,14 @@
#include "base/time/time.h" #include "base/time/time.h"
#include "base/timer/timer.h" #include "base/timer/timer.h"
#include "base/unguessable_token.h" #include "base/unguessable_token.h"
#include "media/audio/audio_input_controller.h"
#include "media/audio/audio_input_sync_writer.h"
#include "media/base/audio_parameters.h" #include "media/base/audio_parameters.h"
#include "media/mojo/interfaces/audio_data_pipe.mojom.h" #include "media/mojo/interfaces/audio_data_pipe.mojom.h"
#include "media/mojo/interfaces/audio_input_stream.mojom.h" #include "media/mojo/interfaces/audio_input_stream.mojom.h"
#include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/binding.h"
#include "services/audio/group_coordinator.h" #include "services/audio/group_coordinator.h"
#include "services/audio/group_member.h" #include "services/audio/group_member.h"
#include "services/audio/input_controller.h"
#include "services/audio/input_sync_writer.h"
#include "services/audio/snooper_node.h" #include "services/audio/snooper_node.h"
namespace base { namespace base {
...@@ -89,7 +89,7 @@ class LoopbackStream : public media::mojom::AudioInputStream, ...@@ -89,7 +89,7 @@ class LoopbackStream : public media::mojom::AudioInputStream,
network_->set_clock_for_testing(clock); network_->set_clock_for_testing(clock);
} }
void set_sync_writer_for_testing( void set_sync_writer_for_testing(
std::unique_ptr<InputController::SyncWriter> writer) { std::unique_ptr<media::AudioInputController::SyncWriter> writer) {
network_->set_writer_for_testing(std::move(writer)); network_->set_writer_for_testing(std::move(writer));
} }
...@@ -114,12 +114,12 @@ class LoopbackStream : public media::mojom::AudioInputStream, ...@@ -114,12 +114,12 @@ class LoopbackStream : public media::mojom::AudioInputStream,
public: public:
FlowNetwork(scoped_refptr<base::SequencedTaskRunner> flow_task_runner, FlowNetwork(scoped_refptr<base::SequencedTaskRunner> flow_task_runner,
const media::AudioParameters& output_params, const media::AudioParameters& output_params,
std::unique_ptr<InputSyncWriter> writer); std::unique_ptr<media::AudioInputSyncWriter> writer);
// These must be called to override the Clock/SyncWriter before Start(). // These must be called to override the Clock/SyncWriter before Start().
void set_clock_for_testing(const base::TickClock* clock) { clock_ = clock; } void set_clock_for_testing(const base::TickClock* clock) { clock_ = clock; }
void set_writer_for_testing( void set_writer_for_testing(
std::unique_ptr<InputController::SyncWriter> writer) { std::unique_ptr<media::AudioInputController::SyncWriter> writer) {
writer_ = std::move(writer); writer_ = std::move(writer);
} }
...@@ -169,7 +169,7 @@ class LoopbackStream : public media::mojom::AudioInputStream, ...@@ -169,7 +169,7 @@ class LoopbackStream : public media::mojom::AudioInputStream,
const media::AudioParameters output_params_; const media::AudioParameters output_params_;
// Destination for the output of this FlowNetwork. // Destination for the output of this FlowNetwork.
std::unique_ptr<InputController::SyncWriter> writer_; std::unique_ptr<media::AudioInputController::SyncWriter> writer_;
// Ensures thread-safe access to changing the |inputs_| and |volume_| while // Ensures thread-safe access to changing the |inputs_| and |volume_| while
// running. // running.
......
...@@ -87,7 +87,8 @@ class MockClientAndObserver : public media::mojom::AudioInputStreamClient, ...@@ -87,7 +87,8 @@ class MockClientAndObserver : public media::mojom::AudioInputStreamClient,
// Subclass of FakeConsumer that adapts the SyncWriter interface to allow the // Subclass of FakeConsumer that adapts the SyncWriter interface to allow the
// tests to record and analyze the audio data from the LoopbackStream. // tests to record and analyze the audio data from the LoopbackStream.
class FakeSyncWriter : public FakeConsumer, public InputController::SyncWriter { class FakeSyncWriter : public FakeConsumer,
public media::AudioInputController::SyncWriter {
public: public:
FakeSyncWriter(int channels, int sample_rate) FakeSyncWriter(int channels, int sample_rate)
: FakeConsumer(channels, sample_rate) {} : FakeConsumer(channels, sample_rate) {}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment