/* * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #ifndef API_VIDEO_CODECS_VIDEO_DECODER_FACTORY_TEMPLATE_H_ #define API_VIDEO_CODECS_VIDEO_DECODER_FACTORY_TEMPLATE_H_ #include #include #include "absl/algorithm/container.h" #include "api/array_view.h" #include "api/video_codecs/video_decoder.h" #include "api/video_codecs/video_decoder_factory.h" namespace webrtc { // The VideoDecoderFactoryTemplate supports decoder implementations given as // template arguments. // // To include a decoder in the factory it requires two static members // functions to be defined: // // // Returns the supported SdpVideoFormats this decoder can decode. // static std::vector SupportedFormats(); // // // Creates a decoder instance for the given format. // static std::unique_ptr // CreateDecoder(const SdpVideoFormat& format); // // Note that the order of the template arguments matter as the factory will // return the first decoder implementation supporting the given SdpVideoFormat. template class VideoDecoderFactoryTemplate : public VideoDecoderFactory { public: std::vector GetSupportedFormats() const override { return GetSupportedFormatsInternal(); } std::unique_ptr CreateVideoDecoder( const SdpVideoFormat& format) override { return CreateVideoDecoderInternal(format); } private: bool IsFormatInList( const SdpVideoFormat& format, rtc::ArrayView supported_formats) const { return absl::c_any_of( supported_formats, [&](const SdpVideoFormat& supported_format) { return supported_format.name == format.name && supported_format.parameters == format.parameters; }); } template std::vector GetSupportedFormatsInternal() const { auto supported_formats = V::SupportedFormats(); if constexpr (sizeof...(Vs) > 0) { // Supported formats may overlap between implementations, so duplicates // should be filtered out. for (const auto& other_format : GetSupportedFormatsInternal()) { if (!IsFormatInList(other_format, supported_formats)) { supported_formats.push_back(other_format); } } } return supported_formats; } template std::unique_ptr CreateVideoDecoderInternal( const SdpVideoFormat& format) { if (IsFormatInList(format, V::SupportedFormats())) { return V::CreateDecoder(format); } if constexpr (sizeof...(Vs) > 0) { return CreateVideoDecoderInternal(format); } return nullptr; } }; } // namespace webrtc #endif // API_VIDEO_CODECS_VIDEO_DECODER_FACTORY_TEMPLATE_H_