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" |
(...skipping 26 matching lines...) Expand all Loading... |
37 duration_(end_of_stream_ | 37 duration_(end_of_stream_ |
38 ? base::TimeDelta() | 38 ? base::TimeDelta() |
39 : CalculateDuration(adjusted_frame_count_, sample_rate_)), | 39 : CalculateDuration(adjusted_frame_count_, sample_rate_)), |
40 data_size_(0) { | 40 data_size_(0) { |
41 CHECK_GE(channel_count_, 0); | 41 CHECK_GE(channel_count_, 0); |
42 CHECK_LE(channel_count_, limits::kMaxChannels); | 42 CHECK_LE(channel_count_, limits::kMaxChannels); |
43 CHECK_GE(frame_count, 0); | 43 CHECK_GE(frame_count, 0); |
44 DCHECK(channel_layout == CHANNEL_LAYOUT_DISCRETE || | 44 DCHECK(channel_layout == CHANNEL_LAYOUT_DISCRETE || |
45 ChannelLayoutToChannelCount(channel_layout) == channel_count); | 45 ChannelLayoutToChannelCount(channel_layout) == channel_count); |
46 | 46 |
| 47 int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format); |
| 48 DCHECK_LE(bytes_per_channel, kChannelAlignment); |
| 49 |
47 // Empty buffer? | 50 // Empty buffer? |
48 if (!create_buffer) | 51 if (!create_buffer) |
49 return; | 52 return; |
50 | 53 |
51 AllocateAndCopy(data, frame_count, 0); | 54 int data_size_per_channel = frame_count * bytes_per_channel; |
52 } | 55 if (IsPlanar(sample_format)) { |
53 | |
54 AudioBuffer::~AudioBuffer() {} | |
55 | |
56 void AudioBuffer::AllocateAndCopy(const uint8_t* const* data, | |
57 int frame_count, | |
58 int silence_frames) { | |
59 if (!channel_data_.empty()) | |
60 channel_data_.clear(); | |
61 | |
62 int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format_); | |
63 DCHECK_LE(bytes_per_channel, kChannelAlignment); | |
64 DCHECK_GT(bytes_per_channel, 0); | |
65 | |
66 int data_size_per_channel = | |
67 (frame_count + silence_frames) * bytes_per_channel; | |
68 | |
69 if (IsPlanar(sample_format_)) { | |
70 // Planar data, so need to allocate buffer for each channel. | 56 // Planar data, so need to allocate buffer for each channel. |
71 // Determine per channel data size, taking into account alignment. | 57 // Determine per channel data size, taking into account alignment. |
72 int block_size_per_channel = | 58 int block_size_per_channel = |
73 (data_size_per_channel + kChannelAlignment - 1) & | 59 (data_size_per_channel + kChannelAlignment - 1) & |
74 ~(kChannelAlignment - 1); | 60 ~(kChannelAlignment - 1); |
75 DCHECK_GE(block_size_per_channel, data_size_per_channel); | 61 DCHECK_GE(block_size_per_channel, data_size_per_channel); |
76 | 62 |
77 // Allocate a contiguous buffer for all the channel data. | 63 // Allocate a contiguous buffer for all the channel data. |
78 data_size_ = channel_count_ * block_size_per_channel; | 64 data_size_ = channel_count_ * block_size_per_channel; |
79 data_.reset(static_cast<uint8_t*>( | 65 data_.reset(static_cast<uint8_t*>( |
80 base::AlignedAlloc(data_size_, kChannelAlignment))); | 66 base::AlignedAlloc(data_size_, kChannelAlignment))); |
81 channel_data_.reserve(channel_count_); | 67 channel_data_.reserve(channel_count_); |
82 | 68 |
83 // Size of silence per channel. | |
84 int silence_bytes = silence_frames * bytes_per_channel; | |
85 | |
86 // Copy each channel's data into the appropriate spot. | 69 // Copy each channel's data into the appropriate spot. |
87 for (int i = 0; i < channel_count_; ++i) { | 70 for (int i = 0; i < channel_count_; ++i) { |
88 channel_data_.push_back(data_.get() + i * block_size_per_channel); | 71 channel_data_.push_back(data_.get() + i * block_size_per_channel); |
89 memset(channel_data_[i], 0, silence_bytes); | 72 if (data) |
90 if (data) { | 73 memcpy(channel_data_[i], data[i], data_size_per_channel); |
91 memcpy(channel_data_[i] + silence_bytes, data[i], | |
92 data_size_per_channel - silence_bytes); | |
93 } | |
94 } | 74 } |
95 return; | 75 return; |
96 } | 76 } |
97 | 77 |
98 // Remaining formats are interleaved data. | 78 // Remaining formats are interleaved data. |
99 DCHECK(IsInterleaved(sample_format_)) << sample_format_; | 79 DCHECK(IsInterleaved(sample_format)) << sample_format_; |
100 // Allocate our own buffer and copy the supplied data into it. Buffer must | 80 // Allocate our own buffer and copy the supplied data into it. Buffer must |
101 // contain the data for all channels. | 81 // contain the data for all channels. |
102 data_size_ = data_size_per_channel * channel_count_; | 82 data_size_ = data_size_per_channel * channel_count_; |
103 data_.reset( | 83 data_.reset( |
104 static_cast<uint8_t*>(base::AlignedAlloc(data_size_, kChannelAlignment))); | 84 static_cast<uint8_t*>(base::AlignedAlloc(data_size_, kChannelAlignment))); |
105 channel_data_.reserve(1); | 85 channel_data_.reserve(1); |
106 channel_data_.push_back(data_.get()); | 86 channel_data_.push_back(data_.get()); |
107 | |
108 int silence_bytes = silence_frames * channel_count_ * bytes_per_channel; | |
109 memset(data_.get(), 0, silence_bytes); | |
110 if (data) | 87 if (data) |
111 memcpy(data_.get() + silence_bytes, data[0], data_size_ - silence_bytes); | 88 memcpy(data_.get(), data[0], data_size_); |
112 } | 89 } |
113 | 90 |
114 void AudioBuffer::PadStart(int silence_frames) { | 91 AudioBuffer::~AudioBuffer() {} |
115 DCHECK_GE(silence_frames, 0); | |
116 | |
117 if (silence_frames > 0) { | |
118 // Only adjust allocation if not currently an empty buffer. Empty buffer's | |
119 // are implicitly silent, so just increase the frame count for that case. | |
120 if (data_) { | |
121 std::unique_ptr<uint8_t, base::AlignedFreeDeleter> orig_data = | |
122 std::move(data_); | |
123 std::vector<uint8_t*> orig_channel_data(channel_data_); | |
124 AllocateAndCopy(&orig_channel_data[0], adjusted_frame_count_, | |
125 silence_frames); | |
126 } | |
127 | |
128 adjusted_frame_count_ += silence_frames; | |
129 duration_ = CalculateDuration(adjusted_frame_count_, sample_rate_); | |
130 } | |
131 } | |
132 | 92 |
133 // static | 93 // static |
134 scoped_refptr<AudioBuffer> AudioBuffer::CopyFrom( | 94 scoped_refptr<AudioBuffer> AudioBuffer::CopyFrom( |
135 SampleFormat sample_format, | 95 SampleFormat sample_format, |
136 ChannelLayout channel_layout, | 96 ChannelLayout channel_layout, |
137 int channel_count, | 97 int channel_count, |
138 int sample_rate, | 98 int sample_rate, |
139 int frame_count, | 99 int frame_count, |
140 const uint8_t* const* data, | 100 const uint8_t* const* data, |
141 const base::TimeDelta timestamp) { | 101 const base::TimeDelta timestamp) { |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
190 CHANNEL_LAYOUT_NONE, 0, 0, 0, false, | 150 CHANNEL_LAYOUT_NONE, 0, 0, 0, false, |
191 NULL, kNoTimestamp)); | 151 NULL, kNoTimestamp)); |
192 } | 152 } |
193 | 153 |
194 // Convert int16_t values in the range [INT16_MIN, INT16_MAX] to [-1.0, 1.0]. | 154 // Convert int16_t values in the range [INT16_MIN, INT16_MAX] to [-1.0, 1.0]. |
195 inline float ConvertSample(int16_t value) { | 155 inline float ConvertSample(int16_t value) { |
196 return value * (value < 0 ? -1.0f / std::numeric_limits<int16_t>::min() | 156 return value * (value < 0 ? -1.0f / std::numeric_limits<int16_t>::min() |
197 : 1.0f / std::numeric_limits<int16_t>::max()); | 157 : 1.0f / std::numeric_limits<int16_t>::max()); |
198 } | 158 } |
199 | 159 |
200 | |
201 void AudioBuffer::AdjustSampleRate(int sample_rate) { | 160 void AudioBuffer::AdjustSampleRate(int sample_rate) { |
202 DCHECK(!end_of_stream_); | 161 DCHECK(!end_of_stream_); |
203 sample_rate_ = sample_rate; | 162 sample_rate_ = sample_rate; |
204 duration_ = CalculateDuration(adjusted_frame_count_, sample_rate_); | 163 duration_ = CalculateDuration(adjusted_frame_count_, sample_rate_); |
205 } | 164 } |
206 | 165 |
207 void AudioBuffer::ReadFrames(int frames_to_copy, | 166 void AudioBuffer::ReadFrames(int frames_to_copy, |
208 int source_frame_offset, | 167 int source_frame_offset, |
209 int dest_frame_offset, | 168 int dest_frame_offset, |
210 AudioBus* dest) { | 169 AudioBus* dest) { |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
333 } | 292 } |
334 } else { | 293 } else { |
335 CHECK_EQ(frames_to_copy, 0); | 294 CHECK_EQ(frames_to_copy, 0); |
336 } | 295 } |
337 | 296 |
338 // Trim the leftover data off the end of the buffer and update duration. | 297 // Trim the leftover data off the end of the buffer and update duration. |
339 TrimEnd(frames_to_trim); | 298 TrimEnd(frames_to_trim); |
340 } | 299 } |
341 | 300 |
342 } // namespace media | 301 } // namespace media |
OLD | NEW |