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

Side by Side Diff: content/renderer/media/webrtc/webrtc_local_audio_track_adapter.cc

Issue 1647773002: MediaStream audio sourcing: Bypass audio processing for non-WebRTC cases. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: NOT FOR REVIEW -- This will be broken-up across multiple CLs. Created 4 years, 10 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
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "content/renderer/media/webrtc/webrtc_local_audio_track_adapter.h" 5 #include "content/renderer/media/webrtc/webrtc_local_audio_track_adapter.h"
6 6
7 #include <limits>
8
9 #include "base/bind.h"
7 #include "base/location.h" 10 #include "base/location.h"
8 #include "base/logging.h" 11 #include "base/message_loop/message_loop.h"
12 #include "base/synchronization/waitable_event.h"
9 #include "content/renderer/media/media_stream_audio_processor.h" 13 #include "content/renderer/media/media_stream_audio_processor.h"
10 #include "content/renderer/media/webrtc/peer_connection_dependency_factory.h" 14 #include "content/renderer/media/media_stream_audio_track.h"
11 #include "content/renderer/media/webrtc/webrtc_audio_sink_adapter.h" 15 #include "content/renderer/media/webrtc/webrtc_audio_sink_adapter.h"
12 #include "content/renderer/media/webrtc_local_audio_track.h"
13 #include "content/renderer/render_thread_impl.h"
14 #include "third_party/webrtc/api/mediastreaminterface.h" 16 #include "third_party/webrtc/api/mediastreaminterface.h"
15 17
16 namespace content { 18 namespace content {
17 19
18 static const char kAudioTrackKind[] = "audio"; 20 static const char kAudioTrackKind[] = "audio";
19 21
20 scoped_refptr<WebRtcLocalAudioTrackAdapter> 22 scoped_refptr<WebRtcLocalAudioTrackAdapter>
21 WebRtcLocalAudioTrackAdapter::Create( 23 WebRtcLocalAudioTrackAdapter::Create(
22 const std::string& label, 24 const std::string& label,
23 webrtc::AudioSourceInterface* track_source) { 25 webrtc::AudioSourceInterface* track_source,
24 // TODO(tommi): Change this so that the signaling thread is one of the 26 const scoped_refptr<base::SingleThreadTaskRunner>& signaling_task_runner) {
25 // parameters to this method. 27 return new rtc::RefCountedObject<WebRtcLocalAudioTrackAdapter>(
26 scoped_refptr<base::SingleThreadTaskRunner> signaling_thread; 28 label, track_source, signaling_task_runner);
27 RenderThreadImpl* current = RenderThreadImpl::current();
28 if (current) {
29 PeerConnectionDependencyFactory* pc_factory =
30 current->GetPeerConnectionDependencyFactory();
31 signaling_thread = pc_factory->GetWebRtcSignalingThread();
32 }
33
34 LOG_IF(ERROR, !signaling_thread.get()) << "No signaling thread!";
35
36 rtc::RefCountedObject<WebRtcLocalAudioTrackAdapter>* adapter =
37 new rtc::RefCountedObject<WebRtcLocalAudioTrackAdapter>(
38 label, track_source, signaling_thread);
39 return adapter;
40 } 29 }
41 30
42 WebRtcLocalAudioTrackAdapter::WebRtcLocalAudioTrackAdapter( 31 WebRtcLocalAudioTrackAdapter::WebRtcLocalAudioTrackAdapter(
43 const std::string& label, 32 const std::string& label,
44 webrtc::AudioSourceInterface* track_source, 33 webrtc::AudioSourceInterface* track_source,
45 const scoped_refptr<base::SingleThreadTaskRunner>& signaling_thread) 34 const scoped_refptr<base::SingleThreadTaskRunner>& signaling_task_runner)
46 : webrtc::MediaStreamTrack<webrtc::AudioTrackInterface>(label), 35 : webrtc::MediaStreamTrack<webrtc::AudioTrackInterface>(label),
47 owner_(NULL),
48 track_source_(track_source), 36 track_source_(track_source),
49 signaling_thread_(signaling_thread), 37 signaling_task_runner_(signaling_task_runner),
50 signal_level_(0) { 38 track_(nullptr) {
51 signaling_thread_checker_.DetachFromThread(); 39 // Note: Single-threaded unit tests might not provide a task runner (or a
52 capture_thread_.DetachFromThread(); 40 // main-thread MessageLoop).
41 if (signaling_task_runner) {
42 if (base::MessageLoop* main_loop = base::MessageLoop::current())
43 main_task_runner_ = main_loop->task_runner();
44 }
53 } 45 }
54 46
55 WebRtcLocalAudioTrackAdapter::~WebRtcLocalAudioTrackAdapter() { 47 WebRtcLocalAudioTrackAdapter::~WebRtcLocalAudioTrackAdapter() {
56 } 48 }
57 49
58 void WebRtcLocalAudioTrackAdapter::Initialize(WebRtcLocalAudioTrack* owner) { 50 void WebRtcLocalAudioTrackAdapter::SetMediaStreamAudioTrack(
59 DCHECK(!owner_); 51 MediaStreamAudioTrack* track) {
60 DCHECK(owner); 52 DCHECK(!main_task_runner_ || main_task_runner_->RunsTasksOnCurrentThread());
61 owner_ = owner; 53 track_ = track;
62 } 54 }
63 55
64 void WebRtcLocalAudioTrackAdapter::SetAudioProcessor( 56 void WebRtcLocalAudioTrackAdapter::SetAudioProcessor(
65 const scoped_refptr<MediaStreamAudioProcessor>& processor) { 57 const scoped_refptr<MediaStreamAudioProcessor>& processor) {
66 // SetAudioProcessor will be called when a new capture thread has been
67 // initialized, so we need to detach from any current capture thread we're
68 // checking and attach to the current one.
69 capture_thread_.DetachFromThread();
70 DCHECK(capture_thread_.CalledOnValidThread());
71 base::AutoLock auto_lock(lock_); 58 base::AutoLock auto_lock(lock_);
72 audio_processor_ = processor; 59 audio_processor_ = processor;
73 } 60 }
74 61
62 void WebRtcLocalAudioTrackAdapter::SetReportedLevel(
63 const scoped_refptr<MediaStreamAudioLevelCalculator::ReportedLevel>&
64 reported_level) {
65 base::AutoLock auto_lock(lock_);
66 reported_level_ = reported_level;
67 }
68
69
75 std::string WebRtcLocalAudioTrackAdapter::kind() const { 70 std::string WebRtcLocalAudioTrackAdapter::kind() const {
76 return kAudioTrackKind; 71 return kAudioTrackKind;
77 } 72 }
78 73
79 bool WebRtcLocalAudioTrackAdapter::set_enabled(bool enable) { 74 bool WebRtcLocalAudioTrackAdapter::set_enabled(bool enable) {
80 // If we're not called on the signaling thread, we need to post a task to 75 // If we're not called on the signaling thread, we need to post a task to
81 // change the state on the correct thread. 76 // change the state on the correct thread.
82 if (signaling_thread_.get() && !signaling_thread_->BelongsToCurrentThread()) { 77 if (signaling_task_runner_.get() &&
83 signaling_thread_->PostTask(FROM_HERE, 78 !signaling_task_runner_->RunsTasksOnCurrentThread()) {
79 signaling_task_runner_->PostTask(FROM_HERE,
84 base::Bind( 80 base::Bind(
85 base::IgnoreResult(&WebRtcLocalAudioTrackAdapter::set_enabled), 81 base::IgnoreResult(&WebRtcLocalAudioTrackAdapter::set_enabled),
86 this, enable)); 82 this, enable));
87 return true; 83 return true;
88 } 84 }
89 85
90 return webrtc::MediaStreamTrack<webrtc::AudioTrackInterface>:: 86 return webrtc::MediaStreamTrack<webrtc::AudioTrackInterface>::
91 set_enabled(enable); 87 set_enabled(enable);
92 } 88 }
93 89
94 void WebRtcLocalAudioTrackAdapter::AddSink( 90 void WebRtcLocalAudioTrackAdapter::AddSink(
95 webrtc::AudioTrackSinkInterface* sink) { 91 webrtc::AudioTrackSinkInterface* sink) {
96 DCHECK(signaling_thread_checker_.CalledOnValidThread());
97 DCHECK(sink); 92 DCHECK(sink);
93
94 // Normal case: WebRtc will call into this method on the signaling thread. In
95 // this case, post a task to the main thread to add the sink, since the
96 // MediaStream object graph may only be modified from there.
97 if (main_task_runner_.get() &&
98 !main_task_runner_->RunsTasksOnCurrentThread()) {
99 DCHECK(signaling_task_runner_ &&
100 signaling_task_runner_->RunsTasksOnCurrentThread());
101 main_task_runner_->PostTask(
102 FROM_HERE,
103 base::Bind(&WebRtcLocalAudioTrackAdapter::AddSink, this, sink));
104 return;
105 }
106
98 #ifndef NDEBUG 107 #ifndef NDEBUG
99 // Verify that |sink| has not been added. 108 // Verify that |sink| has not been added.
100 for (ScopedVector<WebRtcAudioSinkAdapter>::const_iterator it = 109 for (ScopedVector<WebRtcAudioSinkAdapter>::const_iterator it =
101 sink_adapters_.begin(); 110 sink_adapters_.begin();
102 it != sink_adapters_.end(); ++it) { 111 it != sink_adapters_.end(); ++it) {
103 DCHECK(!(*it)->IsEqual(sink)); 112 DCHECK(!(*it)->IsEqual(sink));
104 } 113 }
105 #endif 114 #endif
106 115
107 scoped_ptr<WebRtcAudioSinkAdapter> adapter( 116 scoped_ptr<WebRtcAudioSinkAdapter> adapter(new WebRtcAudioSinkAdapter(sink));
108 new WebRtcAudioSinkAdapter(sink)); 117 if (track_)
109 owner_->AddSink(adapter.get()); 118 track_->AddSink(adapter.get());
110 sink_adapters_.push_back(adapter.release()); 119 sink_adapters_.push_back(std::move(adapter));
111 } 120 }
112 121
113 void WebRtcLocalAudioTrackAdapter::RemoveSink( 122 void WebRtcLocalAudioTrackAdapter::RemoveSink(
114 webrtc::AudioTrackSinkInterface* sink) { 123 webrtc::AudioTrackSinkInterface* sink) {
115 DCHECK(signaling_thread_checker_.CalledOnValidThread()); 124 // Normal case: WebRtc will call into this method on the signaling thread. In
125 // this case, post a task to the main thread to remove the sink, since the
126 // MediaStream object graph may only be modified from there. Furthermore,
127 // block the current thread until the task has completed to ensure the audio
128 // flow to |sink| has been stopped by the time this method returns.
129 if (main_task_runner_.get() &&
130 !main_task_runner_->RunsTasksOnCurrentThread()) {
131 DCHECK(signaling_task_runner_ &&
132 signaling_task_runner_->RunsTasksOnCurrentThread());
133 base::WaitableEvent done_event(false, false);
134 main_task_runner_->PostTask(
135 FROM_HERE,
136 base::Bind(&WebRtcLocalAudioTrackAdapter::RemoveSinkOnMainThread,
137 this, sink, &done_event));
138 done_event.Wait();
139 return;
140 }
141
142 // For single-threaded unit tests:
143 RemoveSinkOnMainThread(sink, nullptr);
144 }
145
146 void WebRtcLocalAudioTrackAdapter::RemoveSinkOnMainThread(
147 webrtc::AudioTrackSinkInterface* sink,
148 base::WaitableEvent* done_event) {
149 DCHECK(!main_task_runner_ || main_task_runner_->RunsTasksOnCurrentThread());
116 DCHECK(sink); 150 DCHECK(sink);
117 for (ScopedVector<WebRtcAudioSinkAdapter>::iterator it = 151 for (ScopedVector<WebRtcAudioSinkAdapter>::iterator it =
118 sink_adapters_.begin(); 152 sink_adapters_.begin();
119 it != sink_adapters_.end(); ++it) { 153 it != sink_adapters_.end(); ++it) {
120 if ((*it)->IsEqual(sink)) { 154 if ((*it)->IsEqual(sink)) {
121 owner_->RemoveSink(*it); 155 if (track_)
156 track_->RemoveSink(*it);
122 sink_adapters_.erase(it); 157 sink_adapters_.erase(it);
123 return; 158 break;
124 } 159 }
125 } 160 }
161 if (done_event)
162 done_event->Signal();
126 } 163 }
127 164
128 bool WebRtcLocalAudioTrackAdapter::GetSignalLevel(int* level) { 165 bool WebRtcLocalAudioTrackAdapter::GetSignalLevel(int* level) {
129 DCHECK(signaling_thread_checker_.CalledOnValidThread()); 166 // Note: Called on the signaling thread by WebRtc.
130 167 float signal_level = 0.0f;
131 base::AutoLock auto_lock(lock_); 168 {
132 *level = signal_level_; 169 base::AutoLock auto_lock(lock_);
170 if (!reported_level_)
171 return false;
172 signal_level = reported_level_->Get();
173 }
174 DCHECK_GE(signal_level, 0.0f);
175 DCHECK_LE(signal_level, 1.0f);
176 *level = static_cast<int>(signal_level * std::numeric_limits<int16_t>::max() +
177 0.5f /* rounding to nearest int */);
133 return true; 178 return true;
134 } 179 }
135 180
136 rtc::scoped_refptr<webrtc::AudioProcessorInterface> 181 rtc::scoped_refptr<webrtc::AudioProcessorInterface>
137 WebRtcLocalAudioTrackAdapter::GetAudioProcessor() { 182 WebRtcLocalAudioTrackAdapter::GetAudioProcessor() {
138 DCHECK(signaling_thread_checker_.CalledOnValidThread()); 183 // Note: Called on the signaling thread by WebRtc.
139 base::AutoLock auto_lock(lock_); 184 base::AutoLock auto_lock(lock_);
140 return audio_processor_.get(); 185 return audio_processor_.get();
141 } 186 }
142 187
143 void WebRtcLocalAudioTrackAdapter::SetSignalLevel(int signal_level) {
144 DCHECK(capture_thread_.CalledOnValidThread());
145 base::AutoLock auto_lock(lock_);
146 signal_level_ = signal_level;
147 }
148
149 webrtc::AudioSourceInterface* WebRtcLocalAudioTrackAdapter::GetSource() const { 188 webrtc::AudioSourceInterface* WebRtcLocalAudioTrackAdapter::GetSource() const {
150 DCHECK(signaling_thread_checker_.CalledOnValidThread()); 189 // Note: Called on the signaling thread by WebRtc.
151 return track_source_; 190 return track_source_;
152 } 191 }
153 192
154 } // namespace content 193 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698