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" |
11 #include "media/base/limits.h" | 11 #include "media/base/limits.h" |
12 #include "media/base/timestamp_constants.h" | 12 #include "media/base/timestamp_constants.h" |
13 | 13 |
14 namespace media { | 14 namespace media { |
15 | 15 |
16 static base::TimeDelta CalculateDuration(int frames, double sample_rate) { | 16 static base::TimeDelta CalculateDuration(int frames, double sample_rate) { |
17 DCHECK_GT(sample_rate, 0); | 17 DCHECK_GT(sample_rate, 0); |
18 return base::TimeDelta::FromMicroseconds( | 18 return base::TimeDelta::FromMicroseconds( |
19 frames * base::Time::kMicrosecondsPerSecond / sample_rate); | 19 frames * base::Time::kMicrosecondsPerSecond / sample_rate); |
20 } | 20 } |
21 | 21 |
22 AudioBuffer::AudioBuffer(SampleFormat sample_format, | 22 AudioBuffer::AudioBuffer(SampleFormat sample_format, |
23 ChannelLayout channel_layout, | 23 ChannelLayout channel_layout, |
24 int channel_count, | 24 int channel_count, |
25 int sample_rate, | 25 int sample_rate, |
26 int frame_count, | 26 int frame_count, |
27 bool create_buffer, | 27 bool create_buffer, |
28 const uint8_t* const* data, | 28 const uint8_t* const* data, |
29 size_t data_size, | |
29 const base::TimeDelta timestamp) | 30 const base::TimeDelta timestamp) |
30 : sample_format_(sample_format), | 31 : sample_format_(sample_format), |
31 channel_layout_(channel_layout), | 32 channel_layout_(channel_layout), |
32 channel_count_(channel_count), | 33 channel_count_(channel_count), |
33 sample_rate_(sample_rate), | 34 sample_rate_(sample_rate), |
34 adjusted_frame_count_(frame_count), | 35 adjusted_frame_count_(frame_count), |
35 end_of_stream_(!create_buffer && data == NULL && frame_count == 0), | 36 end_of_stream_(!create_buffer && data == NULL && frame_count == 0), |
36 timestamp_(timestamp), | 37 timestamp_(timestamp), |
37 duration_(end_of_stream_ | 38 duration_(end_of_stream_ |
38 ? base::TimeDelta() | 39 ? base::TimeDelta() |
39 : CalculateDuration(adjusted_frame_count_, sample_rate_)), | 40 : CalculateDuration(adjusted_frame_count_, sample_rate_)), |
40 data_size_(0) { | 41 data_size_(data_size) { |
41 CHECK_GE(channel_count_, 0); | 42 CHECK_GE(channel_count_, 0); |
42 CHECK_LE(channel_count_, limits::kMaxChannels); | 43 CHECK_LE(channel_count_, limits::kMaxChannels); |
43 CHECK_GE(frame_count, 0); | 44 CHECK_GE(frame_count, 0); |
44 DCHECK(channel_layout == CHANNEL_LAYOUT_DISCRETE || | 45 DCHECK(channel_layout == CHANNEL_LAYOUT_DISCRETE || |
45 ChannelLayoutToChannelCount(channel_layout) == channel_count); | 46 ChannelLayoutToChannelCount(channel_layout) == channel_count); |
46 | 47 |
47 int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format); | 48 int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format); |
48 DCHECK_LE(bytes_per_channel, kChannelAlignment); | 49 DCHECK_LE(bytes_per_channel, kChannelAlignment); |
49 | 50 |
50 // Empty buffer? | 51 // Empty buffer? |
(...skipping 21 matching lines...) Expand all Loading... | |
72 if (data) | 73 if (data) |
73 memcpy(channel_data_[i], data[i], data_size_per_channel); | 74 memcpy(channel_data_[i], data[i], data_size_per_channel); |
74 } | 75 } |
75 return; | 76 return; |
76 } | 77 } |
77 | 78 |
78 // Remaining formats are interleaved data. | 79 // Remaining formats are interleaved data. |
79 DCHECK(IsInterleaved(sample_format)) << sample_format_; | 80 DCHECK(IsInterleaved(sample_format)) << sample_format_; |
80 // Allocate our own buffer and copy the supplied data into it. Buffer must | 81 // Allocate our own buffer and copy the supplied data into it. Buffer must |
81 // contain the data for all channels. | 82 // contain the data for all channels. |
82 data_size_ = data_size_per_channel * channel_count_; | 83 if (!IsBitstream(sample_format)) |
chcunningham
2016/12/16 22:03:14
I feel like the interleaved code path is the only
AndyWu
2017/05/02 23:41:03
I do make (E)AC3 as interleaved formats:
https://c
| |
84 data_size_ = data_size_per_channel * channel_count_; | |
83 data_.reset( | 85 data_.reset( |
84 static_cast<uint8_t*>(base::AlignedAlloc(data_size_, kChannelAlignment))); | 86 static_cast<uint8_t*>(base::AlignedAlloc(data_size_, kChannelAlignment))); |
85 channel_data_.reserve(1); | 87 channel_data_.reserve(1); |
86 channel_data_.push_back(data_.get()); | 88 channel_data_.push_back(data_.get()); |
87 if (data) | 89 if (data) |
88 memcpy(data_.get(), data[0], data_size_); | 90 memcpy(data_.get(), data[0], data_size_); |
89 } | 91 } |
90 | 92 |
91 AudioBuffer::~AudioBuffer() {} | 93 AudioBuffer::~AudioBuffer() {} |
92 | 94 |
93 // static | 95 // static |
94 scoped_refptr<AudioBuffer> AudioBuffer::CopyFrom( | 96 scoped_refptr<AudioBuffer> AudioBuffer::CopyFrom( |
95 SampleFormat sample_format, | 97 SampleFormat sample_format, |
96 ChannelLayout channel_layout, | 98 ChannelLayout channel_layout, |
97 int channel_count, | 99 int channel_count, |
98 int sample_rate, | 100 int sample_rate, |
99 int frame_count, | 101 int frame_count, |
100 const uint8_t* const* data, | 102 const uint8_t* const* data, |
101 const base::TimeDelta timestamp) { | 103 const base::TimeDelta timestamp) { |
102 // If you hit this CHECK you likely have a bug in a demuxer. Go fix it. | 104 // If you hit this CHECK you likely have a bug in a demuxer. Go fix it. |
103 CHECK_GT(frame_count, 0); // Otherwise looks like an EOF buffer. | 105 CHECK_GT(frame_count, 0); // Otherwise looks like an EOF buffer. |
104 CHECK(data[0]); | 106 CHECK(data[0]); |
105 return make_scoped_refptr(new AudioBuffer(sample_format, | 107 return make_scoped_refptr( |
106 channel_layout, | 108 new AudioBuffer(sample_format, channel_layout, channel_count, sample_rate, |
107 channel_count, | 109 frame_count, true, data, 0, timestamp)); |
108 sample_rate, | |
109 frame_count, | |
110 true, | |
111 data, | |
112 timestamp)); | |
113 } | 110 } |
114 | 111 |
115 // static | 112 // static |
113 scoped_refptr<AudioBuffer> AudioBuffer::CopyBitstreamFrom( | |
114 SampleFormat sample_format, | |
115 ChannelLayout channel_layout, | |
116 int channel_count, | |
117 int sample_rate, | |
118 int frame_count, | |
119 const uint8_t* const* data, | |
120 const size_t data_size, | |
121 const base::TimeDelta timestamp) { | |
122 // If you hit this CHECK you likely have a bug in a demuxer. Go fix it. | |
123 CHECK_GT(frame_count, 0); // Otherwise looks like an EOF buffer. | |
124 CHECK(data[0]); | |
chcunningham
2016/12/16 22:03:14
Are we confident that data[0] would never return 0
AndyWu
2017/05/02 23:41:03
data[0] is a pointer; null pointer is unexpected.
| |
125 return make_scoped_refptr( | |
126 new AudioBuffer(sample_format, channel_layout, channel_count, sample_rate, | |
127 frame_count, true, data, data_size, timestamp)); | |
128 } | |
129 | |
130 // static | |
116 scoped_refptr<AudioBuffer> AudioBuffer::CreateBuffer( | 131 scoped_refptr<AudioBuffer> AudioBuffer::CreateBuffer( |
117 SampleFormat sample_format, | 132 SampleFormat sample_format, |
118 ChannelLayout channel_layout, | 133 ChannelLayout channel_layout, |
119 int channel_count, | 134 int channel_count, |
120 int sample_rate, | 135 int sample_rate, |
121 int frame_count) { | 136 int frame_count) { |
122 CHECK_GT(frame_count, 0); // Otherwise looks like an EOF buffer. | 137 CHECK_GT(frame_count, 0); // Otherwise looks like an EOF buffer. |
123 return make_scoped_refptr( | 138 return make_scoped_refptr( |
124 new AudioBuffer(sample_format, channel_layout, channel_count, sample_rate, | 139 new AudioBuffer(sample_format, channel_layout, channel_count, sample_rate, |
125 frame_count, true, NULL, kNoTimestamp)); | 140 frame_count, true, NULL, 0, kNoTimestamp)); |
126 } | 141 } |
127 | 142 |
128 // static | 143 // static |
144 scoped_refptr<AudioBuffer> AudioBuffer::CreateBitstreamBuffer( | |
145 SampleFormat sample_format, | |
146 ChannelLayout channel_layout, | |
147 int channel_count, | |
148 int sample_rate, | |
149 int frame_count, | |
150 size_t data_size) { | |
151 CHECK_GT(frame_count, 0); // Otherwise looks like an EOF buffer. | |
152 return make_scoped_refptr( | |
153 new AudioBuffer(sample_format, channel_layout, channel_count, sample_rate, | |
154 frame_count, true, NULL, data_size, kNoTimestamp)); | |
155 } | |
156 | |
157 // static | |
129 scoped_refptr<AudioBuffer> AudioBuffer::CreateEmptyBuffer( | 158 scoped_refptr<AudioBuffer> AudioBuffer::CreateEmptyBuffer( |
130 ChannelLayout channel_layout, | 159 ChannelLayout channel_layout, |
131 int channel_count, | 160 int channel_count, |
132 int sample_rate, | 161 int sample_rate, |
133 int frame_count, | 162 int frame_count, |
134 const base::TimeDelta timestamp) { | 163 const base::TimeDelta timestamp) { |
135 CHECK_GT(frame_count, 0); // Otherwise looks like an EOF buffer. | 164 CHECK_GT(frame_count, 0); // Otherwise looks like an EOF buffer. |
136 // Since data == NULL, format doesn't matter. | 165 // Since data == NULL, format doesn't matter. |
137 return make_scoped_refptr(new AudioBuffer(kSampleFormatF32, | 166 return make_scoped_refptr( |
138 channel_layout, | 167 new AudioBuffer(kSampleFormatF32, channel_layout, channel_count, |
139 channel_count, | 168 sample_rate, frame_count, false, NULL, 0, timestamp)); |
140 sample_rate, | |
141 frame_count, | |
142 false, | |
143 NULL, | |
144 timestamp)); | |
145 } | 169 } |
146 | 170 |
147 // static | 171 // static |
148 scoped_refptr<AudioBuffer> AudioBuffer::CreateEOSBuffer() { | 172 scoped_refptr<AudioBuffer> AudioBuffer::CreateEOSBuffer() { |
149 return make_scoped_refptr(new AudioBuffer(kUnknownSampleFormat, | 173 return make_scoped_refptr(new AudioBuffer(kUnknownSampleFormat, |
150 CHANNEL_LAYOUT_NONE, 0, 0, 0, false, | 174 CHANNEL_LAYOUT_NONE, 0, 0, 0, false, |
151 NULL, kNoTimestamp)); | 175 NULL, 0, kNoTimestamp)); |
152 } | 176 } |
153 | 177 |
154 // Convert int16_t values in the range [INT16_MIN, INT16_MAX] to [-1.0, 1.0]. | 178 // Convert int16_t values in the range [INT16_MIN, INT16_MAX] to [-1.0, 1.0]. |
155 inline float ConvertSample(int16_t value) { | 179 inline float ConvertSample(int16_t value) { |
156 return value * (value < 0 ? -1.0f / std::numeric_limits<int16_t>::min() | 180 return value * (value < 0 ? -1.0f / std::numeric_limits<int16_t>::min() |
157 : 1.0f / std::numeric_limits<int16_t>::max()); | 181 : 1.0f / std::numeric_limits<int16_t>::max()); |
158 } | 182 } |
159 | 183 |
160 void AudioBuffer::AdjustSampleRate(int sample_rate) { | 184 void AudioBuffer::AdjustSampleRate(int sample_rate) { |
161 DCHECK(!end_of_stream_); | 185 DCHECK(!end_of_stream_); |
162 sample_rate_ = sample_rate; | 186 sample_rate_ = sample_rate; |
163 duration_ = CalculateDuration(adjusted_frame_count_, sample_rate_); | 187 duration_ = CalculateDuration(adjusted_frame_count_, sample_rate_); |
164 } | 188 } |
165 | 189 |
166 void AudioBuffer::ReadFrames(int frames_to_copy, | 190 void AudioBuffer::ReadFrames(int frames_to_copy, |
167 int source_frame_offset, | 191 int source_frame_offset, |
168 int dest_frame_offset, | 192 int dest_frame_offset, |
169 AudioBus* dest) { | 193 AudioBus* dest) { |
170 // Deinterleave each channel (if necessary) and convert to 32bit | 194 // Deinterleave each channel (if necessary) and convert to 32bit |
171 // floating-point with nominal range -1.0 -> +1.0 (if necessary). | 195 // floating-point with nominal range -1.0 -> +1.0 (if necessary). |
172 | 196 |
173 // |dest| must have the same number of channels, and the number of frames | 197 // |dest| must have the same number of channels, and the number of frames |
174 // specified must be in range. | 198 // specified must be in range. |
175 DCHECK(!end_of_stream()); | 199 DCHECK(!end_of_stream()); |
176 DCHECK_EQ(dest->channels(), channel_count_); | 200 DCHECK_EQ(dest->channels(), channel_count_); |
177 DCHECK_LE(source_frame_offset + frames_to_copy, adjusted_frame_count_); | 201 DCHECK_LE(source_frame_offset + frames_to_copy, adjusted_frame_count_); |
202 | |
203 const bool is_bitstream_format = IsBitstream(sample_format_); | |
204 | |
205 if (is_bitstream_format) { | |
206 // TODO(tsunghung): Implement it along with AudioBus changes. | |
207 NOTREACHED() << "Invalid sample format!"; | |
208 } | |
209 | |
178 DCHECK_LE(dest_frame_offset + frames_to_copy, dest->frames()); | 210 DCHECK_LE(dest_frame_offset + frames_to_copy, dest->frames()); |
179 | 211 |
180 if (!data_) { | 212 if (!data_) { |
181 // Special case for an empty buffer. | 213 // Special case for an empty buffer. |
182 dest->ZeroFramesPartial(dest_frame_offset, frames_to_copy); | 214 dest->ZeroFramesPartial(dest_frame_offset, frames_to_copy); |
183 return; | 215 return; |
184 } | 216 } |
185 | 217 |
186 if (sample_format_ == kSampleFormatPlanarF32) { | 218 if (sample_format_ == kSampleFormatPlanarF32) { |
187 // Format is planar float32. Copy the data from each channel as a block. | 219 // 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... | |
233 int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format_); | 265 int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format_); |
234 int frame_size = channel_count_ * bytes_per_channel; | 266 int frame_size = channel_count_ * bytes_per_channel; |
235 const uint8_t* source_data = data_.get() + source_frame_offset * frame_size; | 267 const uint8_t* source_data = data_.get() + source_frame_offset * frame_size; |
236 dest->FromInterleavedPartial( | 268 dest->FromInterleavedPartial( |
237 source_data, dest_frame_offset, frames_to_copy, bytes_per_channel); | 269 source_data, dest_frame_offset, frames_to_copy, bytes_per_channel); |
238 } | 270 } |
239 | 271 |
240 void AudioBuffer::TrimStart(int frames_to_trim) { | 272 void AudioBuffer::TrimStart(int frames_to_trim) { |
241 CHECK_GE(frames_to_trim, 0); | 273 CHECK_GE(frames_to_trim, 0); |
242 CHECK_LE(frames_to_trim, adjusted_frame_count_); | 274 CHECK_LE(frames_to_trim, adjusted_frame_count_); |
275 DCHECK(!IsBitstream(sample_format_)); | |
243 | 276 |
244 TrimRange(0, frames_to_trim); | 277 TrimRange(0, frames_to_trim); |
245 } | 278 } |
246 | 279 |
247 void AudioBuffer::TrimEnd(int frames_to_trim) { | 280 void AudioBuffer::TrimEnd(int frames_to_trim) { |
248 CHECK_GE(frames_to_trim, 0); | 281 CHECK_GE(frames_to_trim, 0); |
249 CHECK_LE(frames_to_trim, adjusted_frame_count_); | 282 CHECK_LE(frames_to_trim, adjusted_frame_count_); |
283 DCHECK(!IsBitstream(sample_format_)); | |
250 | 284 |
251 // Adjust the number of frames and duration for this buffer. | 285 // Adjust the number of frames and duration for this buffer. |
252 adjusted_frame_count_ -= frames_to_trim; | 286 adjusted_frame_count_ -= frames_to_trim; |
253 duration_ = CalculateDuration(adjusted_frame_count_, sample_rate_); | 287 duration_ = CalculateDuration(adjusted_frame_count_, sample_rate_); |
254 } | 288 } |
255 | 289 |
256 void AudioBuffer::TrimRange(int start, int end) { | 290 void AudioBuffer::TrimRange(int start, int end) { |
257 CHECK_GE(start, 0); | 291 CHECK_GE(start, 0); |
258 CHECK_LE(end, adjusted_frame_count_); | 292 CHECK_LE(end, adjusted_frame_count_); |
293 DCHECK(!IsBitstream(sample_format_)); | |
259 | 294 |
260 const int frames_to_trim = end - start; | 295 const int frames_to_trim = end - start; |
261 CHECK_GE(frames_to_trim, 0); | 296 CHECK_GE(frames_to_trim, 0); |
262 CHECK_LE(frames_to_trim, adjusted_frame_count_); | 297 CHECK_LE(frames_to_trim, adjusted_frame_count_); |
263 | 298 |
264 const int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format_); | 299 const int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format_); |
265 const int frames_to_copy = adjusted_frame_count_ - end; | 300 const int frames_to_copy = adjusted_frame_count_ - end; |
266 if (frames_to_copy > 0) { | 301 if (frames_to_copy > 0) { |
267 switch (sample_format_) { | 302 switch (sample_format_) { |
268 case kSampleFormatPlanarS16: | 303 case kSampleFormatPlanarS16: |
(...skipping 25 matching lines...) Expand all Loading... | |
294 } | 329 } |
295 } else { | 330 } else { |
296 CHECK_EQ(frames_to_copy, 0); | 331 CHECK_EQ(frames_to_copy, 0); |
297 } | 332 } |
298 | 333 |
299 // Trim the leftover data off the end of the buffer and update duration. | 334 // Trim the leftover data off the end of the buffer and update duration. |
300 TrimEnd(frames_to_trim); | 335 TrimEnd(frames_to_trim); |
301 } | 336 } |
302 | 337 |
303 } // namespace media | 338 } // namespace media |
OLD | NEW |