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

Side by Side Diff: services/media/framework/conversion_pipeline_builder.cc

Issue 1822333002: Motown: wholesale clang-format (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: dalesat Created 4 years, 9 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
1 // Copyright 2016 The Chromium Authors. All rights reserved. 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 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 "services/media/framework/conversion_pipeline_builder.h" 5 #include "services/media/framework/conversion_pipeline_builder.h"
6 #include "services/media/framework/formatting.h" 6 #include "services/media/framework/formatting.h"
7 #include "services/media/framework/parts/decoder.h" 7 #include "services/media/framework/parts/decoder.h"
8 #include "services/media/framework/parts/lpcm_reformatter.h" 8 #include "services/media/framework/parts/lpcm_reformatter.h"
9 9
10 namespace mojo { 10 namespace mojo {
11 namespace media { 11 namespace media {
12 12
13 namespace { 13 namespace {
14 14
15 enum class AddResult { 15 enum class AddResult {
16 kFailed, // Can't convert. 16 kFailed, // Can't convert.
17 kProgressed, // Added a conversion transform. 17 kProgressed, // Added a conversion transform.
18 kFinished // Done adding conversion transforms. 18 kFinished // Done adding conversion transforms.
19 }; 19 };
20 20
21 // Produces a score for in_type with respect to out_type_set. The score 21 // Produces a score for in_type with respect to out_type_set. The score
22 // is used to compare type sets to see which represents the best goal for 22 // is used to compare type sets to see which represents the best goal for
23 // conversion. Higher scores are preferred. A score of zero indicates that 23 // conversion. Higher scores are preferred. A score of zero indicates that
24 // in_type is incompatible with out_type_set. 24 // in_type is incompatible with out_type_set.
25 int Score( 25 int Score(const LpcmStreamType& in_type,
26 const LpcmStreamType& in_type, 26 const LpcmStreamTypeSet& out_type_set) {
27 const LpcmStreamTypeSet& out_type_set) {
28 // TODO(dalesat): Plenty of room for more subtlety here. Maybe actually 27 // TODO(dalesat): Plenty of room for more subtlety here. Maybe actually
29 // measure conversion costs (cpu, quality, etc) and reflect them here. 28 // measure conversion costs (cpu, quality, etc) and reflect them here.
30 29
31 int score = 1; // We can convert anything, so 1 is the minimum score. 30 int score = 1; // We can convert anything, so 1 is the minimum score.
32 31
33 if (in_type.sample_format() == out_type_set.sample_format() || 32 if (in_type.sample_format() == out_type_set.sample_format() ||
34 out_type_set.sample_format() == LpcmStreamType::SampleFormat::kAny) { 33 out_type_set.sample_format() == LpcmStreamType::SampleFormat::kAny) {
35 // Prefer not to convert sample format. 34 // Prefer not to convert sample format.
36 score += 10; 35 score += 10;
37 } else { 36 } else {
38 // Prefer higher-quality formats. 37 // Prefer higher-quality formats.
39 switch (out_type_set.sample_format()) { 38 switch (out_type_set.sample_format()) {
40 case LpcmStreamType::SampleFormat::kUnsigned8: 39 case LpcmStreamType::SampleFormat::kUnsigned8:
41 break; 40 break;
42 case LpcmStreamType::SampleFormat::kSigned16: 41 case LpcmStreamType::SampleFormat::kSigned16:
43 score += 1; 42 score += 1;
44 break; 43 break;
45 case LpcmStreamType::SampleFormat::kSigned24In32: 44 case LpcmStreamType::SampleFormat::kSigned24In32:
46 score += 2; 45 score += 2;
47 break; 46 break;
48 case LpcmStreamType::SampleFormat::kFloat: 47 case LpcmStreamType::SampleFormat::kFloat:
49 score += 3; 48 score += 3;
50 break; 49 break;
51 default: 50 default:
52 NOTREACHED() << "unsupported sample format " 51 NOTREACHED() << "unsupported sample format "
53 << out_type_set.sample_format(); 52 << out_type_set.sample_format();
54 } 53 }
55 } 54 }
56 55
57 if (out_type_set.channels().contains(in_type.channels())) { 56 if (out_type_set.channels().contains(in_type.channels())) {
58 // Prefer not to mixdown/up. 57 // Prefer not to mixdown/up.
59 score += 10; 58 score += 10;
60 } else { 59 } else {
61 return 0; // TODO(dalesat): Remove when we have mixdown/up. 60 return 0; // TODO(dalesat): Remove when we have mixdown/up.
62 } 61 }
63 62
64 if (out_type_set.frames_per_second(). 63 if (out_type_set.frames_per_second().contains(in_type.frames_per_second())) {
65 contains(in_type.frames_per_second())) {
66 // Very much prefer not to resample. 64 // Very much prefer not to resample.
67 score += 50; 65 score += 50;
68 } else { 66 } else {
69 return 0; // TODO(dalesat): Remove when we have resamplers. 67 return 0; // TODO(dalesat): Remove when we have resamplers.
70 } 68 }
71 69
72 return score; 70 return score;
73 } 71 }
74 72
75 // Finds the media type set that best matches in_type. 73 // Finds the media type set that best matches in_type.
76 const std::unique_ptr<StreamTypeSet>* FindBestLpcm( 74 const std::unique_ptr<StreamTypeSet>* FindBestLpcm(
77 const LpcmStreamType& in_type, 75 const LpcmStreamType& in_type,
78 const std::vector<std::unique_ptr<StreamTypeSet>>& out_type_sets) { 76 const std::vector<std::unique_ptr<StreamTypeSet>>& out_type_sets) {
79 const std::unique_ptr<StreamTypeSet>* best = nullptr; 77 const std::unique_ptr<StreamTypeSet>* best = nullptr;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 // No candidates found. 141 // No candidates found.
144 *out_type = nullptr; 142 *out_type = nullptr;
145 return AddResult::kFailed; 143 return AddResult::kFailed;
146 } 144 }
147 145
148 DCHECK_EQ((*best)->scheme(), StreamType::Scheme::kLpcm); 146 DCHECK_EQ((*best)->scheme(), StreamType::Scheme::kLpcm);
149 147
150 // Need to decode. Create a decoder and go from there. 148 // Need to decode. Create a decoder and go from there.
151 std::shared_ptr<Decoder> decoder; 149 std::shared_ptr<Decoder> decoder;
152 Result result = Decoder::Create(in_type, &decoder); 150 Result result = Decoder::Create(in_type, &decoder);
153 if (result != Result::kOk) { 151 if (result != Result::kOk) {
154 // No decoder found. 152 // No decoder found.
155 *out_type = nullptr; 153 *out_type = nullptr;
156 return AddResult::kFailed; 154 return AddResult::kFailed;
157 } 155 }
158 156
159 *output = graph->ConnectOutputToPart(*output, graph->Add(decoder)).output(); 157 *output = graph->ConnectOutputToPart(*output, graph->Add(decoder)).output();
160 *out_type = decoder->output_stream_type(); 158 *out_type = decoder->output_stream_type();
161 159
162 return AddResult::kProgressed; 160 return AddResult::kProgressed;
163 } 161 }
164 162
165 // Attempts to add transforms to the pipeline given an input LPCM stream type 163 // Attempts to add transforms to the pipeline given an input LPCM stream type
166 // (in_type) and the output lpcm stream type set for the type we need to convert 164 // (in_type) and the output lpcm stream type set for the type we need to convert
167 // to (out_type_set). If the call succeeds, *out_type is set to the new output 165 // to (out_type_set). If the call succeeds, *out_type is set to the new output
168 // type. Otherwise, *out_type is set to nullptr. 166 // type. Otherwise, *out_type is set to nullptr.
169 AddResult AddTransformsForLpcm( 167 AddResult AddTransformsForLpcm(const LpcmStreamType& in_type,
170 const LpcmStreamType& in_type, 168 const LpcmStreamTypeSet& out_type_set,
171 const LpcmStreamTypeSet& out_type_set, 169 Graph* graph,
172 Graph* graph, 170 OutputRef* output,
173 OutputRef* output, 171 std::unique_ptr<StreamType>* out_type) {
174 std::unique_ptr<StreamType>* out_type) {
175 DCHECK(graph); 172 DCHECK(graph);
176 DCHECK(out_type); 173 DCHECK(out_type);
177 174
178 // TODO(dalesat): Room for more intelligence here wrt transform ordering and 175 // TODO(dalesat): Room for more intelligence here wrt transform ordering and
179 // transforms that handle more than one conversion. 176 // transforms that handle more than one conversion.
180 if (in_type.sample_format() != out_type_set.sample_format() && 177 if (in_type.sample_format() != out_type_set.sample_format() &&
181 out_type_set.sample_format() != LpcmStreamType::SampleFormat::kAny) { 178 out_type_set.sample_format() != LpcmStreamType::SampleFormat::kAny) {
182 *output = graph->ConnectOutputToPart( 179 *output =
183 *output, 180 graph
184 graph->Add(LpcmReformatter::Create(in_type, out_type_set))).output(); 181 ->ConnectOutputToPart(*output, graph->Add(LpcmReformatter::Create(
182 in_type, out_type_set)))
183 .output();
185 } 184 }
186 185
187 if (!out_type_set.channels().contains(in_type.channels())) { 186 if (!out_type_set.channels().contains(in_type.channels())) {
188 // TODO(dalesat): Insert mixdown/up transform. 187 // TODO(dalesat): Insert mixdown/up transform.
189 NOTREACHED() << "conversion requires mixdown/up - not supported"; 188 NOTREACHED() << "conversion requires mixdown/up - not supported";
190 *out_type = nullptr; 189 *out_type = nullptr;
191 return AddResult::kFailed; 190 return AddResult::kFailed;
192 } 191 }
193 192
194 if (!out_type_set.frames_per_second().contains(in_type.frames_per_second())) { 193 if (!out_type_set.frames_per_second().contains(in_type.frames_per_second())) {
195 // TODO(dalesat): Insert resampler. 194 // TODO(dalesat): Insert resampler.
196 NOTREACHED() << "conversion requires resampling - not supported"; 195 NOTREACHED() << "conversion requires resampling - not supported";
197 *out_type = nullptr; 196 *out_type = nullptr;
198 return AddResult::kFailed; 197 return AddResult::kFailed;
199 } 198 }
200 199
201 // Build the resulting media type. 200 // Build the resulting media type.
202 *out_type = LpcmStreamType::Create( 201 *out_type = LpcmStreamType::Create(
203 out_type_set.sample_format() == LpcmStreamType::SampleFormat::kAny ? 202 out_type_set.sample_format() == LpcmStreamType::SampleFormat::kAny
204 in_type.sample_format() : 203 ? in_type.sample_format()
205 out_type_set.sample_format(), 204 : out_type_set.sample_format(),
206 in_type.channels(), 205 in_type.channels(), in_type.frames_per_second());
207 in_type.frames_per_second());
208 206
209 return AddResult::kFinished; 207 return AddResult::kFinished;
210 } 208 }
211 209
212 // Attempts to add transforms to the pipeline given an input media type with 210 // Attempts to add transforms to the pipeline given an input media type with
213 // scheme LPCM (in_type) and the set of output types we need to convert to 211 // scheme LPCM (in_type) and the set of output types we need to convert to
214 // (out_type_sets). If the call succeeds, *out_type is set to the new output 212 // (out_type_sets). If the call succeeds, *out_type is set to the new output
215 // type. Otherwise, *out_type is set to nullptr. 213 // type. Otherwise, *out_type is set to nullptr.
216 AddResult AddTransformsForLpcm( 214 AddResult AddTransformsForLpcm(
217 const LpcmStreamType& in_type, 215 const LpcmStreamType& in_type,
(...skipping 14 matching lines...) Expand all
232 } 230 }
233 231
234 switch ((*best)->scheme()) { 232 switch ((*best)->scheme()) {
235 case StreamType::Scheme::kAnyElementary: 233 case StreamType::Scheme::kAnyElementary:
236 case StreamType::Scheme::kAnyAudio: 234 case StreamType::Scheme::kAnyAudio:
237 case StreamType::Scheme::kAny: 235 case StreamType::Scheme::kAny:
238 // Wildcard scheme allows any type without conversion. 236 // Wildcard scheme allows any type without conversion.
239 *out_type = in_type.Clone(); 237 *out_type = in_type.Clone();
240 return AddResult::kFinished; 238 return AddResult::kFinished;
241 case StreamType::Scheme::kLpcm: 239 case StreamType::Scheme::kLpcm:
242 return AddTransformsForLpcm( 240 return AddTransformsForLpcm(in_type, *(*best)->lpcm(), graph, output,
243 in_type, 241 out_type);
244 *(*best)->lpcm(),
245 graph,
246 output,
247 out_type);
248 default: 242 default:
249 NOTREACHED() << "FindBestLpcm produced unexpected type set scheme" 243 NOTREACHED() << "FindBestLpcm produced unexpected type set scheme"
250 << (*best)->scheme(); 244 << (*best)->scheme();
251 return AddResult::kFailed; 245 return AddResult::kFailed;
252 } 246 }
253 } 247 }
254 248
255 // Attempts to add transforms to the pipeline given an input media type of any 249 // Attempts to add transforms to the pipeline given an input media type of any
256 // scheme (in_type) and the set of output types we need to convert to 250 // scheme (in_type) and the set of output types we need to convert to
257 // (out_type_sets). If the call succeeds, *out_type is set to the new output 251 // (out_type_sets). If the call succeeds, *out_type is set to the new output
258 // type. Otherwise, *out_type is set to nullptr. 252 // type. Otherwise, *out_type is set to nullptr.
259 AddResult AddTransforms( 253 AddResult AddTransforms(
260 const StreamType& in_type, 254 const StreamType& in_type,
261 const std::vector<std::unique_ptr<StreamTypeSet>>& out_type_sets, 255 const std::vector<std::unique_ptr<StreamTypeSet>>& out_type_sets,
262 Graph* graph, 256 Graph* graph,
263 OutputRef* output, 257 OutputRef* output,
264 std::unique_ptr<StreamType>* out_type) { 258 std::unique_ptr<StreamType>* out_type) {
265 DCHECK(graph); 259 DCHECK(graph);
266 DCHECK(out_type); 260 DCHECK(out_type);
267 261
268 switch (in_type.scheme()) { 262 switch (in_type.scheme()) {
269 case StreamType::Scheme::kLpcm: 263 case StreamType::Scheme::kLpcm:
270 return AddTransformsForLpcm( 264 return AddTransformsForLpcm(*in_type.lpcm(), out_type_sets, graph, output,
271 *in_type.lpcm(), 265 out_type);
272 out_type_sets,
273 graph,
274 output,
275 out_type);
276 case StreamType::Scheme::kCompressedAudio: 266 case StreamType::Scheme::kCompressedAudio:
277 return AddTransformsForCompressedAudio( 267 return AddTransformsForCompressedAudio(
278 *in_type.compressed_audio(), 268 *in_type.compressed_audio(), out_type_sets, graph, output, out_type);
279 out_type_sets,
280 graph,
281 output,
282 out_type);
283 default: 269 default:
284 NOTREACHED() << "conversion not supported for scheme" 270 NOTREACHED() << "conversion not supported for scheme" << in_type.scheme();
285 << in_type.scheme();
286 *out_type = nullptr; 271 *out_type = nullptr;
287 return AddResult::kFailed; 272 return AddResult::kFailed;
288 } 273 }
289 } 274 }
290 275
291 } // namespace 276 } // namespace
292 277
293 bool BuildConversionPipeline( 278 bool BuildConversionPipeline(
294 const StreamType& in_type, 279 const StreamType& in_type,
295 const std::vector<std::unique_ptr<StreamTypeSet>>& out_type_sets, 280 const std::vector<std::unique_ptr<StreamTypeSet>>& out_type_sets,
296 Graph* graph, 281 Graph* graph,
297 OutputRef* output, 282 OutputRef* output,
298 std::unique_ptr<StreamType>* out_type) { 283 std::unique_ptr<StreamType>* out_type) {
299 DCHECK(graph); 284 DCHECK(graph);
300 DCHECK(output); 285 DCHECK(output);
301 DCHECK(out_type); 286 DCHECK(out_type);
302 287
303 OutputRef out = *output; 288 OutputRef out = *output;
304 const StreamType* type_to_convert = &in_type; 289 const StreamType* type_to_convert = &in_type;
305 std::unique_ptr<StreamType> converted_type; 290 std::unique_ptr<StreamType> converted_type;
306 while (true) { 291 while (true) {
307 switch (AddTransforms( 292 switch (AddTransforms(*type_to_convert, out_type_sets, graph, &out,
308 *type_to_convert, 293 &converted_type)) {
309 out_type_sets,
310 graph,
311 &out,
312 &converted_type)) {
313 case AddResult::kFailed: 294 case AddResult::kFailed:
314 // Failed to find a suitable conversion. Return the pipeline to its 295 // Failed to find a suitable conversion. Return the pipeline to its
315 // original state. 296 // original state.
316 graph->RemovePartsConnectedToOutput(*output); 297 graph->RemovePartsConnectedToOutput(*output);
317 *out_type = nullptr; 298 *out_type = nullptr;
318 return false; 299 return false;
319 case AddResult::kProgressed: 300 case AddResult::kProgressed:
320 // Made progress. Continue. 301 // Made progress. Continue.
321 break; 302 break;
322 case AddResult::kFinished: 303 case AddResult::kFinished:
323 // No further conversion required. 304 // No further conversion required.
324 *output = out; 305 *output = out;
325 *out_type = std::move(converted_type); 306 *out_type = std::move(converted_type);
326 return true; 307 return true;
327 } 308 }
328 309
329 type_to_convert = converted_type.get(); 310 type_to_convert = converted_type.get();
330 } 311 }
331 } 312 }
332 313
333 } // namespace media 314 } // namespace media
334 } // namespace mojo 315 } // namespace mojo
OLDNEW
« no previous file with comments | « services/media/framework/conversion_pipeline_builder.h ('k') | services/media/framework/engine.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698