Check existence of Widevince CDM/Adapter on load failure on Win.
[chromium-blink-merge.git] / media / base / audio_buffer.cc
blobeba658bf02691b1e4377903a769454cf93af24e7
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
3 // found in the LICENSE file.
5 #include "media/base/audio_buffer.h"
7 #include "base/logging.h"
8 #include "media/base/audio_bus.h"
9 #include "media/base/buffers.h"
10 #include "media/base/limits.h"
12 namespace media {
14 AudioBuffer::AudioBuffer(SampleFormat sample_format,
15 ChannelLayout channel_layout,
16 int sample_rate,
17 int frame_count,
18 bool create_buffer,
19 const uint8* const* data,
20 const base::TimeDelta timestamp,
21 const base::TimeDelta duration)
22 : sample_format_(sample_format),
23 channel_layout_(channel_layout),
24 channel_count_(ChannelLayoutToChannelCount(channel_layout)),
25 sample_rate_(sample_rate),
26 adjusted_frame_count_(frame_count),
27 trim_start_(0),
28 end_of_stream_(!create_buffer && data == NULL && frame_count == 0),
29 timestamp_(timestamp),
30 duration_(duration) {
31 CHECK_GE(channel_count_, 0);
32 CHECK_LE(channel_count_, limits::kMaxChannels);
33 CHECK_GE(frame_count, 0);
34 int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format);
35 DCHECK_LE(bytes_per_channel, kChannelAlignment);
36 int data_size = frame_count * bytes_per_channel;
38 // Empty buffer?
39 if (!create_buffer)
40 return;
42 if (sample_format == kSampleFormatPlanarF32 ||
43 sample_format == kSampleFormatPlanarS16) {
44 // Planar data, so need to allocate buffer for each channel.
45 // Determine per channel data size, taking into account alignment.
46 int block_size_per_channel =
47 (data_size + kChannelAlignment - 1) & ~(kChannelAlignment - 1);
48 DCHECK_GE(block_size_per_channel, data_size);
50 // Allocate a contiguous buffer for all the channel data.
51 data_.reset(static_cast<uint8*>(base::AlignedAlloc(
52 channel_count_ * block_size_per_channel, kChannelAlignment)));
53 channel_data_.reserve(channel_count_);
55 // Copy each channel's data into the appropriate spot.
56 for (int i = 0; i < channel_count_; ++i) {
57 channel_data_.push_back(data_.get() + i * block_size_per_channel);
58 if (data)
59 memcpy(channel_data_[i], data[i], data_size);
61 return;
64 // Remaining formats are interleaved data.
65 DCHECK(sample_format_ == kSampleFormatU8 ||
66 sample_format_ == kSampleFormatS16 ||
67 sample_format_ == kSampleFormatS32 ||
68 sample_format_ == kSampleFormatF32) << sample_format_;
69 // Allocate our own buffer and copy the supplied data into it. Buffer must
70 // contain the data for all channels.
71 data_size *= channel_count_;
72 data_.reset(
73 static_cast<uint8*>(base::AlignedAlloc(data_size, kChannelAlignment)));
74 channel_data_.reserve(1);
75 channel_data_.push_back(data_.get());
76 if (data)
77 memcpy(data_.get(), data[0], data_size);
80 AudioBuffer::~AudioBuffer() {}
82 // static
83 scoped_refptr<AudioBuffer> AudioBuffer::CopyFrom(
84 SampleFormat sample_format,
85 ChannelLayout channel_layout,
86 int sample_rate,
87 int frame_count,
88 const uint8* const* data,
89 const base::TimeDelta timestamp,
90 const base::TimeDelta duration) {
91 // If you hit this CHECK you likely have a bug in a demuxer. Go fix it.
92 CHECK_GT(frame_count, 0); // Otherwise looks like an EOF buffer.
93 CHECK(data[0]);
94 return make_scoped_refptr(new AudioBuffer(sample_format,
95 channel_layout,
96 sample_rate,
97 frame_count,
98 true,
99 data,
100 timestamp,
101 duration));
104 // static
105 scoped_refptr<AudioBuffer> AudioBuffer::CreateBuffer(
106 SampleFormat sample_format,
107 ChannelLayout channel_layout,
108 int sample_rate,
109 int frame_count) {
110 CHECK_GT(frame_count, 0); // Otherwise looks like an EOF buffer.
111 return make_scoped_refptr(new AudioBuffer(sample_format,
112 channel_layout,
113 sample_rate,
114 frame_count,
115 true,
116 NULL,
117 kNoTimestamp(),
118 kNoTimestamp()));
121 // static
122 scoped_refptr<AudioBuffer> AudioBuffer::CreateEmptyBuffer(
123 ChannelLayout channel_layout,
124 int sample_rate,
125 int frame_count,
126 const base::TimeDelta timestamp,
127 const base::TimeDelta duration) {
128 CHECK_GT(frame_count, 0); // Otherwise looks like an EOF buffer.
129 // Since data == NULL, format doesn't matter.
130 return make_scoped_refptr(new AudioBuffer(kSampleFormatF32,
131 channel_layout,
132 sample_rate,
133 frame_count,
134 false,
135 NULL,
136 timestamp,
137 duration));
140 // static
141 scoped_refptr<AudioBuffer> AudioBuffer::CreateEOSBuffer() {
142 return make_scoped_refptr(new AudioBuffer(kUnknownSampleFormat,
143 CHANNEL_LAYOUT_NONE,
146 false,
147 NULL,
148 kNoTimestamp(),
149 kNoTimestamp()));
152 // Convert int16 values in the range [kint16min, kint16max] to [-1.0, 1.0].
153 static inline float ConvertS16ToFloat(int16 value) {
154 return value * (value < 0 ? -1.0f / kint16min : 1.0f / kint16max);
157 void AudioBuffer::ReadFrames(int frames_to_copy,
158 int source_frame_offset,
159 int dest_frame_offset,
160 AudioBus* dest) {
161 // Deinterleave each channel (if necessary) and convert to 32bit
162 // floating-point with nominal range -1.0 -> +1.0 (if necessary).
164 // |dest| must have the same number of channels, and the number of frames
165 // specified must be in range.
166 DCHECK(!end_of_stream());
167 DCHECK_EQ(dest->channels(), channel_count_);
168 DCHECK_LE(source_frame_offset + frames_to_copy, adjusted_frame_count_);
169 DCHECK_LE(dest_frame_offset + frames_to_copy, dest->frames());
171 // Move the start past any frames that have been trimmed.
172 source_frame_offset += trim_start_;
174 if (!data_) {
175 // Special case for an empty buffer.
176 dest->ZeroFramesPartial(dest_frame_offset, frames_to_copy);
177 return;
180 if (sample_format_ == kSampleFormatPlanarF32) {
181 // Format is planar float32. Copy the data from each channel as a block.
182 for (int ch = 0; ch < channel_count_; ++ch) {
183 const float* source_data =
184 reinterpret_cast<const float*>(channel_data_[ch]) +
185 source_frame_offset;
186 memcpy(dest->channel(ch) + dest_frame_offset,
187 source_data,
188 sizeof(float) * frames_to_copy);
190 return;
193 if (sample_format_ == kSampleFormatPlanarS16) {
194 // Format is planar signed16. Convert each value into float and insert into
195 // output channel data.
196 for (int ch = 0; ch < channel_count_; ++ch) {
197 const int16* source_data =
198 reinterpret_cast<const int16*>(channel_data_[ch]) +
199 source_frame_offset;
200 float* dest_data = dest->channel(ch) + dest_frame_offset;
201 for (int i = 0; i < frames_to_copy; ++i) {
202 dest_data[i] = ConvertS16ToFloat(source_data[i]);
205 return;
208 if (sample_format_ == kSampleFormatF32) {
209 // Format is interleaved float32. Copy the data into each channel.
210 const float* source_data = reinterpret_cast<const float*>(data_.get()) +
211 source_frame_offset * channel_count_;
212 for (int ch = 0; ch < channel_count_; ++ch) {
213 float* dest_data = dest->channel(ch) + dest_frame_offset;
214 for (int i = 0, offset = ch; i < frames_to_copy;
215 ++i, offset += channel_count_) {
216 dest_data[i] = source_data[offset];
219 return;
222 // Remaining formats are integer interleaved data. Use the deinterleaving code
223 // in AudioBus to copy the data.
224 DCHECK(sample_format_ == kSampleFormatU8 ||
225 sample_format_ == kSampleFormatS16 ||
226 sample_format_ == kSampleFormatS32);
227 int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format_);
228 int frame_size = channel_count_ * bytes_per_channel;
229 const uint8* source_data = data_.get() + source_frame_offset * frame_size;
230 dest->FromInterleavedPartial(
231 source_data, dest_frame_offset, frames_to_copy, bytes_per_channel);
234 void AudioBuffer::TrimStart(int frames_to_trim) {
235 CHECK_GE(frames_to_trim, 0);
236 CHECK_LE(frames_to_trim, adjusted_frame_count_);
238 // Adjust timestamp_ and duration_ to reflect the smaller number of frames.
239 double offset = static_cast<double>(duration_.InMicroseconds()) *
240 frames_to_trim / adjusted_frame_count_;
241 base::TimeDelta offset_as_time =
242 base::TimeDelta::FromMicroseconds(static_cast<int64>(offset));
243 timestamp_ += offset_as_time;
244 duration_ -= offset_as_time;
246 // Finally adjust the number of frames in this buffer and where the start
247 // really is.
248 adjusted_frame_count_ -= frames_to_trim;
249 trim_start_ += frames_to_trim;
252 void AudioBuffer::TrimEnd(int frames_to_trim) {
253 CHECK_GE(frames_to_trim, 0);
254 CHECK_LE(frames_to_trim, adjusted_frame_count_);
256 // Adjust duration_ only to reflect the smaller number of frames.
257 double offset = static_cast<double>(duration_.InMicroseconds()) *
258 frames_to_trim / adjusted_frame_count_;
259 base::TimeDelta offset_as_time =
260 base::TimeDelta::FromMicroseconds(static_cast<int64>(offset));
261 duration_ -= offset_as_time;
263 // Finally adjust the number of frames in this buffer.
264 adjusted_frame_count_ -= frames_to_trim;
267 } // namespace media