| 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" | 
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 42   entries_.emplace_back(std::move(memory), size); | 42   entries_.emplace_back(std::move(memory), size); | 
| 43 } | 43 } | 
| 44 | 44 | 
| 45 AudioBuffer::AudioBuffer(SampleFormat sample_format, | 45 AudioBuffer::AudioBuffer(SampleFormat sample_format, | 
| 46                          ChannelLayout channel_layout, | 46                          ChannelLayout channel_layout, | 
| 47                          int channel_count, | 47                          int channel_count, | 
| 48                          int sample_rate, | 48                          int sample_rate, | 
| 49                          int frame_count, | 49                          int frame_count, | 
| 50                          bool create_buffer, | 50                          bool create_buffer, | 
| 51                          const uint8_t* const* data, | 51                          const uint8_t* const* data, | 
|  | 52                          const size_t data_size, | 
| 52                          const base::TimeDelta timestamp, | 53                          const base::TimeDelta timestamp, | 
| 53                          scoped_refptr<AudioBufferMemoryPool> pool) | 54                          scoped_refptr<AudioBufferMemoryPool> pool) | 
| 54     : sample_format_(sample_format), | 55     : sample_format_(sample_format), | 
| 55       channel_layout_(channel_layout), | 56       channel_layout_(channel_layout), | 
| 56       channel_count_(channel_count), | 57       channel_count_(channel_count), | 
| 57       sample_rate_(sample_rate), | 58       sample_rate_(sample_rate), | 
| 58       adjusted_frame_count_(frame_count), | 59       adjusted_frame_count_(frame_count), | 
| 59       end_of_stream_(!create_buffer && !data && !frame_count), | 60       end_of_stream_(!create_buffer && !data && !frame_count), | 
| 60       timestamp_(timestamp), | 61       timestamp_(timestamp), | 
| 61       duration_(end_of_stream_ | 62       duration_(end_of_stream_ | 
| 62                     ? base::TimeDelta() | 63                     ? base::TimeDelta() | 
| 63                     : CalculateDuration(adjusted_frame_count_, sample_rate_)), | 64                     : CalculateDuration(adjusted_frame_count_, sample_rate_)), | 
| 64       data_size_(0), | 65       data_size_(data_size), | 
| 65       pool_(std::move(pool)) { | 66       pool_(std::move(pool)) { | 
| 66   CHECK_GE(channel_count_, 0); | 67   CHECK_GE(channel_count_, 0); | 
| 67   CHECK_LE(channel_count_, limits::kMaxChannels); | 68   CHECK_LE(channel_count_, limits::kMaxChannels); | 
| 68   CHECK_GE(frame_count, 0); | 69   CHECK_GE(frame_count, 0); | 
| 69   DCHECK(channel_layout == CHANNEL_LAYOUT_DISCRETE || | 70   DCHECK(channel_layout == CHANNEL_LAYOUT_DISCRETE || | 
| 70          ChannelLayoutToChannelCount(channel_layout) == channel_count); | 71          ChannelLayoutToChannelCount(channel_layout) == channel_count); | 
| 71 | 72 | 
| 72   int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format); | 73   int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format); | 
| 73   DCHECK_LE(bytes_per_channel, kChannelAlignment); | 74   DCHECK_LE(bytes_per_channel, kChannelAlignment); | 
| 74 | 75 | 
| 75   // Empty buffer? | 76   // Empty buffer? | 
| 76   if (!create_buffer) | 77   if (!create_buffer) | 
| 77     return; | 78     return; | 
| 78 | 79 | 
| 79   int data_size_per_channel = frame_count * bytes_per_channel; | 80   int data_size_per_channel = frame_count * bytes_per_channel; | 
| 80   if (IsPlanar(sample_format)) { | 81   if (IsPlanar(sample_format)) { | 
|  | 82     DCHECK(!IsBitstreamFormat()) << sample_format_; | 
| 81     // Planar data, so need to allocate buffer for each channel. | 83     // Planar data, so need to allocate buffer for each channel. | 
| 82     // Determine per channel data size, taking into account alignment. | 84     // Determine per channel data size, taking into account alignment. | 
| 83     int block_size_per_channel = | 85     int block_size_per_channel = | 
| 84         (data_size_per_channel + kChannelAlignment - 1) & | 86         (data_size_per_channel + kChannelAlignment - 1) & | 
| 85         ~(kChannelAlignment - 1); | 87         ~(kChannelAlignment - 1); | 
| 86     DCHECK_GE(block_size_per_channel, data_size_per_channel); | 88     DCHECK_GE(block_size_per_channel, data_size_per_channel); | 
| 87 | 89 | 
| 88     // Allocate a contiguous buffer for all the channel data. | 90     // Allocate a contiguous buffer for all the channel data. | 
| 89     data_size_ = channel_count_ * block_size_per_channel; | 91     data_size_ = channel_count_ * block_size_per_channel; | 
| 90     if (pool_) { | 92     if (pool_) { | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
| 101       if (data) | 103       if (data) | 
| 102         memcpy(channel_data_[i], data[i], data_size_per_channel); | 104         memcpy(channel_data_[i], data[i], data_size_per_channel); | 
| 103     } | 105     } | 
| 104     return; | 106     return; | 
| 105   } | 107   } | 
| 106 | 108 | 
| 107   // Remaining formats are interleaved data. | 109   // Remaining formats are interleaved data. | 
| 108   DCHECK(IsInterleaved(sample_format)) << sample_format_; | 110   DCHECK(IsInterleaved(sample_format)) << sample_format_; | 
| 109   // Allocate our own buffer and copy the supplied data into it. Buffer must | 111   // Allocate our own buffer and copy the supplied data into it. Buffer must | 
| 110   // contain the data for all channels. | 112   // contain the data for all channels. | 
| 111   data_size_ = data_size_per_channel * channel_count_; | 113   if (!IsBitstreamFormat()) | 
|  | 114     data_size_ = data_size_per_channel * channel_count_; | 
|  | 115   else | 
|  | 116     DCHECK(data_size_ > 0); | 
| 112 | 117 | 
| 113   if (pool_) { | 118   if (pool_) { | 
| 114     data_ = pool_->CreateBuffer(data_size_); | 119     data_ = pool_->CreateBuffer(data_size_); | 
| 115   } else { | 120   } else { | 
| 116     data_.reset(static_cast<uint8_t*>( | 121     data_.reset(static_cast<uint8_t*>( | 
| 117         base::AlignedAlloc(data_size_, kChannelAlignment))); | 122         base::AlignedAlloc(data_size_, kChannelAlignment))); | 
| 118   } | 123   } | 
| 119 | 124 | 
| 120   channel_data_.reserve(1); | 125   channel_data_.reserve(1); | 
| 121   channel_data_.push_back(data_.get()); | 126   channel_data_.push_back(data_.get()); | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
| 136     int sample_rate, | 141     int sample_rate, | 
| 137     int frame_count, | 142     int frame_count, | 
| 138     const uint8_t* const* data, | 143     const uint8_t* const* data, | 
| 139     const base::TimeDelta timestamp, | 144     const base::TimeDelta timestamp, | 
| 140     scoped_refptr<AudioBufferMemoryPool> pool) { | 145     scoped_refptr<AudioBufferMemoryPool> pool) { | 
| 141   // If you hit this CHECK you likely have a bug in a demuxer. Go fix it. | 146   // If you hit this CHECK you likely have a bug in a demuxer. Go fix it. | 
| 142   CHECK_GT(frame_count, 0);  // Otherwise looks like an EOF buffer. | 147   CHECK_GT(frame_count, 0);  // Otherwise looks like an EOF buffer. | 
| 143   CHECK(data[0]); | 148   CHECK(data[0]); | 
| 144   return make_scoped_refptr( | 149   return make_scoped_refptr( | 
| 145       new AudioBuffer(sample_format, channel_layout, channel_count, sample_rate, | 150       new AudioBuffer(sample_format, channel_layout, channel_count, sample_rate, | 
| 146                       frame_count, true, data, timestamp, std::move(pool))); | 151                       frame_count, true, data, 0, timestamp, std::move(pool))); | 
| 147 } | 152 } | 
| 148 | 153 | 
| 149 // static | 154 // static | 
|  | 155 scoped_refptr<AudioBuffer> AudioBuffer::CopyBitstreamFrom( | 
|  | 156     SampleFormat sample_format, | 
|  | 157     ChannelLayout channel_layout, | 
|  | 158     int channel_count, | 
|  | 159     int sample_rate, | 
|  | 160     int frame_count, | 
|  | 161     const uint8_t* const* data, | 
|  | 162     const size_t data_size, | 
|  | 163     const base::TimeDelta timestamp, | 
|  | 164     scoped_refptr<AudioBufferMemoryPool> pool) { | 
|  | 165   // If you hit this CHECK you likely have a bug in a demuxer. Go fix it. | 
|  | 166   CHECK_GT(frame_count, 0);  // Otherwise looks like an EOF buffer. | 
|  | 167   CHECK(data[0]); | 
|  | 168   return make_scoped_refptr(new AudioBuffer( | 
|  | 169       sample_format, channel_layout, channel_count, sample_rate, frame_count, | 
|  | 170       true, data, data_size, timestamp, std::move(pool))); | 
|  | 171 } | 
|  | 172 | 
|  | 173 // static | 
| 150 scoped_refptr<AudioBuffer> AudioBuffer::CreateBuffer( | 174 scoped_refptr<AudioBuffer> AudioBuffer::CreateBuffer( | 
| 151     SampleFormat sample_format, | 175     SampleFormat sample_format, | 
| 152     ChannelLayout channel_layout, | 176     ChannelLayout channel_layout, | 
| 153     int channel_count, | 177     int channel_count, | 
| 154     int sample_rate, | 178     int sample_rate, | 
| 155     int frame_count, | 179     int frame_count, | 
| 156     scoped_refptr<AudioBufferMemoryPool> pool) { | 180     scoped_refptr<AudioBufferMemoryPool> pool) { | 
| 157   CHECK_GT(frame_count, 0);  // Otherwise looks like an EOF buffer. | 181   CHECK_GT(frame_count, 0);  // Otherwise looks like an EOF buffer. | 
| 158   return make_scoped_refptr(new AudioBuffer( | 182   return make_scoped_refptr(new AudioBuffer( | 
| 159       sample_format, channel_layout, channel_count, sample_rate, frame_count, | 183       sample_format, channel_layout, channel_count, sample_rate, frame_count, | 
| 160       true, nullptr, kNoTimestamp, std::move(pool))); | 184       true, nullptr, 0, kNoTimestamp, std::move(pool))); | 
| 161 } | 185 } | 
| 162 | 186 | 
| 163 // static | 187 // static | 
|  | 188 scoped_refptr<AudioBuffer> AudioBuffer::CreateBitstreamBuffer( | 
|  | 189     SampleFormat sample_format, | 
|  | 190     ChannelLayout channel_layout, | 
|  | 191     int channel_count, | 
|  | 192     int sample_rate, | 
|  | 193     int frame_count, | 
|  | 194     size_t data_size, | 
|  | 195     scoped_refptr<AudioBufferMemoryPool> pool) { | 
|  | 196   CHECK_GT(frame_count, 0);  // Otherwise looks like an EOF buffer. | 
|  | 197   return make_scoped_refptr(new AudioBuffer( | 
|  | 198       sample_format, channel_layout, channel_count, sample_rate, frame_count, | 
|  | 199       true, nullptr, data_size, kNoTimestamp, std::move(pool))); | 
|  | 200 } | 
|  | 201 | 
|  | 202 // static | 
| 164 scoped_refptr<AudioBuffer> AudioBuffer::CreateEmptyBuffer( | 203 scoped_refptr<AudioBuffer> AudioBuffer::CreateEmptyBuffer( | 
| 165     ChannelLayout channel_layout, | 204     ChannelLayout channel_layout, | 
| 166     int channel_count, | 205     int channel_count, | 
| 167     int sample_rate, | 206     int sample_rate, | 
| 168     int frame_count, | 207     int frame_count, | 
| 169     const base::TimeDelta timestamp) { | 208     const base::TimeDelta timestamp) { | 
| 170   CHECK_GT(frame_count, 0);  // Otherwise looks like an EOF buffer. | 209   CHECK_GT(frame_count, 0);  // Otherwise looks like an EOF buffer. | 
| 171   // Since data == nullptr, format doesn't matter. | 210   // Since data == nullptr, format doesn't matter. | 
| 172   return make_scoped_refptr(new AudioBuffer( | 211   return make_scoped_refptr(new AudioBuffer( | 
| 173       kSampleFormatF32, channel_layout, channel_count, sample_rate, frame_count, | 212       kSampleFormatF32, channel_layout, channel_count, sample_rate, frame_count, | 
| 174       false, nullptr, timestamp, nullptr)); | 213       false, nullptr, 0, timestamp, nullptr)); | 
| 175 } | 214 } | 
| 176 | 215 | 
| 177 // static | 216 // static | 
| 178 scoped_refptr<AudioBuffer> AudioBuffer::CreateEOSBuffer() { | 217 scoped_refptr<AudioBuffer> AudioBuffer::CreateEOSBuffer() { | 
| 179   return make_scoped_refptr(new AudioBuffer(kUnknownSampleFormat, | 218   return make_scoped_refptr(new AudioBuffer(kUnknownSampleFormat, | 
| 180                                             CHANNEL_LAYOUT_NONE, 0, 0, 0, false, | 219                                             CHANNEL_LAYOUT_NONE, 0, 0, 0, false, | 
| 181                                             nullptr, kNoTimestamp, nullptr)); | 220                                             nullptr, 0, kNoTimestamp, nullptr)); | 
| 182 } | 221 } | 
| 183 | 222 | 
| 184 // Convert int16_t values in the range [INT16_MIN, INT16_MAX] to [-1.0, 1.0]. | 223 // Convert int16_t values in the range [INT16_MIN, INT16_MAX] to [-1.0, 1.0]. | 
| 185 inline float ConvertSample(int16_t value) { | 224 inline float ConvertSample(int16_t value) { | 
| 186   return value * (value < 0 ? -1.0f / std::numeric_limits<int16_t>::min() | 225   return value * (value < 0 ? -1.0f / std::numeric_limits<int16_t>::min() | 
| 187                             : 1.0f / std::numeric_limits<int16_t>::max()); | 226                             : 1.0f / std::numeric_limits<int16_t>::max()); | 
| 188 } | 227 } | 
| 189 | 228 | 
| 190 void AudioBuffer::AdjustSampleRate(int sample_rate) { | 229 void AudioBuffer::AdjustSampleRate(int sample_rate) { | 
| 191   DCHECK(!end_of_stream_); | 230   DCHECK(!end_of_stream_); | 
| 192   sample_rate_ = sample_rate; | 231   sample_rate_ = sample_rate; | 
| 193   duration_ = CalculateDuration(adjusted_frame_count_, sample_rate_); | 232   duration_ = CalculateDuration(adjusted_frame_count_, sample_rate_); | 
| 194 } | 233 } | 
| 195 | 234 | 
| 196 void AudioBuffer::ReadFrames(int frames_to_copy, | 235 void AudioBuffer::ReadFrames(int frames_to_copy, | 
| 197                              int source_frame_offset, | 236                              int source_frame_offset, | 
| 198                              int dest_frame_offset, | 237                              int dest_frame_offset, | 
| 199                              AudioBus* dest) { | 238                              AudioBus* dest) { | 
| 200   // Deinterleave each channel (if necessary) and convert to 32bit | 239   // Deinterleave each channel (if necessary) and convert to 32bit | 
| 201   // floating-point with nominal range -1.0 -> +1.0 (if necessary). | 240   // floating-point with nominal range -1.0 -> +1.0 (if necessary). | 
| 202 | 241 | 
| 203   // |dest| must have the same number of channels, and the number of frames | 242   // |dest| must have the same number of channels, and the number of frames | 
| 204   // specified must be in range. | 243   // specified must be in range. | 
| 205   DCHECK(!end_of_stream()); | 244   DCHECK(!end_of_stream()); | 
| 206   DCHECK_EQ(dest->channels(), channel_count_); | 245   DCHECK_EQ(dest->channels(), channel_count_); | 
| 207   DCHECK_LE(source_frame_offset + frames_to_copy, adjusted_frame_count_); | 246   DCHECK_LE(source_frame_offset + frames_to_copy, adjusted_frame_count_); | 
|  | 247 | 
|  | 248   if (IsBitstreamFormat()) { | 
|  | 249     // TODO(tsunghung): Implement it along with AudioBus changes. | 
|  | 250     NOTREACHED() << "Invalid sample format!"; | 
|  | 251   } | 
|  | 252 | 
| 208   DCHECK_LE(dest_frame_offset + frames_to_copy, dest->frames()); | 253   DCHECK_LE(dest_frame_offset + frames_to_copy, dest->frames()); | 
| 209 | 254 | 
| 210   if (!data_) { | 255   if (!data_) { | 
| 211     // Special case for an empty buffer. | 256     // Special case for an empty buffer. | 
| 212     dest->ZeroFramesPartial(dest_frame_offset, frames_to_copy); | 257     dest->ZeroFramesPartial(dest_frame_offset, frames_to_copy); | 
| 213     return; | 258     return; | 
| 214   } | 259   } | 
| 215 | 260 | 
| 216   if (sample_format_ == kSampleFormatPlanarF32) { | 261   if (sample_format_ == kSampleFormatPlanarF32) { | 
| 217     // Format is planar float32. Copy the data from each channel as a block. | 262     // Format is planar float32. Copy the data from each channel as a block. | 
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 263   int frame_size = channel_count_ * bytes_per_channel; | 308   int frame_size = channel_count_ * bytes_per_channel; | 
| 264   const uint8_t* source_data = data_.get() + source_frame_offset * frame_size; | 309   const uint8_t* source_data = data_.get() + source_frame_offset * frame_size; | 
| 265   dest->FromInterleavedPartial(source_data, dest_frame_offset, frames_to_copy, | 310   dest->FromInterleavedPartial(source_data, dest_frame_offset, frames_to_copy, | 
| 266                                bytes_per_channel); | 311                                bytes_per_channel); | 
| 267 } | 312 } | 
| 268 | 313 | 
| 269 void AudioBuffer::TrimStart(int frames_to_trim) { | 314 void AudioBuffer::TrimStart(int frames_to_trim) { | 
| 270   CHECK_GE(frames_to_trim, 0); | 315   CHECK_GE(frames_to_trim, 0); | 
| 271   CHECK_LE(frames_to_trim, adjusted_frame_count_); | 316   CHECK_LE(frames_to_trim, adjusted_frame_count_); | 
| 272 | 317 | 
|  | 318   if (IsBitstreamFormat()) { | 
|  | 319     LOG(ERROR) << "Not allowed to trim an audio bitstream buffer."; | 
|  | 320     return; | 
|  | 321   } | 
|  | 322 | 
| 273   TrimRange(0, frames_to_trim); | 323   TrimRange(0, frames_to_trim); | 
| 274 } | 324 } | 
| 275 | 325 | 
| 276 void AudioBuffer::TrimEnd(int frames_to_trim) { | 326 void AudioBuffer::TrimEnd(int frames_to_trim) { | 
| 277   CHECK_GE(frames_to_trim, 0); | 327   CHECK_GE(frames_to_trim, 0); | 
| 278   CHECK_LE(frames_to_trim, adjusted_frame_count_); | 328   CHECK_LE(frames_to_trim, adjusted_frame_count_); | 
| 279 | 329 | 
|  | 330   if (IsBitstreamFormat()) { | 
|  | 331     LOG(ERROR) << "Not allowed to trim an audio bitstream buffer."; | 
|  | 332     return; | 
|  | 333   } | 
|  | 334 | 
| 280   // Adjust the number of frames and duration for this buffer. | 335   // Adjust the number of frames and duration for this buffer. | 
| 281   adjusted_frame_count_ -= frames_to_trim; | 336   adjusted_frame_count_ -= frames_to_trim; | 
| 282   duration_ = CalculateDuration(adjusted_frame_count_, sample_rate_); | 337   duration_ = CalculateDuration(adjusted_frame_count_, sample_rate_); | 
| 283 } | 338 } | 
| 284 | 339 | 
| 285 void AudioBuffer::TrimRange(int start, int end) { | 340 void AudioBuffer::TrimRange(int start, int end) { | 
| 286   CHECK_GE(start, 0); | 341   CHECK_GE(start, 0); | 
| 287   CHECK_LE(end, adjusted_frame_count_); | 342   CHECK_LE(end, adjusted_frame_count_); | 
| 288 | 343 | 
|  | 344   if (IsBitstreamFormat()) { | 
|  | 345     LOG(ERROR) << "Not allowed to trim an audio bitstream buffer."; | 
|  | 346     return; | 
|  | 347   } | 
|  | 348 | 
| 289   const int frames_to_trim = end - start; | 349   const int frames_to_trim = end - start; | 
| 290   CHECK_GE(frames_to_trim, 0); | 350   CHECK_GE(frames_to_trim, 0); | 
| 291   CHECK_LE(frames_to_trim, adjusted_frame_count_); | 351   CHECK_LE(frames_to_trim, adjusted_frame_count_); | 
| 292 | 352 | 
| 293   const int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format_); | 353   const int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format_); | 
| 294   const int frames_to_copy = adjusted_frame_count_ - end; | 354   const int frames_to_copy = adjusted_frame_count_ - end; | 
| 295   if (frames_to_copy > 0) { | 355   if (frames_to_copy > 0) { | 
| 296     switch (sample_format_) { | 356     switch (sample_format_) { | 
| 297       case kSampleFormatPlanarS16: | 357       case kSampleFormatPlanarS16: | 
| 298       case kSampleFormatPlanarF32: | 358       case kSampleFormatPlanarF32: | 
| (...skipping 23 matching lines...) Expand all  Loading... | 
| 322         NOTREACHED() << "Invalid sample format!"; | 382         NOTREACHED() << "Invalid sample format!"; | 
| 323     } | 383     } | 
| 324   } else { | 384   } else { | 
| 325     CHECK_EQ(frames_to_copy, 0); | 385     CHECK_EQ(frames_to_copy, 0); | 
| 326   } | 386   } | 
| 327 | 387 | 
| 328   // Trim the leftover data off the end of the buffer and update duration. | 388   // Trim the leftover data off the end of the buffer and update duration. | 
| 329   TrimEnd(frames_to_trim); | 389   TrimEnd(frames_to_trim); | 
| 330 } | 390 } | 
| 331 | 391 | 
|  | 392 bool AudioBuffer::IsBitstreamFormat() { | 
|  | 393   return IsBitstream(sample_format_); | 
|  | 394 } | 
|  | 395 | 
| 332 }  // namespace media | 396 }  // namespace media | 
| OLD | NEW | 
|---|