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

Side by Side Diff: remoting/protocol/webrtc_audio_source_adapter.cc

Issue 2392963003: Add Audio support in Chromoting host when using WebRTC. (Closed)
Patch Set: . Created 4 years, 2 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
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "remoting/protocol/webrtc_audio_source_adapter.h"
6
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "base/synchronization/lock.h"
10 #include "base/threading/thread_checker.h"
11 #include "remoting/proto/audio.pb.h"
12 #include "remoting/protocol/audio_source.h"
13
14 namespace remoting {
15 namespace protocol {
16
17 static const int kChannels = 2;
18 static const int kBytesPerSample = 2;
19
20 static constexpr base::TimeDelta kAudioFrameDuration =
21 base::TimeDelta::FromMilliseconds(10);
22
23
24 class WebrtcAudioSourceAdapter::Core{
Jamie 2016/10/04 23:36:05 Nit: Space after Core
Sergey Ulanov 2016/10/05 21:52:23 Done.
25 public:
26 Core();
27 ~Core();
28
29 void Start(std::unique_ptr<AudioSource> audio_source);
30 void Pause(bool pause);
31 void AddSink(webrtc::AudioTrackSinkInterface* sink);
32 void RemoveSink(webrtc::AudioTrackSinkInterface* sink);
33
34 private:
35 void OnAudioPacket(std::unique_ptr<AudioPacket> packet);
36
37 std::unique_ptr<AudioSource> audio_source_;
38
39 bool paused_ = false;
40
41 int sampling_rate_ = 0;
42 std::vector<uint8_t> leftover_samples_;
Jamie 2016/10/04 23:36:05 I'm not sure I fully understand the use of this me
Sergey Ulanov 2016/10/05 21:52:23 webrtc::AudioTrackSinkInterface expects to get aud
43
44 base::ObserverList<webrtc::AudioTrackSinkInterface> audio_sinks_;
45 base::Lock audio_sinks_lock_;
46
47 base::ThreadChecker thread_checker_;
48 };
49
50 WebrtcAudioSourceAdapter::Core::Core() {
51 thread_checker_.DetachFromThread();
52 }
Jamie 2016/10/04 23:36:05 Nit: Add blank line
Sergey Ulanov 2016/10/05 21:52:23 Done.
53 WebrtcAudioSourceAdapter::Core::~Core() {}
54
55 void WebrtcAudioSourceAdapter::Core::Start(
56 std::unique_ptr<AudioSource> audio_source) {
57 DCHECK(thread_checker_.CalledOnValidThread());
58 audio_source_ = std::move(audio_source);
59 audio_source_->Start(
60 base::Bind(&Core::OnAudioPacket, base::Unretained(this)));
61 }
62
63 void WebrtcAudioSourceAdapter::Core::Pause(bool pause) {
64 DCHECK(thread_checker_.CalledOnValidThread());
65 paused_ = pause;
66 }
67
68 void WebrtcAudioSourceAdapter::Core::AddSink(
69 webrtc::AudioTrackSinkInterface* sink) {
70 // Can be called on any thread.
71 base::AutoLock lock(audio_sinks_lock_);
72 audio_sinks_.AddObserver(sink);
73 }
74
75 void WebrtcAudioSourceAdapter::Core::RemoveSink(
76 webrtc::AudioTrackSinkInterface* sink) {
77 // Can be called on any thread.
78 base::AutoLock lock(audio_sinks_lock_);
79 audio_sinks_.RemoveObserver(sink);
80 }
81
82 void WebrtcAudioSourceAdapter::Core::OnAudioPacket(
83 std::unique_ptr<AudioPacket> packet) {
84 DCHECK(thread_checker_.CalledOnValidThread());
85
86 if (paused_)
87 return;
88
89 DCHECK_EQ(packet->channels(), kChannels);
90 DCHECK_EQ(packet->bytes_per_sample(), kBytesPerSample);
91
92 if (sampling_rate_ != packet->sampling_rate()) {
93 sampling_rate_ = packet->sampling_rate();
94 leftover_samples_.clear();
95 }
96
97 size_t samples_per_frame =
98 kAudioFrameDuration * sampling_rate_ / base::TimeDelta::FromSeconds(1);
99 size_t bytes_per_frame = kBytesPerSample * kChannels * samples_per_frame;
100
101 const std::string& data = packet->data(0);
102
103 size_t position = 0;
104
105 base::AutoLock lock(audio_sinks_lock_);
106
Jamie 2016/10/04 23:36:05 If I'm reading this correctly, the intent is to en
Sergey Ulanov 2016/10/05 21:52:23 This is a good catch. I wrote this code with incor
107 if (!leftover_samples_.empty()) {
108 size_t bytes_to_append = bytes_per_frame - leftover_samples_.size();
109 position += bytes_to_append;
110 leftover_samples_.insert(leftover_samples_.end(), data.data(),
111 data.data() + bytes_to_append);
112 FOR_EACH_OBSERVER(webrtc::AudioTrackSinkInterface, audio_sinks_,
113 OnData(&leftover_samples_.front(), kBytesPerSample * 8,
114 sampling_rate_, kChannels, samples_per_frame));
115 }
116
117 while (position + bytes_per_frame <= data.size()) {
118 FOR_EACH_OBSERVER(webrtc::AudioTrackSinkInterface, audio_sinks_,
119 OnData(data.data() + position, kBytesPerSample * 8,
120 sampling_rate_, kChannels, samples_per_frame));
121 position += bytes_per_frame;
122 }
123
124 leftover_samples_.assign(data.data() + position, data.data() + data.size());
125 }
126
127 WebrtcAudioSourceAdapter::WebrtcAudioSourceAdapter(
128 scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner)
129 : audio_task_runner_(audio_task_runner), core_(new Core()) {}
130
131 WebrtcAudioSourceAdapter::~WebrtcAudioSourceAdapter() {
132 audio_task_runner_->DeleteSoon(FROM_HERE, core_.release());
133 }
134
135 void WebrtcAudioSourceAdapter::Start(
136 std::unique_ptr<AudioSource> audio_source) {
137 audio_task_runner_->PostTask(
138 FROM_HERE, base::Bind(&Core::Start, base::Unretained(core_.get()),
139 base::Passed(&audio_source)));
140 }
141
142 void WebrtcAudioSourceAdapter::Pause(bool pause) {
143 audio_task_runner_->PostTask(
144 FROM_HERE,
145 base::Bind(&Core::Pause, base::Unretained(core_.get()), pause));
146 }
147
148 WebrtcAudioSourceAdapter::SourceState WebrtcAudioSourceAdapter::state() const {
149 return kLive;
150 }
151
152 bool WebrtcAudioSourceAdapter::remote() const {
153 return false;
154 }
155
156 void WebrtcAudioSourceAdapter::RegisterAudioObserver(AudioObserver* observer) {}
157
158 void WebrtcAudioSourceAdapter::UnregisterAudioObserver(
159 AudioObserver* observer) {}
160
161 void WebrtcAudioSourceAdapter::AddSink(webrtc::AudioTrackSinkInterface* sink) {
162 core_->AddSink(sink);
163 }
164 void WebrtcAudioSourceAdapter::RemoveSink(
165 webrtc::AudioTrackSinkInterface* sink) {
166 core_->RemoveSink(sink);
167 }
168
169 void WebrtcAudioSourceAdapter::RegisterObserver(
170 webrtc::ObserverInterface* observer) {}
171 void WebrtcAudioSourceAdapter::UnregisterObserver(
172 webrtc::ObserverInterface* observer) {}
173
174 } // namespace protocol
175 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698