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 3 // found in the LICENSE file. 4 5 #include "media/base/audio_buffer.h" 6 7 #include "base/logging.h" 8 #include "media/base/audio_bus.h" 9 #include "media/base/buffers.h" 10 #include "media/base/limits.h" 11 12 namespace media { 13 14 // Alignment of each channel's data; this must match what ffmpeg expects 15 // (which may be 0, 16, or 32, depending on the processor). Selecting 32 in 16 // order to work on all processors. 17 enum { kChannelAlignment = 32 }; 18 19 AudioBuffer::AudioBuffer(SampleFormat sample_format, 20 int channel_count, 21 int frame_count, 22 bool create_buffer, 23 const uint8* const* data, 24 const base::TimeDelta timestamp, 25 const base::TimeDelta duration) 26 : sample_format_(sample_format), 27 channel_count_(channel_count), 28 adjusted_frame_count_(frame_count), 29 trim_start_(0), 30 end_of_stream_(!create_buffer && data == NULL && frame_count == 0), 31 timestamp_(timestamp), 32 duration_(duration) { 33 CHECK_GE(channel_count, 0); 34 CHECK_LE(channel_count, limits::kMaxChannels); 35 CHECK_GE(frame_count, 0); 36 int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format); 37 DCHECK_LE(bytes_per_channel, kChannelAlignment); 38 int data_size = frame_count * bytes_per_channel; 39 40 // Empty buffer? 41 if (!create_buffer) 42 return; 43 44 if (sample_format == kSampleFormatPlanarF32 || 45 sample_format == kSampleFormatPlanarS16) { 46 // Planar data, so need to allocate buffer for each channel. 47 // Determine per channel data size, taking into account alignment. 48 int block_size_per_channel = 49 (data_size + kChannelAlignment - 1) & ~(kChannelAlignment - 1); 50 DCHECK_GE(block_size_per_channel, data_size); 51 52 // Allocate a contiguous buffer for all the channel data. 53 data_.reset(static_cast<uint8*>(base::AlignedAlloc( 54 channel_count * block_size_per_channel, kChannelAlignment))); 55 channel_data_.reserve(channel_count); 56 57 // Copy each channel's data into the appropriate spot. 58 for (int i = 0; i < channel_count; ++i) { 59 channel_data_.push_back(data_.get() + i * block_size_per_channel); 60 if (data) 61 memcpy(channel_data_[i], data[i], data_size); 62 } 63 return; 64 } 65 66 // Remaining formats are interleaved data. 67 DCHECK(sample_format_ == kSampleFormatU8 || 68 sample_format_ == kSampleFormatS16 || 69 sample_format_ == kSampleFormatS32 || 70 sample_format_ == kSampleFormatF32) << sample_format_; 71 // Allocate our own buffer and copy the supplied data into it. Buffer must 72 // contain the data for all channels. 73 data_size *= channel_count; 74 data_.reset( 75 static_cast<uint8*>(base::AlignedAlloc(data_size, kChannelAlignment))); 76 if (data) 77 memcpy(data_.get(), data[0], data_size); 78 } 79 80 AudioBuffer::~AudioBuffer() {} 81 82 // static 83 scoped_refptr<AudioBuffer> AudioBuffer::CopyFrom( 84 SampleFormat sample_format, 85 int channel_count, 86 int frame_count, 87 const uint8* const* data, 88 const base::TimeDelta timestamp, 89 const base::TimeDelta duration) { 90 // If you hit this CHECK you likely have a bug in a demuxer. Go fix it. 91 CHECK_GT(frame_count, 0); // Otherwise looks like an EOF buffer. 92 CHECK(data[0]); 93 return make_scoped_refptr(new AudioBuffer(sample_format, 94 channel_count, 95 frame_count, 96 true, 97 data, 98 timestamp, 99 duration)); 100 } 101 102 // static 103 scoped_refptr<AudioBuffer> AudioBuffer::CreateBuffer(SampleFormat sample_format, 104 int channel_count, 105 int frame_count) { 106 CHECK_GT(frame_count, 0); // Otherwise looks like an EOF buffer. 107 return make_scoped_refptr(new AudioBuffer(sample_format, 108 channel_count, 109 frame_count, 110 true, 111 NULL, 112 kNoTimestamp(), 113 kNoTimestamp())); 114 } 115 116 // static 117 scoped_refptr<AudioBuffer> AudioBuffer::CreateEmptyBuffer( 118 int channel_count, 119 int frame_count, 120 const base::TimeDelta timestamp, 121 const base::TimeDelta duration) { 122 CHECK_GT(frame_count, 0); // Otherwise looks like an EOF buffer. 123 // Since data == NULL, format doesn't matter. 124 return make_scoped_refptr(new AudioBuffer(kSampleFormatF32, 125 channel_count, 126 frame_count, 127 false, 128 NULL, 129 timestamp, 130 duration)); 131 } 132 133 // static 134 scoped_refptr<AudioBuffer> AudioBuffer::CreateEOSBuffer() { 135 return make_scoped_refptr(new AudioBuffer( 136 kUnknownSampleFormat, 1, 0, false, NULL, kNoTimestamp(), kNoTimestamp())); 137 } 138 139 // Convert int16 values in the range [kint16min, kint16max] to [-1.0, 1.0]. 140 static inline float ConvertS16ToFloat(int16 value) { 141 return value * (value < 0 ? -1.0f / kint16min : 1.0f / kint16max); 142 } 143 144 void AudioBuffer::ReadFrames(int frames_to_copy, 145 int source_frame_offset, 146 int dest_frame_offset, 147 AudioBus* dest) { 148 // Deinterleave each channel (if necessary) and convert to 32bit 149 // floating-point with nominal range -1.0 -> +1.0 (if necessary). 150 151 // |dest| must have the same number of channels, and the number of frames 152 // specified must be in range. 153 DCHECK(!end_of_stream()); 154 DCHECK_EQ(dest->channels(), channel_count_); 155 DCHECK_LE(source_frame_offset + frames_to_copy, adjusted_frame_count_); 156 DCHECK_LE(dest_frame_offset + frames_to_copy, dest->frames()); 157 158 // Move the start past any frames that have been trimmed. 159 source_frame_offset += trim_start_; 160 161 if (!data_) { 162 // Special case for an empty buffer. 163 dest->ZeroFramesPartial(dest_frame_offset, frames_to_copy); 164 return; 165 } 166 167 if (sample_format_ == kSampleFormatPlanarF32) { 168 // Format is planar float32. Copy the data from each channel as a block. 169 for (int ch = 0; ch < channel_count_; ++ch) { 170 const float* source_data = 171 reinterpret_cast<const float*>(channel_data_[ch]) + 172 source_frame_offset; 173 memcpy(dest->channel(ch) + dest_frame_offset, 174 source_data, 175 sizeof(float) * frames_to_copy); 176 } 177 return; 178 } 179 180 if (sample_format_ == kSampleFormatPlanarS16) { 181 // Format is planar signed16. Convert each value into float and insert into 182 // output channel data. 183 for (int ch = 0; ch < channel_count_; ++ch) { 184 const int16* source_data = 185 reinterpret_cast<const int16*>(channel_data_[ch]) + 186 source_frame_offset; 187 float* dest_data = dest->channel(ch) + dest_frame_offset; 188 for (int i = 0; i < frames_to_copy; ++i) { 189 dest_data[i] = ConvertS16ToFloat(source_data[i]); 190 } 191 } 192 return; 193 } 194 195 if (sample_format_ == kSampleFormatF32) { 196 // Format is interleaved float32. Copy the data into each channel. 197 const float* source_data = reinterpret_cast<const float*>(data_.get()) + 198 source_frame_offset * channel_count_; 199 for (int ch = 0; ch < channel_count_; ++ch) { 200 float* dest_data = dest->channel(ch) + dest_frame_offset; 201 for (int i = 0, offset = ch; i < frames_to_copy; 202 ++i, offset += channel_count_) { 203 dest_data[i] = source_data[offset]; 204 } 205 } 206 return; 207 } 208 209 // Remaining formats are integer interleaved data. Use the deinterleaving code 210 // in AudioBus to copy the data. 211 DCHECK(sample_format_ == kSampleFormatU8 || 212 sample_format_ == kSampleFormatS16 || 213 sample_format_ == kSampleFormatS32); 214 int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format_); 215 int frame_size = channel_count_ * bytes_per_channel; 216 const uint8* source_data = data_.get() + source_frame_offset * frame_size; 217 dest->FromInterleavedPartial( 218 source_data, dest_frame_offset, frames_to_copy, bytes_per_channel); 219 } 220 221 void AudioBuffer::TrimStart(int frames_to_trim) { 222 CHECK_GE(frames_to_trim, 0); 223 CHECK_LE(frames_to_trim, adjusted_frame_count_); 224 225 // Adjust timestamp_ and duration_ to reflect the smaller number of frames. 226 double offset = static_cast<double>(duration_.InMicroseconds()) * 227 frames_to_trim / adjusted_frame_count_; 228 base::TimeDelta offset_as_time = 229 base::TimeDelta::FromMicroseconds(static_cast<int64>(offset)); 230 timestamp_ += offset_as_time; 231 duration_ -= offset_as_time; 232 233 // Finally adjust the number of frames in this buffer and where the start 234 // really is. 235 adjusted_frame_count_ -= frames_to_trim; 236 trim_start_ += frames_to_trim; 237 } 238 239 void AudioBuffer::TrimEnd(int frames_to_trim) { 240 CHECK_GE(frames_to_trim, 0); 241 CHECK_LE(frames_to_trim, adjusted_frame_count_); 242 243 // Adjust duration_ only to reflect the smaller number of frames. 244 double offset = static_cast<double>(duration_.InMicroseconds()) * 245 frames_to_trim / adjusted_frame_count_; 246 base::TimeDelta offset_as_time = 247 base::TimeDelta::FromMicroseconds(static_cast<int64>(offset)); 248 duration_ -= offset_as_time; 249 250 // Finally adjust the number of frames in this buffer. 251 adjusted_frame_count_ -= frames_to_trim; 252 } 253 254 } // namespace media 255