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