Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(241)

Side by Side Diff: services/media/framework/parts/lpcm_reformatter.cc

Issue 1577953002: Motown in-proc streaming framework used to implement media services. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Sync, updates based on feedback, some functions declared const. Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 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.
4
5 #include "base/logging.h"
6 #include "services/media/framework/parts/lpcm_reformatter.h"
7
8 namespace mojo {
9 namespace media {
10
11 // LpcmReformatter implementation that accepts samples of type TIn and
12 // produces samples of type TOut.
13 template<typename TIn, typename TOut>
14 class LpcmReformatterImpl : public LpcmReformatter {
15 public:
16 LpcmReformatterImpl(
17 const LpcmStreamType& in_type,
18 const LpcmStreamTypeSet& out_type);
19
20 ~LpcmReformatterImpl() override;
21
22 // LpcmTransform implementation.
23 const LpcmStreamType& input_stream_type() const override;
24
25 const LpcmStreamType& output_stream_type() const override;
26
27 void TransformFrames(LpcmFrames* source, LpcmFrames* dest, bool mix) override;
28
29 private:
30 LpcmStreamType in_type_;
31 LpcmStreamType out_type_;
32 };
33
34 LpcmReformatterPtr LpcmReformatter::New(
35 const LpcmStreamType& in_type,
36 const LpcmStreamTypeSet& out_type) {
37 LpcmReformatter* result = nullptr;
38
39 switch (in_type.sample_format()) {
40 case LpcmStreamType::SampleFormat::kUnsigned8:
41 switch (out_type.sample_format()) {
42 case LpcmStreamType::SampleFormat::kUnsigned8:
43 case LpcmStreamType::SampleFormat::kAny:
44 result = new LpcmReformatterImpl<uint8_t, uint8_t>(
jeffbrown 2016/02/02 05:35:48 Do you think these allocations could become a bott
dalesat 2016/02/02 21:46:40 This is done once per LpcmReformatter, which means
45 in_type, out_type);
46 break;
47 case LpcmStreamType::SampleFormat::kSigned16:
48 result = new LpcmReformatterImpl<uint8_t, int16_t>(
49 in_type, out_type);
50 break;
51 case LpcmStreamType::SampleFormat::kSigned24In32:
52 result = new LpcmReformatterImpl<uint8_t, int32_t>(
53 in_type, out_type);
54 break;
55 case LpcmStreamType::SampleFormat::kFloat:
56 result = new LpcmReformatterImpl<uint8_t, float>(
57 in_type, out_type);
58 break;
59 default:
60 NOTREACHED() << "unsupported sample format";
61 result = nullptr;
62 break;
63 }
64 break;
65 case LpcmStreamType::SampleFormat::kSigned16:
66 switch (out_type.sample_format()) {
67 case LpcmStreamType::SampleFormat::kUnsigned8:
68 result = new LpcmReformatterImpl<int16_t, uint8_t>(
69 in_type, out_type);
70 break;
71 case LpcmStreamType::SampleFormat::kSigned16:
72 case LpcmStreamType::SampleFormat::kAny:
73 result = new LpcmReformatterImpl<int16_t, int16_t>(
74 in_type, out_type);
75 break;
76 case LpcmStreamType::SampleFormat::kSigned24In32:
77 result = new LpcmReformatterImpl<int16_t, int32_t>(
78 in_type, out_type);
79 break;
80 case LpcmStreamType::SampleFormat::kFloat:
81 result = new LpcmReformatterImpl<int16_t, float>(
82 in_type, out_type);
83 break;
84 default:
85 NOTREACHED() << "unsupported sample format";
86 result = nullptr;
87 break;
88 }
89 break;
90 case LpcmStreamType::SampleFormat::kSigned24In32:
91 switch (out_type.sample_format()) {
92 case LpcmStreamType::SampleFormat::kUnsigned8:
93 result = new LpcmReformatterImpl<int32_t, uint8_t>(
94 in_type, out_type);
95 break;
96 case LpcmStreamType::SampleFormat::kSigned16:
97 result = new LpcmReformatterImpl<int32_t, int16_t>(
98 in_type, out_type);
99 break;
100 case LpcmStreamType::SampleFormat::kSigned24In32:
101 case LpcmStreamType::SampleFormat::kAny:
102 result = new LpcmReformatterImpl<int32_t, int32_t>(
103 in_type, out_type);
104 break;
105 case LpcmStreamType::SampleFormat::kFloat:
106 result = new LpcmReformatterImpl<int32_t, float>(
107 in_type, out_type);
108 break;
109 default:
110 NOTREACHED() << "unsupported sample format";
111 result = nullptr;
112 break;
113 }
114 break;
115 case LpcmStreamType::SampleFormat::kFloat:
116 switch (out_type.sample_format()) {
117 case LpcmStreamType::SampleFormat::kUnsigned8:
118 result = new LpcmReformatterImpl<float, uint8_t>(
119 in_type, out_type);
120 break;
121 case LpcmStreamType::SampleFormat::kSigned16:
122 result = new LpcmReformatterImpl<float, int16_t>(
123 in_type, out_type);
124 break;
125 case LpcmStreamType::SampleFormat::kSigned24In32:
126 result = new LpcmReformatterImpl<float, int32_t>(
127 in_type, out_type);
128 break;
129 case LpcmStreamType::SampleFormat::kFloat:
130 case LpcmStreamType::SampleFormat::kAny:
131 result = new LpcmReformatterImpl<float, float>(in_type, out_type);
132 break;
133 default:
134 NOTREACHED() << "unsupported sample format";
135 result = nullptr;
136 break;
137 }
138 break;
139 default:
140 NOTREACHED() << "unsupported sample format";
141 result = nullptr;
142 break;
143 }
144
145 return LpcmReformatterPtr(result);
146 }
147
148 template<typename TIn, typename TOut>
149 LpcmReformatterImpl<TIn, TOut>::LpcmReformatterImpl(
150 const LpcmStreamType& in_type,
151 const LpcmStreamTypeSet& out_type) :
152 in_type_(in_type),
153 out_type_(
154 out_type.sample_format() == LpcmStreamType::SampleFormat::kAny ?
155 in_type.sample_format() :
156 out_type.sample_format(),
157 in_type.channels(),
158 in_type.frames_per_second()) {}
159
160 template<typename TIn, typename TOut>
161 LpcmReformatterImpl<TIn, TOut>::~LpcmReformatterImpl() {}
162
163 namespace {
164
165 template <typename T>
166 inline constexpr T Clamp(T val, T min, T max) {
167 return (val > max) ? max : ((val < min) ? min : val);
168 }
169
170 template <typename T>
171 inline constexpr T Clamp(T val);
172
173 template <>
174 inline constexpr float Clamp(float val) {
175 return Clamp(val, -1.0f, 1.0f);
176 }
177
178 template <>
179 inline constexpr int32_t Clamp(int32_t val) {
180 return Clamp(val, 1 << 23, -(1 << 23));
181 }
182
183 template<typename TIn, typename TOut>
184 inline void CopySample(TOut* dest, TIn* source) {
185 *dest = static_cast<TOut>(*source);
186 }
187
188 inline void CopySample(uint8_t* dest, int16_t* source) {
189 *dest = static_cast<uint8_t>((*source >> 8) ^ 0x80);
190 }
191
192 inline void CopySample(uint8_t* dest, int32_t* source) {
193 *dest = static_cast<uint8_t>((Clamp(*source) >> 16) ^ 0x80);
194 }
195
196 inline void CopySample(uint8_t* dest, float* source) {
197 *dest = static_cast<uint8_t>((Clamp(*source) * 0x7f) + 128);
198 }
199
200 inline void CopySample(int16_t* dest, uint8_t* source) {
201 *dest = static_cast<int16_t>(*source ^ 0x80) << 8;
202 }
203
204 inline void CopySample(int16_t* dest, int32_t* source) {
205 *dest = static_cast<int16_t>(Clamp(*source) >> 8);
206 }
207
208 inline void CopySample(int16_t* dest, float* source) {
209 *dest = static_cast<int16_t>(Clamp(*source) * 0x7fff);
210 }
211
212 inline void CopySample(int32_t* dest, uint8_t* source) {
213 *dest = static_cast<int32_t>(*source ^ 0x80) << 16;
214 }
215
216 inline void CopySample(int32_t* dest, int16_t* source) {
217 *dest = static_cast<int32_t>(*source << 8);
218 }
219
220 inline void CopySample(int32_t* dest, float* source) {
221 *dest = static_cast<int32_t>(Clamp(*source) * 0x7fffff);
222 }
223
224 inline void CopySample(float* dest, uint8_t* source) {
225 *dest = static_cast<float>(*source ^ 0x80) / 0x80;
226 }
227
228 inline void CopySample(float* dest, int16_t* source) {
229 *dest = static_cast<float>(*source) / 0x8000;
230 }
231
232 inline void CopySample(float* dest, int32_t* source) {
233 *dest = static_cast<float>(Clamp(*source)) / 0x800000;
234 }
235
236 template<typename TIn, typename TOut>
237 inline void MixSample(TOut* dest, TIn* source) {
238 *dest += static_cast<TOut>(*source);
239 }
240
241 inline void MixSample(uint8_t* dest, int16_t* source) {
242 *dest += static_cast<uint8_t>((*source >> 8) ^ 0x80);
243 }
244
245 inline void MixSample(uint8_t* dest, int32_t* source) {
246 *dest += static_cast<uint8_t>((Clamp(*source) >> 16) ^ 0x80);
247 }
248
249 inline void MixSample(uint8_t* dest, float* source) {
250 *dest += static_cast<uint8_t>((Clamp(*source) * 0x7f) + 128);
251 }
252
253 inline void MixSample(int16_t* dest, uint8_t* source) {
254 *dest += static_cast<int16_t>(*source ^ 0x80) << 8;
255 }
256
257 inline void MixSample(int16_t* dest, int32_t* source) {
258 *dest += static_cast<int16_t>(Clamp(*source) >> 8);
259 }
260
261 inline void MixSample(int16_t* dest, float* source) {
262 *dest += static_cast<int16_t>(Clamp(*source) * 0x7fff);
263 }
264
265 inline void MixSample(int32_t* dest, uint8_t* source) {
266 *dest += static_cast<int32_t>(*source ^ 0x80) << 16;
267 }
268
269 inline void MixSample(int32_t* dest, int16_t* source) {
270 *dest += static_cast<int32_t>(*source << 8);
271 }
272
273 inline void MixSample(int32_t* dest, float* source) {
274 *dest += static_cast<int32_t>(Clamp(*source) * 0x7fffff);
275 }
276
277 inline void MixSample(float* dest, uint8_t* source) {
278 *dest += static_cast<float>(*source ^ 0x80) / 0x80;
279 }
280
281 inline void MixSample(float* dest, int16_t* source) {
282 *dest += static_cast<float>(*source) / 0x8000;
283 }
284
285 inline void MixSample(float* dest, int32_t* source) {
286 *dest += static_cast<float>(Clamp(*source)) / 0x800000;
287 }
288
289 } // namespace
290
291 template<typename TIn, typename TOut>
292 const LpcmStreamType& LpcmReformatterImpl<TIn, TOut>::input_stream_type()
293 const {
294 return in_type_;
295 }
296
297 template<typename TIn, typename TOut>
298 const LpcmStreamType& LpcmReformatterImpl<TIn, TOut>::output_stream_type()
299 const {
300 return out_type_;
301 }
302
303 template<typename TIn, typename TOut>
304 void LpcmReformatterImpl<TIn, TOut>::TransformFrames(
305 LpcmFrames* source,
306 LpcmFrames* dest,
307 bool mix) {
308 DCHECK(source);
309 DCHECK(dest);
310 DCHECK(source->buffer());
311 DCHECK(source->frame_count());
312 DCHECK(dest->buffer());
313 DCHECK(dest->frame_count());
314
315 uint64_t frame_count = std::min(source->frame_count(), dest->frame_count());
316
317 uint8_t* in_channel = static_cast<uint8_t*>(source->buffer());
318 uint8_t* out_channel = static_cast<uint8_t*>(dest->buffer());
319
320 for (uint32_t channel = 0; channel < in_type_.channels(); channel++) {
321 TIn* in_sample = reinterpret_cast<TIn*>(in_channel);
322 TOut* out_sample = reinterpret_cast<TOut*>(out_channel);
323 if (mix) {
324 for (uint64_t sample = 0; sample < frame_count; sample++) {
325 MixSample(out_sample, in_sample);
326 in_sample += in_type_.channels();
327 out_sample += out_type_.channels();
328 }
329 } else {
330 for (uint64_t sample = 0; sample < frame_count; sample++) {
331 CopySample(out_sample, in_sample);
332 in_sample += in_type_.channels();
333 out_sample += out_type_.channels();
334 }
335 }
336 in_channel += in_type_.sample_size();
337 out_channel += out_type_.sample_size();
338 }
339
340 source->advance(frame_count);
341 dest->advance(frame_count);
342 }
343
344 } // namespace media
345 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698