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

Side by Side Diff: content/renderer/pepper/pepper_media_stream_audio_track_host.cc

Issue 290993005: Support configuring number of audio buffers in MediaStream Pepper API. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased Created 6 years, 6 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/pepper/pepper_media_stream_audio_track_host.h" 5 #include "content/renderer/pepper/pepper_media_stream_audio_track_host.h"
6 6
7 #include <algorithm>
8
7 #include "base/bind.h" 9 #include "base/bind.h"
8 #include "base/location.h" 10 #include "base/location.h"
9 #include "base/logging.h" 11 #include "base/logging.h"
10 #include "base/macros.h" 12 #include "base/macros.h"
11 #include "base/message_loop/message_loop_proxy.h" 13 #include "base/message_loop/message_loop_proxy.h"
12 #include "ppapi/c/pp_errors.h" 14 #include "ppapi/c/pp_errors.h"
13 #include "ppapi/c/ppb_audio_buffer.h" 15 #include "ppapi/c/ppb_audio_buffer.h"
16 #include "ppapi/host/dispatch_host_message.h"
17 #include "ppapi/host/host_message_context.h"
18 #include "ppapi/proxy/ppapi_messages.h"
19 #include "ppapi/shared_impl/media_stream_audio_track_shared.h"
14 #include "ppapi/shared_impl/media_stream_buffer.h" 20 #include "ppapi/shared_impl/media_stream_buffer.h"
15 21
16 using media::AudioParameters; 22 using media::AudioParameters;
23 using ppapi::host::HostMessageContext;
24 using ppapi::MediaStreamAudioTrackShared;
17 25
18 namespace { 26 namespace {
19 27
20 // Max audio buffer duration in milliseconds. 28 // Max audio buffer duration in milliseconds.
21 const uint32_t kMaxDuration = 10; 29 const uint32_t kMaxDuration = 10;
22 30
23 // TODO(penghuang): make this configurable. 31 const int32_t kDefaultNumberOfBuffers = 4;
24 const int32_t kNumberOfBuffers = 4; 32 const int32_t kMaxNumberOfBuffers = 1000; // 10 sec
25 33
26 // Returns true if the |sample_rate| is supported in 34 // Returns true if the |sample_rate| is supported in
27 // |PP_AudioBuffer_SampleRate|, otherwise false. 35 // |PP_AudioBuffer_SampleRate|, otherwise false.
28 PP_AudioBuffer_SampleRate GetPPSampleRate(int sample_rate) { 36 PP_AudioBuffer_SampleRate GetPPSampleRate(int sample_rate) {
29 switch (sample_rate) { 37 switch (sample_rate) {
30 case 8000: 38 case 8000:
31 return PP_AUDIOBUFFER_SAMPLERATE_8000; 39 return PP_AUDIOBUFFER_SAMPLERATE_8000;
32 case 16000: 40 case 16000:
33 return PP_AUDIOBUFFER_SAMPLERATE_16000; 41 return PP_AUDIOBUFFER_SAMPLERATE_16000;
34 case 22050: 42 case 22050:
(...skipping 15 matching lines...) Expand all
50 58
51 } // namespace 59 } // namespace
52 60
53 namespace content { 61 namespace content {
54 62
55 PepperMediaStreamAudioTrackHost::AudioSink::AudioSink( 63 PepperMediaStreamAudioTrackHost::AudioSink::AudioSink(
56 PepperMediaStreamAudioTrackHost* host) 64 PepperMediaStreamAudioTrackHost* host)
57 : host_(host), 65 : host_(host),
58 buffer_data_size_(0), 66 buffer_data_size_(0),
59 main_message_loop_proxy_(base::MessageLoopProxy::current()), 67 main_message_loop_proxy_(base::MessageLoopProxy::current()),
60 weak_factory_(this) {} 68 weak_factory_(this),
69 number_of_buffers_(kDefaultNumberOfBuffers),
70 bytes_per_second_(0) {}
61 71
62 PepperMediaStreamAudioTrackHost::AudioSink::~AudioSink() { 72 PepperMediaStreamAudioTrackHost::AudioSink::~AudioSink() {
63 DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current()); 73 DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current());
64 } 74 }
65 75
66 void PepperMediaStreamAudioTrackHost::AudioSink::EnqueueBuffer(int32_t index) { 76 void PepperMediaStreamAudioTrackHost::AudioSink::EnqueueBuffer(int32_t index) {
67 DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current()); 77 DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current());
68 DCHECK_GE(index, 0); 78 DCHECK_GE(index, 0);
69 DCHECK_LT(index, host_->buffer_manager()->number_of_buffers()); 79 DCHECK_LT(index, host_->buffer_manager()->number_of_buffers());
70 base::AutoLock lock(lock_); 80 base::AutoLock lock(lock_);
71 buffers_.push_back(index); 81 buffers_.push_back(index);
72 } 82 }
73 83
74 void PepperMediaStreamAudioTrackHost::AudioSink::InitBuffersOnMainThread( 84 void PepperMediaStreamAudioTrackHost::AudioSink::Configure(
75 int32_t number_of_buffers, 85 int32_t number_of_buffers) {
76 int32_t buffer_size) {
77 DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current()); 86 DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current());
78 bool result = host_->InitBuffers(number_of_buffers, buffer_size, kRead); 87 bool changed;
88 if (number_of_buffers != number_of_buffers_)
89 changed = true;
90 number_of_buffers_ = number_of_buffers;
91
92 // Initialize later in OnSetFormat if bytes_per_second_ is not know yet.
93 if (changed && bytes_per_second_ > 0)
94 InitBuffers();
95 }
96
97 void PepperMediaStreamAudioTrackHost::AudioSink::SetFormatOnMainThread(
98 int bytes_per_second) {
99 bytes_per_second_ = bytes_per_second;
100 InitBuffers();
101 }
102
103 void PepperMediaStreamAudioTrackHost::AudioSink::InitBuffers() {
104 DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current());
105 // The size is slightly bigger than necessary, because 8 extra bytes are
106 // added into the struct. Also see |MediaStreamBuffer|.
107 size_t buffer_size = sizeof(ppapi::MediaStreamBuffer::Audio) +
108 bytes_per_second_ * kMaxDuration / base::Time::kMillisecondsPerSecond;
109 bool result = host_->InitBuffers(number_of_buffers_,
110 static_cast<int32_t>(buffer_size),
dcheng 2014/05/28 15:55:44 Will we need to be concerned about overflow in the
thembrown 2014/05/28 17:13:11 Hm - with audio @192kHz, 16Bit, 10ch bytes_per_sec
dcheng 2014/05/28 17:21:06 We use bytes per second though, not bits. So it's
thembrown 2014/05/28 19:09:54 I was concerned about the intermediate result of (
111 kRead);
79 // TODO(penghuang): Send PP_ERROR_NOMEMORY to plugin. 112 // TODO(penghuang): Send PP_ERROR_NOMEMORY to plugin.
80 CHECK(result); 113 CHECK(result);
81 base::AutoLock lock(lock_); 114 base::AutoLock lock(lock_);
82 for (int32_t i = 0; i < number_of_buffers; ++i) { 115 buffers_.clear();
116 for (int32_t i = 0; i < number_of_buffers_; ++i) {
83 int32_t index = host_->buffer_manager()->DequeueBuffer(); 117 int32_t index = host_->buffer_manager()->DequeueBuffer();
84 DCHECK_GE(index, 0); 118 DCHECK_GE(index, 0);
85 buffers_.push_back(index); 119 buffers_.push_back(index);
86 } 120 }
87 } 121 }
88 122
89 void PepperMediaStreamAudioTrackHost::AudioSink:: 123 void PepperMediaStreamAudioTrackHost::AudioSink::
90 SendEnqueueBufferMessageOnMainThread(int32_t index) { 124 SendEnqueueBufferMessageOnMainThread(int32_t index) {
91 DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current()); 125 DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current());
92 host_->SendEnqueueBufferMessageToPlugin(index); 126 host_->SendEnqueueBufferMessageToPlugin(index);
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 buffer_data_size_ = params.GetBytesPerBuffer(); 181 buffer_data_size_ = params.GetBytesPerBuffer();
148 182
149 if (original_audio_params_.IsValid()) { 183 if (original_audio_params_.IsValid()) {
150 DCHECK_EQ(params.sample_rate(), original_audio_params_.sample_rate()); 184 DCHECK_EQ(params.sample_rate(), original_audio_params_.sample_rate());
151 DCHECK_EQ(params.bits_per_sample(), 185 DCHECK_EQ(params.bits_per_sample(),
152 original_audio_params_.bits_per_sample()); 186 original_audio_params_.bits_per_sample());
153 DCHECK_EQ(params.channels(), original_audio_params_.channels()); 187 DCHECK_EQ(params.channels(), original_audio_params_.channels());
154 } else { 188 } else {
155 audio_thread_checker_.DetachFromThread(); 189 audio_thread_checker_.DetachFromThread();
156 original_audio_params_ = params; 190 original_audio_params_ = params;
157 // The size is slightly bigger than necessary, because 8 extra bytes are
158 // added into the struct. Also see |MediaStreamBuffer|.
159 size_t max_data_size = params.sample_rate() * params.bits_per_sample() / 8 *
160 params.channels() * kMaxDuration / 1000;
161 size_t size = sizeof(ppapi::MediaStreamBuffer::Audio) + max_data_size;
162 191
163 main_message_loop_proxy_->PostTask( 192 main_message_loop_proxy_->PostTask(
164 FROM_HERE, 193 FROM_HERE,
165 base::Bind(&AudioSink::InitBuffersOnMainThread, 194 base::Bind(&AudioSink::SetFormatOnMainThread,
166 weak_factory_.GetWeakPtr(), 195 weak_factory_.GetWeakPtr(),
167 kNumberOfBuffers, 196 params.GetBytesPerSecond()));
168 static_cast<int32_t>(size)));
169 } 197 }
170 } 198 }
171 199
172 PepperMediaStreamAudioTrackHost::PepperMediaStreamAudioTrackHost( 200 PepperMediaStreamAudioTrackHost::PepperMediaStreamAudioTrackHost(
173 RendererPpapiHost* host, 201 RendererPpapiHost* host,
174 PP_Instance instance, 202 PP_Instance instance,
175 PP_Resource resource, 203 PP_Resource resource,
176 const blink::WebMediaStreamTrack& track) 204 const blink::WebMediaStreamTrack& track)
177 : PepperMediaStreamTrackHostBase(host, instance, resource), 205 : PepperMediaStreamTrackHostBase(host, instance, resource),
178 track_(track), 206 track_(track),
179 connected_(false), 207 connected_(false),
180 audio_sink_(this) { 208 audio_sink_(this) {
181 DCHECK(!track_.isNull()); 209 DCHECK(!track_.isNull());
182 } 210 }
183 211
184 PepperMediaStreamAudioTrackHost::~PepperMediaStreamAudioTrackHost() { 212 PepperMediaStreamAudioTrackHost::~PepperMediaStreamAudioTrackHost() {
185 OnClose(); 213 OnClose();
186 } 214 }
187 215
216 int32_t PepperMediaStreamAudioTrackHost::OnResourceMessageReceived(
217 const IPC::Message& msg,
218 HostMessageContext* context) {
219 PPAPI_BEGIN_MESSAGE_MAP(PepperMediaStreamAudioTrackHost, msg)
220 PPAPI_DISPATCH_HOST_RESOURCE_CALL(
221 PpapiHostMsg_MediaStreamAudioTrack_Configure, OnHostMsgConfigure)
222 PPAPI_END_MESSAGE_MAP()
223 return PepperMediaStreamTrackHostBase::OnResourceMessageReceived(msg,
224 context);
225 }
226
227 int32_t PepperMediaStreamAudioTrackHost::OnHostMsgConfigure(
228 HostMessageContext* context,
229 const MediaStreamAudioTrackShared::Attributes& attributes) {
230 if (!MediaStreamAudioTrackShared::VerifyAttributes(attributes))
231 return PP_ERROR_BADARGUMENT;
232
233 int32_t buffers = attributes.buffers
234 ? std::min(kMaxNumberOfBuffers, attributes.buffers)
235 : kDefaultNumberOfBuffers;
236 audio_sink_.Configure(buffers);
237
238 context->reply_msg = PpapiPluginMsg_MediaStreamAudioTrack_ConfigureReply();
239 return PP_OK;
240 }
241
188 void PepperMediaStreamAudioTrackHost::OnClose() { 242 void PepperMediaStreamAudioTrackHost::OnClose() {
189 if (connected_) { 243 if (connected_) {
190 MediaStreamAudioSink::RemoveFromAudioTrack(&audio_sink_, track_); 244 MediaStreamAudioSink::RemoveFromAudioTrack(&audio_sink_, track_);
191 connected_ = false; 245 connected_ = false;
192 } 246 }
193 } 247 }
194 248
195 void PepperMediaStreamAudioTrackHost::OnNewBufferEnqueued() { 249 void PepperMediaStreamAudioTrackHost::OnNewBufferEnqueued() {
196 int32_t index = buffer_manager()->DequeueBuffer(); 250 int32_t index = buffer_manager()->DequeueBuffer();
197 DCHECK_GE(index, 0); 251 DCHECK_GE(index, 0);
198 audio_sink_.EnqueueBuffer(index); 252 audio_sink_.EnqueueBuffer(index);
199 } 253 }
200 254
201 void PepperMediaStreamAudioTrackHost::DidConnectPendingHostToResource() { 255 void PepperMediaStreamAudioTrackHost::DidConnectPendingHostToResource() {
202 if (!connected_) { 256 if (!connected_) {
203 MediaStreamAudioSink::AddToAudioTrack(&audio_sink_, track_); 257 MediaStreamAudioSink::AddToAudioTrack(&audio_sink_, track_);
204 connected_ = true; 258 connected_ = true;
205 } 259 }
206 } 260 }
207 261
208 } // namespace content 262 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698