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

Side by Side Diff: content/renderer/media/webrtc_local_audio_track.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 o1ka's 2nd round of comments. 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 (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 "content/renderer/media/webrtc_local_audio_track.h" 5 #include "content/renderer/media/webrtc_local_audio_track.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <limits> 9 #include <limits>
10 10
11 #include "content/public/renderer/media_stream_audio_sink.h" 11 #include "content/public/renderer/media_stream_audio_sink.h"
12 #include "content/renderer/media/media_stream_audio_level_calculator.h"
13 #include "content/renderer/media/media_stream_audio_processor.h" 12 #include "content/renderer/media/media_stream_audio_processor.h"
14 #include "content/renderer/media/media_stream_audio_sink_owner.h" 13 #include "content/renderer/media/media_stream_audio_sink_owner.h"
15 #include "content/renderer/media/media_stream_audio_track_sink.h" 14 #include "content/renderer/media/media_stream_audio_track_sink.h"
16 #include "content/renderer/media/webaudio_capturer_source.h"
17 #include "content/renderer/media/webrtc/webrtc_local_audio_track_adapter.h" 15 #include "content/renderer/media/webrtc/webrtc_local_audio_track_adapter.h"
18 #include "content/renderer/media/webrtc_audio_capturer.h"
19 16
20 namespace content { 17 namespace content {
21 18
22 WebRtcLocalAudioTrack::WebRtcLocalAudioTrack( 19 WebRtcLocalAudioTrack::WebRtcLocalAudioTrack(
23 WebRtcLocalAudioTrackAdapter* adapter, 20 scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter)
24 const scoped_refptr<WebRtcAudioCapturer>& capturer, 21 : MediaStreamAudioTrack(true), adapter_(adapter) {
25 WebAudioCapturerSource* webaudio_source)
26 : MediaStreamAudioTrack(true),
27 adapter_(adapter),
28 capturer_(capturer),
29 webaudio_source_(webaudio_source) {
30 DCHECK(capturer.get() || webaudio_source);
31 signal_thread_checker_.DetachFromThread(); 22 signal_thread_checker_.DetachFromThread();
23 DVLOG(1) << "WebRtcLocalAudioTrack::WebRtcLocalAudioTrack()";
32 24
33 adapter_->Initialize(this); 25 adapter_->Initialize(this);
34
35 DVLOG(1) << "WebRtcLocalAudioTrack::WebRtcLocalAudioTrack()";
36 } 26 }
37 27
38 WebRtcLocalAudioTrack::~WebRtcLocalAudioTrack() { 28 WebRtcLocalAudioTrack::~WebRtcLocalAudioTrack() {
39 DCHECK(main_render_thread_checker_.CalledOnValidThread()); 29 DCHECK(main_render_thread_checker_.CalledOnValidThread());
40 DVLOG(1) << "WebRtcLocalAudioTrack::~WebRtcLocalAudioTrack()"; 30 DVLOG(1) << "WebRtcLocalAudioTrack::~WebRtcLocalAudioTrack()";
41 // Users might not call Stop() on the track. 31 // Ensure the track is stopped.
42 Stop(); 32 MediaStreamAudioTrack::Stop();
43 } 33 }
44 34
45 media::AudioParameters WebRtcLocalAudioTrack::GetOutputFormat() const { 35 media::AudioParameters WebRtcLocalAudioTrack::GetOutputFormat() const {
46 DCHECK(main_render_thread_checker_.CalledOnValidThread()); 36 DCHECK(main_render_thread_checker_.CalledOnValidThread());
47 if (webaudio_source_.get()) { 37 base::AutoLock auto_lock(lock_);
48 return media::AudioParameters(); 38 return audio_parameters_;
49 } else {
50 return capturer_->GetOutputFormat();
51 }
52 } 39 }
53 40
54 void WebRtcLocalAudioTrack::Capture(const media::AudioBus& audio_bus, 41 void WebRtcLocalAudioTrack::Capture(const media::AudioBus& audio_bus,
55 base::TimeTicks estimated_capture_time, 42 base::TimeTicks estimated_capture_time) {
56 bool force_report_nonzero_energy) {
57 DCHECK(capture_thread_checker_.CalledOnValidThread()); 43 DCHECK(capture_thread_checker_.CalledOnValidThread());
58 DCHECK(!estimated_capture_time.is_null()); 44 DCHECK(!estimated_capture_time.is_null());
59 45
60 // Calculate the signal level regardless of whether the track is disabled or
61 // enabled. If |force_report_nonzero_energy| is true, |audio_bus| contains
62 // post-processed data that may be all zeros even though the signal contained
63 // energy before the processing. In this case, report nonzero energy even if
64 // the energy of the data in |audio_bus| is zero.
65 const float minimum_signal_level =
66 force_report_nonzero_energy ? 1.0f / std::numeric_limits<int16_t>::max()
67 : 0.0f;
68 const float signal_level = std::max(
69 minimum_signal_level,
70 std::min(1.0f, level_calculator_->Calculate(audio_bus)));
71 const int signal_level_as_pcm16 =
72 static_cast<int>(signal_level * std::numeric_limits<int16_t>::max() +
73 0.5f /* rounding to nearest int */);
74 adapter_->SetSignalLevel(signal_level_as_pcm16);
75
76 scoped_refptr<WebRtcAudioCapturer> capturer;
77 SinkList::ItemList sinks; 46 SinkList::ItemList sinks;
78 SinkList::ItemList sinks_to_notify_format; 47 SinkList::ItemList sinks_to_notify_format;
79 { 48 {
80 base::AutoLock auto_lock(lock_); 49 base::AutoLock auto_lock(lock_);
81 capturer = capturer_;
82 sinks = sinks_.Items(); 50 sinks = sinks_.Items();
83 sinks_.RetrieveAndClearTags(&sinks_to_notify_format); 51 sinks_.RetrieveAndClearTags(&sinks_to_notify_format);
84 } 52 }
85 53
86 // Notify the tracks on when the format changes. This will do nothing if 54 // Notify the tracks on when the format changes. This will do nothing if
87 // |sinks_to_notify_format| is empty. 55 // |sinks_to_notify_format| is empty. Note that accessing |audio_parameters_|
56 // without holding the |lock_| is valid since |audio_parameters_| is only
57 // changed on the current thread.
88 for (const auto& sink : sinks_to_notify_format) 58 for (const auto& sink : sinks_to_notify_format)
89 sink->OnSetFormat(audio_parameters_); 59 sink->OnSetFormat(audio_parameters_);
90 60
91 // Feed the data to the sinks. 61 // Feed the data to the sinks.
92 // TODO(jiayl): we should not pass the real audio data down if the track is 62 // TODO(jiayl): we should not pass the real audio data down if the track is
93 // disabled. This is currently done so to feed input to WebRTC typing 63 // disabled. This is currently done so to feed input to WebRTC typing
94 // detection and should be changed when audio processing is moved from 64 // detection and should be changed when audio processing is moved from
95 // WebRTC to the track. 65 // WebRTC to the track.
96 for (const auto& sink : sinks) 66 for (const auto& sink : sinks)
97 sink->OnData(audio_bus, estimated_capture_time); 67 sink->OnData(audio_bus, estimated_capture_time);
98 } 68 }
99 69
100 void WebRtcLocalAudioTrack::OnSetFormat( 70 void WebRtcLocalAudioTrack::OnSetFormat(
101 const media::AudioParameters& params) { 71 const media::AudioParameters& params) {
102 DVLOG(1) << "WebRtcLocalAudioTrack::OnSetFormat()"; 72 DVLOG(1) << "WebRtcLocalAudioTrack::OnSetFormat()";
103 // If the source is restarted, we might have changed to another capture 73 // If the source is restarted, we might have changed to another capture
104 // thread. 74 // thread.
105 capture_thread_checker_.DetachFromThread(); 75 capture_thread_checker_.DetachFromThread();
106 DCHECK(capture_thread_checker_.CalledOnValidThread()); 76 DCHECK(capture_thread_checker_.CalledOnValidThread());
107 77
78 base::AutoLock auto_lock(lock_);
108 audio_parameters_ = params; 79 audio_parameters_ = params;
109 level_calculator_.reset(new MediaStreamAudioLevelCalculator());
110
111 base::AutoLock auto_lock(lock_);
112 // Remember to notify all sinks of the new format. 80 // Remember to notify all sinks of the new format.
113 sinks_.TagAll(); 81 sinks_.TagAll();
114 } 82 }
115 83
116 void WebRtcLocalAudioTrack::SetAudioProcessor(
117 const scoped_refptr<MediaStreamAudioProcessor>& processor) {
118 // if the |processor| does not have audio processing, which can happen if
119 // kDisableAudioTrackProcessing is set set or all the constraints in
120 // the |processor| are turned off. In such case, we pass NULL to the
121 // adapter to indicate that no stats can be gotten from the processor.
122 adapter_->SetAudioProcessor(processor->has_audio_processing() ?
123 processor : NULL);
124 }
125
126 void WebRtcLocalAudioTrack::AddSink(MediaStreamAudioSink* sink) { 84 void WebRtcLocalAudioTrack::AddSink(MediaStreamAudioSink* sink) {
127 // This method is called from webrtc, on the signaling thread, when the local 85 // This method is called from webrtc, on the signaling thread, when the local
128 // description is set and from the main thread from WebMediaPlayerMS::load 86 // description is set and from the main thread from WebMediaPlayerMS::load
129 // (via WebRtcLocalAudioRenderer::Start). 87 // (via WebRtcLocalAudioRenderer::Start).
130 DCHECK(main_render_thread_checker_.CalledOnValidThread() || 88 DCHECK(main_render_thread_checker_.CalledOnValidThread() ||
131 signal_thread_checker_.CalledOnValidThread()); 89 signal_thread_checker_.CalledOnValidThread());
132 DVLOG(1) << "WebRtcLocalAudioTrack::AddSink()"; 90 DVLOG(1) << "WebRtcLocalAudioTrack::AddSink()";
133 base::AutoLock auto_lock(lock_); 91 base::AutoLock auto_lock(lock_);
134 92
135 // Verify that |sink| is not already added to the list. 93 // Verify that |sink| is not already added to the list.
(...skipping 23 matching lines...) Expand all
159 MediaStreamAudioTrackSink::WrapsMediaStreamSink(sink)); 117 MediaStreamAudioTrackSink::WrapsMediaStreamSink(sink));
160 } 118 }
161 119
162 // Clear the delegate to ensure that no more capture callbacks will 120 // Clear the delegate to ensure that no more capture callbacks will
163 // be sent to this sink. Also avoids a possible crash which can happen 121 // be sent to this sink. Also avoids a possible crash which can happen
164 // if this method is called while capturing is active. 122 // if this method is called while capturing is active.
165 if (removed_item.get()) 123 if (removed_item.get())
166 removed_item->Reset(); 124 removed_item->Reset();
167 } 125 }
168 126
169 void WebRtcLocalAudioTrack::Start() {
170 DCHECK(main_render_thread_checker_.CalledOnValidThread());
171 DVLOG(1) << "WebRtcLocalAudioTrack::Start()";
172 if (webaudio_source_.get()) {
173 // If the track is hooking up with WebAudio, do NOT add the track to the
174 // capturer as its sink otherwise two streams in different clock will be
175 // pushed through the same track.
176 webaudio_source_->Start(this);
177 } else if (capturer_.get()) {
178 capturer_->AddTrack(this);
179 }
180
181 SinkList::ItemList sinks;
182 {
183 base::AutoLock auto_lock(lock_);
184 sinks = sinks_.Items();
185 }
186 for (SinkList::ItemList::const_iterator it = sinks.begin();
187 it != sinks.end();
188 ++it) {
189 (*it)->OnReadyStateChanged(blink::WebMediaStreamSource::ReadyStateLive);
190 }
191 }
192
193 void WebRtcLocalAudioTrack::SetEnabled(bool enabled) { 127 void WebRtcLocalAudioTrack::SetEnabled(bool enabled) {
194 DCHECK(main_render_thread_checker_.CalledOnValidThread()); 128 DCHECK(main_render_thread_checker_.CalledOnValidThread());
195 if (adapter_.get()) 129 if (adapter_.get())
196 adapter_->set_enabled(enabled); 130 adapter_->set_enabled(enabled);
197 } 131 }
198 132
199 void WebRtcLocalAudioTrack::Stop() { 133 void WebRtcLocalAudioTrack::OnStop() {
200 DCHECK(main_render_thread_checker_.CalledOnValidThread()); 134 DCHECK(main_render_thread_checker_.CalledOnValidThread());
201 DVLOG(1) << "WebRtcLocalAudioTrack::Stop()"; 135 DVLOG(1) << "WebRtcLocalAudioTrack::OnStop()";
202 if (!capturer_.get() && !webaudio_source_.get())
203 return;
204 136
205 if (webaudio_source_.get()) { 137 // Protect the pointers using the lock when accessing |sinks_|.
206 // Called Stop() on the |webaudio_source_| explicitly so that
207 // |webaudio_source_| won't push more data to the track anymore.
208 // Also note that the track is not registered as a sink to the |capturer_|
209 // in such case and no need to call RemoveTrack().
210 webaudio_source_->Stop();
211 } else {
212 // It is necessary to call RemoveTrack on the |capturer_| to avoid getting
213 // audio callback after Stop().
214 capturer_->RemoveTrack(this);
215 }
216
217 // Protect the pointers using the lock when accessing |sinks_| and
218 // setting the |capturer_| to NULL.
219 SinkList::ItemList sinks; 138 SinkList::ItemList sinks;
220 { 139 {
221 base::AutoLock auto_lock(lock_); 140 base::AutoLock auto_lock(lock_);
222 sinks = sinks_.Items(); 141 sinks = sinks_.Items();
223 sinks_.Clear(); 142 sinks_.Clear();
o1ka 2016/03/02 16:31:14 Not your change, but probably RetrieveAndClearTags
miu 2016/03/02 23:38:10 The call to sinks_.Clear() also empties the tagged
o1ka 2016/03/07 16:00:28 Acknowledged.
224 webaudio_source_ = NULL;
225 capturer_ = NULL;
226 } 143 }
227 144
228 for (SinkList::ItemList::const_iterator it = sinks.begin(); 145 for (SinkList::ItemList::const_iterator it = sinks.begin();
229 it != sinks.end(); 146 it != sinks.end();
230 ++it){ 147 ++it){
231 (*it)->OnReadyStateChanged(blink::WebMediaStreamSource::ReadyStateEnded); 148 (*it)->OnReadyStateChanged(blink::WebMediaStreamSource::ReadyStateEnded);
232 (*it)->Reset(); 149 (*it)->Reset();
233 } 150 }
234 } 151 }
235 152
236 webrtc::AudioTrackInterface* WebRtcLocalAudioTrack::GetAudioAdapter() { 153 webrtc::AudioTrackInterface* WebRtcLocalAudioTrack::GetAudioAdapter() {
237 DCHECK(main_render_thread_checker_.CalledOnValidThread()); 154 DCHECK(main_render_thread_checker_.CalledOnValidThread());
238 return adapter_.get(); 155 return adapter_.get();
239 } 156 }
240 157
241 } // namespace content 158 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698