| Index: remoting/host/linux/audio_pipe_reader.cc
|
| diff --git a/remoting/host/audio_capturer_linux.cc b/remoting/host/linux/audio_pipe_reader.cc
|
| similarity index 66%
|
| copy from remoting/host/audio_capturer_linux.cc
|
| copy to remoting/host/linux/audio_pipe_reader.cc
|
| index b4a8fd0eeedfef1919d4ce2983e1405392cbdcc5..4bd340030cd28abc8810ce4e79771dc125e00d55 100644
|
| --- a/remoting/host/audio_capturer_linux.cc
|
| +++ b/remoting/host/linux/audio_pipe_reader.cc
|
| @@ -2,7 +2,7 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| -#include "remoting/host/audio_capturer_linux.h"
|
| +#include "remoting/host/linux/audio_pipe_reader.h"
|
|
|
| #include <fcntl.h>
|
| #include <sys/stat.h>
|
| @@ -11,11 +11,8 @@
|
|
|
| #include "base/eintr_wrapper.h"
|
| #include "base/file_path.h"
|
| -#include "base/lazy_instance.h"
|
| #include "base/logging.h"
|
| #include "base/stl_util.h"
|
| -#include "remoting/proto/audio.pb.h"
|
| -#include "remoting/host/chromoting_host_context.h"
|
|
|
| namespace remoting {
|
|
|
| @@ -23,7 +20,7 @@ namespace {
|
|
|
| // PulseAudio's module-pipe-sink must be configured to use the following
|
| // parameters for the sink we read from.
|
| -const AudioPacket_SamplingRate kSamplingRate = AudioPacket::SAMPLING_RATE_44100;
|
| +const int kSamplingRate = 48000;
|
| const int kChannels = 2;
|
| const int kBytesPerSample = 2;
|
|
|
| @@ -36,12 +33,6 @@ const int kCapturingPeriodMs = 40;
|
| #define F_SETPIPE_SZ 1031
|
| #endif // defined(F_SETPIPE_SZ)
|
|
|
| -// Pipename used to capture audio stream from.
|
| -// TODO(sergeyu): Pass this to AudioCapturerLinux constructor once we have
|
| -// Linux-specific DesktopEnvironmentFactory
|
| -base::LazyInstance<FilePath>::Leaky
|
| - g_audio_pipe_name = LAZY_INSTANCE_INITIALIZER;
|
| -
|
| const int IsPacketOfSilence(const std::string& data) {
|
| const int64* int_buf = reinterpret_cast<const int64*>(data.data());
|
| for (size_t i = 0; i < data.size() / sizeof(int64); i++) {
|
| @@ -58,7 +49,18 @@ const int IsPacketOfSilence(const std::string& data) {
|
|
|
| } // namespace
|
|
|
| -AudioCapturerLinux::AudioCapturerLinux(const FilePath& pipe_name) {
|
| +AudioPipeReader::AudioPipeReader(
|
| + scoped_refptr<base::SingleThreadTaskRunner> task_runner,
|
| + const FilePath& pipe_name)
|
| + : task_runner_(task_runner),
|
| + observers_(new ObserverListThreadSafe<StreamObserver>()) {
|
| + task_runner_->PostTask(FROM_HERE, base::Bind(
|
| + &AudioPipeReader::StartOnAudioThread, this, pipe_name));
|
| +}
|
| +
|
| +void AudioPipeReader::StartOnAudioThread(const FilePath& pipe_name) {
|
| + DCHECK(task_runner_->BelongsToCurrentThread());
|
| +
|
| pipe_fd_ = HANDLE_EINTR(open(
|
| pipe_name.value().c_str(), O_RDONLY | O_NONBLOCK));
|
| if (pipe_fd_ < 0) {
|
| @@ -78,43 +80,35 @@ AudioCapturerLinux::AudioCapturerLinux(const FilePath& pipe_name) {
|
| WaitForPipeReadable();
|
| }
|
|
|
| -AudioCapturerLinux::~AudioCapturerLinux() {
|
| -}
|
| -
|
| -bool AudioCapturerLinux::Start(const PacketCapturedCallback& callback) {
|
| - if (pipe_fd_ < 0)
|
| - return false;
|
| -
|
| - callback_ = callback;
|
| -
|
| - return true;
|
| +AudioPipeReader::~AudioPipeReader() {
|
| }
|
|
|
| -void AudioCapturerLinux::Stop() {
|
| - callback_.Reset();
|
| +void AudioPipeReader::AddObserver(StreamObserver* observer) {
|
| + observers_->AddObserver(observer);
|
| }
|
| -
|
| -bool AudioCapturerLinux::IsStarted() {
|
| - return !callback_.is_null();
|
| +void AudioPipeReader::RemoveObserver(StreamObserver* observer) {
|
| + observers_->RemoveObserver(observer);
|
| }
|
|
|
| -void AudioCapturerLinux::OnFileCanReadWithoutBlocking(int fd) {
|
| +void AudioPipeReader::OnFileCanReadWithoutBlocking(int fd) {
|
| DCHECK_EQ(fd, pipe_fd_);
|
| StartTimer();
|
| }
|
|
|
| -void AudioCapturerLinux::OnFileCanWriteWithoutBlocking(int fd) {
|
| +void AudioPipeReader::OnFileCanWriteWithoutBlocking(int fd) {
|
| NOTREACHED();
|
| }
|
|
|
| -void AudioCapturerLinux::StartTimer() {
|
| +void AudioPipeReader::StartTimer() {
|
| + DCHECK(task_runner_->BelongsToCurrentThread());
|
| started_time_ = base::TimeTicks::Now();
|
| last_capture_samples_ = 0;
|
| timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(kCapturingPeriodMs),
|
| - this, &AudioCapturerLinux::DoCapture);
|
| + this, &AudioPipeReader::DoCapture);
|
| }
|
|
|
| -void AudioCapturerLinux::DoCapture() {
|
| +void AudioPipeReader::DoCapture() {
|
| + DCHECK(task_runner_->BelongsToCurrentThread());
|
| DCHECK_GT(pipe_fd_, 0);
|
|
|
| // Calculate how much we need read from the pipe. Pulseaudio doesn't control
|
| @@ -158,41 +152,20 @@ void AudioCapturerLinux::DoCapture() {
|
| incomplete_samples_bytes);
|
| data.resize(pos - incomplete_samples_bytes);
|
|
|
| - if (callback_.is_null())
|
| - return;
|
| -
|
| if (IsPacketOfSilence(data))
|
| return;
|
|
|
| - scoped_ptr<AudioPacket> packet(new AudioPacket());
|
| - packet->add_data(data);
|
| - packet->set_encoding(AudioPacket::ENCODING_RAW);
|
| - packet->set_sampling_rate(kSamplingRate);
|
| - packet->set_bytes_per_sample(AudioPacket::BYTES_PER_SAMPLE_2);
|
| - packet->set_channels(AudioPacket::CHANNELS_STEREO);
|
| - callback_.Run(packet.Pass());
|
| + // Dispatch asynchronous notification to the stream observers.
|
| + scoped_refptr<base::RefCountedString> data_ref =
|
| + base::RefCountedString::TakeString(&data);
|
| + observers_->Notify(&StreamObserver::OnDataRead, data_ref);
|
| }
|
|
|
| -void AudioCapturerLinux::WaitForPipeReadable() {
|
| +void AudioPipeReader::WaitForPipeReadable() {
|
| timer_.Stop();
|
| MessageLoopForIO::current()->WatchFileDescriptor(
|
| pipe_fd_, false, MessageLoopForIO::WATCH_READ,
|
| &file_descriptor_watcher_, this);
|
| }
|
|
|
| -void AudioCapturerLinux::SetPipeName(const FilePath& pipe_name) {
|
| - g_audio_pipe_name.Get() = pipe_name;
|
| -}
|
| -
|
| -bool AudioCapturer::IsSupported() {
|
| - return !g_audio_pipe_name.Get().empty();
|
| -}
|
| -
|
| -scoped_ptr<AudioCapturer> AudioCapturer::Create() {
|
| - FilePath path = g_audio_pipe_name.Get();
|
| - if (path.empty())
|
| - return scoped_ptr<AudioCapturer>();
|
| - return scoped_ptr<AudioCapturer>(new AudioCapturerLinux(path));
|
| -}
|
| -
|
| } // namespace remoting
|
|
|