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? |
51 if (!create_buffer) | 52 if (!create_buffer) |
52 return; | 53 return; |
53 | 54 |
55 if (sample_format == kSampleFormatRaw) { | |
AndyWu
2016/11/04 18:04:24
I refactored the code a little to avoid code dupli
| |
56 if (data_size_) { | |
57 data_.reset(static_cast<uint8_t*>( | |
58 base::AlignedAlloc(data_size_, kChannelAlignment))); | |
DaleCurtis
2016/11/01 23:05:13
AlignedAlloc shouldn't be necessary in this case.
AndyWu
2016/11/04 18:04:24
|data_| is defined as:
std::unique_ptr<uint8_t, ba
| |
59 channel_data_.reserve(1); | |
DaleCurtis
2016/11/01 23:05:13
Just channel_data_ = std::vector(1, data_.get()) ?
AndyWu
2016/11/04 18:04:24
Yes, it should work. It's better in terms of line
| |
60 channel_data_.push_back(data_.get()); | |
61 if (data) | |
DaleCurtis
2016/11/01 23:05:13
This should never be null now right?
AndyWu
2016/11/04 18:04:24
In current use cases, yes. But I would prefer to k
| |
62 memcpy(data_.get(), data[0], data_size_); | |
63 } | |
64 return; | |
65 } | |
66 | |
54 int data_size_per_channel = frame_count * bytes_per_channel; | 67 int data_size_per_channel = frame_count * bytes_per_channel; |
55 if (IsPlanar(sample_format)) { | 68 if (IsPlanar(sample_format)) { |
56 // Planar data, so need to allocate buffer for each channel. | 69 // Planar data, so need to allocate buffer for each channel. |
57 // Determine per channel data size, taking into account alignment. | 70 // Determine per channel data size, taking into account alignment. |
58 int block_size_per_channel = | 71 int block_size_per_channel = |
59 (data_size_per_channel + kChannelAlignment - 1) & | 72 (data_size_per_channel + kChannelAlignment - 1) & |
60 ~(kChannelAlignment - 1); | 73 ~(kChannelAlignment - 1); |
61 DCHECK_GE(block_size_per_channel, data_size_per_channel); | 74 DCHECK_GE(block_size_per_channel, data_size_per_channel); |
62 | 75 |
63 // Allocate a contiguous buffer for all the channel data. | 76 // Allocate a contiguous buffer for all the channel data. |
(...skipping 27 matching lines...) Expand all Loading... | |
91 AudioBuffer::~AudioBuffer() {} | 104 AudioBuffer::~AudioBuffer() {} |
92 | 105 |
93 // static | 106 // static |
94 scoped_refptr<AudioBuffer> AudioBuffer::CopyFrom( | 107 scoped_refptr<AudioBuffer> AudioBuffer::CopyFrom( |
95 SampleFormat sample_format, | 108 SampleFormat sample_format, |
96 ChannelLayout channel_layout, | 109 ChannelLayout channel_layout, |
97 int channel_count, | 110 int channel_count, |
98 int sample_rate, | 111 int sample_rate, |
99 int frame_count, | 112 int frame_count, |
100 const uint8_t* const* data, | 113 const uint8_t* const* data, |
101 const base::TimeDelta timestamp) { | 114 const base::TimeDelta timestamp, |
115 const size_t data_size) { | |
DaleCurtis
2016/11/01 23:05:13
Instead of adding this, if you specify the appropr
AndyWu
2016/11/04 18:04:24
I see your point, but it would also introduce anot
DaleCurtis
2016/11/04 19:48:29
Hmm, I guess you're saying that we don't always en
DaleCurtis
2016/11/04 21:17:33
Actually, why can't you just define these sample f
AndyWu
2016/11/08 00:04:21
The |data_size_| calculation is based on
https://c
| |
102 // If you hit this CHECK you likely have a bug in a demuxer. Go fix it. | 116 // 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. | 117 CHECK_GT(frame_count, 0); // Otherwise looks like an EOF buffer. |
104 CHECK(data[0]); | 118 CHECK(data[0]); |
105 return make_scoped_refptr(new AudioBuffer(sample_format, | 119 return make_scoped_refptr( |
106 channel_layout, | 120 new AudioBuffer(sample_format, channel_layout, channel_count, sample_rate, |
107 channel_count, | 121 frame_count, true, data, data_size, timestamp)); |
108 sample_rate, | |
109 frame_count, | |
110 true, | |
111 data, | |
112 timestamp)); | |
113 } | 122 } |
114 | 123 |
115 // static | 124 // static |
116 scoped_refptr<AudioBuffer> AudioBuffer::CreateBuffer( | 125 scoped_refptr<AudioBuffer> AudioBuffer::CreateBuffer( |
117 SampleFormat sample_format, | 126 SampleFormat sample_format, |
118 ChannelLayout channel_layout, | 127 ChannelLayout channel_layout, |
119 int channel_count, | 128 int channel_count, |
120 int sample_rate, | 129 int sample_rate, |
121 int frame_count) { | 130 int frame_count, |
131 size_t data_size) { | |
122 CHECK_GT(frame_count, 0); // Otherwise looks like an EOF buffer. | 132 CHECK_GT(frame_count, 0); // Otherwise looks like an EOF buffer. |
123 return make_scoped_refptr( | 133 return make_scoped_refptr( |
124 new AudioBuffer(sample_format, channel_layout, channel_count, sample_rate, | 134 new AudioBuffer(sample_format, channel_layout, channel_count, sample_rate, |
125 frame_count, true, NULL, kNoTimestamp)); | 135 frame_count, true, NULL, data_size, kNoTimestamp)); |
126 } | 136 } |
127 | 137 |
128 // static | 138 // static |
129 scoped_refptr<AudioBuffer> AudioBuffer::CreateEmptyBuffer( | 139 scoped_refptr<AudioBuffer> AudioBuffer::CreateEmptyBuffer( |
130 ChannelLayout channel_layout, | 140 ChannelLayout channel_layout, |
131 int channel_count, | 141 int channel_count, |
132 int sample_rate, | 142 int sample_rate, |
133 int frame_count, | 143 int frame_count, |
134 const base::TimeDelta timestamp) { | 144 const base::TimeDelta timestamp) { |
135 CHECK_GT(frame_count, 0); // Otherwise looks like an EOF buffer. | 145 CHECK_GT(frame_count, 0); // Otherwise looks like an EOF buffer. |
136 // Since data == NULL, format doesn't matter. | 146 // Since data == NULL, format doesn't matter. |
137 return make_scoped_refptr(new AudioBuffer(kSampleFormatF32, | 147 return make_scoped_refptr( |
138 channel_layout, | 148 new AudioBuffer(kSampleFormatF32, channel_layout, channel_count, |
139 channel_count, | 149 sample_rate, frame_count, false, NULL, 0, timestamp)); |
140 sample_rate, | |
141 frame_count, | |
142 false, | |
143 NULL, | |
144 timestamp)); | |
145 } | 150 } |
146 | 151 |
147 // static | 152 // static |
148 scoped_refptr<AudioBuffer> AudioBuffer::CreateEOSBuffer() { | 153 scoped_refptr<AudioBuffer> AudioBuffer::CreateEOSBuffer() { |
149 return make_scoped_refptr(new AudioBuffer(kUnknownSampleFormat, | 154 return make_scoped_refptr(new AudioBuffer(kUnknownSampleFormat, |
150 CHANNEL_LAYOUT_NONE, 0, 0, 0, false, | 155 CHANNEL_LAYOUT_NONE, 0, 0, 0, false, |
151 NULL, kNoTimestamp)); | 156 NULL, 0, kNoTimestamp)); |
152 } | 157 } |
153 | 158 |
154 // Convert int16_t values in the range [INT16_MIN, INT16_MAX] to [-1.0, 1.0]. | 159 // Convert int16_t values in the range [INT16_MIN, INT16_MAX] to [-1.0, 1.0]. |
155 inline float ConvertSample(int16_t value) { | 160 inline float ConvertSample(int16_t value) { |
156 return value * (value < 0 ? -1.0f / std::numeric_limits<int16_t>::min() | 161 return value * (value < 0 ? -1.0f / std::numeric_limits<int16_t>::min() |
157 : 1.0f / std::numeric_limits<int16_t>::max()); | 162 : 1.0f / std::numeric_limits<int16_t>::max()); |
158 } | 163 } |
159 | 164 |
160 void AudioBuffer::AdjustSampleRate(int sample_rate) { | 165 void AudioBuffer::AdjustSampleRate(int sample_rate) { |
161 DCHECK(!end_of_stream_); | 166 DCHECK(!end_of_stream_); |
162 sample_rate_ = sample_rate; | 167 sample_rate_ = sample_rate; |
163 duration_ = CalculateDuration(adjusted_frame_count_, sample_rate_); | 168 duration_ = CalculateDuration(adjusted_frame_count_, sample_rate_); |
164 } | 169 } |
165 | 170 |
166 void AudioBuffer::ReadFrames(int frames_to_copy, | 171 void AudioBuffer::ReadFrames(int frames_to_copy, |
167 int source_frame_offset, | 172 int source_frame_offset, |
168 int dest_frame_offset, | 173 int dest_frame_offset, |
169 AudioBus* dest) { | 174 AudioBus* dest) { |
170 // Deinterleave each channel (if necessary) and convert to 32bit | 175 // Deinterleave each channel (if necessary) and convert to 32bit |
171 // floating-point with nominal range -1.0 -> +1.0 (if necessary). | 176 // floating-point with nominal range -1.0 -> +1.0 (if necessary). |
172 | 177 |
173 // |dest| must have the same number of channels, and the number of frames | 178 // |dest| must have the same number of channels, and the number of frames |
174 // specified must be in range. | 179 // specified must be in range. |
175 DCHECK(!end_of_stream()); | 180 DCHECK(!end_of_stream()); |
176 DCHECK_EQ(dest->channels(), channel_count_); | 181 DCHECK_EQ(dest->channels(), channel_count_); |
177 DCHECK_LE(source_frame_offset + frames_to_copy, adjusted_frame_count_); | 182 DCHECK_LE(source_frame_offset + frames_to_copy, adjusted_frame_count_); |
183 | |
184 bool is_raw_format = (sample_format_ == kSampleFormatRaw); | |
185 dest->set_is_raw_format(is_raw_format); | |
186 | |
187 if (is_raw_format) { | |
188 DCHECK(!source_frame_offset); | |
189 uint8_t* dest_data = | |
190 reinterpret_cast<uint8_t*>(dest->channel(0)) + dest->data_size(); | |
191 | |
192 memcpy(dest_data, channel_data_[0], data_size()); | |
193 dest->set_data_size(dest_frame_offset + data_size()); | |
194 dest->set_frames(dest->frames() + frame_count()); | |
195 return; | |
196 } | |
197 | |
178 DCHECK_LE(dest_frame_offset + frames_to_copy, dest->frames()); | 198 DCHECK_LE(dest_frame_offset + frames_to_copy, dest->frames()); |
179 | 199 |
180 if (!data_) { | 200 if (!data_) { |
181 // Special case for an empty buffer. | 201 // Special case for an empty buffer. |
182 dest->ZeroFramesPartial(dest_frame_offset, frames_to_copy); | 202 dest->ZeroFramesPartial(dest_frame_offset, frames_to_copy); |
183 return; | 203 return; |
184 } | 204 } |
185 | 205 |
186 if (sample_format_ == kSampleFormatPlanarF32) { | 206 if (sample_format_ == kSampleFormatPlanarF32) { |
187 // Format is planar float32. Copy the data from each channel as a block. | 207 // Format is planar float32. Copy the data from each channel as a block. |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
280 case kSampleFormatS24: | 300 case kSampleFormatS24: |
281 case kSampleFormatS32: | 301 case kSampleFormatS32: |
282 case kSampleFormatF32: { | 302 case kSampleFormatF32: { |
283 // Interleaved data can be shifted all at once. | 303 // Interleaved data can be shifted all at once. |
284 const int frame_size = channel_count_ * bytes_per_channel; | 304 const int frame_size = channel_count_ * bytes_per_channel; |
285 memmove(channel_data_[0] + start * frame_size, | 305 memmove(channel_data_[0] + start * frame_size, |
286 channel_data_[0] + end * frame_size, | 306 channel_data_[0] + end * frame_size, |
287 frame_size * frames_to_copy); | 307 frame_size * frames_to_copy); |
288 break; | 308 break; |
289 } | 309 } |
310 case kSampleFormatRaw: | |
290 case kUnknownSampleFormat: | 311 case kUnknownSampleFormat: |
291 NOTREACHED() << "Invalid sample format!"; | 312 NOTREACHED() << "Invalid sample format!"; |
292 } | 313 } |
293 } else { | 314 } else { |
294 CHECK_EQ(frames_to_copy, 0); | 315 CHECK_EQ(frames_to_copy, 0); |
295 } | 316 } |
296 | 317 |
297 // Trim the leftover data off the end of the buffer and update duration. | 318 // Trim the leftover data off the end of the buffer and update duration. |
298 TrimEnd(frames_to_trim); | 319 TrimEnd(frames_to_trim); |
299 } | 320 } |
300 | 321 |
301 } // namespace media | 322 } // namespace media |
OLD | NEW |