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 "base/logging.h" | 7 #include "base/logging.h" |
8 #include "media/base/audio_bus.h" | 8 #include "media/base/audio_bus.h" |
9 #include "media/base/buffers.h" | 9 #include "media/base/buffers.h" |
10 #include "media/base/limits.h" | 10 #include "media/base/limits.h" |
11 | 11 |
12 namespace media { | 12 namespace media { |
13 | 13 |
14 static base::TimeDelta CalculateDuration(int frames, double sample_rate) { | |
15 return base::TimeDelta::FromMicroseconds( | |
16 frames * base::Time::kMicrosecondsPerSecond / sample_rate); | |
17 } | |
18 | |
14 AudioBuffer::AudioBuffer(SampleFormat sample_format, | 19 AudioBuffer::AudioBuffer(SampleFormat sample_format, |
15 ChannelLayout channel_layout, | 20 ChannelLayout channel_layout, |
16 int channel_count, | 21 int channel_count, |
17 int sample_rate, | 22 int sample_rate, |
18 int frame_count, | 23 int frame_count, |
19 bool create_buffer, | 24 bool create_buffer, |
20 const uint8* const* data, | 25 const uint8* const* data, |
21 const base::TimeDelta timestamp, | 26 const base::TimeDelta timestamp) |
22 const base::TimeDelta duration) | |
23 : sample_format_(sample_format), | 27 : sample_format_(sample_format), |
24 channel_layout_(channel_layout), | 28 channel_layout_(channel_layout), |
25 channel_count_(channel_count), | 29 channel_count_(channel_count), |
26 sample_rate_(sample_rate), | 30 sample_rate_(sample_rate), |
27 adjusted_frame_count_(frame_count), | 31 adjusted_frame_count_(frame_count), |
28 trim_start_(0), | 32 trim_start_(0), |
29 end_of_stream_(!create_buffer && data == NULL && frame_count == 0), | 33 end_of_stream_(!create_buffer && data == NULL && frame_count == 0), |
30 timestamp_(timestamp), | 34 timestamp_(timestamp), |
31 duration_(duration) { | 35 duration_(CalculateDuration(adjusted_frame_count_, sample_rate_)) { |
jrummell
2014/05/01 20:26:26
nit: Would it be better to compute the duration on
DaleCurtis
2014/05/01 20:33:18
It's cheap to calculate and I don't want to have t
| |
32 CHECK_GE(channel_count_, 0); | 36 CHECK_GE(channel_count_, 0); |
33 CHECK_LE(channel_count_, limits::kMaxChannels); | 37 CHECK_LE(channel_count_, limits::kMaxChannels); |
34 CHECK_GE(frame_count, 0); | 38 CHECK_GE(frame_count, 0); |
35 DCHECK(channel_layout == CHANNEL_LAYOUT_DISCRETE || | 39 DCHECK(channel_layout == CHANNEL_LAYOUT_DISCRETE || |
36 ChannelLayoutToChannelCount(channel_layout) == channel_count); | 40 ChannelLayoutToChannelCount(channel_layout) == channel_count); |
37 | 41 |
38 int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format); | 42 int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format); |
39 DCHECK_LE(bytes_per_channel, kChannelAlignment); | 43 DCHECK_LE(bytes_per_channel, kChannelAlignment); |
40 int data_size = frame_count * bytes_per_channel; | 44 int data_size = frame_count * bytes_per_channel; |
41 | 45 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
84 AudioBuffer::~AudioBuffer() {} | 88 AudioBuffer::~AudioBuffer() {} |
85 | 89 |
86 // static | 90 // static |
87 scoped_refptr<AudioBuffer> AudioBuffer::CopyFrom( | 91 scoped_refptr<AudioBuffer> AudioBuffer::CopyFrom( |
88 SampleFormat sample_format, | 92 SampleFormat sample_format, |
89 ChannelLayout channel_layout, | 93 ChannelLayout channel_layout, |
90 int channel_count, | 94 int channel_count, |
91 int sample_rate, | 95 int sample_rate, |
92 int frame_count, | 96 int frame_count, |
93 const uint8* const* data, | 97 const uint8* const* data, |
94 const base::TimeDelta timestamp, | 98 const base::TimeDelta timestamp) { |
95 const base::TimeDelta duration) { | |
96 // If you hit this CHECK you likely have a bug in a demuxer. Go fix it. | 99 // If you hit this CHECK you likely have a bug in a demuxer. Go fix it. |
97 CHECK_GT(frame_count, 0); // Otherwise looks like an EOF buffer. | 100 CHECK_GT(frame_count, 0); // Otherwise looks like an EOF buffer. |
98 CHECK(data[0]); | 101 CHECK(data[0]); |
99 return make_scoped_refptr(new AudioBuffer(sample_format, | 102 return make_scoped_refptr(new AudioBuffer(sample_format, |
100 channel_layout, | 103 channel_layout, |
101 channel_count, | 104 channel_count, |
102 sample_rate, | 105 sample_rate, |
103 frame_count, | 106 frame_count, |
104 true, | 107 true, |
105 data, | 108 data, |
106 timestamp, | 109 timestamp)); |
107 duration)); | |
108 } | 110 } |
109 | 111 |
110 // static | 112 // static |
111 scoped_refptr<AudioBuffer> AudioBuffer::CreateBuffer( | 113 scoped_refptr<AudioBuffer> AudioBuffer::CreateBuffer( |
112 SampleFormat sample_format, | 114 SampleFormat sample_format, |
113 ChannelLayout channel_layout, | 115 ChannelLayout channel_layout, |
114 int channel_count, | 116 int channel_count, |
115 int sample_rate, | 117 int sample_rate, |
116 int frame_count) { | 118 int frame_count) { |
117 CHECK_GT(frame_count, 0); // Otherwise looks like an EOF buffer. | 119 CHECK_GT(frame_count, 0); // Otherwise looks like an EOF buffer. |
118 return make_scoped_refptr(new AudioBuffer(sample_format, | 120 return make_scoped_refptr(new AudioBuffer(sample_format, |
119 channel_layout, | 121 channel_layout, |
120 channel_count, | 122 channel_count, |
121 sample_rate, | 123 sample_rate, |
122 frame_count, | 124 frame_count, |
123 true, | 125 true, |
124 NULL, | 126 NULL, |
125 kNoTimestamp(), | |
126 kNoTimestamp())); | 127 kNoTimestamp())); |
127 } | 128 } |
128 | 129 |
129 // static | 130 // static |
130 scoped_refptr<AudioBuffer> AudioBuffer::CreateEmptyBuffer( | 131 scoped_refptr<AudioBuffer> AudioBuffer::CreateEmptyBuffer( |
131 ChannelLayout channel_layout, | 132 ChannelLayout channel_layout, |
132 int channel_count, | 133 int channel_count, |
133 int sample_rate, | 134 int sample_rate, |
134 int frame_count, | 135 int frame_count, |
135 const base::TimeDelta timestamp, | 136 const base::TimeDelta timestamp) { |
136 const base::TimeDelta duration) { | |
137 CHECK_GT(frame_count, 0); // Otherwise looks like an EOF buffer. | 137 CHECK_GT(frame_count, 0); // Otherwise looks like an EOF buffer. |
138 // Since data == NULL, format doesn't matter. | 138 // Since data == NULL, format doesn't matter. |
139 return make_scoped_refptr(new AudioBuffer(kSampleFormatF32, | 139 return make_scoped_refptr(new AudioBuffer(kSampleFormatF32, |
140 channel_layout, | 140 channel_layout, |
141 channel_count, | 141 channel_count, |
142 sample_rate, | 142 sample_rate, |
143 frame_count, | 143 frame_count, |
144 false, | 144 false, |
145 NULL, | 145 NULL, |
146 timestamp, | 146 timestamp)); |
147 duration)); | |
148 } | 147 } |
149 | 148 |
150 // static | 149 // static |
151 scoped_refptr<AudioBuffer> AudioBuffer::CreateEOSBuffer() { | 150 scoped_refptr<AudioBuffer> AudioBuffer::CreateEOSBuffer() { |
152 return make_scoped_refptr(new AudioBuffer(kUnknownSampleFormat, | 151 return make_scoped_refptr(new AudioBuffer(kUnknownSampleFormat, |
153 CHANNEL_LAYOUT_NONE, | 152 CHANNEL_LAYOUT_NONE, |
154 0, | 153 0, |
155 0, | 154 0, |
156 0, | 155 0, |
157 false, | 156 false, |
158 NULL, | 157 NULL, |
159 kNoTimestamp(), | |
160 kNoTimestamp())); | 158 kNoTimestamp())); |
161 } | 159 } |
162 | 160 |
163 // Convert int16 values in the range [kint16min, kint16max] to [-1.0, 1.0]. | 161 // Convert int16 values in the range [kint16min, kint16max] to [-1.0, 1.0]. |
164 static inline float ConvertS16ToFloat(int16 value) { | 162 static inline float ConvertS16ToFloat(int16 value) { |
165 return value * (value < 0 ? -1.0f / kint16min : 1.0f / kint16max); | 163 return value * (value < 0 ? -1.0f / kint16min : 1.0f / kint16max); |
166 } | 164 } |
167 | 165 |
168 void AudioBuffer::ReadFrames(int frames_to_copy, | 166 void AudioBuffer::ReadFrames(int frames_to_copy, |
169 int source_frame_offset, | 167 int source_frame_offset, |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
239 int frame_size = channel_count_ * bytes_per_channel; | 237 int frame_size = channel_count_ * bytes_per_channel; |
240 const uint8* source_data = data_.get() + source_frame_offset * frame_size; | 238 const uint8* source_data = data_.get() + source_frame_offset * frame_size; |
241 dest->FromInterleavedPartial( | 239 dest->FromInterleavedPartial( |
242 source_data, dest_frame_offset, frames_to_copy, bytes_per_channel); | 240 source_data, dest_frame_offset, frames_to_copy, bytes_per_channel); |
243 } | 241 } |
244 | 242 |
245 void AudioBuffer::TrimStart(int frames_to_trim) { | 243 void AudioBuffer::TrimStart(int frames_to_trim) { |
246 CHECK_GE(frames_to_trim, 0); | 244 CHECK_GE(frames_to_trim, 0); |
247 CHECK_LE(frames_to_trim, adjusted_frame_count_); | 245 CHECK_LE(frames_to_trim, adjusted_frame_count_); |
248 | 246 |
249 // Adjust timestamp_ and duration_ to reflect the smaller number of frames. | 247 // Adjust the number of frames in this buffer and where the start really is. |
250 double offset = static_cast<double>(duration_.InMicroseconds()) * | |
251 frames_to_trim / adjusted_frame_count_; | |
252 base::TimeDelta offset_as_time = | |
253 base::TimeDelta::FromMicroseconds(static_cast<int64>(offset)); | |
254 timestamp_ += offset_as_time; | |
255 duration_ -= offset_as_time; | |
256 | |
257 // Finally adjust the number of frames in this buffer and where the start | |
258 // really is. | |
259 adjusted_frame_count_ -= frames_to_trim; | 248 adjusted_frame_count_ -= frames_to_trim; |
260 trim_start_ += frames_to_trim; | 249 trim_start_ += frames_to_trim; |
250 | |
251 // Adjust timestamp_ and duration_ to reflect the smaller number of frames. | |
252 const base::TimeDelta old_duration = duration_; | |
253 duration_ = CalculateDuration(adjusted_frame_count_, sample_rate_); | |
254 timestamp_ += old_duration - duration_; | |
261 } | 255 } |
262 | 256 |
263 void AudioBuffer::TrimEnd(int frames_to_trim) { | 257 void AudioBuffer::TrimEnd(int frames_to_trim) { |
264 CHECK_GE(frames_to_trim, 0); | 258 CHECK_GE(frames_to_trim, 0); |
265 CHECK_LE(frames_to_trim, adjusted_frame_count_); | 259 CHECK_LE(frames_to_trim, adjusted_frame_count_); |
266 | 260 |
267 // Adjust duration_ only to reflect the smaller number of frames. | 261 // Adjust the number of frames and duration for this buffer. |
268 double offset = static_cast<double>(duration_.InMicroseconds()) * | |
269 frames_to_trim / adjusted_frame_count_; | |
270 base::TimeDelta offset_as_time = | |
271 base::TimeDelta::FromMicroseconds(static_cast<int64>(offset)); | |
272 duration_ -= offset_as_time; | |
273 | |
274 // Finally adjust the number of frames in this buffer. | |
275 adjusted_frame_count_ -= frames_to_trim; | 262 adjusted_frame_count_ -= frames_to_trim; |
263 duration_ = CalculateDuration(adjusted_frame_count_, sample_rate_); | |
276 } | 264 } |
277 | 265 |
278 } // namespace media | 266 } // namespace media |
OLD | NEW |