| Index: content/renderer/pepper/pepper_media_stream_audio_track_host.cc
|
| diff --git a/content/renderer/pepper/pepper_media_stream_audio_track_host.cc b/content/renderer/pepper/pepper_media_stream_audio_track_host.cc
|
| index d972c2c061e2882eb1257d92fc9981e18a296ba5..c1edfddeb4eda4c772a5cb059bd4116b17a86669 100644
|
| --- a/content/renderer/pepper/pepper_media_stream_audio_track_host.cc
|
| +++ b/content/renderer/pepper/pepper_media_stream_audio_track_host.cc
|
| @@ -65,6 +65,7 @@ PepperMediaStreamAudioTrackHost::AudioSink::AudioSink(
|
| PepperMediaStreamAudioTrackHost* host)
|
| : host_(host),
|
| buffer_data_size_(0),
|
| + buffers_generation_(0),
|
| main_message_loop_proxy_(base::MessageLoopProxy::current()),
|
| weak_factory_(this),
|
| number_of_buffers_(kDefaultNumberOfBuffers),
|
| @@ -103,19 +104,30 @@ void PepperMediaStreamAudioTrackHost::AudioSink::SetFormatOnMainThread(
|
|
|
| void PepperMediaStreamAudioTrackHost::AudioSink::InitBuffers() {
|
| DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current());
|
| + {
|
| + base::AutoLock lock(lock_);
|
| + // Clear |buffers_|, so the audio thread will drop all incoming audio data.
|
| + buffers_.clear();
|
| + buffers_generation_++;
|
| + }
|
| // The size is slightly bigger than necessary, because 8 extra bytes are
|
| // added into the struct. Also see |MediaStreamBuffer|.
|
| base::CheckedNumeric<int32_t> buffer_size = bytes_per_second_;
|
| buffer_size *= kMaxDuration;
|
| buffer_size /= base::Time::kMillisecondsPerSecond;
|
| buffer_size += sizeof(ppapi::MediaStreamBuffer::Audio);
|
| +
|
| + // We don't need to hold |lock_| during |host->InitBuffers()| call, because
|
| + // we just cleared |buffers_| , so the audio thread will drop all incoming
|
| + // audio data, and not use buffers in |host_|.
|
| bool result = host_->InitBuffers(number_of_buffers_,
|
| buffer_size.ValueOrDie(),
|
| kRead);
|
| // TODO(penghuang): Send PP_ERROR_NOMEMORY to plugin.
|
| CHECK(result);
|
| +
|
| + // Fill the |buffers_|, so the audio thread can continue receiving audio data.
|
| base::AutoLock lock(lock_);
|
| - buffers_.clear();
|
| for (int32_t i = 0; i < number_of_buffers_; ++i) {
|
| int32_t index = host_->buffer_manager()->DequeueBuffer();
|
| DCHECK_GE(index, 0);
|
| @@ -124,9 +136,15 @@ void PepperMediaStreamAudioTrackHost::AudioSink::InitBuffers() {
|
| }
|
|
|
| void PepperMediaStreamAudioTrackHost::AudioSink::
|
| - SendEnqueueBufferMessageOnMainThread(int32_t index) {
|
| + SendEnqueueBufferMessageOnMainThread(int32_t index,
|
| + int32_t buffers_generation) {
|
| DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current());
|
| - host_->SendEnqueueBufferMessageToPlugin(index);
|
| + // If |InitBuffers()| is called after this task being posted from the audio
|
| + // thread, the buffer should become invalid already. We should ignore it.
|
| + // And because only the main thread modifies the |buffers_generation_|,
|
| + // so we don't need to lock |lock_| here (main thread).
|
| + if (buffers_generation == buffers_generation_)
|
| + host_->SendEnqueueBufferMessageToPlugin(index);
|
| }
|
|
|
| void PepperMediaStreamAudioTrackHost::AudioSink::OnData(const int16* audio_data,
|
| @@ -138,16 +156,11 @@ void PepperMediaStreamAudioTrackHost::AudioSink::OnData(const int16* audio_data,
|
| DCHECK_EQ(sample_rate, audio_params_.sample_rate());
|
| DCHECK_EQ(number_of_channels, audio_params_.channels());
|
| DCHECK_EQ(number_of_frames, audio_params_.frames_per_buffer());
|
| - int32_t index = -1;
|
| - {
|
| - base::AutoLock lock(lock_);
|
| - if (!buffers_.empty()) {
|
| - index = buffers_.front();
|
| - buffers_.pop_front();
|
| - }
|
| - }
|
|
|
| - if (index != -1) {
|
| + base::AutoLock lock(lock_);
|
| + if (!buffers_.empty()) {
|
| + int index = buffers_.front();
|
| + buffers_.pop_front();
|
| // TODO(penghuang): support re-sampling, etc.
|
| ppapi::MediaStreamBuffer::Audio* buffer =
|
| &(host_->buffer_manager()->GetBufferPointer(index)->audio);
|
| @@ -164,7 +177,8 @@ void PepperMediaStreamAudioTrackHost::AudioSink::OnData(const int16* audio_data,
|
| FROM_HERE,
|
| base::Bind(&AudioSink::SendEnqueueBufferMessageOnMainThread,
|
| weak_factory_.GetWeakPtr(),
|
| - index));
|
| + index,
|
| + buffers_generation_));
|
| }
|
| timestamp_ += buffer_duration_;
|
| }
|
|
|