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

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

Issue 1599533003: MediaCaptureFromElement: add support for audio captureStream(). (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 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
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/renderer/media/html_audio_element_capturer_source.h"
6
7 #include "base/threading/thread_task_runner_handle.h"
8 #include "base/timer/elapsed_timer.h"
miu 2016/05/13 23:40:35 Seems this is not used.
mcasas 2016/05/14 02:23:47 Done.
9 #include "media/base/audio_fifo.h"
10 #include "media/base/audio_parameters.h"
11 #include "media/base/audio_renderer_sink.h"
12 #include "media/blink/webmediaplayer_impl.h"
13 #include "third_party/WebKit/public/platform/WebMediaPlayer.h"
14
15 namespace content {
16
17 namespace {
18
19 // Maximum amount of buffers that can be held in the AudioFifo.
20 static const size_t kMaxNumberOfBuffers = 10;
miu 2016/05/13 23:40:35 This can be deleted if you agree w/ my advice abou
mcasas 2016/05/14 02:23:47 Done.
21
22 } // anonymous namespace
23
24 //static
25 scoped_refptr<HtmlAudioElementCapturerSource>
26 HtmlAudioElementCapturerSource::CreateFromWebMediaPlayerImpl(
27 blink::WebMediaPlayer* player) {
28 DCHECK(player);
29 return make_scoped_refptr(new HtmlAudioElementCapturerSource(
30 static_cast<media::WebAudioSourceProviderImpl*>(
31 player->getAudioSourceProvider())
32 ->AsWeakPtr()));
33 }
34
35 HtmlAudioElementCapturerSource::HtmlAudioElementCapturerSource(
36 const base::WeakPtr<media::WebAudioSourceProviderImpl>& audio_source)
37 : audio_input_cb_(
38 base::Bind(&HtmlAudioElementCapturerSource::OnAudioBus, this)),
39 audio_source_(audio_source),
40 min_fifo_frames_for_conversion_(0) {
41 DCHECK(audio_source_);
42 }
43
44 void HtmlAudioElementCapturerSource::Initialize(
45 const media::AudioParameters& params,
46 CaptureCallback* callback,
47 int session_id) {
48 DVLOG(1) << __FUNCTION__ << params.AsHumanReadableString();
49 DCHECK(thread_checker_.CalledOnValidThread());
50
51 capture_callback_ = callback;
52 output_params_ = params;
53 }
54
55 void HtmlAudioElementCapturerSource::Start() {
56 DCHECK(thread_checker_.CalledOnValidThread());
57 if (audio_source_)
58 audio_source_->SetCopyAudioCallback(audio_input_cb_);
miu 2016/05/13 23:40:35 By creating the closure in the ctor, HtmlAudioElem
mcasas 2016/05/14 02:23:47 Absolutely! Done.
59 }
60
61 void HtmlAudioElementCapturerSource::Stop() {
62 DCHECK(thread_checker_.CalledOnValidThread());
63 if (audio_source_)
64 audio_source_->ClearCopyAudioCallback();
65 capture_callback_ = nullptr;
66 }
67
68 void HtmlAudioElementCapturerSource::SetVolume(double volume) {
69 DCHECK(thread_checker_.CalledOnValidThread());
70 }
71
72 void HtmlAudioElementCapturerSource::SetAutomaticGainControl(bool enable) {
73 DCHECK(thread_checker_.CalledOnValidThread());
74 }
75
76 void HtmlAudioElementCapturerSource::OnAudioBus(
77 std::unique_ptr<media::AudioBus> audio_bus,
78 uint32_t delay_milliseconds,
79 int sample_rate) {
80 // Create |converter_| on first frame arrival.
81 // TODO(mcasas): What if the input parameters change?
82 if (!converter_) {
83 // This parameter signifies the minimum input frames to produce a successful
84 // conversion, and is usually smaller than |audio_bus.frames()|. We use it
85 // to pull one by one converted AudioBuses out of AudioConverter.
86 min_fifo_frames_for_conversion_ = output_params_.frames_per_buffer() *
87 sample_rate /
88 output_params_.sample_rate();
89
90 input_params_ = media::AudioParameters(
91 output_params_.format(),
92 media::GuessChannelLayout(audio_bus->channels()), sample_rate,
93 output_params_.bits_per_sample(), min_fifo_frames_for_conversion_);
94 DCHECK(input_params_.IsValid());
95
96 CreateConverter();
97 }
98 DCHECK_EQ(input_params_.channels(), audio_bus->channels());
99
100 fifo_->Push(audio_bus.get());
miu 2016/05/13 23:40:35 All this code from here to the end of this method
mcasas 2016/05/14 02:23:47 Done.
101
102 // Convert() while there are enough frames queued up in |fifo_| to guarantee a
103 // satisfactory conversion and retrieval of an output buffer, i.e. there are
104 // at least |min_fifo_frames_for_conversion_|.
105 const int input_block_size = audio_bus->frames();
106 while (fifo_->frames() >= min_fifo_frames_for_conversion_) {
107 // Calculated the delay for Capture() based on the position of the converted
108 // frames in the input buffer. Frequently there are frames left over from a
109 // previous |audio_bus| and this delay will be negative.
110 const int output_block_delay = (input_block_size - fifo_->frames()) *
111 base::Time::kMillisecondsPerSecond /
112 input_params_.sample_rate();
113
114 std::unique_ptr<media::AudioBus> converted_bus = media::AudioBus::Create(
115 output_params_.channels(), output_params_.frames_per_buffer());
116 converter_->Convert(converted_bus.get());
117
118 // TODO(mcasas): The conversion process might take some time that might need
119 // to be discounted: if that's the case, add a base::ElapsedTimer before
120 // Convert() and subtract the Elapsed() time.
121 DVLOG(3) << __FUNCTION__;
122 capture_callback_->Capture(converted_bus.get(), output_block_delay,
123 1.0 /* volume */, false /* key_pressed */);
124 }
125 }
126
127 double HtmlAudioElementCapturerSource::ProvideInput(
128 media::AudioBus* audio_bus,
129 base::TimeDelta buffer_delay) {
130 DCHECK_EQ(min_fifo_frames_for_conversion_, audio_bus->frames());
131 fifo_->Consume(audio_bus, 0, audio_bus->frames());
132 return 1.0; // Return volume greater than zero to indicate we have more data.
133 }
134
135 HtmlAudioElementCapturerSource::~HtmlAudioElementCapturerSource() {
136 DCHECK(thread_checker_.CalledOnValidThread());
137 }
138
139 void HtmlAudioElementCapturerSource::CreateConverter() {
140 DCHECK(output_params_.IsValid());
141 DVLOG(1) << " Converting from: " << input_params_.AsHumanReadableString()
142 << " --> " << output_params_.AsHumanReadableString();
143
144 converter_.reset(new media::AudioConverter(input_params_, output_params_,
145 false /* disable_fifo */));
146 converter_->AddInput(this);
147 converter_->PrimeWithSilence();
148
149 fifo_.reset(new media::AudioFifo(
150 input_params_.channels(),
151 kMaxNumberOfBuffers * input_params_.frames_per_buffer()));
152 }
153
154 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698