| 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 "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/location.h" | 8 #include "base/location.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/macros.h" | 10 #include "base/macros.h" |
| 11 #include "base/message_loop/message_loop_proxy.h" | 11 #include "base/message_loop/message_loop_proxy.h" |
| 12 #include "ppapi/c/pp_errors.h" | 12 #include "ppapi/c/pp_errors.h" |
| 13 #include "ppapi/c/ppb_audio_buffer.h" | 13 #include "ppapi/c/ppb_audio_buffer.h" |
| 14 #include "ppapi/shared_impl/media_stream_buffer.h" | 14 #include "ppapi/shared_impl/media_stream_buffer.h" |
| 15 | 15 |
| 16 using media::AudioParameters; | 16 using media::AudioParameters; |
| 17 | 17 |
| 18 namespace { | 18 namespace { |
| 19 | 19 |
| 20 // Max audio buffer duration in milliseconds. | 20 // Max audio buffer duration in milliseconds. |
| 21 const uint32_t kMaxDuration = 10; | 21 const uint32_t kMaxDuration = 10; |
| 22 | 22 |
| 23 // TODO(penghuang): make this configurable. | 23 // TODO(penghuang): make this configurable. |
| 24 const int32_t kNumberOfBuffers = 4; | 24 const int32_t kNumberOfBuffers = 4; |
| 25 | 25 |
| 26 // Returns true if the |sample_rate| is supported in | 26 // Returns true if the |sample_rate| is supported in |
| 27 // |PP_AudioBuffer_SampleRate|, otherwise false. | 27 // |PP_AudioBuffer_SampleRate|, otherwise false. |
| 28 PP_AudioBuffer_SampleRate GetPPSampleRate(int sample_rate) { | 28 PP_AudioBuffer_SampleRate GetPPSampleRate(int sample_rate) { |
| 29 switch (sample_rate) { | 29 switch (sample_rate) { |
| 30 case 8000: return PP_AUDIOBUFFER_SAMPLERATE_8000; | 30 case 8000: |
| 31 case 16000: return PP_AUDIOBUFFER_SAMPLERATE_16000; | 31 return PP_AUDIOBUFFER_SAMPLERATE_8000; |
| 32 case 22050: return PP_AUDIOBUFFER_SAMPLERATE_22050; | 32 case 16000: |
| 33 case 32000: return PP_AUDIOBUFFER_SAMPLERATE_32000; | 33 return PP_AUDIOBUFFER_SAMPLERATE_16000; |
| 34 case 44100: return PP_AUDIOBUFFER_SAMPLERATE_44100; | 34 case 22050: |
| 35 case 48000: return PP_AUDIOBUFFER_SAMPLERATE_48000; | 35 return PP_AUDIOBUFFER_SAMPLERATE_22050; |
| 36 case 96000: return PP_AUDIOBUFFER_SAMPLERATE_96000; | 36 case 32000: |
| 37 case 192000: return PP_AUDIOBUFFER_SAMPLERATE_192000; | 37 return PP_AUDIOBUFFER_SAMPLERATE_32000; |
| 38 default: return PP_AUDIOBUFFER_SAMPLERATE_UNKNOWN; | 38 case 44100: |
| 39 return PP_AUDIOBUFFER_SAMPLERATE_44100; |
| 40 case 48000: |
| 41 return PP_AUDIOBUFFER_SAMPLERATE_48000; |
| 42 case 96000: |
| 43 return PP_AUDIOBUFFER_SAMPLERATE_96000; |
| 44 case 192000: |
| 45 return PP_AUDIOBUFFER_SAMPLERATE_192000; |
| 46 default: |
| 47 return PP_AUDIOBUFFER_SAMPLERATE_UNKNOWN; |
| 39 } | 48 } |
| 40 } | 49 } |
| 41 | 50 |
| 42 } // namespace | 51 } // namespace |
| 43 | 52 |
| 44 namespace content { | 53 namespace content { |
| 45 | 54 |
| 46 PepperMediaStreamAudioTrackHost::AudioSink::AudioSink( | 55 PepperMediaStreamAudioTrackHost::AudioSink::AudioSink( |
| 47 PepperMediaStreamAudioTrackHost* host) | 56 PepperMediaStreamAudioTrackHost* host) |
| 48 : host_(host), | 57 : host_(host), |
| 49 buffer_data_size_(0), | 58 buffer_data_size_(0), |
| 50 main_message_loop_proxy_(base::MessageLoopProxy::current()), | 59 main_message_loop_proxy_(base::MessageLoopProxy::current()), |
| 51 weak_factory_(this) { | 60 weak_factory_(this) {} |
| 52 } | |
| 53 | 61 |
| 54 PepperMediaStreamAudioTrackHost::AudioSink::~AudioSink() { | 62 PepperMediaStreamAudioTrackHost::AudioSink::~AudioSink() { |
| 55 DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current()); | 63 DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current()); |
| 56 } | 64 } |
| 57 | 65 |
| 58 void PepperMediaStreamAudioTrackHost::AudioSink::EnqueueBuffer(int32_t index) { | 66 void PepperMediaStreamAudioTrackHost::AudioSink::EnqueueBuffer(int32_t index) { |
| 59 DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current()); | 67 DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current()); |
| 60 DCHECK_GE(index, 0); | 68 DCHECK_GE(index, 0); |
| 61 DCHECK_LT(index, host_->buffer_manager()->number_of_buffers()); | 69 DCHECK_LT(index, host_->buffer_manager()->number_of_buffers()); |
| 62 base::AutoLock lock(lock_); | 70 base::AutoLock lock(lock_); |
| 63 buffers_.push_back(index); | 71 buffers_.push_back(index); |
| 64 } | 72 } |
| 65 | 73 |
| 66 void PepperMediaStreamAudioTrackHost::AudioSink::InitBuffersOnMainThread( | 74 void PepperMediaStreamAudioTrackHost::AudioSink::InitBuffersOnMainThread( |
| 67 int32_t number_of_buffers, int32_t buffer_size) { | 75 int32_t number_of_buffers, |
| 76 int32_t buffer_size) { |
| 68 DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current()); | 77 DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current()); |
| 69 bool result = host_->InitBuffers(number_of_buffers, buffer_size); | 78 bool result = host_->InitBuffers(number_of_buffers, buffer_size); |
| 70 // TODO(penghuang): Send PP_ERROR_NOMEMORY to plugin. | 79 // TODO(penghuang): Send PP_ERROR_NOMEMORY to plugin. |
| 71 CHECK(result); | 80 CHECK(result); |
| 72 base::AutoLock lock(lock_); | 81 base::AutoLock lock(lock_); |
| 73 for (int32_t i = 0; i < number_of_buffers; ++i) { | 82 for (int32_t i = 0; i < number_of_buffers; ++i) { |
| 74 int32_t index = host_->buffer_manager()->DequeueBuffer(); | 83 int32_t index = host_->buffer_manager()->DequeueBuffer(); |
| 75 DCHECK_GE(index, 0); | 84 DCHECK_GE(index, 0); |
| 76 buffers_.push_back(index); | 85 buffers_.push_back(index); |
| 77 } | 86 } |
| 78 } | 87 } |
| 79 | 88 |
| 80 void | 89 void PepperMediaStreamAudioTrackHost::AudioSink:: |
| 81 PepperMediaStreamAudioTrackHost::AudioSink:: | |
| 82 SendEnqueueBufferMessageOnMainThread(int32_t index) { | 90 SendEnqueueBufferMessageOnMainThread(int32_t index) { |
| 83 DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current()); | 91 DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current()); |
| 84 host_->SendEnqueueBufferMessageToPlugin(index); | 92 host_->SendEnqueueBufferMessageToPlugin(index); |
| 85 } | 93 } |
| 86 | 94 |
| 87 void PepperMediaStreamAudioTrackHost::AudioSink::OnData(const int16* audio_data, | 95 void PepperMediaStreamAudioTrackHost::AudioSink::OnData(const int16* audio_data, |
| 88 int sample_rate, | 96 int sample_rate, |
| 89 int number_of_channels, | 97 int number_of_channels, |
| 90 int number_of_frames) { | 98 int number_of_frames) { |
| 91 DCHECK(audio_thread_checker_.CalledOnValidThread()); | 99 DCHECK(audio_thread_checker_.CalledOnValidThread()); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 111 buffer->timestamp = timestamp_.InMillisecondsF(); | 119 buffer->timestamp = timestamp_.InMillisecondsF(); |
| 112 buffer->sample_rate = static_cast<PP_AudioBuffer_SampleRate>(sample_rate); | 120 buffer->sample_rate = static_cast<PP_AudioBuffer_SampleRate>(sample_rate); |
| 113 buffer->number_of_channels = number_of_channels; | 121 buffer->number_of_channels = number_of_channels; |
| 114 buffer->number_of_samples = number_of_channels * number_of_frames; | 122 buffer->number_of_samples = number_of_channels * number_of_frames; |
| 115 buffer->data_size = buffer_data_size_; | 123 buffer->data_size = buffer_data_size_; |
| 116 memcpy(buffer->data, audio_data, buffer_data_size_); | 124 memcpy(buffer->data, audio_data, buffer_data_size_); |
| 117 | 125 |
| 118 main_message_loop_proxy_->PostTask( | 126 main_message_loop_proxy_->PostTask( |
| 119 FROM_HERE, | 127 FROM_HERE, |
| 120 base::Bind(&AudioSink::SendEnqueueBufferMessageOnMainThread, | 128 base::Bind(&AudioSink::SendEnqueueBufferMessageOnMainThread, |
| 121 weak_factory_.GetWeakPtr(), index)); | 129 weak_factory_.GetWeakPtr(), |
| 130 index)); |
| 122 } | 131 } |
| 123 timestamp_ += buffer_duration_; | 132 timestamp_ += buffer_duration_; |
| 124 } | 133 } |
| 125 | 134 |
| 126 void PepperMediaStreamAudioTrackHost::AudioSink::OnSetFormat( | 135 void PepperMediaStreamAudioTrackHost::AudioSink::OnSetFormat( |
| 127 const AudioParameters& params) { | 136 const AudioParameters& params) { |
| 128 DCHECK(params.IsValid()); | 137 DCHECK(params.IsValid()); |
| 129 DCHECK_LE(params.GetBufferDuration().InMilliseconds(), kMaxDuration); | 138 DCHECK_LE(params.GetBufferDuration().InMilliseconds(), kMaxDuration); |
| 130 DCHECK_EQ(params.bits_per_sample(), 16); | 139 DCHECK_EQ(params.bits_per_sample(), 16); |
| 131 DCHECK_NE(GetPPSampleRate(params.sample_rate()), | 140 DCHECK_NE(GetPPSampleRate(params.sample_rate()), |
| 132 PP_AUDIOBUFFER_SAMPLERATE_UNKNOWN); | 141 PP_AUDIOBUFFER_SAMPLERATE_UNKNOWN); |
| 133 | 142 |
| 134 audio_params_ = params; | 143 audio_params_ = params; |
| 135 | 144 |
| 136 // TODO(penghuang): support setting format more than once. | 145 // TODO(penghuang): support setting format more than once. |
| 137 buffer_duration_ = params.GetBufferDuration(); | 146 buffer_duration_ = params.GetBufferDuration(); |
| 138 buffer_data_size_ = params.GetBytesPerBuffer(); | 147 buffer_data_size_ = params.GetBytesPerBuffer(); |
| 139 | 148 |
| 140 if (original_audio_params_.IsValid()) { | 149 if (original_audio_params_.IsValid()) { |
| 141 DCHECK_EQ(params.sample_rate(), original_audio_params_.sample_rate()); | 150 DCHECK_EQ(params.sample_rate(), original_audio_params_.sample_rate()); |
| 142 DCHECK_EQ(params.bits_per_sample(), | 151 DCHECK_EQ(params.bits_per_sample(), |
| 143 original_audio_params_.bits_per_sample()); | 152 original_audio_params_.bits_per_sample()); |
| 144 DCHECK_EQ(params.channels(), original_audio_params_.channels()); | 153 DCHECK_EQ(params.channels(), original_audio_params_.channels()); |
| 145 } else { | 154 } else { |
| 146 audio_thread_checker_.DetachFromThread(); | 155 audio_thread_checker_.DetachFromThread(); |
| 147 original_audio_params_ = params; | 156 original_audio_params_ = params; |
| 148 // The size is slightly bigger than necessary, because 8 extra bytes are | 157 // The size is slightly bigger than necessary, because 8 extra bytes are |
| 149 // added into the struct. Also see |MediaStreamBuffer|. | 158 // added into the struct. Also see |MediaStreamBuffer|. |
| 150 size_t max_data_size = | 159 size_t max_data_size = params.sample_rate() * params.bits_per_sample() / 8 * |
| 151 params.sample_rate() * params.bits_per_sample() / 8 * | 160 params.channels() * kMaxDuration / 1000; |
| 152 params.channels() * kMaxDuration / 1000; | |
| 153 size_t size = sizeof(ppapi::MediaStreamBuffer::Audio) + max_data_size; | 161 size_t size = sizeof(ppapi::MediaStreamBuffer::Audio) + max_data_size; |
| 154 | 162 |
| 155 main_message_loop_proxy_->PostTask( | 163 main_message_loop_proxy_->PostTask( |
| 156 FROM_HERE, | 164 FROM_HERE, |
| 157 base::Bind(&AudioSink::InitBuffersOnMainThread, | 165 base::Bind(&AudioSink::InitBuffersOnMainThread, |
| 158 weak_factory_.GetWeakPtr(), | 166 weak_factory_.GetWeakPtr(), |
| 159 kNumberOfBuffers, | 167 kNumberOfBuffers, |
| 160 static_cast<int32_t>(size))); | 168 static_cast<int32_t>(size))); |
| 161 } | 169 } |
| 162 } | 170 } |
| (...skipping 28 matching lines...) Expand all Loading... |
| 191 } | 199 } |
| 192 | 200 |
| 193 void PepperMediaStreamAudioTrackHost::DidConnectPendingHostToResource() { | 201 void PepperMediaStreamAudioTrackHost::DidConnectPendingHostToResource() { |
| 194 if (!connected_) { | 202 if (!connected_) { |
| 195 MediaStreamAudioSink::AddToAudioTrack(&audio_sink_, track_); | 203 MediaStreamAudioSink::AddToAudioTrack(&audio_sink_, track_); |
| 196 connected_ = true; | 204 connected_ = true; |
| 197 } | 205 } |
| 198 } | 206 } |
| 199 | 207 |
| 200 } // namespace content | 208 } // namespace content |
| OLD | NEW |