Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(844)

Side by Side Diff: media/base/audio_buffer.cc

Issue 2572573007: Use passthrough decoder for (E)AC3 formats (Closed)
Patch Set: Sanity checks Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « media/base/audio_buffer.h ('k') | media/base/audio_buffer_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « media/base/audio_buffer.h ('k') | media/base/audio_buffer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698