| // Copyright 2016 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "src/media/playback/mediaplayer/decode/decoder.h" |
| |
| #include <vector> |
| |
| #include "src/media/playback/mediaplayer/ffmpeg/ffmpeg_decoder_factory.h" |
| #include "src/media/playback/mediaplayer/fidl/fidl_decoder_factory.h" |
| |
| namespace media_player { |
| namespace { |
| |
| // A docoder factory that polls other decoder factories. |
| class CompositeDecoderFactory : public DecoderFactory { |
| public: |
| // Creates a composite decoder factory. |
| static std::unique_ptr<CompositeDecoderFactory> Create(); |
| |
| CompositeDecoderFactory(); |
| |
| ~CompositeDecoderFactory() override; |
| |
| // Adds a child factory. Child factories are polled in the order they're |
| // added. Calls to this method are not permitted when a |CreateDecoder| |
| // operation is underway. |
| void AddFactory(std::unique_ptr<DecoderFactory> factory); |
| |
| // DecoderFactory implementation. |
| void CreateDecoder( |
| const StreamType& stream_type, |
| fit::function<void(std::shared_ptr<Decoder>)> callback) override; |
| |
| private: |
| void ContinueCreateDecoder( |
| std::vector<std::unique_ptr<DecoderFactory>>::iterator iter, |
| const StreamType& stream_type, |
| fit::function<void(std::shared_ptr<Decoder>)> callback); |
| |
| std::vector<std::unique_ptr<DecoderFactory>> children_; |
| }; |
| |
| // static |
| std::unique_ptr<CompositeDecoderFactory> CompositeDecoderFactory::Create() { |
| return std::make_unique<CompositeDecoderFactory>(); |
| } |
| |
| CompositeDecoderFactory::CompositeDecoderFactory() {} |
| |
| CompositeDecoderFactory::~CompositeDecoderFactory() {} |
| |
| void CompositeDecoderFactory::AddFactory( |
| std::unique_ptr<DecoderFactory> factory) { |
| children_.push_back(std::move(factory)); |
| } |
| |
| void CompositeDecoderFactory::CreateDecoder( |
| const StreamType& stream_type, |
| fit::function<void(std::shared_ptr<Decoder>)> callback) { |
| FXL_DCHECK(callback); |
| |
| ContinueCreateDecoder(children_.begin(), stream_type, std::move(callback)); |
| } |
| |
| void CompositeDecoderFactory::ContinueCreateDecoder( |
| std::vector<std::unique_ptr<DecoderFactory>>::iterator iter, |
| const StreamType& stream_type, |
| fit::function<void(std::shared_ptr<Decoder>)> callback) { |
| FXL_DCHECK(callback); |
| |
| if (iter == children_.end()) { |
| callback(nullptr); |
| return; |
| } |
| |
| FXL_DCHECK(*iter); |
| |
| (*iter)->CreateDecoder( |
| stream_type, [this, iter, &stream_type, callback = std::move(callback)]( |
| std::shared_ptr<Decoder> decoder) mutable { |
| if (decoder) { |
| callback(decoder); |
| return; |
| } |
| |
| ContinueCreateDecoder(++iter, stream_type, std::move(callback)); |
| }); |
| } |
| |
| } // namespace |
| |
| std::unique_ptr<DecoderFactory> DecoderFactory::Create( |
| component::StartupContext* startup_context) { |
| auto parent_factory = CompositeDecoderFactory::Create(); |
| parent_factory->AddFactory(FidlDecoderFactory::Create(startup_context)); |
| parent_factory->AddFactory(FfmpegDecoderFactory::Create(startup_context)); |
| return parent_factory; |
| } |
| |
| } // namespace media_player |