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

Side by Side Diff: media/audio/virtual_audio_input_stream.cc

Issue 11298006: Browser-wide audio mirroring for TabCapture API (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Adress comments Created 8 years 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 | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "media/audio/virtual_audio_input_stream.h"
6
7 #include <algorithm>
8
9 #include "base/bind.h"
10 #include "base/message_loop.h"
11 #include "media/audio/virtual_audio_output_stream.h"
12
13 namespace media {
14
15 // AudioConverter that can also be used an as InputCallback. This allows this
16 // audio conversion from input to output params to be used as an input stream to
17 // other AudioConverters.
18 class LoopbackAudioConverter
19 : public AudioConverter,
20 public AudioConverter::InputCallback {
21 public:
22 LoopbackAudioConverter(const AudioParameters& input_params,
23 const AudioParameters& output_params);
24 virtual ~LoopbackAudioConverter() {}
25
26 private:
27 virtual double ProvideInput(
28 AudioBus* audio_bus, base::TimeDelta buffer_delay) OVERRIDE;
29
30 DISALLOW_COPY_AND_ASSIGN(LoopbackAudioConverter);
31 };
32
33 VirtualAudioInputStream* VirtualAudioInputStream::MakeStream(
34 AudioManagerBase* manager, const AudioParameters& params) {
35 return new VirtualAudioInputStream(manager, params);
36 }
37
38 VirtualAudioInputStream::VirtualAudioInputStream(AudioManagerBase* manager,
39 const AudioParameters& params)
40 : audio_manager_(manager),
41 callback_(NULL),
42 callback_delay_(static_cast<float>(params.frames_per_buffer())
miu 2012/11/26 21:14:55 Consider changing this to: callback_delay_(base
justinlin 2012/11/27 22:26:12 Done. Thanks
43 / params.sample_rate()
44 * base::Time::kMillisecondsPerSecond),
45 buffer_(new uint8[params.GetBytesPerBuffer()]),
46 params_(params),
47 audio_bus_(AudioBus::Create(params_)),
48 mixer_(params_, params_, false) {
49 }
50
51 VirtualAudioInputStream::~VirtualAudioInputStream() {
52 for (AudioConvertersMap::iterator it = converters_.begin();
53 it != converters_.end(); ++it) {
54 delete it->second;
55 }
56 }
57
58 bool VirtualAudioInputStream::Open() {
59 memset(buffer_.get(), 0, params_.GetBytesPerBuffer());
60 return true;
61 }
62
63 void VirtualAudioInputStream::Start(AudioInputCallback* callback) {
64 DCHECK(audio_manager_->GetMessageLoop()->BelongsToCurrentThread());
65 callback_ = callback;
66 on_more_data_cb_.Reset(base::Bind(
67 &VirtualAudioInputStream::DoCallback, base::Unretained(this)));
68 audio_manager_->GetMessageLoop()->PostTask(
69 FROM_HERE, on_more_data_cb_.callback());
70 }
71
72 void VirtualAudioInputStream::Stop() {
73 on_more_data_cb_.Cancel();
74 }
75
76 void VirtualAudioInputStream::AddOutputStream(
77 VirtualAudioOutputStream* stream, const AudioParameters& params) {
78 DCHECK(audio_manager_->GetMessageLoop()->BelongsToCurrentThread());
79 output_params_.insert(std::make_pair(stream, params));
80
81 LoopbackAudioConverter*& converter = converters_[params];
82 if (!converter) {
83 converter = new LoopbackAudioConverter(params, params_);
84 // Add to main mixer if we just added a new AudioTransform.
85 mixer_.AddInput(converter);
86 }
87 converter->AddInput(stream);
88 }
89
90 void VirtualAudioInputStream::RemoveOutputStream(
91 VirtualAudioOutputStream* stream) {
92 DCHECK(audio_manager_->GetMessageLoop()->BelongsToCurrentThread());
93 DCHECK(output_params_.find(stream) != output_params_.end());
94 const AudioParameters& params = output_params_[stream];
95
96 DCHECK(converters_.find(params) != converters_.end());
97 converters_[params]->RemoveInput(stream);
98 // TODO(justinlin): Do we need to delete the AudioConverter and remove it from
99 // the mixer when there's no more input streams?
100
101 output_params_.erase(stream);
102 }
103
104 void VirtualAudioInputStream::DoCallback() {
105 DCHECK(audio_manager_->GetMessageLoop()->BelongsToCurrentThread());
106 DCHECK(callback_);
107
108 mixer_.Convert(audio_bus_.get());
109 audio_bus_->ToInterleaved(params_.frames_per_buffer(),
110 params_.bits_per_sample() / 8,
111 buffer_.get());
112
113 callback_->OnData(this, buffer_.get(), params_.GetBytesPerBuffer(),
114 params_.GetBytesPerBuffer(), 1.0);
115
116 // TODO(justinlin): DO_NOT_SUBMIT, try out Yuri's idea for scheduling next
miu 2012/11/26 21:14:55 I think you meant to include the timestamp-based s
justinlin 2012/11/27 22:26:12 Done.
117 // time.
118
119 MessageLoop::current()->PostDelayedTask(
no longer working on chromium 2012/11/27 12:36:15 you should cache the message loop for the polling
justinlin 2012/11/27 22:26:12 Hmm.. is it safe to schedule into that message loo
120 FROM_HERE, on_more_data_cb_.callback(),
121 base::TimeDelta::FromMilliseconds(callback_delay_));
122 }
123
124 void VirtualAudioInputStream::Close() {
125 DCHECK(audio_manager_->GetMessageLoop()->BelongsToCurrentThread());
126 if (callback_) {
127 DCHECK(on_more_data_cb_.IsCancelled());
128 callback_->OnClose(this);
129 callback_ = NULL;
130 }
131 audio_manager_->ReleaseInputStream(this);
132 }
133
134 double VirtualAudioInputStream::GetMaxVolume() {
135 return 1.0;
136 }
137
138 void VirtualAudioInputStream::SetVolume(double volume) {}
139
140 double VirtualAudioInputStream::GetVolume() {
141 return 1.0;
142 }
143
144 void VirtualAudioInputStream::SetAutomaticGainControl(bool enabled) {}
145
146 bool VirtualAudioInputStream::GetAutomaticGainControl() {
147 return false;
148 }
149
150 LoopbackAudioConverter::LoopbackAudioConverter(
151 const AudioParameters& input_params, const AudioParameters& output_params)
152 : AudioConverter(input_params, output_params, false) {
153 }
154
155 double LoopbackAudioConverter::ProvideInput(
156 AudioBus* audio_bus, base::TimeDelta buffer_delay) {
157 Convert(audio_bus);
158 return 1.0;
159 }
160
161 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698