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

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: Fix review issues 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
dmichael (off chromium) 2014/05/27 20:22:33 I'm slightly surprised that this isn't part of the
thembrown 2014/05/28 10:55:59 Hm, adding it to Attributes::VerifyAttributes woul
dmichael (off chromium) 2014/05/28 15:27:43 Makes sense, thanks.
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
84 void PepperMediaStreamAudioTrackHost::AudioSink::Configure(
85 int32_t number_of_buffers) {
86 bool changed;
dmichael (off chromium) 2014/05/27 20:22:33 I think it would be good to have the same DCHECK_E
thembrown 2014/05/28 10:55:59 Done.
87 if (number_of_buffers != number_of_buffers_)
88 changed = true;
89 number_of_buffers_ = number_of_buffers;
90
91 // Initialize later in OnSetFormat if bytes_per_second_ is not know yet.
92 if (changed && bytes_per_second_ > 0)
93 InitBuffers();
94 }
95
74 void PepperMediaStreamAudioTrackHost::AudioSink::InitBuffersOnMainThread( 96 void PepperMediaStreamAudioTrackHost::AudioSink::InitBuffersOnMainThread(
75 int32_t number_of_buffers, 97 int bytes_per_second) {
76 int32_t buffer_size) { 98 bytes_per_second_ = bytes_per_second;
99 InitBuffers();
100 }
101
102 void PepperMediaStreamAudioTrackHost::AudioSink::InitBuffers() {
dmichael (off chromium) 2014/05/27 20:22:33 These two names (InitBuffers and InitBuffersOnMain
thembrown 2014/05/28 10:55:59 Agreed. Changed to SetFormatOnMainThread.
77 DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current()); 103 DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current());
78 bool result = host_->InitBuffers(number_of_buffers, buffer_size, kRead); 104 // The size is slightly bigger than necessary, because 8 extra bytes are
105 // added into the struct. Also see |MediaStreamBuffer|.
106 size_t buffer_size = sizeof(ppapi::MediaStreamBuffer::Audio) +
107 bytes_per_second_ * kMaxDuration / base::Time::kMicrosecondsPerSecond;
dmichael (off chromium) 2014/05/27 20:22:33 The way I'm reading this, you're now dividing by 1
thembrown 2014/05/28 10:55:59 Changed. I guess it was too late for me yesterday.
108 bool result = host_->InitBuffers(number_of_buffers_,
109 static_cast<int32_t>(buffer_size),
110 kRead);
dmichael (off chromium) 2014/05/27 20:22:33 nit: indentation is off. It looks like they all wi
thembrown 2014/05/28 10:55:59 Done.
79 // TODO(penghuang): Send PP_ERROR_NOMEMORY to plugin. 111 // TODO(penghuang): Send PP_ERROR_NOMEMORY to plugin.
80 CHECK(result); 112 CHECK(result);
81 base::AutoLock lock(lock_); 113 base::AutoLock lock(lock_);
82 for (int32_t i = 0; i < number_of_buffers; ++i) { 114 buffers_.clear();
115 for (int32_t i = 0; i < number_of_buffers_; ++i) {
83 int32_t index = host_->buffer_manager()->DequeueBuffer(); 116 int32_t index = host_->buffer_manager()->DequeueBuffer();
84 DCHECK_GE(index, 0); 117 DCHECK_GE(index, 0);
85 buffers_.push_back(index); 118 buffers_.push_back(index);
86 } 119 }
87 } 120 }
88 121
89 void PepperMediaStreamAudioTrackHost::AudioSink:: 122 void PepperMediaStreamAudioTrackHost::AudioSink::
90 SendEnqueueBufferMessageOnMainThread(int32_t index) { 123 SendEnqueueBufferMessageOnMainThread(int32_t index) {
91 DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current()); 124 DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current());
92 host_->SendEnqueueBufferMessageToPlugin(index); 125 host_->SendEnqueueBufferMessageToPlugin(index);
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 buffer_data_size_ = params.GetBytesPerBuffer(); 180 buffer_data_size_ = params.GetBytesPerBuffer();
148 181
149 if (original_audio_params_.IsValid()) { 182 if (original_audio_params_.IsValid()) {
150 DCHECK_EQ(params.sample_rate(), original_audio_params_.sample_rate()); 183 DCHECK_EQ(params.sample_rate(), original_audio_params_.sample_rate());
151 DCHECK_EQ(params.bits_per_sample(), 184 DCHECK_EQ(params.bits_per_sample(),
152 original_audio_params_.bits_per_sample()); 185 original_audio_params_.bits_per_sample());
153 DCHECK_EQ(params.channels(), original_audio_params_.channels()); 186 DCHECK_EQ(params.channels(), original_audio_params_.channels());
154 } else { 187 } else {
155 audio_thread_checker_.DetachFromThread(); 188 audio_thread_checker_.DetachFromThread();
156 original_audio_params_ = params; 189 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 190
163 main_message_loop_proxy_->PostTask( 191 main_message_loop_proxy_->PostTask(
164 FROM_HERE, 192 FROM_HERE,
165 base::Bind(&AudioSink::InitBuffersOnMainThread, 193 base::Bind(&AudioSink::InitBuffersOnMainThread,
166 weak_factory_.GetWeakPtr(), 194 weak_factory_.GetWeakPtr(),
167 kNumberOfBuffers, 195 params.GetBytesPerSecond()));
168 static_cast<int32_t>(size)));
169 } 196 }
170 } 197 }
171 198
172 PepperMediaStreamAudioTrackHost::PepperMediaStreamAudioTrackHost( 199 PepperMediaStreamAudioTrackHost::PepperMediaStreamAudioTrackHost(
173 RendererPpapiHost* host, 200 RendererPpapiHost* host,
174 PP_Instance instance, 201 PP_Instance instance,
175 PP_Resource resource, 202 PP_Resource resource,
176 const blink::WebMediaStreamTrack& track) 203 const blink::WebMediaStreamTrack& track)
177 : PepperMediaStreamTrackHostBase(host, instance, resource), 204 : PepperMediaStreamTrackHostBase(host, instance, resource),
178 track_(track), 205 track_(track),
179 connected_(false), 206 connected_(false),
180 audio_sink_(this) { 207 audio_sink_(this) {
181 DCHECK(!track_.isNull()); 208 DCHECK(!track_.isNull());
182 } 209 }
183 210
184 PepperMediaStreamAudioTrackHost::~PepperMediaStreamAudioTrackHost() { 211 PepperMediaStreamAudioTrackHost::~PepperMediaStreamAudioTrackHost() {
185 OnClose(); 212 OnClose();
186 } 213 }
187 214
215 int32_t PepperMediaStreamAudioTrackHost::OnResourceMessageReceived(
216 const IPC::Message& msg,
217 HostMessageContext* context) {
218 PPAPI_BEGIN_MESSAGE_MAP(PepperMediaStreamAudioTrackHost, msg)
219 PPAPI_DISPATCH_HOST_RESOURCE_CALL(
220 PpapiHostMsg_MediaStreamAudioTrack_Configure, OnHostMsgConfigure)
221 PPAPI_END_MESSAGE_MAP()
222 return PepperMediaStreamTrackHostBase::OnResourceMessageReceived(msg,
223 context);
224 }
225
226 int32_t PepperMediaStreamAudioTrackHost::OnHostMsgConfigure(
227 HostMessageContext* context,
228 const MediaStreamAudioTrackShared::Attributes& attributes) {
229 CHECK(MediaStreamAudioTrackShared::VerifyAttributes(attributes));
dmichael (off chromium) 2014/05/27 20:22:33 I don't think we should CHECK here. We're crashing
thembrown 2014/05/28 10:55:59 Agreed. How about PP_ERROR_BADARGUMENT like in Med
dmichael (off chromium) 2014/05/28 15:27:43 That's fine.
230
231 int32_t buffers = attributes.buffers
232 ? std::min(kMaxNumberOfBuffers, attributes.buffers)
233 : kDefaultNumberOfBuffers;
234 audio_sink_.Configure(buffers);
235
236 context->reply_msg = PpapiPluginMsg_MediaStreamAudioTrack_ConfigureReply();
237 return PP_OK;
238 }
239
188 void PepperMediaStreamAudioTrackHost::OnClose() { 240 void PepperMediaStreamAudioTrackHost::OnClose() {
189 if (connected_) { 241 if (connected_) {
190 MediaStreamAudioSink::RemoveFromAudioTrack(&audio_sink_, track_); 242 MediaStreamAudioSink::RemoveFromAudioTrack(&audio_sink_, track_);
191 connected_ = false; 243 connected_ = false;
192 } 244 }
193 } 245 }
194 246
195 void PepperMediaStreamAudioTrackHost::OnNewBufferEnqueued() { 247 void PepperMediaStreamAudioTrackHost::OnNewBufferEnqueued() {
196 int32_t index = buffer_manager()->DequeueBuffer(); 248 int32_t index = buffer_manager()->DequeueBuffer();
197 DCHECK_GE(index, 0); 249 DCHECK_GE(index, 0);
198 audio_sink_.EnqueueBuffer(index); 250 audio_sink_.EnqueueBuffer(index);
199 } 251 }
200 252
201 void PepperMediaStreamAudioTrackHost::DidConnectPendingHostToResource() { 253 void PepperMediaStreamAudioTrackHost::DidConnectPendingHostToResource() {
202 if (!connected_) { 254 if (!connected_) {
203 MediaStreamAudioSink::AddToAudioTrack(&audio_sink_, track_); 255 MediaStreamAudioSink::AddToAudioTrack(&audio_sink_, track_);
204 connected_ = true; 256 connected_ = true;
205 } 257 }
206 } 258 }
207 259
208 } // namespace content 260 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698