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)) { |
81 // Planar data, so need to allocate buffer for each channel. | 82 // Planar data, so need to allocate buffer for each channel. |
chcunningham
2017/05/05 01:14:12
DCHECK(!IsBitstreamFormat(...))
AndyWu
2017/05/06 01:46:48
Done.
| |
82 // Determine per channel data size, taking into account alignment. | 83 // Determine per channel data size, taking into account alignment. |
83 int block_size_per_channel = | 84 int block_size_per_channel = |
84 (data_size_per_channel + kChannelAlignment - 1) & | 85 (data_size_per_channel + kChannelAlignment - 1) & |
85 ~(kChannelAlignment - 1); | 86 ~(kChannelAlignment - 1); |
86 DCHECK_GE(block_size_per_channel, data_size_per_channel); | 87 DCHECK_GE(block_size_per_channel, data_size_per_channel); |
87 | 88 |
88 // Allocate a contiguous buffer for all the channel data. | 89 // Allocate a contiguous buffer for all the channel data. |
89 data_size_ = channel_count_ * block_size_per_channel; | 90 data_size_ = channel_count_ * block_size_per_channel; |
90 if (pool_) { | 91 if (pool_) { |
91 data_ = pool_->CreateBuffer(data_size_); | 92 data_ = pool_->CreateBuffer(data_size_); |
92 } else { | 93 } else { |
93 data_.reset(static_cast<uint8_t*>( | 94 data_.reset(static_cast<uint8_t*>( |
94 base::AlignedAlloc(data_size_, kChannelAlignment))); | 95 base::AlignedAlloc(data_size_, kChannelAlignment))); |
95 } | 96 } |
96 channel_data_.reserve(channel_count_); | 97 channel_data_.reserve(channel_count_); |
97 | 98 |
98 // Copy each channel's data into the appropriate spot. | 99 // Copy each channel's data into the appropriate spot. |
99 for (int i = 0; i < channel_count_; ++i) { | 100 for (int i = 0; i < channel_count_; ++i) { |
100 channel_data_.push_back(data_.get() + i * block_size_per_channel); | 101 channel_data_.push_back(data_.get() + i * block_size_per_channel); |
101 if (data) | 102 if (data) |
102 memcpy(channel_data_[i], data[i], data_size_per_channel); | 103 memcpy(channel_data_[i], data[i], data_size_per_channel); |
103 } | 104 } |
104 return; | 105 return; |
105 } | 106 } |
106 | 107 |
107 // Remaining formats are interleaved data. | 108 // Remaining formats are interleaved data. |
108 DCHECK(IsInterleaved(sample_format)) << sample_format_; | 109 DCHECK(IsInterleaved(sample_format)) << sample_format_; |
109 // Allocate our own buffer and copy the supplied data into it. Buffer must | 110 // Allocate our own buffer and copy the supplied data into it. Buffer must |
110 // contain the data for all channels. | 111 // contain the data for all channels. |
111 data_size_ = data_size_per_channel * channel_count_; | 112 if (!IsBitstream(sample_format)) |
113 data_size_ = data_size_per_channel * channel_count_; | |
chcunningham
2017/05/05 01:14:12
else DCHECK(data_size_ > 0)?
AndyWu
2017/05/06 01:46:48
Done.
| |
112 | 114 |
113 if (pool_) { | 115 if (pool_) { |
114 data_ = pool_->CreateBuffer(data_size_); | 116 data_ = pool_->CreateBuffer(data_size_); |
115 } else { | 117 } else { |
116 data_.reset(static_cast<uint8_t*>( | 118 data_.reset(static_cast<uint8_t*>( |
117 base::AlignedAlloc(data_size_, kChannelAlignment))); | 119 base::AlignedAlloc(data_size_, kChannelAlignment))); |
118 } | 120 } |
119 | 121 |
120 channel_data_.reserve(1); | 122 channel_data_.reserve(1); |
121 channel_data_.push_back(data_.get()); | 123 channel_data_.push_back(data_.get()); |
(...skipping 14 matching lines...) Expand all Loading... | |
136 int sample_rate, | 138 int sample_rate, |
137 int frame_count, | 139 int frame_count, |
138 const uint8_t* const* data, | 140 const uint8_t* const* data, |
139 const base::TimeDelta timestamp, | 141 const base::TimeDelta timestamp, |
140 scoped_refptr<AudioBufferMemoryPool> pool) { | 142 scoped_refptr<AudioBufferMemoryPool> pool) { |
141 // If you hit this CHECK you likely have a bug in a demuxer. Go fix it. | 143 // 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. | 144 CHECK_GT(frame_count, 0); // Otherwise looks like an EOF buffer. |
143 CHECK(data[0]); | 145 CHECK(data[0]); |
144 return make_scoped_refptr( | 146 return make_scoped_refptr( |
145 new AudioBuffer(sample_format, channel_layout, channel_count, sample_rate, | 147 new AudioBuffer(sample_format, channel_layout, channel_count, sample_rate, |
146 frame_count, true, data, timestamp, std::move(pool))); | 148 frame_count, true, data, 0, timestamp, std::move(pool))); |
147 } | 149 } |
148 | 150 |
149 // static | 151 // static |
152 scoped_refptr<AudioBuffer> AudioBuffer::CopyBitstreamFrom( | |
153 SampleFormat sample_format, | |
154 ChannelLayout channel_layout, | |
155 int channel_count, | |
156 int sample_rate, | |
157 int frame_count, | |
158 const uint8_t* const* data, | |
159 const size_t data_size, | |
160 const base::TimeDelta timestamp, | |
161 scoped_refptr<AudioBufferMemoryPool> pool) { | |
162 // If you hit this CHECK you likely have a bug in a demuxer. Go fix it. | |
163 CHECK_GT(frame_count, 0); // Otherwise looks like an EOF buffer. | |
164 CHECK(data[0]); | |
165 return make_scoped_refptr(new AudioBuffer( | |
166 sample_format, channel_layout, channel_count, sample_rate, frame_count, | |
167 true, data, data_size, timestamp, std::move(pool))); | |
168 } | |
169 | |
170 // static | |
150 scoped_refptr<AudioBuffer> AudioBuffer::CreateBuffer( | 171 scoped_refptr<AudioBuffer> AudioBuffer::CreateBuffer( |
151 SampleFormat sample_format, | 172 SampleFormat sample_format, |
152 ChannelLayout channel_layout, | 173 ChannelLayout channel_layout, |
153 int channel_count, | 174 int channel_count, |
154 int sample_rate, | 175 int sample_rate, |
155 int frame_count, | 176 int frame_count, |
156 scoped_refptr<AudioBufferMemoryPool> pool) { | 177 scoped_refptr<AudioBufferMemoryPool> pool) { |
157 CHECK_GT(frame_count, 0); // Otherwise looks like an EOF buffer. | 178 CHECK_GT(frame_count, 0); // Otherwise looks like an EOF buffer. |
158 return make_scoped_refptr(new AudioBuffer( | 179 return make_scoped_refptr(new AudioBuffer( |
159 sample_format, channel_layout, channel_count, sample_rate, frame_count, | 180 sample_format, channel_layout, channel_count, sample_rate, frame_count, |
160 true, nullptr, kNoTimestamp, std::move(pool))); | 181 true, nullptr, 0, kNoTimestamp, std::move(pool))); |
161 } | 182 } |
162 | 183 |
163 // static | 184 // static |
185 scoped_refptr<AudioBuffer> AudioBuffer::CreateBitstreamBuffer( | |
186 SampleFormat sample_format, | |
187 ChannelLayout channel_layout, | |
188 int channel_count, | |
189 int sample_rate, | |
190 int frame_count, | |
191 size_t data_size, | |
192 scoped_refptr<AudioBufferMemoryPool> pool) { | |
193 CHECK_GT(frame_count, 0); // Otherwise looks like an EOF buffer. | |
194 return make_scoped_refptr(new AudioBuffer( | |
195 sample_format, channel_layout, channel_count, sample_rate, frame_count, | |
196 true, nullptr, data_size, kNoTimestamp, std::move(pool))); | |
197 } | |
198 | |
199 // static | |
164 scoped_refptr<AudioBuffer> AudioBuffer::CreateEmptyBuffer( | 200 scoped_refptr<AudioBuffer> AudioBuffer::CreateEmptyBuffer( |
165 ChannelLayout channel_layout, | 201 ChannelLayout channel_layout, |
166 int channel_count, | 202 int channel_count, |
167 int sample_rate, | 203 int sample_rate, |
168 int frame_count, | 204 int frame_count, |
169 const base::TimeDelta timestamp) { | 205 const base::TimeDelta timestamp) { |
170 CHECK_GT(frame_count, 0); // Otherwise looks like an EOF buffer. | 206 CHECK_GT(frame_count, 0); // Otherwise looks like an EOF buffer. |
171 // Since data == nullptr, format doesn't matter. | 207 // Since data == nullptr, format doesn't matter. |
172 return make_scoped_refptr(new AudioBuffer( | 208 return make_scoped_refptr(new AudioBuffer( |
173 kSampleFormatF32, channel_layout, channel_count, sample_rate, frame_count, | 209 kSampleFormatF32, channel_layout, channel_count, sample_rate, frame_count, |
174 false, nullptr, timestamp, nullptr)); | 210 false, nullptr, 0, timestamp, nullptr)); |
175 } | 211 } |
176 | 212 |
177 // static | 213 // static |
178 scoped_refptr<AudioBuffer> AudioBuffer::CreateEOSBuffer() { | 214 scoped_refptr<AudioBuffer> AudioBuffer::CreateEOSBuffer() { |
179 return make_scoped_refptr(new AudioBuffer(kUnknownSampleFormat, | 215 return make_scoped_refptr(new AudioBuffer(kUnknownSampleFormat, |
180 CHANNEL_LAYOUT_NONE, 0, 0, 0, false, | 216 CHANNEL_LAYOUT_NONE, 0, 0, 0, false, |
181 nullptr, kNoTimestamp, nullptr)); | 217 nullptr, 0, kNoTimestamp, nullptr)); |
182 } | 218 } |
183 | 219 |
184 // Convert int16_t values in the range [INT16_MIN, INT16_MAX] to [-1.0, 1.0]. | 220 // Convert int16_t values in the range [INT16_MIN, INT16_MAX] to [-1.0, 1.0]. |
185 inline float ConvertSample(int16_t value) { | 221 inline float ConvertSample(int16_t value) { |
186 return value * (value < 0 ? -1.0f / std::numeric_limits<int16_t>::min() | 222 return value * (value < 0 ? -1.0f / std::numeric_limits<int16_t>::min() |
187 : 1.0f / std::numeric_limits<int16_t>::max()); | 223 : 1.0f / std::numeric_limits<int16_t>::max()); |
188 } | 224 } |
189 | 225 |
190 void AudioBuffer::AdjustSampleRate(int sample_rate) { | 226 void AudioBuffer::AdjustSampleRate(int sample_rate) { |
191 DCHECK(!end_of_stream_); | 227 DCHECK(!end_of_stream_); |
192 sample_rate_ = sample_rate; | 228 sample_rate_ = sample_rate; |
193 duration_ = CalculateDuration(adjusted_frame_count_, sample_rate_); | 229 duration_ = CalculateDuration(adjusted_frame_count_, sample_rate_); |
194 } | 230 } |
195 | 231 |
196 void AudioBuffer::ReadFrames(int frames_to_copy, | 232 void AudioBuffer::ReadFrames(int frames_to_copy, |
197 int source_frame_offset, | 233 int source_frame_offset, |
198 int dest_frame_offset, | 234 int dest_frame_offset, |
199 AudioBus* dest) { | 235 AudioBus* dest) { |
200 // Deinterleave each channel (if necessary) and convert to 32bit | 236 // Deinterleave each channel (if necessary) and convert to 32bit |
201 // floating-point with nominal range -1.0 -> +1.0 (if necessary). | 237 // floating-point with nominal range -1.0 -> +1.0 (if necessary). |
202 | 238 |
203 // |dest| must have the same number of channels, and the number of frames | 239 // |dest| must have the same number of channels, and the number of frames |
204 // specified must be in range. | 240 // specified must be in range. |
205 DCHECK(!end_of_stream()); | 241 DCHECK(!end_of_stream()); |
206 DCHECK_EQ(dest->channels(), channel_count_); | 242 DCHECK_EQ(dest->channels(), channel_count_); |
207 DCHECK_LE(source_frame_offset + frames_to_copy, adjusted_frame_count_); | 243 DCHECK_LE(source_frame_offset + frames_to_copy, adjusted_frame_count_); |
244 | |
245 bool is_compressed_format = IsBitstream(sample_format_); | |
246 dest->set_is_compressed_format(is_compressed_format); | |
chcunningham
2017/05/05 01:14:11
is_compressed_format is slightly different name fr
AndyWu
2017/05/06 01:46:48
Sorry, this change should not be included in this
| |
247 | |
248 if (is_compressed_format) { | |
249 DCHECK(!source_frame_offset); | |
250 uint8_t* dest_data = | |
251 reinterpret_cast<uint8_t*>(dest->channel(0)) + dest->data_size(); | |
252 | |
253 memcpy(dest_data, channel_data_[0], data_size()); | |
254 dest->set_data_size(dest_frame_offset + data_size()); | |
255 dest->set_frames(dest->frames() + frame_count()); | |
256 return; | |
257 } | |
258 | |
208 DCHECK_LE(dest_frame_offset + frames_to_copy, dest->frames()); | 259 DCHECK_LE(dest_frame_offset + frames_to_copy, dest->frames()); |
209 | 260 |
210 if (!data_) { | 261 if (!data_) { |
211 // Special case for an empty buffer. | 262 // Special case for an empty buffer. |
212 dest->ZeroFramesPartial(dest_frame_offset, frames_to_copy); | 263 dest->ZeroFramesPartial(dest_frame_offset, frames_to_copy); |
213 return; | 264 return; |
214 } | 265 } |
215 | 266 |
216 if (sample_format_ == kSampleFormatPlanarF32) { | 267 if (sample_format_ == kSampleFormatPlanarF32) { |
217 // Format is planar float32. Copy the data from each channel as a block. | 268 // Format is planar float32. Copy the data from each channel as a block. |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
262 int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format_); | 313 int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format_); |
263 int frame_size = channel_count_ * bytes_per_channel; | 314 int frame_size = channel_count_ * bytes_per_channel; |
264 const uint8_t* source_data = data_.get() + source_frame_offset * frame_size; | 315 const uint8_t* source_data = data_.get() + source_frame_offset * frame_size; |
265 dest->FromInterleavedPartial(source_data, dest_frame_offset, frames_to_copy, | 316 dest->FromInterleavedPartial(source_data, dest_frame_offset, frames_to_copy, |
266 bytes_per_channel); | 317 bytes_per_channel); |
267 } | 318 } |
268 | 319 |
269 void AudioBuffer::TrimStart(int frames_to_trim) { | 320 void AudioBuffer::TrimStart(int frames_to_trim) { |
270 CHECK_GE(frames_to_trim, 0); | 321 CHECK_GE(frames_to_trim, 0); |
271 CHECK_LE(frames_to_trim, adjusted_frame_count_); | 322 CHECK_LE(frames_to_trim, adjusted_frame_count_); |
323 DCHECK(!IsBitstream(sample_format_)); | |
chcunningham
2017/05/05 01:14:11
These methods are called in frame_processor as par
AndyWu
2017/05/06 01:46:48
Done. However, we really should prevent trimming c
chcunningham
2017/05/08 20:01:02
They current MediaSource API doesn't really afford
| |
272 | 324 |
273 TrimRange(0, frames_to_trim); | 325 TrimRange(0, frames_to_trim); |
274 } | 326 } |
275 | 327 |
276 void AudioBuffer::TrimEnd(int frames_to_trim) { | 328 void AudioBuffer::TrimEnd(int frames_to_trim) { |
277 CHECK_GE(frames_to_trim, 0); | 329 CHECK_GE(frames_to_trim, 0); |
278 CHECK_LE(frames_to_trim, adjusted_frame_count_); | 330 CHECK_LE(frames_to_trim, adjusted_frame_count_); |
331 DCHECK(!IsBitstream(sample_format_)); | |
279 | 332 |
280 // Adjust the number of frames and duration for this buffer. | 333 // Adjust the number of frames and duration for this buffer. |
281 adjusted_frame_count_ -= frames_to_trim; | 334 adjusted_frame_count_ -= frames_to_trim; |
282 duration_ = CalculateDuration(adjusted_frame_count_, sample_rate_); | 335 duration_ = CalculateDuration(adjusted_frame_count_, sample_rate_); |
283 } | 336 } |
284 | 337 |
285 void AudioBuffer::TrimRange(int start, int end) { | 338 void AudioBuffer::TrimRange(int start, int end) { |
286 CHECK_GE(start, 0); | 339 CHECK_GE(start, 0); |
287 CHECK_LE(end, adjusted_frame_count_); | 340 CHECK_LE(end, adjusted_frame_count_); |
341 DCHECK(!IsBitstream(sample_format_)); | |
288 | 342 |
289 const int frames_to_trim = end - start; | 343 const int frames_to_trim = end - start; |
290 CHECK_GE(frames_to_trim, 0); | 344 CHECK_GE(frames_to_trim, 0); |
291 CHECK_LE(frames_to_trim, adjusted_frame_count_); | 345 CHECK_LE(frames_to_trim, adjusted_frame_count_); |
292 | 346 |
293 const int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format_); | 347 const int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format_); |
294 const int frames_to_copy = adjusted_frame_count_ - end; | 348 const int frames_to_copy = adjusted_frame_count_ - end; |
295 if (frames_to_copy > 0) { | 349 if (frames_to_copy > 0) { |
296 switch (sample_format_) { | 350 switch (sample_format_) { |
297 case kSampleFormatPlanarS16: | 351 case kSampleFormatPlanarS16: |
(...skipping 25 matching lines...) Expand all Loading... | |
323 } | 377 } |
324 } else { | 378 } else { |
325 CHECK_EQ(frames_to_copy, 0); | 379 CHECK_EQ(frames_to_copy, 0); |
326 } | 380 } |
327 | 381 |
328 // Trim the leftover data off the end of the buffer and update duration. | 382 // Trim the leftover data off the end of the buffer and update duration. |
329 TrimEnd(frames_to_trim); | 383 TrimEnd(frames_to_trim); |
330 } | 384 } |
331 | 385 |
332 } // namespace media | 386 } // namespace media |
OLD | NEW |