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

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

Issue 1678433002: Motown: Remove LPCM optimizations, fix prepare, add flush, add ActiveMultistreamSink model/stage (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Sync 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
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 {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 // Very much prefer not to resample. 66 // Very much prefer not to resample.
67 score += 50; 67 score += 50;
68 } else { 68 } else {
69 return 0; // TODO(dalesat): Remove when we have resamplers. 69 return 0; // TODO(dalesat): Remove when we have resamplers.
70 } 70 }
71 71
72 return score; 72 return score;
73 } 73 }
74 74
75 // Finds the media type set that best matches in_type. 75 // Finds the media type set that best matches in_type.
76 const StreamTypeSetPtr* FindBestLpcm( 76 const std::unique_ptr<StreamTypeSet>* FindBestLpcm(
77 const LpcmStreamType& in_type, 77 const LpcmStreamType& in_type,
78 const StreamTypeSetsPtr& out_type_sets) { 78 const std::unique_ptr<std::vector<std::unique_ptr<StreamTypeSet>>>&
79 const StreamTypeSetPtr* best = nullptr; 79 out_type_sets) {
80 const std::unique_ptr<StreamTypeSet>* best = nullptr;
80 int best_score = 0; 81 int best_score = 0;
81 for (const StreamTypeSetPtr& out_type_set : *out_type_sets) { 82 for (const std::unique_ptr<StreamTypeSet>& out_type_set : *out_type_sets) {
82 switch (out_type_set->scheme()) { 83 switch (out_type_set->scheme()) {
83 case StreamType::Scheme::kAnyElementary: 84 case StreamType::Scheme::kAnyElementary:
84 case StreamType::Scheme::kAnyAudio: 85 case StreamType::Scheme::kAnyAudio:
85 case StreamType::Scheme::kAny: 86 case StreamType::Scheme::kAny:
86 // Wildcard scheme allows any type without conversion. 87 // Wildcard scheme allows any type without conversion.
87 return &out_type_set; 88 return &out_type_set;
88 case StreamType::Scheme::kLpcm: { 89 case StreamType::Scheme::kLpcm: {
89 int score = Score(in_type, *out_type_set->lpcm()); 90 int score = Score(in_type, *out_type_set->lpcm());
90 if (best_score < score) { 91 if (best_score < score) {
91 best_score = score; 92 best_score = score;
92 best = &out_type_set; 93 best = &out_type_set;
93 } 94 }
94 break; 95 break;
95 } 96 }
96 default: 97 default:
97 break; 98 break;
98 } 99 }
99 } 100 }
100 return best; 101 return best;
101 } 102 }
102 103
103 // Attempts to add transforms to the pipeline given an input compressed audio 104 // Attempts to add transforms to the pipeline given an input compressed audio
104 // stream type with (in_type) and the set of output types we need to convert to 105 // stream type with (in_type) and the set of output types we need to convert to
105 // (out_type_sets). If the call succeeds, *out_type is set to the new output 106 // (out_type_sets). If the call succeeds, *out_type is set to the new output
106 // type. Otherwise, *out_type is set to nullptr. 107 // type. Otherwise, *out_type is set to nullptr.
107 AddResult AddTransformsForCompressedAudio( 108 AddResult AddTransformsForCompressedAudio(
108 const CompressedAudioStreamType& in_type, 109 const CompressedAudioStreamType& in_type,
109 const StreamTypePtr& in_type_ptr, 110 const std::unique_ptr<StreamType>& in_type_ptr,
110 const StreamTypeSetsPtr& out_type_sets, 111 const std::unique_ptr<std::vector<std::unique_ptr<StreamTypeSet>>>&
111 Engine* engine, 112 out_type_sets,
112 Engine::Output* output, 113 Graph* graph,
113 StreamTypePtr* out_type) { 114 OutputRef* output,
115 std::unique_ptr<StreamType>* out_type) {
114 DCHECK(out_type); 116 DCHECK(out_type);
115 DCHECK(engine); 117 DCHECK(graph);
116 118
117 // See if we have a matching COMPRESSED_AUDIO type. 119 // See if we have a matching COMPRESSED_AUDIO type.
118 for (const StreamTypeSetPtr& out_type_set : *out_type_sets) { 120 for (const std::unique_ptr<StreamTypeSet>& out_type_set : *out_type_sets) {
119 switch (out_type_set->scheme()) { 121 switch (out_type_set->scheme()) {
120 case StreamType::Scheme::kAnyElementary: 122 case StreamType::Scheme::kAnyElementary:
121 case StreamType::Scheme::kAnyAudio: 123 case StreamType::Scheme::kAnyAudio:
122 case StreamType::Scheme::kAny: 124 case StreamType::Scheme::kAny:
123 // Wildcard scheme allows any type without conversion. 125 // Wildcard scheme allows any type without conversion.
124 *out_type = in_type.Clone(); 126 *out_type = in_type.Clone();
125 return AddResult::kFinished; 127 return AddResult::kFinished;
126 case StreamType::Scheme::kCompressedAudio: { 128 case StreamType::Scheme::kCompressedAudio: {
127 if (out_type_set->compressed_audio()->contains(in_type)) { 129 if (out_type_set->compressed_audio()->contains(in_type)) {
128 // No transform needed. 130 // No transform needed.
129 *out_type = in_type.Clone(); 131 *out_type = in_type.Clone();
130 return AddResult::kFinished; 132 return AddResult::kFinished;
131 } 133 }
132 break; 134 break;
133 } 135 }
134 default: 136 default:
135 break; 137 break;
136 } 138 }
137 // TODO(dalesat): Support a different compressed output type by transcoding. 139 // TODO(dalesat): Support a different compressed output type by transcoding.
138 } 140 }
139 141
140 // Find the best LPCM output type. 142 // Find the best LPCM output type.
141 const StreamTypeSetPtr* best = FindBestLpcm(in_type, out_type_sets); 143 const std::unique_ptr<StreamTypeSet>* best =
144 FindBestLpcm(in_type, out_type_sets);
142 if (best == nullptr) { 145 if (best == nullptr) {
143 // No candidates found. 146 // No candidates found.
144 *out_type = nullptr; 147 *out_type = nullptr;
145 return AddResult::kFailed; 148 return AddResult::kFailed;
146 } 149 }
147 150
148 DCHECK_EQ((*best)->scheme(), StreamType::Scheme::kLpcm); 151 DCHECK_EQ((*best)->scheme(), StreamType::Scheme::kLpcm);
149 152
150 // Need to decode. Create a decoder and go from there. 153 // Need to decode. Create a decoder and go from there.
151 DecoderPtr decoder; 154 std::shared_ptr<Decoder> decoder;
152 Result result = Decoder::Create(in_type_ptr, &decoder); 155 Result result = Decoder::Create(in_type_ptr, &decoder);
153 if (result != Result::kOk) { 156 if (result != Result::kOk) {
154 // No decoder found. 157 // No decoder found.
155 *out_type = nullptr; 158 *out_type = nullptr;
156 return AddResult::kFailed; 159 return AddResult::kFailed;
157 } 160 }
158 161
159 *output = engine->ConnectOutputToPart(*output, engine->Add(decoder)).output(); 162 *output = graph->ConnectOutputToPart(*output, graph->Add(decoder)).output();
160 *out_type = decoder->output_stream_type(); 163 *out_type = decoder->output_stream_type();
161 164
162 return AddResult::kProgressed; 165 return AddResult::kProgressed;
163 } 166 }
164 167
165 // Attempts to add transforms to the pipeline given an input LPCM stream type 168 // 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 169 // (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 170 // 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. 171 // type. Otherwise, *out_type is set to nullptr.
169 AddResult AddTransformsForLpcm( 172 AddResult AddTransformsForLpcm(
170 const LpcmStreamType& in_type, 173 const LpcmStreamType& in_type,
171 const LpcmStreamTypeSet& out_type_set, 174 const LpcmStreamTypeSet& out_type_set,
172 Engine* engine, 175 Graph* graph,
173 Engine::Output* output, 176 OutputRef* output,
174 StreamTypePtr* out_type) { 177 std::unique_ptr<StreamType>* out_type) {
175 DCHECK(engine); 178 DCHECK(graph);
176 DCHECK(out_type); 179 DCHECK(out_type);
177 180
178 // TODO(dalesat): Room for more intelligence here wrt transform ordering and 181 // TODO(dalesat): Room for more intelligence here wrt transform ordering and
179 // transforms that handle more than one conversion. 182 // transforms that handle more than one conversion.
180 if (in_type.sample_format() != out_type_set.sample_format() && 183 if (in_type.sample_format() != out_type_set.sample_format() &&
181 out_type_set.sample_format() != LpcmStreamType::SampleFormat::kAny) { 184 out_type_set.sample_format() != LpcmStreamType::SampleFormat::kAny) {
182 // The reformatter will fix interleave conversion. 185 // The reformatter will fix interleave conversion.
183 *output = engine->ConnectOutputToPart( 186 *output = graph->ConnectOutputToPart(
184 *output, 187 *output,
185 engine->Add(LpcmReformatter::Create(in_type, out_type_set))).output(); 188 graph->Add(LpcmReformatter::Create(in_type, out_type_set))).output();
186 } 189 }
187 190
188 if (!out_type_set.channels().contains(in_type.channels())) { 191 if (!out_type_set.channels().contains(in_type.channels())) {
189 // TODO(dalesat): Insert mixdown/up transform. 192 // TODO(dalesat): Insert mixdown/up transform.
190 NOTREACHED() << "conversion requires mixdown/up - not supported"; 193 NOTREACHED() << "conversion requires mixdown/up - not supported";
191 *out_type = nullptr; 194 *out_type = nullptr;
192 return AddResult::kFailed; 195 return AddResult::kFailed;
193 } 196 }
194 197
195 if (!out_type_set.frames_per_second().contains(in_type.frames_per_second())) { 198 if (!out_type_set.frames_per_second().contains(in_type.frames_per_second())) {
(...skipping 13 matching lines...) Expand all
209 212
210 return AddResult::kFinished; 213 return AddResult::kFinished;
211 } 214 }
212 215
213 // Attempts to add transforms to the pipeline given an input media type with 216 // Attempts to add transforms to the pipeline given an input media type with
214 // scheme LPCM (in_type) and the set of output types we need to convert to 217 // scheme LPCM (in_type) and the set of output types we need to convert to
215 // (out_type_sets). If the call succeeds, *out_type is set to the new output 218 // (out_type_sets). If the call succeeds, *out_type is set to the new output
216 // type. Otherwise, *out_type is set to nullptr. 219 // type. Otherwise, *out_type is set to nullptr.
217 AddResult AddTransformsForLpcm( 220 AddResult AddTransformsForLpcm(
218 const LpcmStreamType& in_type, 221 const LpcmStreamType& in_type,
219 const StreamTypeSetsPtr& out_type_sets, 222 const std::unique_ptr<std::vector<std::unique_ptr<StreamTypeSet>>>&
220 Engine* engine, 223 out_type_sets,
221 Engine::Output* output, 224 Graph* graph,
222 StreamTypePtr* out_type) { 225 OutputRef* output,
223 DCHECK(engine); 226 std::unique_ptr<StreamType>* out_type) {
227 DCHECK(graph);
224 DCHECK(out_type); 228 DCHECK(out_type);
225 229
226 const StreamTypeSetPtr* best = FindBestLpcm(in_type, out_type_sets); 230 const std::unique_ptr<StreamTypeSet>* best =
231 FindBestLpcm(in_type, out_type_sets);
227 if (best == nullptr) { 232 if (best == nullptr) {
228 // TODO(dalesat): Support a compressed output type by encoding. 233 // TODO(dalesat): Support a compressed output type by encoding.
229 NOTREACHED() << "conversion using encoder not supported"; 234 NOTREACHED() << "conversion using encoder not supported";
230 *out_type = nullptr; 235 *out_type = nullptr;
231 return AddResult::kFailed; 236 return AddResult::kFailed;
232 } 237 }
233 238
234 switch ((*best)->scheme()) { 239 switch ((*best)->scheme()) {
235 case StreamType::Scheme::kAnyElementary: 240 case StreamType::Scheme::kAnyElementary:
236 case StreamType::Scheme::kAnyAudio: 241 case StreamType::Scheme::kAnyAudio:
237 case StreamType::Scheme::kAny: 242 case StreamType::Scheme::kAny:
238 // Wildcard scheme allows any type without conversion. 243 // Wildcard scheme allows any type without conversion.
239 *out_type = in_type.Clone(); 244 *out_type = in_type.Clone();
240 return AddResult::kFinished; 245 return AddResult::kFinished;
241 case StreamType::Scheme::kLpcm: 246 case StreamType::Scheme::kLpcm:
242 return AddTransformsForLpcm( 247 return AddTransformsForLpcm(
243 in_type, 248 in_type,
244 *(*best)->lpcm(), 249 *(*best)->lpcm(),
245 engine, 250 graph,
246 output, 251 output,
247 out_type); 252 out_type);
248 default: 253 default:
249 NOTREACHED() << "FindBestLpcm produced unexpected type set scheme" 254 NOTREACHED() << "FindBestLpcm produced unexpected type set scheme"
250 << (*best)->scheme(); 255 << (*best)->scheme();
251 return AddResult::kFailed; 256 return AddResult::kFailed;
252 } 257 }
253 } 258 }
254 259
255 // Attempts to add transforms to the pipeline given an input media type of any 260 // 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 261 // 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 262 // (out_type_sets). If the call succeeds, *out_type is set to the new output
258 // type. Otherwise, *out_type is set to nullptr. 263 // type. Otherwise, *out_type is set to nullptr.
259 AddResult AddTransforms( 264 AddResult AddTransforms(
260 const StreamTypePtr& in_type, 265 const std::unique_ptr<StreamType>& in_type,
261 const StreamTypeSetsPtr& out_type_sets, 266 const std::unique_ptr<std::vector<std::unique_ptr<StreamTypeSet>>>&
262 Engine* engine, 267 out_type_sets,
263 Engine::Output* output, 268 Graph* graph,
264 StreamTypePtr* out_type) { 269 OutputRef* output,
270 std::unique_ptr<StreamType>* out_type) {
265 DCHECK(in_type); 271 DCHECK(in_type);
266 DCHECK(engine); 272 DCHECK(graph);
267 DCHECK(out_type); 273 DCHECK(out_type);
268 274
269 switch (in_type->scheme()) { 275 switch (in_type->scheme()) {
270 case StreamType::Scheme::kLpcm: 276 case StreamType::Scheme::kLpcm:
271 return AddTransformsForLpcm( 277 return AddTransformsForLpcm(
272 *in_type->lpcm(), 278 *in_type->lpcm(),
273 out_type_sets, 279 out_type_sets,
274 engine, 280 graph,
275 output, 281 output,
276 out_type); 282 out_type);
277 case StreamType::Scheme::kCompressedAudio: 283 case StreamType::Scheme::kCompressedAudio:
278 return AddTransformsForCompressedAudio( 284 return AddTransformsForCompressedAudio(
279 *in_type->compressed_audio(), 285 *in_type->compressed_audio(),
280 in_type, 286 in_type,
281 out_type_sets, 287 out_type_sets,
282 engine, 288 graph,
283 output, 289 output,
284 out_type); 290 out_type);
285 default: 291 default:
286 NOTREACHED() << "conversion not supported for scheme" 292 NOTREACHED() << "conversion not supported for scheme"
287 << in_type->scheme(); 293 << in_type->scheme();
288 *out_type = nullptr; 294 *out_type = nullptr;
289 return AddResult::kFailed; 295 return AddResult::kFailed;
290 } 296 }
291 } 297 }
292 298
293 } // namespace 299 } // namespace
294 300
295 bool BuildConversionPipeline( 301 bool BuildConversionPipeline(
296 const StreamTypePtr& in_type, 302 const std::unique_ptr<StreamType>& in_type,
297 const StreamTypeSetsPtr& out_type_sets, 303 const std::unique_ptr<std::vector<std::unique_ptr<StreamTypeSet>>>&
298 Engine* engine, 304 out_type_sets,
299 Engine::Output* output, 305 Graph* graph,
300 StreamTypePtr* out_type) { 306 OutputRef* output,
307 std::unique_ptr<StreamType>* out_type) {
301 DCHECK(in_type); 308 DCHECK(in_type);
302 DCHECK(out_type_sets); 309 DCHECK(out_type_sets);
303 DCHECK(engine); 310 DCHECK(graph);
304 DCHECK(output); 311 DCHECK(output);
305 DCHECK(out_type); 312 DCHECK(out_type);
306 313
307 Engine::Output out = *output; 314 OutputRef out = *output;
308 315
309 const StreamTypePtr* type_to_convert = &in_type; 316 const std::unique_ptr<StreamType>* type_to_convert = &in_type;
310 StreamTypePtr next_in_type; 317 std::unique_ptr<StreamType> next_in_type;
311 while (true) { 318 while (true) {
312 StreamTypePtr converted_type; 319 std::unique_ptr<StreamType> converted_type;
313 switch (AddTransforms( 320 switch (AddTransforms(
314 *type_to_convert, 321 *type_to_convert,
315 out_type_sets, 322 out_type_sets,
316 engine, 323 graph,
317 &out, 324 &out,
318 &converted_type)) { 325 &converted_type)) {
319 case AddResult::kFailed: 326 case AddResult::kFailed:
320 // Failed to find a suitable conversion. Return the pipeline to its 327 // Failed to find a suitable conversion. Return the pipeline to its
321 // original state. 328 // original state.
322 engine->RemovePartsConnectedToOutput(*output); 329 graph->RemovePartsConnectedToOutput(*output);
323 *out_type = nullptr; 330 *out_type = nullptr;
324 return false; 331 return false;
325 case AddResult::kProgressed: 332 case AddResult::kProgressed:
326 // Made progress. Continue. 333 // Made progress. Continue.
327 break; 334 break;
328 case AddResult::kFinished: 335 case AddResult::kFinished:
329 // No further conversion required. 336 // No further conversion required.
330 *output = out; 337 *output = out;
331 *out_type = std::move(converted_type); 338 *out_type = std::move(converted_type);
332 return true; 339 return true;
333 } 340 }
334 341
335 next_in_type = std::move(converted_type); 342 next_in_type = std::move(converted_type);
336 type_to_convert = &next_in_type; 343 type_to_convert = &next_in_type;
337 } 344 }
338 } 345 }
339 346
340 } // namespace media 347 } // namespace media
341 } // namespace mojo 348 } // 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