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

Side by Side Diff: content/renderer/media/webrtc_local_audio_track.cc

Issue 1780653002: Revert of MediaStream audio object graph untangling and clean-ups. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 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" 12 #include "content/renderer/media/media_stream_audio_level_calculator.h"
13 #include "content/renderer/media/media_stream_audio_processor.h" 13 #include "content/renderer/media/media_stream_audio_processor.h"
14 #include "content/renderer/media/media_stream_audio_sink_owner.h" 14 #include "content/renderer/media/media_stream_audio_sink_owner.h"
15 #include "content/renderer/media/media_stream_audio_track_sink.h" 15 #include "content/renderer/media/media_stream_audio_track_sink.h"
16 #include "content/renderer/media/webaudio_capturer_source.h"
16 #include "content/renderer/media/webrtc/webrtc_local_audio_track_adapter.h" 17 #include "content/renderer/media/webrtc/webrtc_local_audio_track_adapter.h"
18 #include "content/renderer/media/webrtc_audio_capturer.h"
17 19
18 namespace content { 20 namespace content {
19 21
20 WebRtcLocalAudioTrack::WebRtcLocalAudioTrack( 22 WebRtcLocalAudioTrack::WebRtcLocalAudioTrack(
21 scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter) 23 WebRtcLocalAudioTrackAdapter* adapter,
22 : MediaStreamAudioTrack(true), adapter_(std::move(adapter)) { 24 const scoped_refptr<WebRtcAudioCapturer>& capturer,
25 WebAudioCapturerSource* webaudio_source)
26 : MediaStreamAudioTrack(true),
27 adapter_(adapter),
28 capturer_(capturer),
29 webaudio_source_(webaudio_source) {
30 DCHECK(capturer.get() || webaudio_source);
23 signal_thread_checker_.DetachFromThread(); 31 signal_thread_checker_.DetachFromThread();
24 DVLOG(1) << "WebRtcLocalAudioTrack::WebRtcLocalAudioTrack()";
25 32
26 adapter_->Initialize(this); 33 adapter_->Initialize(this);
34
35 DVLOG(1) << "WebRtcLocalAudioTrack::WebRtcLocalAudioTrack()";
27 } 36 }
28 37
29 WebRtcLocalAudioTrack::~WebRtcLocalAudioTrack() { 38 WebRtcLocalAudioTrack::~WebRtcLocalAudioTrack() {
30 DCHECK(main_render_thread_checker_.CalledOnValidThread()); 39 DCHECK(main_render_thread_checker_.CalledOnValidThread());
31 DVLOG(1) << "WebRtcLocalAudioTrack::~WebRtcLocalAudioTrack()"; 40 DVLOG(1) << "WebRtcLocalAudioTrack::~WebRtcLocalAudioTrack()";
32 // Ensure the track is stopped. 41 // Users might not call Stop() on the track.
33 MediaStreamAudioTrack::Stop(); 42 Stop();
34 } 43 }
35 44
36 media::AudioParameters WebRtcLocalAudioTrack::GetOutputFormat() const { 45 media::AudioParameters WebRtcLocalAudioTrack::GetOutputFormat() const {
37 DCHECK(main_render_thread_checker_.CalledOnValidThread()); 46 DCHECK(main_render_thread_checker_.CalledOnValidThread());
38 base::AutoLock auto_lock(lock_); 47 if (webaudio_source_.get()) {
39 return audio_parameters_; 48 return media::AudioParameters();
49 } else {
50 return capturer_->GetOutputFormat();
51 }
40 } 52 }
41 53
42 void WebRtcLocalAudioTrack::Capture(const media::AudioBus& audio_bus, 54 void WebRtcLocalAudioTrack::Capture(const media::AudioBus& audio_bus,
43 base::TimeTicks estimated_capture_time) { 55 base::TimeTicks estimated_capture_time,
56 bool force_report_nonzero_energy) {
44 DCHECK(capture_thread_checker_.CalledOnValidThread()); 57 DCHECK(capture_thread_checker_.CalledOnValidThread());
45 DCHECK(!estimated_capture_time.is_null()); 58 DCHECK(!estimated_capture_time.is_null());
46 59
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;
47 SinkList::ItemList sinks; 77 SinkList::ItemList sinks;
48 SinkList::ItemList sinks_to_notify_format; 78 SinkList::ItemList sinks_to_notify_format;
49 { 79 {
50 base::AutoLock auto_lock(lock_); 80 base::AutoLock auto_lock(lock_);
81 capturer = capturer_;
51 sinks = sinks_.Items(); 82 sinks = sinks_.Items();
52 sinks_.RetrieveAndClearTags(&sinks_to_notify_format); 83 sinks_.RetrieveAndClearTags(&sinks_to_notify_format);
53 } 84 }
54 85
55 // Notify the tracks on when the format changes. This will do nothing if 86 // Notify the tracks on when the format changes. This will do nothing if
56 // |sinks_to_notify_format| is empty. Note that accessing |audio_parameters_| 87 // |sinks_to_notify_format| is empty.
57 // without holding the |lock_| is valid since |audio_parameters_| is only
58 // changed on the current thread.
59 for (const auto& sink : sinks_to_notify_format) 88 for (const auto& sink : sinks_to_notify_format)
60 sink->OnSetFormat(audio_parameters_); 89 sink->OnSetFormat(audio_parameters_);
61 90
62 // Feed the data to the sinks. 91 // Feed the data to the sinks.
63 // TODO(jiayl): we should not pass the real audio data down if the track is 92 // TODO(jiayl): we should not pass the real audio data down if the track is
64 // disabled. This is currently done so to feed input to WebRTC typing 93 // disabled. This is currently done so to feed input to WebRTC typing
65 // detection and should be changed when audio processing is moved from 94 // detection and should be changed when audio processing is moved from
66 // WebRTC to the track. 95 // WebRTC to the track.
67 for (const auto& sink : sinks) 96 for (const auto& sink : sinks)
68 sink->OnData(audio_bus, estimated_capture_time); 97 sink->OnData(audio_bus, estimated_capture_time);
69 } 98 }
70 99
71 void WebRtcLocalAudioTrack::OnSetFormat( 100 void WebRtcLocalAudioTrack::OnSetFormat(
72 const media::AudioParameters& params) { 101 const media::AudioParameters& params) {
73 DVLOG(1) << "WebRtcLocalAudioTrack::OnSetFormat()"; 102 DVLOG(1) << "WebRtcLocalAudioTrack::OnSetFormat()";
74 // If the source is restarted, we might have changed to another capture 103 // If the source is restarted, we might have changed to another capture
75 // thread. 104 // thread.
76 capture_thread_checker_.DetachFromThread(); 105 capture_thread_checker_.DetachFromThread();
77 DCHECK(capture_thread_checker_.CalledOnValidThread()); 106 DCHECK(capture_thread_checker_.CalledOnValidThread());
78 107
108 audio_parameters_ = params;
109 level_calculator_.reset(new MediaStreamAudioLevelCalculator());
110
79 base::AutoLock auto_lock(lock_); 111 base::AutoLock auto_lock(lock_);
80 audio_parameters_ = params;
81 // Remember to notify all sinks of the new format. 112 // Remember to notify all sinks of the new format.
82 sinks_.TagAll(); 113 sinks_.TagAll();
83 } 114 }
84 115
85 void WebRtcLocalAudioTrack::SetLevel(
86 scoped_refptr<MediaStreamAudioLevelCalculator::Level> level) {
87 adapter_->SetLevel(std::move(level));
88 }
89
90 void WebRtcLocalAudioTrack::SetAudioProcessor( 116 void WebRtcLocalAudioTrack::SetAudioProcessor(
91 scoped_refptr<MediaStreamAudioProcessor> processor) { 117 const scoped_refptr<MediaStreamAudioProcessor>& processor) {
92 adapter_->SetAudioProcessor(std::move(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);
93 } 124 }
94 125
95 void WebRtcLocalAudioTrack::AddSink(MediaStreamAudioSink* sink) { 126 void WebRtcLocalAudioTrack::AddSink(MediaStreamAudioSink* sink) {
96 // This method is called from webrtc, on the signaling thread, when the local 127 // This method is called from webrtc, on the signaling thread, when the local
97 // description is set and from the main thread from WebMediaPlayerMS::load 128 // description is set and from the main thread from WebMediaPlayerMS::load
98 // (via WebRtcLocalAudioRenderer::Start). 129 // (via WebRtcLocalAudioRenderer::Start).
99 DCHECK(main_render_thread_checker_.CalledOnValidThread() || 130 DCHECK(main_render_thread_checker_.CalledOnValidThread() ||
100 signal_thread_checker_.CalledOnValidThread()); 131 signal_thread_checker_.CalledOnValidThread());
101 DVLOG(1) << "WebRtcLocalAudioTrack::AddSink()"; 132 DVLOG(1) << "WebRtcLocalAudioTrack::AddSink()";
102 base::AutoLock auto_lock(lock_); 133 base::AutoLock auto_lock(lock_);
(...skipping 25 matching lines...) Expand all
128 MediaStreamAudioTrackSink::WrapsMediaStreamSink(sink)); 159 MediaStreamAudioTrackSink::WrapsMediaStreamSink(sink));
129 } 160 }
130 161
131 // Clear the delegate to ensure that no more capture callbacks will 162 // Clear the delegate to ensure that no more capture callbacks will
132 // be sent to this sink. Also avoids a possible crash which can happen 163 // be sent to this sink. Also avoids a possible crash which can happen
133 // if this method is called while capturing is active. 164 // if this method is called while capturing is active.
134 if (removed_item.get()) 165 if (removed_item.get())
135 removed_item->Reset(); 166 removed_item->Reset();
136 } 167 }
137 168
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
138 void WebRtcLocalAudioTrack::SetEnabled(bool enabled) { 193 void WebRtcLocalAudioTrack::SetEnabled(bool enabled) {
139 DCHECK(main_render_thread_checker_.CalledOnValidThread()); 194 DCHECK(main_render_thread_checker_.CalledOnValidThread());
140 if (adapter_.get()) 195 if (adapter_.get())
141 adapter_->set_enabled(enabled); 196 adapter_->set_enabled(enabled);
142 } 197 }
143 198
144 void WebRtcLocalAudioTrack::OnStop() { 199 void WebRtcLocalAudioTrack::Stop() {
145 DCHECK(main_render_thread_checker_.CalledOnValidThread()); 200 DCHECK(main_render_thread_checker_.CalledOnValidThread());
146 DVLOG(1) << "WebRtcLocalAudioTrack::OnStop()"; 201 DVLOG(1) << "WebRtcLocalAudioTrack::Stop()";
202 if (!capturer_.get() && !webaudio_source_.get())
203 return;
147 204
148 // Protect the pointers using the lock when accessing |sinks_|. 205 if (webaudio_source_.get()) {
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.
149 SinkList::ItemList sinks; 219 SinkList::ItemList sinks;
150 { 220 {
151 base::AutoLock auto_lock(lock_); 221 base::AutoLock auto_lock(lock_);
152 sinks = sinks_.Items(); 222 sinks = sinks_.Items();
153 sinks_.Clear(); 223 sinks_.Clear();
224 webaudio_source_ = NULL;
225 capturer_ = NULL;
154 } 226 }
155 227
156 for (SinkList::ItemList::const_iterator it = sinks.begin(); 228 for (SinkList::ItemList::const_iterator it = sinks.begin();
157 it != sinks.end(); 229 it != sinks.end();
158 ++it){ 230 ++it){
159 (*it)->OnReadyStateChanged(blink::WebMediaStreamSource::ReadyStateEnded); 231 (*it)->OnReadyStateChanged(blink::WebMediaStreamSource::ReadyStateEnded);
160 (*it)->Reset(); 232 (*it)->Reset();
161 } 233 }
162 } 234 }
163 235
164 webrtc::AudioTrackInterface* WebRtcLocalAudioTrack::GetAudioAdapter() { 236 webrtc::AudioTrackInterface* WebRtcLocalAudioTrack::GetAudioAdapter() {
165 DCHECK(main_render_thread_checker_.CalledOnValidThread()); 237 DCHECK(main_render_thread_checker_.CalledOnValidThread());
166 return adapter_.get(); 238 return adapter_.get();
167 } 239 }
168 240
169 } // namespace content 241 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/webrtc_local_audio_track.h ('k') | content/renderer/media/webrtc_local_audio_track_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698