1 /* 2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #ifndef API_VIDEO_CODECS_VIDEO_ENCODER_FACTORY_H_ 12 #define API_VIDEO_CODECS_VIDEO_ENCODER_FACTORY_H_ 13 14 #include <memory> 15 #include <string> 16 #include <vector> 17 18 #include "absl/types/optional.h" 19 #include "api/units/data_rate.h" 20 #include "api/video/render_resolution.h" 21 #include "api/video_codecs/sdp_video_format.h" 22 23 namespace webrtc { 24 25 class VideoEncoder; 26 27 // A factory that creates VideoEncoders. 28 // NOTE: This class is still under development and may change without notice. 29 class VideoEncoderFactory { 30 public: 31 struct CodecSupport { 32 bool is_supported = false; 33 bool is_power_efficient = false; 34 }; 35 36 // An injectable class that is continuously updated with encoding conditions 37 // and selects the best encoder given those conditions. An implementation is 38 // typically stateful to avoid toggling between different encoders, which is 39 // costly due to recreation of objects, a new codec will always start with a 40 // key-frame. 41 class EncoderSelectorInterface { 42 public: ~EncoderSelectorInterface()43 virtual ~EncoderSelectorInterface() {} 44 45 // Informs the encoder selector about which encoder that is currently being 46 // used. 47 virtual void OnCurrentEncoder(const SdpVideoFormat& format) = 0; 48 49 // Called every time the available bitrate is updated. Should return a 50 // non-empty if an encoder switch should be performed. 51 virtual absl::optional<SdpVideoFormat> OnAvailableBitrate( 52 const DataRate& rate) = 0; 53 54 // Called every time the encoder input resolution change. Should return a 55 // non-empty if an encoder switch should be performed. OnResolutionChange(const RenderResolution & resolution)56 virtual absl::optional<SdpVideoFormat> OnResolutionChange( 57 const RenderResolution& resolution) { 58 return absl::nullopt; 59 } 60 61 // Called if the currently used encoder reports itself as broken. Should 62 // return a non-empty if an encoder switch should be performed. 63 virtual absl::optional<SdpVideoFormat> OnEncoderBroken() = 0; 64 }; 65 66 // Returns a list of supported video formats in order of preference, to use 67 // for signaling etc. 68 virtual std::vector<SdpVideoFormat> GetSupportedFormats() const = 0; 69 70 // Returns a list of supported video formats in order of preference, that can 71 // also be tagged with additional information to allow the VideoEncoderFactory 72 // to separate between different implementations when CreateVideoEncoder is 73 // called. GetImplementations()74 virtual std::vector<SdpVideoFormat> GetImplementations() const { 75 return GetSupportedFormats(); 76 } 77 78 // Query whether the specifed format is supported or not and if it will be 79 // power efficient, which is currently interpreted as if there is support for 80 // hardware acceleration. 81 // See https://w3c.github.io/webrtc-svc/#scalabilitymodes* for a specification 82 // of valid values for `scalability_mode`. 83 // NOTE: QueryCodecSupport is currently an experimental feature that is 84 // subject to change without notice. QueryCodecSupport(const SdpVideoFormat & format,absl::optional<std::string> scalability_mode)85 virtual CodecSupport QueryCodecSupport( 86 const SdpVideoFormat& format, 87 absl::optional<std::string> scalability_mode) const { 88 // Default implementation, query for supported formats and check if the 89 // specified format is supported. Returns false if scalability_mode is 90 // specified. 91 CodecSupport codec_support; 92 if (!scalability_mode) { 93 codec_support.is_supported = format.IsCodecInList(GetSupportedFormats()); 94 } 95 return codec_support; 96 } 97 98 // Creates a VideoEncoder for the specified format. 99 virtual std::unique_ptr<VideoEncoder> CreateVideoEncoder( 100 const SdpVideoFormat& format) = 0; 101 102 // This method creates a EncoderSelector to use for a VideoSendStream. 103 // (and hence should probably been called CreateEncoderSelector()). 104 // 105 // Note: This method is unsuitable if encoding several streams that 106 // are using same VideoEncoderFactory (either by several streams in one 107 // PeerConnection or streams with different PeerConnection but same 108 // PeerConnectionFactory). This is due to the fact that the method is not 109 // given any stream identifier, nor is the EncoderSelectorInterface given any 110 // stream identifiers, i.e one does not know which stream is being encoded 111 // with help of the selector. 112 // 113 // In such scenario, the `RtpSenderInterface::SetEncoderSelector` is 114 // recommended. 115 // 116 // TODO(bugs.webrtc.org:14122): Deprecate and remove in favor of 117 // `RtpSenderInterface::SetEncoderSelector`. GetEncoderSelector()118 virtual std::unique_ptr<EncoderSelectorInterface> GetEncoderSelector() const { 119 return nullptr; 120 } 121 ~VideoEncoderFactory()122 virtual ~VideoEncoderFactory() {} 123 }; 124 125 } // namespace webrtc 126 127 #endif // API_VIDEO_CODECS_VIDEO_ENCODER_FACTORY_H_ 128