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 |