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

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

Issue 1721273002: MediaStream audio object graph untangling and clean-ups. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed mcasas's 1st round comments, plus REBASE. Created 4 years, 9 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 "base/location.h" 7 #include "base/location.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "content/renderer/media/media_stream_audio_processor.h" 9 #include "content/renderer/media/media_stream_audio_processor.h"
10 #include "content/renderer/media/webrtc/peer_connection_dependency_factory.h" 10 #include "content/renderer/media/webrtc/peer_connection_dependency_factory.h"
11 #include "content/renderer/media/webrtc/webrtc_audio_sink_adapter.h" 11 #include "content/renderer/media/webrtc/webrtc_audio_sink_adapter.h"
12 #include "content/renderer/media/webrtc_local_audio_track.h" 12 #include "content/renderer/media/webrtc_local_audio_track.h"
13 #include "content/renderer/render_thread_impl.h" 13 #include "content/renderer/render_thread_impl.h"
14 #include "third_party/webrtc/api/mediastreaminterface.h" 14 #include "third_party/webrtc/api/mediastreaminterface.h"
15 15
16 namespace content { 16 namespace content {
17 17
18 static const char kAudioTrackKind[] = "audio"; 18 static const char kAudioTrackKind[] = "audio";
19 19
20 scoped_refptr<WebRtcLocalAudioTrackAdapter> 20 scoped_refptr<WebRtcLocalAudioTrackAdapter>
21 WebRtcLocalAudioTrackAdapter::Create( 21 WebRtcLocalAudioTrackAdapter::Create(
22 const std::string& label, 22 const std::string& label,
23 webrtc::AudioSourceInterface* track_source) { 23 webrtc::AudioSourceInterface* track_source) {
24 // TODO(tommi): Change this so that the signaling thread is one of the 24 // TODO(tommi): Change this so that the signaling thread is one of the
25 // parameters to this method. 25 // parameters to this method.
26 scoped_refptr<base::SingleThreadTaskRunner> signaling_thread; 26 scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner;
27 RenderThreadImpl* current = RenderThreadImpl::current(); 27 RenderThreadImpl* current = RenderThreadImpl::current();
28 if (current) { 28 if (current) {
29 PeerConnectionDependencyFactory* pc_factory = 29 PeerConnectionDependencyFactory* pc_factory =
30 current->GetPeerConnectionDependencyFactory(); 30 current->GetPeerConnectionDependencyFactory();
31 signaling_thread = pc_factory->GetWebRtcSignalingThread(); 31 signaling_task_runner = pc_factory->GetWebRtcSignalingThread();
32 } 32 }
33 33
34 LOG_IF(ERROR, !signaling_thread.get()) << "No signaling thread!"; 34 LOG_IF(ERROR, !signaling_task_runner.get()) << "No signaling thread!";
35 35
36 rtc::RefCountedObject<WebRtcLocalAudioTrackAdapter>* adapter = 36 rtc::RefCountedObject<WebRtcLocalAudioTrackAdapter>* adapter =
37 new rtc::RefCountedObject<WebRtcLocalAudioTrackAdapter>( 37 new rtc::RefCountedObject<WebRtcLocalAudioTrackAdapter>(
38 label, track_source, signaling_thread); 38 label, track_source, signaling_task_runner);
39 return adapter; 39 return adapter;
40 } 40 }
41 41
42 WebRtcLocalAudioTrackAdapter::WebRtcLocalAudioTrackAdapter( 42 WebRtcLocalAudioTrackAdapter::WebRtcLocalAudioTrackAdapter(
43 const std::string& label, 43 const std::string& label,
44 webrtc::AudioSourceInterface* track_source, 44 webrtc::AudioSourceInterface* track_source,
45 const scoped_refptr<base::SingleThreadTaskRunner>& signaling_thread) 45 const scoped_refptr<base::SingleThreadTaskRunner>& signaling_task_runner)
46 : webrtc::MediaStreamTrack<webrtc::AudioTrackInterface>(label), 46 : webrtc::MediaStreamTrack<webrtc::AudioTrackInterface>(label),
47 owner_(NULL), 47 owner_(NULL),
48 track_source_(track_source), 48 track_source_(track_source),
49 signaling_thread_(signaling_thread), 49 signaling_task_runner_(signaling_task_runner) {}
o1ka 2016/02/29 14:28:04 How thread safety of the class is guaranteed if si
miu 2016/03/01 09:43:54 Many of the unit tests run single-threaded. See l
o1ka 2016/03/01 14:18:58 Acknowledged.
50 signal_level_(0) {
51 signaling_thread_checker_.DetachFromThread();
52 capture_thread_.DetachFromThread();
53 }
54 50
55 WebRtcLocalAudioTrackAdapter::~WebRtcLocalAudioTrackAdapter() { 51 WebRtcLocalAudioTrackAdapter::~WebRtcLocalAudioTrackAdapter() {
56 } 52 }
57 53
58 void WebRtcLocalAudioTrackAdapter::Initialize(WebRtcLocalAudioTrack* owner) { 54 void WebRtcLocalAudioTrackAdapter::Initialize(WebRtcLocalAudioTrack* owner) {
59 DCHECK(!owner_); 55 DCHECK(!owner_);
60 DCHECK(owner); 56 DCHECK(owner);
61 owner_ = owner; 57 owner_ = owner;
62 } 58 }
63 59
64 void WebRtcLocalAudioTrackAdapter::SetAudioProcessor( 60 void WebRtcLocalAudioTrackAdapter::SetAudioProcessor(
65 const scoped_refptr<MediaStreamAudioProcessor>& processor) { 61 const scoped_refptr<MediaStreamAudioProcessor>& processor) {
66 // SetAudioProcessor will be called when a new capture thread has been 62 // |audio_processor_| must only be set once. This eliminates the need to
67 // initialized, so we need to detach from any current capture thread we're 63 // protect |audio_processor_| with a mutex.
o1ka 2016/02/29 14:28:04 Is there any guarantee that there won't be a race
miu 2016/03/01 09:43:55 No, but the header comments and the DCHECK on line
o1ka 2016/03/01 14:18:59 Agree that calling SetAudioProcessor() second time
miu 2016/03/02 01:12:50 Where is the race condition? I don't see what els
o1ka 2016/03/02 16:31:13 Acknowledged.
68 // checking and attach to the current one. 64 DCHECK(processor.get());
69 capture_thread_.DetachFromThread(); 65 DCHECK(!audio_processor_);
70 DCHECK(capture_thread_.CalledOnValidThread());
71 base::AutoLock auto_lock(lock_);
72 audio_processor_ = processor; 66 audio_processor_ = processor;
73 } 67 }
74 68
69 void WebRtcLocalAudioTrackAdapter::SetLevel(
70 scoped_refptr<MediaStreamAudioLevelCalculator::Level> level) {
71 // |level_| must only be set once. This eliminates the need to protect
72 // |level_| with a mutex.
o1ka 2016/02/29 14:28:04 Same questions as for SetAudioProcessor()
miu 2016/03/01 09:43:55 Good questions. Answered in other comment.
o1ka 2016/03/01 14:18:58 Same as above: looks like just "setting it once" i
miu 2016/03/02 01:12:50 I removed these comments since I think they were m
73 DCHECK(level.get());
74 DCHECK(!level_);
75 level_ = level;
76 }
77
75 std::string WebRtcLocalAudioTrackAdapter::kind() const { 78 std::string WebRtcLocalAudioTrackAdapter::kind() const {
76 return kAudioTrackKind; 79 return kAudioTrackKind;
77 } 80 }
78 81
79 bool WebRtcLocalAudioTrackAdapter::set_enabled(bool enable) { 82 bool WebRtcLocalAudioTrackAdapter::set_enabled(bool enable) {
80 // If we're not called on the signaling thread, we need to post a task to 83 // If we're not called on the signaling thread, we need to post a task to
81 // change the state on the correct thread. 84 // change the state on the correct thread.
82 if (signaling_thread_.get() && !signaling_thread_->BelongsToCurrentThread()) { 85 if (signaling_task_runner_.get() &&
o1ka 2016/02/29 14:28:04 nit: if (signaling_task_runner_ && ...)
miu 2016/03/01 09:43:54 Done.
o1ka 2016/03/01 14:18:59 Acknowledged.
83 signaling_thread_->PostTask(FROM_HERE, 86 !signaling_task_runner_->BelongsToCurrentThread()) {
87 signaling_task_runner_->PostTask(FROM_HERE,
84 base::Bind( 88 base::Bind(
85 base::IgnoreResult(&WebRtcLocalAudioTrackAdapter::set_enabled), 89 base::IgnoreResult(&WebRtcLocalAudioTrackAdapter::set_enabled),
86 this, enable)); 90 this, enable));
87 return true; 91 return true;
88 } 92 }
89 93
90 return webrtc::MediaStreamTrack<webrtc::AudioTrackInterface>:: 94 return webrtc::MediaStreamTrack<webrtc::AudioTrackInterface>::
o1ka 2016/02/29 14:28:04 will be called from a random thread if signaling_
miu 2016/03/01 09:43:55 Explained above.
o1ka 2016/03/01 14:18:59 Acknowledged.
91 set_enabled(enable); 95 set_enabled(enable);
92 } 96 }
93 97
94 void WebRtcLocalAudioTrackAdapter::AddSink( 98 void WebRtcLocalAudioTrackAdapter::AddSink(
95 webrtc::AudioTrackSinkInterface* sink) { 99 webrtc::AudioTrackSinkInterface* sink) {
96 DCHECK(signaling_thread_checker_.CalledOnValidThread()); 100 DCHECK(!signaling_task_runner_ ||
101 signaling_task_runner_->RunsTasksOnCurrentThread());
97 DCHECK(sink); 102 DCHECK(sink);
98 #ifndef NDEBUG 103 #ifndef NDEBUG
99 // Verify that |sink| has not been added. 104 // Verify that |sink| has not been added.
100 for (ScopedVector<WebRtcAudioSinkAdapter>::const_iterator it = 105 for (ScopedVector<WebRtcAudioSinkAdapter>::const_iterator it =
101 sink_adapters_.begin(); 106 sink_adapters_.begin();
102 it != sink_adapters_.end(); ++it) { 107 it != sink_adapters_.end(); ++it) {
103 DCHECK(!(*it)->IsEqual(sink)); 108 DCHECK(!(*it)->IsEqual(sink));
104 } 109 }
105 #endif 110 #endif
106 111
107 scoped_ptr<WebRtcAudioSinkAdapter> adapter( 112 scoped_ptr<WebRtcAudioSinkAdapter> adapter(
108 new WebRtcAudioSinkAdapter(sink)); 113 new WebRtcAudioSinkAdapter(sink));
109 owner_->AddSink(adapter.get()); 114 owner_->AddSink(adapter.get());
110 sink_adapters_.push_back(adapter.release()); 115 sink_adapters_.push_back(adapter.release());
111 } 116 }
112 117
113 void WebRtcLocalAudioTrackAdapter::RemoveSink( 118 void WebRtcLocalAudioTrackAdapter::RemoveSink(
114 webrtc::AudioTrackSinkInterface* sink) { 119 webrtc::AudioTrackSinkInterface* sink) {
115 DCHECK(signaling_thread_checker_.CalledOnValidThread()); 120 DCHECK(!signaling_task_runner_ ||
121 signaling_task_runner_->RunsTasksOnCurrentThread());
116 DCHECK(sink); 122 DCHECK(sink);
117 for (ScopedVector<WebRtcAudioSinkAdapter>::iterator it = 123 for (ScopedVector<WebRtcAudioSinkAdapter>::iterator it =
118 sink_adapters_.begin(); 124 sink_adapters_.begin();
119 it != sink_adapters_.end(); ++it) { 125 it != sink_adapters_.end(); ++it) {
120 if ((*it)->IsEqual(sink)) { 126 if ((*it)->IsEqual(sink)) {
121 owner_->RemoveSink(*it); 127 owner_->RemoveSink(*it);
122 sink_adapters_.erase(it); 128 sink_adapters_.erase(it);
123 return; 129 return;
124 } 130 }
125 } 131 }
126 } 132 }
127 133
128 bool WebRtcLocalAudioTrackAdapter::GetSignalLevel(int* level) { 134 bool WebRtcLocalAudioTrackAdapter::GetSignalLevel(int* level) {
129 DCHECK(signaling_thread_checker_.CalledOnValidThread()); 135 DCHECK(!signaling_task_runner_ ||
136 signaling_task_runner_->RunsTasksOnCurrentThread());
130 137
131 base::AutoLock auto_lock(lock_); 138 // |level_| is only set once, so it's safe to read without first acquiring a
132 *level = signal_level_; 139 // mutex.
140 if (!level_)
o1ka 2016/02/29 14:28:04 How does it guarantee that there is no race?
miu 2016/03/01 09:43:54 Answered in comment above.
o1ka 2016/03/01 14:18:58 Same as above.
141 return false;
142 const float signal_level = level_->GetCurrent();
143 DCHECK_GE(signal_level, 0.0f);
144 DCHECK_LE(signal_level, 1.0f);
145 // Convert from float in range [0.0,1.0] to an int in range [0,32767].
146 *level = static_cast<int>(signal_level * std::numeric_limits<int16_t>::max() +
147 0.5f /* rounding to nearest int */);
133 return true; 148 return true;
134 } 149 }
135 150
136 rtc::scoped_refptr<webrtc::AudioProcessorInterface> 151 rtc::scoped_refptr<webrtc::AudioProcessorInterface>
137 WebRtcLocalAudioTrackAdapter::GetAudioProcessor() { 152 WebRtcLocalAudioTrackAdapter::GetAudioProcessor() {
138 DCHECK(signaling_thread_checker_.CalledOnValidThread()); 153 DCHECK(!signaling_task_runner_ ||
139 base::AutoLock auto_lock(lock_); 154 signaling_task_runner_->RunsTasksOnCurrentThread());
140 return audio_processor_.get(); 155 return audio_processor_.get();
141 } 156 }
142 157
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 { 158 webrtc::AudioSourceInterface* WebRtcLocalAudioTrackAdapter::GetSource() const {
150 DCHECK(signaling_thread_checker_.CalledOnValidThread()); 159 DCHECK(!signaling_task_runner_ ||
160 signaling_task_runner_->RunsTasksOnCurrentThread());
151 return track_source_; 161 return track_source_;
152 } 162 }
153 163
154 } // namespace content 164 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698