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. | |
Tom Sepez
2017/05/08 21:50:18
Which process can this run in? If it's the browse
AndyWu
2017/05/08 22:51:02
Yes, it can run in the browser process. The logic
Tom Sepez
2017/05/08 22:56:56
Ok, then in both places we'll want to change to DC
AndyWu
2017/05/09 01:25:46
Done, I add more sanity checks in media/mojo/commo
| |
167 CHECK(data[0]); | |
168 return make_scoped_refptr(new AudioBuffer( | |
Tom Sepez
2017/05/08 21:50:18
How trusting is the audio_buffer class about havin
AndyWu
2017/05/08 22:51:02
Since it's compressed data, the data_size could be
Tom Sepez
2017/05/08 22:56:56
Ok, that doesn't help much, we may be OK however i
AndyWu
2017/05/09 01:25:46
The compressed data will be passed to audio sink,
| |
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 |