OLD | NEW |
---|---|
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> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/location.h" | 10 #include "base/location.h" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/macros.h" | 12 #include "base/macros.h" |
13 #include "base/message_loop/message_loop_proxy.h" | 13 #include "base/message_loop/message_loop_proxy.h" |
14 #include "base/numerics/safe_math.h" | 14 #include "base/numerics/safe_math.h" |
15 #include "ppapi/c/pp_errors.h" | 15 #include "ppapi/c/pp_errors.h" |
16 #include "ppapi/c/ppb_audio_buffer.h" | 16 #include "ppapi/c/ppb_audio_buffer.h" |
17 #include "ppapi/host/dispatch_host_message.h" | 17 #include "ppapi/host/dispatch_host_message.h" |
18 #include "ppapi/host/host_message_context.h" | 18 #include "ppapi/host/host_message_context.h" |
19 #include "ppapi/proxy/ppapi_messages.h" | 19 #include "ppapi/proxy/ppapi_messages.h" |
20 #include "ppapi/shared_impl/media_stream_audio_track_shared.h" | 20 #include "ppapi/shared_impl/media_stream_audio_track_shared.h" |
21 #include "ppapi/shared_impl/media_stream_buffer.h" | 21 #include "ppapi/shared_impl/media_stream_buffer.h" |
22 | 22 |
23 using media::AudioParameters; | 23 using media::AudioParameters; |
24 using ppapi::host::HostMessageContext; | 24 using ppapi::host::HostMessageContext; |
25 using ppapi::MediaStreamAudioTrackShared; | 25 using ppapi::MediaStreamAudioTrackShared; |
26 | 26 |
27 namespace { | 27 namespace { |
28 | 28 |
29 // Max audio buffer duration in milliseconds. | 29 // Audio buffer durations in milliseconds. |
30 const uint32_t kMaxDuration = 10; | 30 const uint32_t kMinDuration = 10; |
31 const uint32_t kDefaultDuration = 10; | |
31 | 32 |
32 const int32_t kDefaultNumberOfBuffers = 4; | 33 const int32_t kDefaultNumberOfBuffers = 4; |
33 const int32_t kMaxNumberOfBuffers = 1000; // 10 sec | 34 const int32_t kMaxNumberOfBuffers = 1000; // 10 sec |
34 | 35 |
35 // Returns true if the |sample_rate| is supported in | 36 // Returns true if the |sample_rate| is supported in |
36 // |PP_AudioBuffer_SampleRate|, otherwise false. | 37 // |PP_AudioBuffer_SampleRate|, otherwise false. |
37 PP_AudioBuffer_SampleRate GetPPSampleRate(int sample_rate) { | 38 PP_AudioBuffer_SampleRate GetPPSampleRate(int sample_rate) { |
38 switch (sample_rate) { | 39 switch (sample_rate) { |
39 case 8000: | 40 case 8000: |
40 return PP_AUDIOBUFFER_SAMPLERATE_8000; | 41 return PP_AUDIOBUFFER_SAMPLERATE_8000; |
(...skipping 17 matching lines...) Expand all Loading... | |
58 } | 59 } |
59 | 60 |
60 } // namespace | 61 } // namespace |
61 | 62 |
62 namespace content { | 63 namespace content { |
63 | 64 |
64 PepperMediaStreamAudioTrackHost::AudioSink::AudioSink( | 65 PepperMediaStreamAudioTrackHost::AudioSink::AudioSink( |
65 PepperMediaStreamAudioTrackHost* host) | 66 PepperMediaStreamAudioTrackHost* host) |
66 : host_(host), | 67 : host_(host), |
67 buffer_data_size_(0), | 68 buffer_data_size_(0), |
69 active_buffer_index_(-1), | |
70 active_buffer_offset_(0), | |
71 init_buffers_count_(0), | |
68 main_message_loop_proxy_(base::MessageLoopProxy::current()), | 72 main_message_loop_proxy_(base::MessageLoopProxy::current()), |
69 weak_factory_(this), | 73 weak_factory_(this), |
70 number_of_buffers_(kDefaultNumberOfBuffers), | 74 number_of_buffers_(kDefaultNumberOfBuffers), |
71 bytes_per_second_(0) {} | 75 bytes_per_second_(0), |
76 user_buffer_duration_(kDefaultDuration) {} | |
72 | 77 |
73 PepperMediaStreamAudioTrackHost::AudioSink::~AudioSink() { | 78 PepperMediaStreamAudioTrackHost::AudioSink::~AudioSink() { |
74 DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current()); | 79 DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current()); |
75 } | 80 } |
76 | 81 |
77 void PepperMediaStreamAudioTrackHost::AudioSink::EnqueueBuffer(int32_t index) { | 82 void PepperMediaStreamAudioTrackHost::AudioSink::EnqueueBuffer(int32_t index) { |
78 DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current()); | 83 DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current()); |
79 DCHECK_GE(index, 0); | 84 DCHECK_GE(index, 0); |
80 DCHECK_LT(index, host_->buffer_manager()->number_of_buffers()); | 85 DCHECK_LT(index, host_->buffer_manager()->number_of_buffers()); |
81 base::AutoLock lock(lock_); | 86 base::AutoLock lock(lock_); |
82 buffers_.push_back(index); | 87 buffers_.push_back(index); |
83 } | 88 } |
84 | 89 |
85 void PepperMediaStreamAudioTrackHost::AudioSink::Configure( | 90 void PepperMediaStreamAudioTrackHost::AudioSink::Configure( |
86 int32_t number_of_buffers) { | 91 int32_t number_of_buffers, int32_t duration) { |
87 DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current()); | 92 DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current()); |
88 bool changed = false; | 93 bool changed = false; |
89 if (number_of_buffers != number_of_buffers_) | 94 if (number_of_buffers != number_of_buffers_) |
90 changed = true; | 95 changed = true; |
96 if (duration != 0 && duration != user_buffer_duration_) { | |
97 user_buffer_duration_ = duration; | |
98 changed = true; | |
99 } | |
91 number_of_buffers_ = number_of_buffers; | 100 number_of_buffers_ = number_of_buffers; |
92 | 101 |
93 // Initialize later in OnSetFormat if bytes_per_second_ is not know yet. | 102 // Initialize later in OnSetFormat if bytes_per_second_ is not know yet. |
94 if (changed && bytes_per_second_ > 0) | 103 if (changed && bytes_per_second_ > 0 && bytes_per_frame_ > 0) |
95 InitBuffers(); | 104 InitBuffers(); |
96 } | 105 } |
97 | 106 |
98 void PepperMediaStreamAudioTrackHost::AudioSink::SetFormatOnMainThread( | 107 void PepperMediaStreamAudioTrackHost::AudioSink::SetFormatOnMainThread( |
99 int bytes_per_second) { | 108 int bytes_per_second, int bytes_per_frame) { |
100 bytes_per_second_ = bytes_per_second; | 109 bytes_per_second_ = bytes_per_second; |
110 bytes_per_frame_ = bytes_per_frame; | |
101 InitBuffers(); | 111 InitBuffers(); |
102 } | 112 } |
103 | 113 |
104 void PepperMediaStreamAudioTrackHost::AudioSink::InitBuffers() { | 114 void PepperMediaStreamAudioTrackHost::AudioSink::InitBuffers() { |
105 DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current()); | 115 DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current()); |
116 { | |
117 base::AutoLock lock(lock_); | |
118 // Clear |buffers_|, so the audio thread will drop all incoming audio data. | |
119 buffers_.clear(); | |
120 init_buffers_count_++; | |
121 } | |
122 int32_t frame_rate = bytes_per_second_ / bytes_per_frame_; | |
123 base::CheckedNumeric<int32_t> frames_per_buffer = user_buffer_duration_; | |
124 frames_per_buffer *= frame_rate; | |
125 frames_per_buffer /= base::Time::kMillisecondsPerSecond; | |
126 base::CheckedNumeric<int32_t> buffer_audio_size = | |
127 frames_per_buffer * bytes_per_frame_; | |
106 // The size is slightly bigger than necessary, because 8 extra bytes are | 128 // The size is slightly bigger than necessary, because 8 extra bytes are |
107 // added into the struct. Also see |MediaStreamBuffer|. | 129 // added into the struct. Also see |MediaStreamBuffer|. Also, the size of the |
108 base::CheckedNumeric<int32_t> buffer_size = bytes_per_second_; | 130 // buffer may be larger than requested, since the size of each buffer will be |
109 buffer_size *= kMaxDuration; | 131 // 4-byte aligned. |
110 buffer_size /= base::Time::kMillisecondsPerSecond; | 132 base::CheckedNumeric<int32_t> buffer_size = buffer_audio_size; |
111 buffer_size += sizeof(ppapi::MediaStreamBuffer::Audio); | 133 buffer_size += sizeof(ppapi::MediaStreamBuffer::Audio); |
134 | |
135 // We don't need hold |lock_| during |host->InitBuffers()| call, because | |
136 // we just cleared |buffers_| , so the audio thread will drop all incoming | |
137 // audio data, and not use buffers in |host_|. | |
112 bool result = host_->InitBuffers(number_of_buffers_, | 138 bool result = host_->InitBuffers(number_of_buffers_, |
113 buffer_size.ValueOrDie(), | 139 buffer_size.ValueOrDie(), |
114 kRead); | 140 kRead); |
115 // TODO(penghuang): Send PP_ERROR_NOMEMORY to plugin. | 141 // TODO(penghuang): Send PP_ERROR_NOMEMORY to plugin. |
116 CHECK(result); | 142 CHECK(result); |
143 | |
144 // Fill the |buffers_|, so the audio thread can continue receiving audio data. | |
117 base::AutoLock lock(lock_); | 145 base::AutoLock lock(lock_); |
118 buffers_.clear(); | 146 output_buffer_size_ = buffer_audio_size.ValueOrDie(); |
119 for (int32_t i = 0; i < number_of_buffers_; ++i) { | 147 for (int32_t i = 0; i < number_of_buffers_; ++i) { |
120 int32_t index = host_->buffer_manager()->DequeueBuffer(); | 148 int32_t index = host_->buffer_manager()->DequeueBuffer(); |
121 DCHECK_GE(index, 0); | 149 DCHECK_GE(index, 0); |
122 buffers_.push_back(index); | 150 buffers_.push_back(index); |
123 } | 151 } |
124 } | 152 } |
125 | 153 |
126 void PepperMediaStreamAudioTrackHost::AudioSink:: | 154 void PepperMediaStreamAudioTrackHost::AudioSink:: |
127 SendEnqueueBufferMessageOnMainThread(int32_t index) { | 155 SendEnqueueBufferMessageOnMainThread(int32_t index, |
156 int32_t init_buffers_count) { | |
128 DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current()); | 157 DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current()); |
129 host_->SendEnqueueBufferMessageToPlugin(index); | 158 // If |InitBuffers()| is called after this task being posted from the audio |
159 // thread, the buffer should become invalid already. We should ignore it. And | |
160 // because only the main thread modifies the |init_buffers_count_|, so we | |
161 // don't need lock |lock_| here (main thread). | |
162 if (init_buffers_count == init_buffers_count_) | |
163 host_->SendEnqueueBufferMessageToPlugin(index); | |
130 } | 164 } |
131 | 165 |
132 void PepperMediaStreamAudioTrackHost::AudioSink::OnData(const int16* audio_data, | 166 void PepperMediaStreamAudioTrackHost::AudioSink::OnData(const int16* audio_data, |
133 int sample_rate, | 167 int sample_rate, |
134 int number_of_channels, | 168 int number_of_channels, |
135 int number_of_frames) { | 169 int number_of_frames) { |
136 DCHECK(audio_thread_checker_.CalledOnValidThread()); | 170 DCHECK(audio_thread_checker_.CalledOnValidThread()); |
137 DCHECK(audio_data); | 171 DCHECK(audio_data); |
138 DCHECK_EQ(sample_rate, audio_params_.sample_rate()); | 172 DCHECK_EQ(sample_rate, audio_params_.sample_rate()); |
139 DCHECK_EQ(number_of_channels, audio_params_.channels()); | 173 DCHECK_EQ(number_of_channels, audio_params_.channels()); |
140 DCHECK_EQ(number_of_frames, audio_params_.frames_per_buffer()); | 174 DCHECK_EQ(number_of_frames, audio_params_.frames_per_buffer()); |
141 int32_t index = -1; | 175 |
142 { | 176 const uint32_t bytes_per_frame = number_of_channels * |
143 base::AutoLock lock(lock_); | 177 audio_params_.bits_per_sample() / 8; |
144 if (!buffers_.empty()) { | 178 |
145 index = buffers_.front(); | 179 int frames_remaining = number_of_frames; |
146 buffers_.pop_front(); | 180 base::TimeDelta timestamp_offset; |
181 | |
182 base::AutoLock lock(lock_); | |
183 while (frames_remaining) { | |
184 uint32_t output_buffer_size = 0; | |
Peng
2014/07/24 15:38:37
Why not use output_buffer_size_ directly?
Anand Mistry (off Chromium)
2014/07/25 03:38:15
Done. Artifact of before I synced to your change.
| |
185 if (active_buffer_index_ == -1) { | |
186 active_init_buffers_count_ = init_buffers_count_; | |
187 active_buffer_offset_ = 0; | |
188 output_buffer_size = output_buffer_size_; | |
Peng
2014/07/24 15:38:37
Moving above three lines into the if (!buffers_.em
Anand Mistry (off Chromium)
2014/07/25 03:38:15
Done.
| |
189 if (!buffers_.empty()) { | |
190 active_buffer_index_ = buffers_.front(); | |
191 buffers_.pop_front(); | |
192 } | |
193 } else if (active_init_buffers_count_ != init_buffers_count_) { | |
Peng
2014/07/24 15:38:37
Check (active_init_buffers_count_ != init_buffers_
Anand Mistry (off Chromium)
2014/07/25 03:38:15
Done.
| |
194 // Buffers have changed. | |
195 active_buffer_index_ = -1; | |
196 continue; | |
147 } | 197 } |
148 } | 198 if (active_buffer_index_ == -1) { |
199 // Eek! We're dropping frames. Bad, bad, bad! | |
200 break; | |
201 } | |
149 | 202 |
150 if (index != -1) { | |
151 // TODO(penghuang): support re-sampling, etc. | 203 // TODO(penghuang): support re-sampling, etc. |
152 ppapi::MediaStreamBuffer::Audio* buffer = | 204 ppapi::MediaStreamBuffer::Audio* buffer = |
153 &(host_->buffer_manager()->GetBufferPointer(index)->audio); | 205 &(host_->buffer_manager()->GetBufferPointer(active_buffer_index_) |
154 buffer->header.size = host_->buffer_manager()->buffer_size(); | 206 ->audio); |
155 buffer->header.type = ppapi::MediaStreamBuffer::TYPE_AUDIO; | 207 if (active_buffer_offset_ == 0) { |
156 buffer->timestamp = timestamp_.InMillisecondsF(); | 208 // Next buffer. Not using an active buffer. |
Peng
2014/07/24 15:38:37
This comment is confusing.
Maybe:
The active buffe
Anand Mistry (off Chromium)
2014/07/25 03:38:15
Done.
| |
157 buffer->sample_rate = static_cast<PP_AudioBuffer_SampleRate>(sample_rate); | 209 buffer->header.size = host_->buffer_manager()->buffer_size(); |
158 buffer->number_of_channels = number_of_channels; | 210 buffer->header.type = ppapi::MediaStreamBuffer::TYPE_AUDIO; |
159 buffer->number_of_samples = number_of_channels * number_of_frames; | 211 buffer->timestamp = (timestamp_ + timestamp_offset).InMillisecondsF(); |
160 buffer->data_size = buffer_data_size_; | 212 buffer->sample_rate = static_cast<PP_AudioBuffer_SampleRate>(sample_rate); |
161 memcpy(buffer->data, audio_data, buffer_data_size_); | 213 DCHECK_NE(output_buffer_size, 0U); |
214 buffer->data_size = output_buffer_size; | |
215 buffer->number_of_channels = number_of_channels; | |
216 buffer->number_of_samples = buffer->data_size / bytes_per_frame; | |
217 } | |
218 uint32_t buffer_bytes_remaining = | |
219 buffer->data_size - active_buffer_offset_; | |
220 DCHECK_EQ(buffer_bytes_remaining % bytes_per_frame, 0U); | |
221 uint32_t incoming_bytes_remaining = frames_remaining * bytes_per_frame; | |
222 uint32_t bytes_to_copy = std::min(buffer_bytes_remaining, | |
223 incoming_bytes_remaining); | |
224 uint32_t frames_to_copy = bytes_to_copy / bytes_per_frame; | |
225 DCHECK_EQ(bytes_to_copy % bytes_per_frame, 0U); | |
226 memcpy(buffer->data + active_buffer_offset_, | |
227 audio_data, bytes_to_copy); | |
228 active_buffer_offset_ += bytes_to_copy; | |
229 audio_data += bytes_to_copy / sizeof(*audio_data); | |
230 frames_remaining -= frames_to_copy; | |
231 timestamp_offset += base::TimeDelta::FromMilliseconds( | |
232 frames_to_copy * base::Time::kMillisecondsPerSecond / sample_rate); | |
162 | 233 |
163 main_message_loop_proxy_->PostTask( | 234 DCHECK_LE(active_buffer_offset_, buffer->data_size); |
164 FROM_HERE, | 235 if (active_buffer_offset_ == buffer->data_size) { |
165 base::Bind(&AudioSink::SendEnqueueBufferMessageOnMainThread, | 236 main_message_loop_proxy_->PostTask( |
166 weak_factory_.GetWeakPtr(), | 237 FROM_HERE, |
167 index)); | 238 base::Bind(&AudioSink::SendEnqueueBufferMessageOnMainThread, |
239 weak_factory_.GetWeakPtr(), | |
240 active_buffer_index_, | |
241 init_buffers_count_)); | |
242 active_buffer_index_ = -1; | |
243 } | |
168 } | 244 } |
169 timestamp_ += buffer_duration_; | 245 timestamp_ += buffer_duration_; |
170 } | 246 } |
171 | 247 |
172 void PepperMediaStreamAudioTrackHost::AudioSink::OnSetFormat( | 248 void PepperMediaStreamAudioTrackHost::AudioSink::OnSetFormat( |
173 const AudioParameters& params) { | 249 const AudioParameters& params) { |
174 DCHECK(params.IsValid()); | 250 DCHECK(params.IsValid()); |
175 DCHECK_LE(params.GetBufferDuration().InMilliseconds(), kMaxDuration); | 251 // TODO(amistry): How do you handle the case where the user configures a |
252 // duration that's shorter than the received buffer duration? One option is to | |
253 // double buffer, where the size of the intermediate ring buffer is at least | |
254 // max(user requested duration, received buffer duration). There are other | |
255 // ways of dealing with it, but which one is "correct"? | |
256 DCHECK_LE(params.GetBufferDuration().InMilliseconds(), kMinDuration); | |
176 DCHECK_EQ(params.bits_per_sample(), 16); | 257 DCHECK_EQ(params.bits_per_sample(), 16); |
177 DCHECK_NE(GetPPSampleRate(params.sample_rate()), | 258 DCHECK_NE(GetPPSampleRate(params.sample_rate()), |
178 PP_AUDIOBUFFER_SAMPLERATE_UNKNOWN); | 259 PP_AUDIOBUFFER_SAMPLERATE_UNKNOWN); |
179 | 260 |
180 audio_params_ = params; | 261 audio_params_ = params; |
181 | 262 |
182 // TODO(penghuang): support setting format more than once. | 263 // TODO(penghuang): support setting format more than once. |
183 buffer_duration_ = params.GetBufferDuration(); | 264 buffer_duration_ = params.GetBufferDuration(); |
184 buffer_data_size_ = params.GetBytesPerBuffer(); | 265 buffer_data_size_ = params.GetBytesPerBuffer(); |
185 | 266 |
186 if (original_audio_params_.IsValid()) { | 267 if (original_audio_params_.IsValid()) { |
187 DCHECK_EQ(params.sample_rate(), original_audio_params_.sample_rate()); | 268 DCHECK_EQ(params.sample_rate(), original_audio_params_.sample_rate()); |
188 DCHECK_EQ(params.bits_per_sample(), | 269 DCHECK_EQ(params.bits_per_sample(), |
189 original_audio_params_.bits_per_sample()); | 270 original_audio_params_.bits_per_sample()); |
190 DCHECK_EQ(params.channels(), original_audio_params_.channels()); | 271 DCHECK_EQ(params.channels(), original_audio_params_.channels()); |
191 } else { | 272 } else { |
192 audio_thread_checker_.DetachFromThread(); | 273 audio_thread_checker_.DetachFromThread(); |
193 original_audio_params_ = params; | 274 original_audio_params_ = params; |
194 | 275 |
276 int bytes_per_frame = params.channels() * params.bits_per_sample() / 8; | |
195 main_message_loop_proxy_->PostTask( | 277 main_message_loop_proxy_->PostTask( |
196 FROM_HERE, | 278 FROM_HERE, |
197 base::Bind(&AudioSink::SetFormatOnMainThread, | 279 base::Bind(&AudioSink::SetFormatOnMainThread, |
198 weak_factory_.GetWeakPtr(), | 280 weak_factory_.GetWeakPtr(), |
199 params.GetBytesPerSecond())); | 281 params.GetBytesPerSecond(), |
282 bytes_per_frame)); | |
200 } | 283 } |
201 } | 284 } |
202 | 285 |
203 PepperMediaStreamAudioTrackHost::PepperMediaStreamAudioTrackHost( | 286 PepperMediaStreamAudioTrackHost::PepperMediaStreamAudioTrackHost( |
204 RendererPpapiHost* host, | 287 RendererPpapiHost* host, |
205 PP_Instance instance, | 288 PP_Instance instance, |
206 PP_Resource resource, | 289 PP_Resource resource, |
207 const blink::WebMediaStreamTrack& track) | 290 const blink::WebMediaStreamTrack& track) |
208 : PepperMediaStreamTrackHostBase(host, instance, resource), | 291 : PepperMediaStreamTrackHostBase(host, instance, resource), |
209 track_(track), | 292 track_(track), |
(...skipping 19 matching lines...) Expand all Loading... | |
229 | 312 |
230 int32_t PepperMediaStreamAudioTrackHost::OnHostMsgConfigure( | 313 int32_t PepperMediaStreamAudioTrackHost::OnHostMsgConfigure( |
231 HostMessageContext* context, | 314 HostMessageContext* context, |
232 const MediaStreamAudioTrackShared::Attributes& attributes) { | 315 const MediaStreamAudioTrackShared::Attributes& attributes) { |
233 if (!MediaStreamAudioTrackShared::VerifyAttributes(attributes)) | 316 if (!MediaStreamAudioTrackShared::VerifyAttributes(attributes)) |
234 return PP_ERROR_BADARGUMENT; | 317 return PP_ERROR_BADARGUMENT; |
235 | 318 |
236 int32_t buffers = attributes.buffers | 319 int32_t buffers = attributes.buffers |
237 ? std::min(kMaxNumberOfBuffers, attributes.buffers) | 320 ? std::min(kMaxNumberOfBuffers, attributes.buffers) |
238 : kDefaultNumberOfBuffers; | 321 : kDefaultNumberOfBuffers; |
239 audio_sink_.Configure(buffers); | 322 audio_sink_.Configure(buffers, attributes.duration); |
240 | 323 |
241 context->reply_msg = PpapiPluginMsg_MediaStreamAudioTrack_ConfigureReply(); | 324 context->reply_msg = PpapiPluginMsg_MediaStreamAudioTrack_ConfigureReply(); |
242 return PP_OK; | 325 return PP_OK; |
243 } | 326 } |
244 | 327 |
245 void PepperMediaStreamAudioTrackHost::OnClose() { | 328 void PepperMediaStreamAudioTrackHost::OnClose() { |
246 if (connected_) { | 329 if (connected_) { |
247 MediaStreamAudioSink::RemoveFromAudioTrack(&audio_sink_, track_); | 330 MediaStreamAudioSink::RemoveFromAudioTrack(&audio_sink_, track_); |
248 connected_ = false; | 331 connected_ = false; |
249 } | 332 } |
250 } | 333 } |
251 | 334 |
252 void PepperMediaStreamAudioTrackHost::OnNewBufferEnqueued() { | 335 void PepperMediaStreamAudioTrackHost::OnNewBufferEnqueued() { |
253 int32_t index = buffer_manager()->DequeueBuffer(); | 336 int32_t index = buffer_manager()->DequeueBuffer(); |
254 DCHECK_GE(index, 0); | 337 DCHECK_GE(index, 0); |
255 audio_sink_.EnqueueBuffer(index); | 338 audio_sink_.EnqueueBuffer(index); |
256 } | 339 } |
257 | 340 |
258 void PepperMediaStreamAudioTrackHost::DidConnectPendingHostToResource() { | 341 void PepperMediaStreamAudioTrackHost::DidConnectPendingHostToResource() { |
259 if (!connected_) { | 342 if (!connected_) { |
260 MediaStreamAudioSink::AddToAudioTrack(&audio_sink_, track_); | 343 MediaStreamAudioSink::AddToAudioTrack(&audio_sink_, track_); |
261 connected_ = true; | 344 connected_ = true; |
262 } | 345 } |
263 } | 346 } |
264 | 347 |
265 } // namespace content | 348 } // namespace content |
OLD | NEW |