| OLD | NEW |
| 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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 std::unique_ptr<StreamTypeSet>* FindBestLpcm( | 76 const std::unique_ptr<StreamTypeSet>* FindBestLpcm( |
| 77 const LpcmStreamType& in_type, | 77 const LpcmStreamType& in_type, |
| 78 const std::unique_ptr<std::vector<std::unique_ptr<StreamTypeSet>>>& | 78 const std::vector<std::unique_ptr<StreamTypeSet>>& out_type_sets) { |
| 79 out_type_sets) { | |
| 80 const std::unique_ptr<StreamTypeSet>* best = nullptr; | 79 const std::unique_ptr<StreamTypeSet>* best = nullptr; |
| 81 int best_score = 0; | 80 int best_score = 0; |
| 82 for (const std::unique_ptr<StreamTypeSet>& out_type_set : *out_type_sets) { | 81 for (const std::unique_ptr<StreamTypeSet>& out_type_set : out_type_sets) { |
| 83 switch (out_type_set->scheme()) { | 82 switch (out_type_set->scheme()) { |
| 84 case StreamType::Scheme::kAnyElementary: | 83 case StreamType::Scheme::kAnyElementary: |
| 85 case StreamType::Scheme::kAnyAudio: | 84 case StreamType::Scheme::kAnyAudio: |
| 86 case StreamType::Scheme::kAny: | 85 case StreamType::Scheme::kAny: |
| 87 // Wildcard scheme allows any type without conversion. | 86 // Wildcard scheme allows any type without conversion. |
| 88 return &out_type_set; | 87 return &out_type_set; |
| 89 case StreamType::Scheme::kLpcm: { | 88 case StreamType::Scheme::kLpcm: { |
| 90 int score = Score(in_type, *out_type_set->lpcm()); | 89 int score = Score(in_type, *out_type_set->lpcm()); |
| 91 if (best_score < score) { | 90 if (best_score < score) { |
| 92 best_score = score; | 91 best_score = score; |
| 93 best = &out_type_set; | 92 best = &out_type_set; |
| 94 } | 93 } |
| 95 break; | 94 break; |
| 96 } | 95 } |
| 97 default: | 96 default: |
| 98 break; | 97 break; |
| 99 } | 98 } |
| 100 } | 99 } |
| 101 return best; | 100 return best; |
| 102 } | 101 } |
| 103 | 102 |
| 104 // Attempts to add transforms to the pipeline given an input compressed audio | 103 // Attempts to add transforms to the pipeline given an input compressed audio |
| 105 // stream type with (in_type) and the set of output types we need to convert to | 104 // stream type with (in_type) and the set of output types we need to convert to |
| 106 // (out_type_sets). If the call succeeds, *out_type is set to the new output | 105 // (out_type_sets). If the call succeeds, *out_type is set to the new output |
| 107 // type. Otherwise, *out_type is set to nullptr. | 106 // type. Otherwise, *out_type is set to nullptr. |
| 108 AddResult AddTransformsForCompressedAudio( | 107 AddResult AddTransformsForCompressedAudio( |
| 109 const CompressedAudioStreamType& in_type, | 108 const CompressedAudioStreamType& in_type, |
| 110 const std::unique_ptr<StreamType>& in_type_ptr, | 109 const std::vector<std::unique_ptr<StreamTypeSet>>& out_type_sets, |
| 111 const std::unique_ptr<std::vector<std::unique_ptr<StreamTypeSet>>>& | |
| 112 out_type_sets, | |
| 113 Graph* graph, | 110 Graph* graph, |
| 114 OutputRef* output, | 111 OutputRef* output, |
| 115 std::unique_ptr<StreamType>* out_type) { | 112 std::unique_ptr<StreamType>* out_type) { |
| 116 DCHECK(out_type); | 113 DCHECK(out_type); |
| 117 DCHECK(graph); | 114 DCHECK(graph); |
| 118 | 115 |
| 119 // See if we have a matching COMPRESSED_AUDIO type. | 116 // See if we have a matching COMPRESSED_AUDIO type. |
| 120 for (const std::unique_ptr<StreamTypeSet>& out_type_set : *out_type_sets) { | 117 for (const std::unique_ptr<StreamTypeSet>& out_type_set : out_type_sets) { |
| 121 switch (out_type_set->scheme()) { | 118 switch (out_type_set->scheme()) { |
| 122 case StreamType::Scheme::kAnyElementary: | 119 case StreamType::Scheme::kAnyElementary: |
| 123 case StreamType::Scheme::kAnyAudio: | 120 case StreamType::Scheme::kAnyAudio: |
| 124 case StreamType::Scheme::kAny: | 121 case StreamType::Scheme::kAny: |
| 125 // Wildcard scheme allows any type without conversion. | 122 // Wildcard scheme allows any type without conversion. |
| 126 *out_type = in_type.Clone(); | 123 *out_type = in_type.Clone(); |
| 127 return AddResult::kFinished; | 124 return AddResult::kFinished; |
| 128 case StreamType::Scheme::kCompressedAudio: { | 125 case StreamType::Scheme::kCompressedAudio: { |
| 129 if (out_type_set->compressed_audio()->contains(in_type)) { | 126 if (out_type_set->compressed_audio()->contains(in_type)) { |
| 130 // No transform needed. | 127 // No transform needed. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 145 if (best == nullptr) { | 142 if (best == nullptr) { |
| 146 // No candidates found. | 143 // No candidates found. |
| 147 *out_type = nullptr; | 144 *out_type = nullptr; |
| 148 return AddResult::kFailed; | 145 return AddResult::kFailed; |
| 149 } | 146 } |
| 150 | 147 |
| 151 DCHECK_EQ((*best)->scheme(), StreamType::Scheme::kLpcm); | 148 DCHECK_EQ((*best)->scheme(), StreamType::Scheme::kLpcm); |
| 152 | 149 |
| 153 // Need to decode. Create a decoder and go from there. | 150 // Need to decode. Create a decoder and go from there. |
| 154 std::shared_ptr<Decoder> decoder; | 151 std::shared_ptr<Decoder> decoder; |
| 155 Result result = Decoder::Create(in_type_ptr, &decoder); | 152 Result result = Decoder::Create(in_type, &decoder); |
| 156 if (result != Result::kOk) { | 153 if (result != Result::kOk) { |
| 157 // No decoder found. | 154 // No decoder found. |
| 158 *out_type = nullptr; | 155 *out_type = nullptr; |
| 159 return AddResult::kFailed; | 156 return AddResult::kFailed; |
| 160 } | 157 } |
| 161 | 158 |
| 162 *output = graph->ConnectOutputToPart(*output, graph->Add(decoder)).output(); | 159 *output = graph->ConnectOutputToPart(*output, graph->Add(decoder)).output(); |
| 163 *out_type = decoder->output_stream_type(); | 160 *out_type = decoder->output_stream_type(); |
| 164 | 161 |
| 165 return AddResult::kProgressed; | 162 return AddResult::kProgressed; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 | 209 |
| 213 return AddResult::kFinished; | 210 return AddResult::kFinished; |
| 214 } | 211 } |
| 215 | 212 |
| 216 // Attempts to add transforms to the pipeline given an input media type with | 213 // Attempts to add transforms to the pipeline given an input media type with |
| 217 // scheme LPCM (in_type) and the set of output types we need to convert to | 214 // scheme LPCM (in_type) and the set of output types we need to convert to |
| 218 // (out_type_sets). If the call succeeds, *out_type is set to the new output | 215 // (out_type_sets). If the call succeeds, *out_type is set to the new output |
| 219 // type. Otherwise, *out_type is set to nullptr. | 216 // type. Otherwise, *out_type is set to nullptr. |
| 220 AddResult AddTransformsForLpcm( | 217 AddResult AddTransformsForLpcm( |
| 221 const LpcmStreamType& in_type, | 218 const LpcmStreamType& in_type, |
| 222 const std::unique_ptr<std::vector<std::unique_ptr<StreamTypeSet>>>& | 219 const std::vector<std::unique_ptr<StreamTypeSet>>& out_type_sets, |
| 223 out_type_sets, | |
| 224 Graph* graph, | 220 Graph* graph, |
| 225 OutputRef* output, | 221 OutputRef* output, |
| 226 std::unique_ptr<StreamType>* out_type) { | 222 std::unique_ptr<StreamType>* out_type) { |
| 227 DCHECK(graph); | 223 DCHECK(graph); |
| 228 DCHECK(out_type); | 224 DCHECK(out_type); |
| 229 | 225 |
| 230 const std::unique_ptr<StreamTypeSet>* best = | 226 const std::unique_ptr<StreamTypeSet>* best = |
| 231 FindBestLpcm(in_type, out_type_sets); | 227 FindBestLpcm(in_type, out_type_sets); |
| 232 if (best == nullptr) { | 228 if (best == nullptr) { |
| 233 // TODO(dalesat): Support a compressed output type by encoding. | 229 // TODO(dalesat): Support a compressed output type by encoding. |
| (...skipping 21 matching lines...) Expand all Loading... |
| 255 << (*best)->scheme(); | 251 << (*best)->scheme(); |
| 256 return AddResult::kFailed; | 252 return AddResult::kFailed; |
| 257 } | 253 } |
| 258 } | 254 } |
| 259 | 255 |
| 260 // Attempts to add transforms to the pipeline given an input media type of any | 256 // Attempts to add transforms to the pipeline given an input media type of any |
| 261 // scheme (in_type) and the set of output types we need to convert to | 257 // scheme (in_type) and the set of output types we need to convert to |
| 262 // (out_type_sets). If the call succeeds, *out_type is set to the new output | 258 // (out_type_sets). If the call succeeds, *out_type is set to the new output |
| 263 // type. Otherwise, *out_type is set to nullptr. | 259 // type. Otherwise, *out_type is set to nullptr. |
| 264 AddResult AddTransforms( | 260 AddResult AddTransforms( |
| 265 const std::unique_ptr<StreamType>& in_type, | 261 const StreamType& in_type, |
| 266 const std::unique_ptr<std::vector<std::unique_ptr<StreamTypeSet>>>& | 262 const std::vector<std::unique_ptr<StreamTypeSet>>& out_type_sets, |
| 267 out_type_sets, | |
| 268 Graph* graph, | 263 Graph* graph, |
| 269 OutputRef* output, | 264 OutputRef* output, |
| 270 std::unique_ptr<StreamType>* out_type) { | 265 std::unique_ptr<StreamType>* out_type) { |
| 271 DCHECK(in_type); | |
| 272 DCHECK(graph); | 266 DCHECK(graph); |
| 273 DCHECK(out_type); | 267 DCHECK(out_type); |
| 274 | 268 |
| 275 switch (in_type->scheme()) { | 269 switch (in_type.scheme()) { |
| 276 case StreamType::Scheme::kLpcm: | 270 case StreamType::Scheme::kLpcm: |
| 277 return AddTransformsForLpcm( | 271 return AddTransformsForLpcm( |
| 278 *in_type->lpcm(), | 272 *in_type.lpcm(), |
| 279 out_type_sets, | 273 out_type_sets, |
| 280 graph, | 274 graph, |
| 281 output, | 275 output, |
| 282 out_type); | 276 out_type); |
| 283 case StreamType::Scheme::kCompressedAudio: | 277 case StreamType::Scheme::kCompressedAudio: |
| 284 return AddTransformsForCompressedAudio( | 278 return AddTransformsForCompressedAudio( |
| 285 *in_type->compressed_audio(), | 279 *in_type.compressed_audio(), |
| 286 in_type, | |
| 287 out_type_sets, | 280 out_type_sets, |
| 288 graph, | 281 graph, |
| 289 output, | 282 output, |
| 290 out_type); | 283 out_type); |
| 291 default: | 284 default: |
| 292 NOTREACHED() << "conversion not supported for scheme" | 285 NOTREACHED() << "conversion not supported for scheme" |
| 293 << in_type->scheme(); | 286 << in_type.scheme(); |
| 294 *out_type = nullptr; | 287 *out_type = nullptr; |
| 295 return AddResult::kFailed; | 288 return AddResult::kFailed; |
| 296 } | 289 } |
| 297 } | 290 } |
| 298 | 291 |
| 299 } // namespace | 292 } // namespace |
| 300 | 293 |
| 301 bool BuildConversionPipeline( | 294 bool BuildConversionPipeline( |
| 302 const std::unique_ptr<StreamType>& in_type, | 295 const StreamType& in_type, |
| 303 const std::unique_ptr<std::vector<std::unique_ptr<StreamTypeSet>>>& | 296 const std::vector<std::unique_ptr<StreamTypeSet>>& out_type_sets, |
| 304 out_type_sets, | |
| 305 Graph* graph, | 297 Graph* graph, |
| 306 OutputRef* output, | 298 OutputRef* output, |
| 307 std::unique_ptr<StreamType>* out_type) { | 299 std::unique_ptr<StreamType>* out_type) { |
| 308 DCHECK(in_type); | |
| 309 DCHECK(out_type_sets); | |
| 310 DCHECK(graph); | 300 DCHECK(graph); |
| 311 DCHECK(output); | 301 DCHECK(output); |
| 312 DCHECK(out_type); | 302 DCHECK(out_type); |
| 313 | 303 |
| 314 OutputRef out = *output; | 304 OutputRef out = *output; |
| 315 | 305 const StreamType* type_to_convert = &in_type; |
| 316 const std::unique_ptr<StreamType>* type_to_convert = &in_type; | 306 std::unique_ptr<StreamType> converted_type; |
| 317 std::unique_ptr<StreamType> next_in_type; | |
| 318 while (true) { | 307 while (true) { |
| 319 std::unique_ptr<StreamType> converted_type; | |
| 320 switch (AddTransforms( | 308 switch (AddTransforms( |
| 321 *type_to_convert, | 309 *type_to_convert, |
| 322 out_type_sets, | 310 out_type_sets, |
| 323 graph, | 311 graph, |
| 324 &out, | 312 &out, |
| 325 &converted_type)) { | 313 &converted_type)) { |
| 326 case AddResult::kFailed: | 314 case AddResult::kFailed: |
| 327 // Failed to find a suitable conversion. Return the pipeline to its | 315 // Failed to find a suitable conversion. Return the pipeline to its |
| 328 // original state. | 316 // original state. |
| 329 graph->RemovePartsConnectedToOutput(*output); | 317 graph->RemovePartsConnectedToOutput(*output); |
| 330 *out_type = nullptr; | 318 *out_type = nullptr; |
| 331 return false; | 319 return false; |
| 332 case AddResult::kProgressed: | 320 case AddResult::kProgressed: |
| 333 // Made progress. Continue. | 321 // Made progress. Continue. |
| 334 break; | 322 break; |
| 335 case AddResult::kFinished: | 323 case AddResult::kFinished: |
| 336 // No further conversion required. | 324 // No further conversion required. |
| 337 *output = out; | 325 *output = out; |
| 338 *out_type = std::move(converted_type); | 326 *out_type = std::move(converted_type); |
| 339 return true; | 327 return true; |
| 340 } | 328 } |
| 341 | 329 |
| 342 next_in_type = std::move(converted_type); | 330 type_to_convert = converted_type.get(); |
| 343 type_to_convert = &next_in_type; | |
| 344 } | 331 } |
| 345 } | 332 } |
| 346 | 333 |
| 347 } // namespace media | 334 } // namespace media |
| 348 } // namespace mojo | 335 } // namespace mojo |
| OLD | NEW |