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

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

Issue 2572573007: Use passthrough decoder for (E)AC3 formats (Closed)
Patch Set: Use passthrough decoder for (E)AC3 formats 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
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)) {
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698