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

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

Issue 1834323002: MediaStream audio: Refactor 3 separate "glue" implementations into one. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Comments about PS1 addressed. Fixed is_stopped_/StopSource() foo. REBASE Created 4 years, 8 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/webaudio_capturer_source.h" 5 #include "content/renderer/media/webaudio_media_stream_source.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "content/renderer/media/webrtc_local_audio_track.h"
11
12 using media::AudioBus;
13 using media::AudioParameters;
14 using media::ChannelLayout;
15 using media::CHANNEL_LAYOUT_MONO;
16 using media::CHANNEL_LAYOUT_STEREO;
17 10
18 namespace content { 11 namespace content {
19 12
20 WebAudioCapturerSource::WebAudioCapturerSource( 13 WebAudioMediaStreamSource::WebAudioMediaStreamSource(
21 blink::WebMediaStreamSource* blink_source) 14 blink::WebMediaStreamSource* blink_source)
22 : track_(NULL), 15 : MediaStreamAudioSource(false /* is_remote */),
23 audio_format_changed_(false), 16 is_registered_consumer_(false),
24 fifo_(base::Bind(&WebAudioCapturerSource::DeliverRebufferedAudio, 17 fifo_(base::Bind(&WebAudioMediaStreamSource::DeliverRebufferedAudio,
25 base::Unretained(this))), 18 base::Unretained(this))),
26 blink_source_(*blink_source) { 19 blink_source_(*blink_source) {
27 DCHECK(blink_source); 20 DVLOG(1) << "WebAudioMediaStreamSource::WebAudioMediaStreamSource()";
28 DCHECK(!blink_source_.isNull());
29 DVLOG(1) << "WebAudioCapturerSource::WebAudioCapturerSource()";
30 blink_source_.addAudioConsumer(this);
31 } 21 }
32 22
33 WebAudioCapturerSource::~WebAudioCapturerSource() { 23 WebAudioMediaStreamSource::~WebAudioMediaStreamSource() {
34 DCHECK(thread_checker_.CalledOnValidThread()); 24 DVLOG(1) << "WebAudioMediaStreamSource::~WebAudioMediaStreamSource()";
35 DVLOG(1) << "WebAudioCapturerSource::~WebAudioCapturerSource()"; 25 EnsureSourceIsStopped();
36 DeregisterFromBlinkSource();
37 } 26 }
38 27
39 void WebAudioCapturerSource::setFormat( 28 void WebAudioMediaStreamSource::setFormat(size_t number_of_channels,
40 size_t number_of_channels, float sample_rate) { 29 float sample_rate) {
41 DCHECK(thread_checker_.CalledOnValidThread()); 30 DCHECK(thread_checker_.CalledOnValidThread());
42 DVLOG(1) << "WebAudioCapturerSource::setFormat(sample_rate=" 31 VLOG(1) << "WebAudio media stream source changed format to: channels="
43 << sample_rate << ")"; 32 << number_of_channels << ", sample_rate=" << sample_rate;
44 33
45 // If the channel count is greater than 8, use discrete layout. However, 34 // If the channel count is greater than 8, use discrete layout. However,
46 // anything beyond 8 is ignored by the subsequent (WebRTC) audio pipeline. 35 // anything beyond 8 is ignored by some audio tracks/sinks.
47 ChannelLayout channel_layout = 36 media::ChannelLayout channel_layout =
48 number_of_channels > 8 ? media::CHANNEL_LAYOUT_DISCRETE 37 number_of_channels > 8 ? media::CHANNEL_LAYOUT_DISCRETE
49 : media::GuessChannelLayout(number_of_channels); 38 : media::GuessChannelLayout(number_of_channels);
50 39
51 base::AutoLock auto_lock(lock_); 40 // Set the format used by this WebAudioMediaStreamSource. We are using 10ms
41 // data as a buffer size since that is the native buffer size of WebRtc packet
42 // running on.
43 //
44 // TODO(miu): Re-evaluate whether this is needed. For now (this refactoring),
45 // I did not want to change behavior. http://crbug.com/577874
46 fifo_.Reset(sample_rate / 100);
47 media::AudioParameters params(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
48 channel_layout, sample_rate, 16,
49 fifo_.frames_per_buffer());
50 // Take care of the discrete channel layout case.
51 params.set_channels_for_discrete(number_of_channels);
52 MediaStreamAudioSource::SetFormat(params);
52 53
53 // Set the format used by this WebAudioCapturerSource. We are using 10ms data 54 if (!wrapper_bus_ || wrapper_bus_->channels() != params.channels())
54 // as buffer size since that is the native buffer size of WebRtc packet 55 wrapper_bus_ = media::AudioBus::CreateWrapper(params.channels());
55 // running on. 56 }
56 fifo_.Reset(sample_rate / 100);
57 params_.Reset(media::AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout,
58 sample_rate, 16, fifo_.frames_per_buffer());
59 57
60 // Take care of the discrete channel layout case. 58 bool WebAudioMediaStreamSource::EnsureSourceIsStarted() {
61 params_.set_channels_for_discrete(number_of_channels); 59 DCHECK(thread_checker_.CalledOnValidThread());
60 if (is_registered_consumer_)
61 return true;
62 if (blink_source_.isNull() || !blink_source_.requiresAudioConsumer())
63 return false;
64 VLOG(1) << "Starting WebAudio media stream source.";
65 blink_source_.addAudioConsumer(this);
66 is_registered_consumer_ = true;
67 return true;
68 }
62 69
63 audio_format_changed_ = true; 70 void WebAudioMediaStreamSource::EnsureSourceIsStopped() {
64 71 DCHECK(thread_checker_.CalledOnValidThread());
65 if (!wrapper_bus_ || 72 if (is_registered_consumer_) {
66 wrapper_bus_->channels() != static_cast<int>(number_of_channels)) { 73 if (!blink_source_.isNull()) {
67 wrapper_bus_ = AudioBus::CreateWrapper(params_.channels()); 74 blink_source_.removeAudioConsumer(this);
75 blink_source_.reset();
76 is_registered_consumer_ = false;
77 VLOG(1) << "Stopped WebAudio media stream source. Final audio "
78 "parameters={"
79 << GetAudioParameters().AsHumanReadableString() << "}.";
80 }
68 } 81 }
69 } 82 }
70 83
71 void WebAudioCapturerSource::Start(WebRtcLocalAudioTrack* track) { 84 void WebAudioMediaStreamSource::consumeAudio(
72 DCHECK(thread_checker_.CalledOnValidThread());
73 DCHECK(track);
74 base::AutoLock auto_lock(lock_);
75 track_ = track;
76 }
77
78 void WebAudioCapturerSource::Stop() {
79 DCHECK(thread_checker_.CalledOnValidThread());
80 {
81 base::AutoLock auto_lock(lock_);
82 track_ = NULL;
83 }
84 // DeregisterFromBlinkSource() should not be called while |lock_| is acquired,
85 // as it could result in a deadlock.
86 DeregisterFromBlinkSource();
87 }
88
89 void WebAudioCapturerSource::consumeAudio(
90 const blink::WebVector<const float*>& audio_data, 85 const blink::WebVector<const float*>& audio_data,
91 size_t number_of_frames) { 86 size_t number_of_frames) {
92 // TODO(miu): Plumbing is needed to determine the actual capture timestamp 87 // TODO(miu): Plumbing is needed to determine the actual capture timestamp
93 // of the audio, instead of just snapshotting TimeTicks::Now(), for proper 88 // of the audio, instead of just snapshotting TimeTicks::Now(), for proper
94 // audio/video sync. http://crbug.com/335335 89 // audio/video sync. http://crbug.com/335335
95 current_reference_time_ = base::TimeTicks::Now(); 90 current_reference_time_ = base::TimeTicks::Now();
96 91
97 base::AutoLock auto_lock(lock_);
98 if (!track_)
99 return;
100
101 // Update the downstream client if the audio format has been changed.
102 if (audio_format_changed_) {
103 track_->OnSetFormat(params_);
104 audio_format_changed_ = false;
105 }
106
107 wrapper_bus_->set_frames(number_of_frames); 92 wrapper_bus_->set_frames(number_of_frames);
o1ka 2016/04/01 15:11:41 Don't you need to protect |wrapper_bus_| from the
miu 2016/04/08 18:36:47 The header file includes a comment for these metho
108 DCHECK_EQ(params_.channels(), static_cast<int>(audio_data.size())); 93 DCHECK_EQ(wrapper_bus_->channels(), static_cast<int>(audio_data.size()));
109 for (size_t i = 0; i < audio_data.size(); ++i) 94 for (size_t i = 0; i < audio_data.size(); ++i)
110 wrapper_bus_->SetChannelData(i, const_cast<float*>(audio_data[i])); 95 wrapper_bus_->SetChannelData(i, const_cast<float*>(audio_data[i]));
111 96
112 // The following will result in zero, one, or multiple synchronous calls to 97 // The following will result in zero, one, or multiple synchronous calls to
113 // DeliverRebufferedAudio(). 98 // DeliverRebufferedAudio().
114 fifo_.Push(*wrapper_bus_); 99 fifo_.Push(*wrapper_bus_);
115 } 100 }
116 101
117 void WebAudioCapturerSource::DeliverRebufferedAudio( 102 void WebAudioMediaStreamSource::DeliverRebufferedAudio(
118 const media::AudioBus& audio_bus, 103 const media::AudioBus& audio_bus,
119 int frame_delay) { 104 int frame_delay) {
120 lock_.AssertAcquired();
121 const base::TimeTicks reference_time = 105 const base::TimeTicks reference_time =
122 current_reference_time_ + 106 current_reference_time_ +
123 base::TimeDelta::FromMicroseconds(frame_delay * 107 base::TimeDelta::FromMicroseconds(
124 base::Time::kMicrosecondsPerSecond / 108 frame_delay * base::Time::kMicrosecondsPerSecond /
125 params_.sample_rate()); 109 MediaStreamAudioSource::GetAudioParameters().sample_rate());
126 track_->Capture(audio_bus, reference_time); 110 MediaStreamAudioSource::DeliverDataToTracks(audio_bus, reference_time);
127 }
128
129 void WebAudioCapturerSource::DeregisterFromBlinkSource() {
130 if (!blink_source_.isNull()) {
131 blink_source_.removeAudioConsumer(this);
132 blink_source_.reset();
133 }
134 } 111 }
135 112
136 } // namespace content 113 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698