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

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: Created 6 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
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
84 void PepperMediaStreamAudioTrackHost::AudioSink::Configure(
85 int32_t number_of_buffers) {
86 bool changed;
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) {
Peng 2014/05/26 14:48:49 {} is not necessary.
thembrown 2014/05/27 10:36:02 Done.
93 InitBuffers();
94 }
95 }
96
74 void PepperMediaStreamAudioTrackHost::AudioSink::InitBuffersOnMainThread( 97 void PepperMediaStreamAudioTrackHost::AudioSink::InitBuffersOnMainThread(
75 int32_t number_of_buffers, 98 int bytes_per_second) {
76 int32_t buffer_size) { 99 bytes_per_second_ = bytes_per_second;
100 InitBuffers();
101 }
102
103 void PepperMediaStreamAudioTrackHost::AudioSink::InitBuffers() {
77 DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current()); 104 DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current());
78 bool result = host_->InitBuffers(number_of_buffers, buffer_size, kRead); 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;
Peng 2014/05/26 14:48:49 kMaxDuration is in milliseconds. See comment of kM
thembrown 2014/05/27 10:36:02 Done.
109 bool result = host_->InitBuffers(number_of_buffers_,
110 static_cast<int32_t>(buffer_size),
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 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
122
Peng 2014/05/26 14:48:49 remove the extra blank line
thembrown 2014/05/27 10:36:02 Done.
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);
93 } 127 }
94 128
95 void PepperMediaStreamAudioTrackHost::AudioSink::OnData(const int16* audio_data, 129 void PepperMediaStreamAudioTrackHost::AudioSink::OnData(const int16* audio_data,
96 int sample_rate, 130 int sample_rate,
97 int number_of_channels, 131 int number_of_channels,
98 int number_of_frames) { 132 int number_of_frames) {
(...skipping 48 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::InitBuffersOnMainThread,
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 CHECK(MediaStreamAudioTrackShared::VerifyAttributes(attributes));
231
232 int32_t buffers = attributes.buffers
233 ? std::min(kMaxNumberOfBuffers, attributes.buffers)
234 : kDefaultNumberOfBuffers;
235 audio_sink_.Configure(buffers);
236
237 context->reply_msg = PpapiPluginMsg_MediaStreamAudioTrack_ConfigureReply();
238 return PP_OK;
239 }
240
188 void PepperMediaStreamAudioTrackHost::OnClose() { 241 void PepperMediaStreamAudioTrackHost::OnClose() {
189 if (connected_) { 242 if (connected_) {
190 MediaStreamAudioSink::RemoveFromAudioTrack(&audio_sink_, track_); 243 MediaStreamAudioSink::RemoveFromAudioTrack(&audio_sink_, track_);
191 connected_ = false; 244 connected_ = false;
192 } 245 }
193 } 246 }
194 247
195 void PepperMediaStreamAudioTrackHost::OnNewBufferEnqueued() { 248 void PepperMediaStreamAudioTrackHost::OnNewBufferEnqueued() {
196 int32_t index = buffer_manager()->DequeueBuffer(); 249 int32_t index = buffer_manager()->DequeueBuffer();
197 DCHECK_GE(index, 0); 250 DCHECK_GE(index, 0);
198 audio_sink_.EnqueueBuffer(index); 251 audio_sink_.EnqueueBuffer(index);
199 } 252 }
200 253
201 void PepperMediaStreamAudioTrackHost::DidConnectPendingHostToResource() { 254 void PepperMediaStreamAudioTrackHost::DidConnectPendingHostToResource() {
202 if (!connected_) { 255 if (!connected_) {
203 MediaStreamAudioSink::AddToAudioTrack(&audio_sink_, track_); 256 MediaStreamAudioSink::AddToAudioTrack(&audio_sink_, track_);
204 connected_ = true; 257 connected_ = true;
205 } 258 }
206 } 259 }
207 260
208 } // namespace content 261 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698