OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "media/base/audio_buffer.h" | 5 #include "media/base/audio_buffer.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "media/base/audio_bus.h" | 10 #include "media/base/audio_bus.h" |
11 #include "media/base/limits.h" | 11 #include "media/base/limits.h" |
12 #include "media/base/timestamp_constants.h" | 12 #include "media/base/timestamp_constants.h" |
13 | 13 |
14 namespace media { | 14 namespace media { |
15 | 15 |
16 static base::TimeDelta CalculateDuration(int frames, double sample_rate) { | 16 static base::TimeDelta CalculateDuration(int frames, double sample_rate) { |
17 DCHECK_GT(sample_rate, 0); | 17 DCHECK_GT(sample_rate, 0); |
18 return base::TimeDelta::FromMicroseconds( | 18 return base::TimeDelta::FromMicroseconds( |
19 frames * base::Time::kMicrosecondsPerSecond / sample_rate); | 19 frames * base::Time::kMicrosecondsPerSecond / sample_rate); |
20 } | 20 } |
21 | 21 |
22 AudioBuffer::AudioBuffer(SampleFormat sample_format, | 22 AudioBuffer::AudioBuffer(SampleFormat sample_format, |
23 ChannelLayout channel_layout, | 23 ChannelLayout channel_layout, |
24 int channel_count, | 24 int channel_count, |
25 int sample_rate, | 25 int sample_rate, |
26 int frame_count, | 26 int frame_count, |
27 bool create_buffer, | 27 bool create_buffer, |
28 const uint8* const* data, | 28 const uint8_t* const* data, |
29 const base::TimeDelta timestamp) | 29 const base::TimeDelta timestamp) |
30 : sample_format_(sample_format), | 30 : sample_format_(sample_format), |
31 channel_layout_(channel_layout), | 31 channel_layout_(channel_layout), |
32 channel_count_(channel_count), | 32 channel_count_(channel_count), |
33 sample_rate_(sample_rate), | 33 sample_rate_(sample_rate), |
34 adjusted_frame_count_(frame_count), | 34 adjusted_frame_count_(frame_count), |
35 trim_start_(0), | 35 trim_start_(0), |
36 end_of_stream_(!create_buffer && data == NULL && frame_count == 0), | 36 end_of_stream_(!create_buffer && data == NULL && frame_count == 0), |
37 timestamp_(timestamp), | 37 timestamp_(timestamp), |
38 duration_(end_of_stream_ | 38 duration_(end_of_stream_ |
(...skipping 17 matching lines...) Expand all Loading... |
56 if (IsPlanar(sample_format)) { | 56 if (IsPlanar(sample_format)) { |
57 // Planar data, so need to allocate buffer for each channel. | 57 // Planar data, so need to allocate buffer for each channel. |
58 // Determine per channel data size, taking into account alignment. | 58 // Determine per channel data size, taking into account alignment. |
59 int block_size_per_channel = | 59 int block_size_per_channel = |
60 (data_size_per_channel + kChannelAlignment - 1) & | 60 (data_size_per_channel + kChannelAlignment - 1) & |
61 ~(kChannelAlignment - 1); | 61 ~(kChannelAlignment - 1); |
62 DCHECK_GE(block_size_per_channel, data_size_per_channel); | 62 DCHECK_GE(block_size_per_channel, data_size_per_channel); |
63 | 63 |
64 // Allocate a contiguous buffer for all the channel data. | 64 // Allocate a contiguous buffer for all the channel data. |
65 data_size_ = channel_count_ * block_size_per_channel; | 65 data_size_ = channel_count_ * block_size_per_channel; |
66 data_.reset( | 66 data_.reset(static_cast<uint8_t*>( |
67 static_cast<uint8*>(base::AlignedAlloc(data_size_, kChannelAlignment))); | 67 base::AlignedAlloc(data_size_, kChannelAlignment))); |
68 channel_data_.reserve(channel_count_); | 68 channel_data_.reserve(channel_count_); |
69 | 69 |
70 // Copy each channel's data into the appropriate spot. | 70 // Copy each channel's data into the appropriate spot. |
71 for (int i = 0; i < channel_count_; ++i) { | 71 for (int i = 0; i < channel_count_; ++i) { |
72 channel_data_.push_back(data_.get() + i * block_size_per_channel); | 72 channel_data_.push_back(data_.get() + i * block_size_per_channel); |
73 if (data) | 73 if (data) |
74 memcpy(channel_data_[i], data[i], data_size_per_channel); | 74 memcpy(channel_data_[i], data[i], data_size_per_channel); |
75 } | 75 } |
76 return; | 76 return; |
77 } | 77 } |
78 | 78 |
79 // Remaining formats are interleaved data. | 79 // Remaining formats are interleaved data. |
80 DCHECK(IsInterleaved(sample_format)) << sample_format_; | 80 DCHECK(IsInterleaved(sample_format)) << sample_format_; |
81 // Allocate our own buffer and copy the supplied data into it. Buffer must | 81 // Allocate our own buffer and copy the supplied data into it. Buffer must |
82 // contain the data for all channels. | 82 // contain the data for all channels. |
83 data_size_ = data_size_per_channel * channel_count_; | 83 data_size_ = data_size_per_channel * channel_count_; |
84 data_.reset( | 84 data_.reset( |
85 static_cast<uint8*>(base::AlignedAlloc(data_size_, kChannelAlignment))); | 85 static_cast<uint8_t*>(base::AlignedAlloc(data_size_, kChannelAlignment))); |
86 channel_data_.reserve(1); | 86 channel_data_.reserve(1); |
87 channel_data_.push_back(data_.get()); | 87 channel_data_.push_back(data_.get()); |
88 if (data) | 88 if (data) |
89 memcpy(data_.get(), data[0], data_size_); | 89 memcpy(data_.get(), data[0], data_size_); |
90 } | 90 } |
91 | 91 |
92 AudioBuffer::~AudioBuffer() {} | 92 AudioBuffer::~AudioBuffer() {} |
93 | 93 |
94 // static | 94 // static |
95 scoped_refptr<AudioBuffer> AudioBuffer::CopyFrom( | 95 scoped_refptr<AudioBuffer> AudioBuffer::CopyFrom( |
96 SampleFormat sample_format, | 96 SampleFormat sample_format, |
97 ChannelLayout channel_layout, | 97 ChannelLayout channel_layout, |
98 int channel_count, | 98 int channel_count, |
99 int sample_rate, | 99 int sample_rate, |
100 int frame_count, | 100 int frame_count, |
101 const uint8* const* data, | 101 const uint8_t* const* data, |
102 const base::TimeDelta timestamp) { | 102 const base::TimeDelta timestamp) { |
103 // If you hit this CHECK you likely have a bug in a demuxer. Go fix it. | 103 // If you hit this CHECK you likely have a bug in a demuxer. Go fix it. |
104 CHECK_GT(frame_count, 0); // Otherwise looks like an EOF buffer. | 104 CHECK_GT(frame_count, 0); // Otherwise looks like an EOF buffer. |
105 CHECK(data[0]); | 105 CHECK(data[0]); |
106 return make_scoped_refptr(new AudioBuffer(sample_format, | 106 return make_scoped_refptr(new AudioBuffer(sample_format, |
107 channel_layout, | 107 channel_layout, |
108 channel_count, | 108 channel_count, |
109 sample_rate, | 109 sample_rate, |
110 frame_count, | 110 frame_count, |
111 true, | 111 true, |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 0, | 158 0, |
159 0, | 159 0, |
160 false, | 160 false, |
161 NULL, | 161 NULL, |
162 kNoTimestamp())); | 162 kNoTimestamp())); |
163 } | 163 } |
164 | 164 |
165 template <typename Target, typename Dest> | 165 template <typename Target, typename Dest> |
166 static inline Dest ConvertSample(Target value); | 166 static inline Dest ConvertSample(Target value); |
167 | 167 |
168 // Convert int16 values in the range [INT16_MIN, INT16_MAX] to [-1.0, 1.0]. | 168 // Convert int16_t values in the range [INT16_MIN, INT16_MAX] to [-1.0, 1.0]. |
169 template <> | 169 template <> |
170 inline float ConvertSample<int16, float>(int16 value) { | 170 inline float ConvertSample<int16_t, float>(int16_t value) { |
171 return value * (value < 0 ? -1.0f / std::numeric_limits<int16>::min() | 171 return value * (value < 0 ? -1.0f / std::numeric_limits<int16_t>::min() |
172 : 1.0f / std::numeric_limits<int16>::max()); | 172 : 1.0f / std::numeric_limits<int16_t>::max()); |
173 } | 173 } |
174 | 174 |
175 // Specializations for int32 | 175 // Specializations for int32_t |
176 template <> | 176 template <> |
177 inline int32 ConvertSample<int16, int32>(int16 value) { | 177 inline int32_t ConvertSample<int16_t, int32_t>(int16_t value) { |
178 return static_cast<int32>(value) << 16; | 178 return static_cast<int32_t>(value) << 16; |
179 } | 179 } |
180 | 180 |
181 template <> | 181 template <> |
182 inline int32 ConvertSample<int32, int32>(int32 value) { | 182 inline int32_t ConvertSample<int32_t, int32_t>(int32_t value) { |
183 return value; | 183 return value; |
184 } | 184 } |
185 | 185 |
186 template <> | 186 template <> |
187 inline int32 ConvertSample<float, int32>(float value) { | 187 inline int32_t ConvertSample<float, int32_t>(float value) { |
188 return static_cast<int32>(value < 0 | 188 return static_cast<int32_t>( |
189 ? (-value) * std::numeric_limits<int32>::min() | 189 value < 0 ? (-value) * std::numeric_limits<int32_t>::min() |
190 : value * std::numeric_limits<int32>::max()); | 190 : value * std::numeric_limits<int32_t>::max()); |
191 } | 191 } |
192 | 192 |
193 // Specializations for int16 | 193 // Specializations for int16_t |
194 template <> | 194 template <> |
195 inline int16 ConvertSample<int16, int16>(int16 sample) { | 195 inline int16_t ConvertSample<int16_t, int16_t>(int16_t sample) { |
196 return sample; | 196 return sample; |
197 } | 197 } |
198 | 198 |
199 template <> | 199 template <> |
200 inline int16 ConvertSample<int32, int16>(int32 sample) { | 200 inline int16_t ConvertSample<int32_t, int16_t>(int32_t sample) { |
201 return sample >> 16; | 201 return sample >> 16; |
202 } | 202 } |
203 | 203 |
204 template <> | 204 template <> |
205 inline int16 ConvertSample<float, int16>(float sample) { | 205 inline int16_t ConvertSample<float, int16_t>(float sample) { |
206 return static_cast<int16>( | 206 return static_cast<int16_t>( |
207 nearbyint(sample < 0 ? (-sample) * std::numeric_limits<int16>::min() | 207 nearbyint(sample < 0 ? (-sample) * std::numeric_limits<int16_t>::min() |
208 : sample * std::numeric_limits<int16>::max())); | 208 : sample * std::numeric_limits<int16_t>::max())); |
209 } | 209 } |
210 | 210 |
211 void AudioBuffer::ReadFrames(int frames_to_copy, | 211 void AudioBuffer::ReadFrames(int frames_to_copy, |
212 int source_frame_offset, | 212 int source_frame_offset, |
213 int dest_frame_offset, | 213 int dest_frame_offset, |
214 AudioBus* dest) { | 214 AudioBus* dest) { |
215 // Deinterleave each channel (if necessary) and convert to 32bit | 215 // Deinterleave each channel (if necessary) and convert to 32bit |
216 // floating-point with nominal range -1.0 -> +1.0 (if necessary). | 216 // floating-point with nominal range -1.0 -> +1.0 (if necessary). |
217 | 217 |
218 // |dest| must have the same number of channels, and the number of frames | 218 // |dest| must have the same number of channels, and the number of frames |
(...skipping 22 matching lines...) Expand all Loading... |
241 source_data, | 241 source_data, |
242 sizeof(float) * frames_to_copy); | 242 sizeof(float) * frames_to_copy); |
243 } | 243 } |
244 return; | 244 return; |
245 } | 245 } |
246 | 246 |
247 if (sample_format_ == kSampleFormatPlanarS16) { | 247 if (sample_format_ == kSampleFormatPlanarS16) { |
248 // Format is planar signed16. Convert each value into float and insert into | 248 // Format is planar signed16. Convert each value into float and insert into |
249 // output channel data. | 249 // output channel data. |
250 for (int ch = 0; ch < channel_count_; ++ch) { | 250 for (int ch = 0; ch < channel_count_; ++ch) { |
251 const int16* source_data = | 251 const int16_t* source_data = |
252 reinterpret_cast<const int16*>(channel_data_[ch]) + | 252 reinterpret_cast<const int16_t*>(channel_data_[ch]) + |
253 source_frame_offset; | 253 source_frame_offset; |
254 float* dest_data = dest->channel(ch) + dest_frame_offset; | 254 float* dest_data = dest->channel(ch) + dest_frame_offset; |
255 for (int i = 0; i < frames_to_copy; ++i) { | 255 for (int i = 0; i < frames_to_copy; ++i) { |
256 dest_data[i] = ConvertSample<int16, float>(source_data[i]); | 256 dest_data[i] = ConvertSample<int16_t, float>(source_data[i]); |
257 } | 257 } |
258 } | 258 } |
259 return; | 259 return; |
260 } | 260 } |
261 | 261 |
262 if (sample_format_ == kSampleFormatF32) { | 262 if (sample_format_ == kSampleFormatF32) { |
263 // Format is interleaved float32. Copy the data into each channel. | 263 // Format is interleaved float32. Copy the data into each channel. |
264 const float* source_data = reinterpret_cast<const float*>(data_.get()) + | 264 const float* source_data = reinterpret_cast<const float*>(data_.get()) + |
265 source_frame_offset * channel_count_; | 265 source_frame_offset * channel_count_; |
266 for (int ch = 0; ch < channel_count_; ++ch) { | 266 for (int ch = 0; ch < channel_count_; ++ch) { |
267 float* dest_data = dest->channel(ch) + dest_frame_offset; | 267 float* dest_data = dest->channel(ch) + dest_frame_offset; |
268 for (int i = 0, offset = ch; i < frames_to_copy; | 268 for (int i = 0, offset = ch; i < frames_to_copy; |
269 ++i, offset += channel_count_) { | 269 ++i, offset += channel_count_) { |
270 dest_data[i] = source_data[offset]; | 270 dest_data[i] = source_data[offset]; |
271 } | 271 } |
272 } | 272 } |
273 return; | 273 return; |
274 } | 274 } |
275 | 275 |
276 // Remaining formats are integer interleaved data. Use the deinterleaving code | 276 // Remaining formats are integer interleaved data. Use the deinterleaving code |
277 // in AudioBus to copy the data. | 277 // in AudioBus to copy the data. |
278 DCHECK(sample_format_ == kSampleFormatU8 || | 278 DCHECK(sample_format_ == kSampleFormatU8 || |
279 sample_format_ == kSampleFormatS16 || | 279 sample_format_ == kSampleFormatS16 || |
280 sample_format_ == kSampleFormatS32); | 280 sample_format_ == kSampleFormatS32); |
281 int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format_); | 281 int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format_); |
282 int frame_size = channel_count_ * bytes_per_channel; | 282 int frame_size = channel_count_ * bytes_per_channel; |
283 const uint8* source_data = data_.get() + source_frame_offset * frame_size; | 283 const uint8_t* source_data = data_.get() + source_frame_offset * frame_size; |
284 dest->FromInterleavedPartial( | 284 dest->FromInterleavedPartial( |
285 source_data, dest_frame_offset, frames_to_copy, bytes_per_channel); | 285 source_data, dest_frame_offset, frames_to_copy, bytes_per_channel); |
286 } | 286 } |
287 | 287 |
288 template <class Target, typename Dest> | 288 template <class Target, typename Dest> |
289 void InterleaveAndConvert(const std::vector<uint8*>& channel_data, | 289 void InterleaveAndConvert(const std::vector<uint8_t*>& channel_data, |
290 size_t frames_to_copy, | 290 size_t frames_to_copy, |
291 int trim_start, | 291 int trim_start, |
292 Dest* dest_data) { | 292 Dest* dest_data) { |
293 for (size_t ch = 0; ch < channel_data.size(); ++ch) { | 293 for (size_t ch = 0; ch < channel_data.size(); ++ch) { |
294 const Target* source_data = | 294 const Target* source_data = |
295 reinterpret_cast<const Target*>(channel_data[ch]) + trim_start; | 295 reinterpret_cast<const Target*>(channel_data[ch]) + trim_start; |
296 for (size_t i = 0, offset = ch; i < frames_to_copy; | 296 for (size_t i = 0, offset = ch; i < frames_to_copy; |
297 ++i, offset += channel_data.size()) { | 297 ++i, offset += channel_data.size()) { |
298 dest_data[offset] = ConvertSample<Target, Dest>(source_data[i]); | 298 dest_data[offset] = ConvertSample<Target, Dest>(source_data[i]); |
299 } | 299 } |
300 } | 300 } |
301 } | 301 } |
302 | 302 |
303 template <typename Dest> | 303 template <typename Dest> |
304 void ReadFramesInterleaved(const std::vector<uint8*>& channel_data, | 304 void ReadFramesInterleaved(const std::vector<uint8_t*>& channel_data, |
305 int channel_count, | 305 int channel_count, |
306 SampleFormat sample_format, | 306 SampleFormat sample_format, |
307 int frames_to_copy, | 307 int frames_to_copy, |
308 int trim_start, | 308 int trim_start, |
309 Dest* dest_data) { | 309 Dest* dest_data) { |
310 switch (sample_format) { | 310 switch (sample_format) { |
311 case kSampleFormatU8: | 311 case kSampleFormatU8: |
312 NOTREACHED(); | 312 NOTREACHED(); |
313 break; | 313 break; |
314 case kSampleFormatS16: | 314 case kSampleFormatS16: |
315 InterleaveAndConvert<int16, Dest>( | 315 InterleaveAndConvert<int16_t, Dest>( |
316 channel_data, frames_to_copy * channel_count, trim_start, dest_data); | 316 channel_data, frames_to_copy * channel_count, trim_start, dest_data); |
317 break; | 317 break; |
318 case kSampleFormatS24: | 318 case kSampleFormatS24: |
319 case kSampleFormatS32: | 319 case kSampleFormatS32: |
320 InterleaveAndConvert<int32, Dest>( | 320 InterleaveAndConvert<int32_t, Dest>( |
321 channel_data, frames_to_copy * channel_count, trim_start, dest_data); | 321 channel_data, frames_to_copy * channel_count, trim_start, dest_data); |
322 break; | 322 break; |
323 case kSampleFormatF32: | 323 case kSampleFormatF32: |
324 InterleaveAndConvert<float, Dest>( | 324 InterleaveAndConvert<float, Dest>( |
325 channel_data, frames_to_copy * channel_count, trim_start, dest_data); | 325 channel_data, frames_to_copy * channel_count, trim_start, dest_data); |
326 break; | 326 break; |
327 case kSampleFormatPlanarS16: | 327 case kSampleFormatPlanarS16: |
328 InterleaveAndConvert<int16, Dest>(channel_data, frames_to_copy, | 328 InterleaveAndConvert<int16_t, Dest>(channel_data, frames_to_copy, |
329 trim_start, dest_data); | 329 trim_start, dest_data); |
330 break; | 330 break; |
331 case kSampleFormatPlanarF32: | 331 case kSampleFormatPlanarF32: |
332 InterleaveAndConvert<float, Dest>(channel_data, frames_to_copy, | 332 InterleaveAndConvert<float, Dest>(channel_data, frames_to_copy, |
333 trim_start, dest_data); | 333 trim_start, dest_data); |
334 break; | 334 break; |
335 case kSampleFormatPlanarS32: | 335 case kSampleFormatPlanarS32: |
336 InterleaveAndConvert<int32, Dest>(channel_data, frames_to_copy, | 336 InterleaveAndConvert<int32_t, Dest>(channel_data, frames_to_copy, |
337 trim_start, dest_data); | 337 trim_start, dest_data); |
338 break; | 338 break; |
339 case kUnknownSampleFormat: | 339 case kUnknownSampleFormat: |
340 NOTREACHED(); | 340 NOTREACHED(); |
341 break; | 341 break; |
342 } | 342 } |
343 } | 343 } |
344 | 344 |
345 void AudioBuffer::ReadFramesInterleavedS32(int frames_to_copy, | 345 void AudioBuffer::ReadFramesInterleavedS32(int frames_to_copy, |
346 int32* dest_data) { | 346 int32_t* dest_data) { |
347 DCHECK_LE(frames_to_copy, adjusted_frame_count_); | 347 DCHECK_LE(frames_to_copy, adjusted_frame_count_); |
348 ReadFramesInterleaved<int32>(channel_data_, channel_count_, sample_format_, | 348 ReadFramesInterleaved<int32_t>(channel_data_, channel_count_, sample_format_, |
349 frames_to_copy, trim_start_, dest_data); | 349 frames_to_copy, trim_start_, dest_data); |
350 } | 350 } |
351 | 351 |
352 void AudioBuffer::ReadFramesInterleavedS16(int frames_to_copy, | 352 void AudioBuffer::ReadFramesInterleavedS16(int frames_to_copy, |
353 int16* dest_data) { | 353 int16_t* dest_data) { |
354 DCHECK_LE(frames_to_copy, adjusted_frame_count_); | 354 DCHECK_LE(frames_to_copy, adjusted_frame_count_); |
355 ReadFramesInterleaved<int16>(channel_data_, channel_count_, sample_format_, | 355 ReadFramesInterleaved<int16_t>(channel_data_, channel_count_, sample_format_, |
356 frames_to_copy, trim_start_, dest_data); | 356 frames_to_copy, trim_start_, dest_data); |
357 } | 357 } |
358 | 358 |
359 void AudioBuffer::TrimStart(int frames_to_trim) { | 359 void AudioBuffer::TrimStart(int frames_to_trim) { |
360 CHECK_GE(frames_to_trim, 0); | 360 CHECK_GE(frames_to_trim, 0); |
361 CHECK_LE(frames_to_trim, adjusted_frame_count_); | 361 CHECK_LE(frames_to_trim, adjusted_frame_count_); |
362 | 362 |
363 // Adjust the number of frames in this buffer and where the start really is. | 363 // Adjust the number of frames in this buffer and where the start really is. |
364 adjusted_frame_count_ -= frames_to_trim; | 364 adjusted_frame_count_ -= frames_to_trim; |
365 trim_start_ += frames_to_trim; | 365 trim_start_ += frames_to_trim; |
366 | 366 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
418 } | 418 } |
419 } else { | 419 } else { |
420 CHECK_EQ(frames_to_copy, 0); | 420 CHECK_EQ(frames_to_copy, 0); |
421 } | 421 } |
422 | 422 |
423 // Trim the leftover data off the end of the buffer and update duration. | 423 // Trim the leftover data off the end of the buffer and update duration. |
424 TrimEnd(frames_to_trim); | 424 TrimEnd(frames_to_trim); |
425 } | 425 } |
426 | 426 |
427 } // namespace media | 427 } // namespace media |
OLD | NEW |