Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(41)

Side by Side Diff: remoting/host/audio_capturer_linux.cc

Issue 10907041: Implement Linux audio capturer. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « remoting/host/audio_capturer_linux.h ('k') | remoting/host/audio_capturer_win.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "remoting/host/audio_capturer_linux.h"
6
7 #include <fcntl.h>
8 #include <sys/stat.h>
9 #include <sys/types.h>
10 #include <unistd.h>
11
12 #include "base/command_line.h"
13 #include "base/eintr_wrapper.h"
14 #include "base/file_path.h"
5 #include "base/logging.h" 15 #include "base/logging.h"
6 #include "remoting/host/audio_capturer.h" 16 #include "base/stl_util.h"
17 #include "remoting/proto/audio.pb.h"
7 18
8 namespace remoting { 19 namespace remoting {
9 20
21 namespace {
22
23 const char kAudioPipeOptionName[] = "audio-pipe-name";
24
25 // PulseAudio's module-pipe-sink must be configured to use the following
26 // parameters for the sink we read from.
27 const AudioPacket_SamplingRate kSamplingRate = AudioPacket::SAMPLING_RATE_44100;
28 const int kChannels = 2;
29 const int kBytesPerSample = 2;
30
31 // Read data from the pipe every 20ms.
32 const int kCapturingPeriodMs = 20;
33
34 } // namespace
35
36 AudioCapturerLinux::AudioCapturerLinux(const FilePath& pipe_name) {
37 pipe_fd_ = HANDLE_EINTR(open(
38 pipe_name.value().c_str(), O_RDONLY | O_NONBLOCK));
39 if (pipe_fd_ < 0) {
40 LOG(ERROR) << "Failed to open " << pipe_name.value();
41 return;
42 }
43
44 // Set buffer size for the pipe to the double of what's required for samples
45 // of each capturing period.
46 int pipe_buffer_size = 2 * kCapturingPeriodMs * kSamplingRate * kChannels *
47 kBytesPerSample / base::Time::kMillisecondsPerSecond;
48 int result = HANDLE_EINTR(fcntl(pipe_fd_, F_SETPIPE_SZ, pipe_buffer_size));
49 if (result < 0) {
50 PLOG(ERROR) << "fcntl";
51 }
52
53 Sleep();
54 }
55
56 AudioCapturerLinux::~AudioCapturerLinux() {
57 }
58
59 bool AudioCapturerLinux::Start(const PacketCapturedCallback& callback) {
60 if (pipe_fd_ < 0)
61 return false;
62
63 callback_ = callback;
64
65 return true;
66 }
67
68 void AudioCapturerLinux::Stop() {
69 callback_.Reset();
70 }
71
72 bool AudioCapturerLinux::IsRunning() {
73 return !callback_.is_null();
74 }
75
76 void AudioCapturerLinux::OnFileCanReadWithoutBlocking(int fd) {
77 DCHECK_EQ(fd, pipe_fd_);
78 StartTimer();
79 }
80
81 void AudioCapturerLinux::OnFileCanWriteWithoutBlocking(int fd) {
Wez 2012/09/04 21:41:45 nit: NOTREACHED()?
Sergey Ulanov 2012/09/05 01:35:49 Done.
82 }
83
84 void AudioCapturerLinux::StartTimer() {
85 started_time_ = base::TimeTicks::Now();
86 last_capture_time_samples_ = 0;
87 timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(kCapturingPeriodMs),
88 this, &AudioCapturerLinux::DoCapture);
89 }
90
91 void AudioCapturerLinux::DoCapture() {
92 DCHECK_GT(pipe_fd_, 0);
93
94 base::TimeDelta stream_position = base::TimeTicks::Now() - started_time_;
95 int64 stream_position_samples = stream_position.InMilliseconds() *
96 kSamplingRate / base::Time::kMillisecondsPerSecond;
97 int64 samples_to_capture =
98 stream_position_samples - last_capture_time_samples_;
Wez 2012/09/04 21:41:46 Do you need these calculations, and timers going o
Sergey Ulanov 2012/09/05 01:35:49 No. PulseAudio's pipe sink plugin doesn't control
99 last_capture_time_samples_ = stream_position_samples;
100 int64 read_size =
101 samples_to_capture * kChannels * kBytesPerSample;
102
103 std::string data;
104 data.resize(read_size);
105 int pos = 0;
106 while (pos < read_size) {
107 int read_result = HANDLE_EINTR(
108 read(pipe_fd_, string_as_array(&data) + pos, read_size - pos));
109 if (read_result >= 0) {
110 pos += read_result;
111 } else {
112 if (read_result != EWOULDBLOCK && read_result != EAGAIN)
113 PLOG(ERROR) << "read";
114 break;
115 }
116 }
117
118 if (pos == 0) {
119 Sleep();
120 return;
121 }
122
123 if (!callback_.is_null()) {
124 data.resize(pos);
125
126 scoped_ptr<AudioPacket> packet(new AudioPacket());
127 packet->add_data(data);
128 packet->set_encoding(AudioPacket::ENCODING_RAW);
129 packet->set_sampling_rate(kSamplingRate);
130 packet->set_bytes_per_sample(AudioPacket::BYTES_PER_SAMPLE_2);
131 packet->set_channels(AudioPacket::CHANNELS_STEREO);
132 callback_.Run(packet.Pass());
133 }
134 }
135
136 void AudioCapturerLinux::Sleep() {
137 timer_.Stop();
138 MessageLoopForIO::current()->WatchFileDescriptor(
139 pipe_fd_, false, MessageLoopForIO::WATCH_READ,
140 &file_descriptor_watcher_, this);
141 }
142
10 scoped_ptr<AudioCapturer> AudioCapturer::Create() { 143 scoped_ptr<AudioCapturer> AudioCapturer::Create() {
11 NOTIMPLEMENTED(); 144 CommandLine* cl = CommandLine::ForCurrentProcess();
12 return scoped_ptr<AudioCapturer>(NULL); 145 FilePath path = cl->GetSwitchValuePath(kAudioPipeOptionName);
146 if (path.empty())
147 return scoped_ptr<AudioCapturer>();
148 return scoped_ptr<AudioCapturer>(new AudioCapturerLinux(path));
13 } 149 }
14 150
15 } // namespace remoting 151 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/host/audio_capturer_linux.h ('k') | remoting/host/audio_capturer_win.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698