video_source_interface.h (5763B)
1 /* 2 * Copyright (c) 2016 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_VIDEO_SOURCE_INTERFACE_H_ 12 #define API_VIDEO_VIDEO_SOURCE_INTERFACE_H_ 13 14 #include <limits> 15 #include <optional> 16 #include <vector> 17 18 #include "api/video/video_sink_interface.h" 19 #include "rtc_base/system/rtc_export.h" 20 21 namespace webrtc { 22 23 // VideoSinkWants is used for notifying the source of properties a video frame 24 // should have when it is delivered to a certain sink. 25 struct RTC_EXPORT VideoSinkWants { 26 struct FrameSize { 27 FrameSize(int width, int height) : width(width), height(height) {} 28 FrameSize(const FrameSize&) = default; 29 ~FrameSize() = default; 30 31 int width; 32 int height; 33 }; 34 35 VideoSinkWants(); 36 VideoSinkWants(const VideoSinkWants&); 37 ~VideoSinkWants(); 38 39 // Tells the source whether the sink wants frames with rotation applied. 40 // By default, any rotation must be applied by the sink. 41 bool rotation_applied = false; 42 43 // Tells the source that the sink only wants black frames. 44 bool black_frames = false; 45 46 // Tells the source the maximum number of pixels the sink wants. 47 int max_pixel_count = std::numeric_limits<int>::max(); 48 // Tells the source the desired number of pixels the sinks wants. This will 49 // typically be used when stepping the resolution up again when conditions 50 // have improved after an earlier downgrade. The source should select the 51 // closest resolution to this pixel count, but if max_pixel_count is set, it 52 // still sets the absolute upper bound. 53 std::optional<int> target_pixel_count; 54 // Tells the source the maximum framerate the sink wants. 55 int max_framerate_fps = std::numeric_limits<int>::max(); 56 57 // Tells the source that the sink wants width and height of the video frames 58 // to be divisible by `resolution_alignment`. 59 // For example: With I420, this value would be a multiple of 2. 60 // Note that this field is unrelated to any horizontal or vertical stride 61 // requirements the encoder has on the incoming video frame buffers. 62 int resolution_alignment = 1; 63 64 // The resolutions that sink is configured to consume. If the sink is an 65 // encoder this is what the encoder is configured to encode. In singlecast we 66 // only encode one resolution, but in simulcast and SVC this can mean multiple 67 // resolutions per frame. 68 // 69 // The sink is always configured to consume a subset of the 70 // VideoFrame's resolution. In the case of encoding, we usually encode 71 // at VideoFrame's resolution but this may not always be the case due 72 // to scaleResolutionDownBy or turning off simulcast or SVC layers. 73 // 74 // For example, we may capture at 720p and due to adaptation (e.g. applying 75 // `max_pixel_count` constraints) create VideoFrames of size 480p, but 76 // if we do scaleResolutionDownBy:2 then the only resolution we end up 77 // encoding is 240p. In this case we still need to provide VideoFrames 78 // of size 480p but we can optimize internal buffers for 240p, avoiding 79 // downsampling to 480p if possible. 80 // 81 // Note that the `resolutions` can change while frames are in flight and 82 // should only be used as a hint when constructing the VideoFrame. 83 std::vector<FrameSize> resolutions; 84 85 // This is the resolution requested by the user using RtpEncodingParameters, 86 // which is the maximum `scale_resolution_down_by` value of any encoding. 87 std::optional<FrameSize> requested_resolution; 88 89 // `is_active` : Is this VideoSinkWants from an encoder that is encoding any 90 // layer. IF YES, it will affect how the VideoAdapter will choose to 91 // prioritize the OnOutputFormatRequest vs. requested_resolution. IF NO, 92 // VideoAdapter consider this VideoSinkWants as a passive listener (e.g a 93 // VideoRenderer or a VideoEncoder that is not currently actively encoding). 94 bool is_active = false; 95 96 // This sub-struct contains information computed by VideoBroadcaster 97 // that aggregates several VideoSinkWants (and sends them to 98 // AdaptedVideoTrackSource). 99 struct Aggregates { 100 // `any_active_without_requested_resolution` is set by VideoBroadcaster 101 // when aggregating sink wants if there exists any sink (encoder) that is 102 // active but has not set the `requested_resolution`, i.e is relying on 103 // OnOutputFormatRequest to handle encode resolution. 104 bool any_active_without_requested_resolution = false; 105 }; 106 std::optional<Aggregates> aggregates; 107 }; 108 109 inline bool operator==(const VideoSinkWants::FrameSize& a, 110 const VideoSinkWants::FrameSize& b) { 111 return a.width == b.width && a.height == b.height; 112 } 113 114 inline bool operator!=(const VideoSinkWants::FrameSize& a, 115 const VideoSinkWants::FrameSize& b) { 116 return !(a == b); 117 } 118 119 template <typename VideoFrameT> 120 class VideoSourceInterface { 121 public: 122 virtual ~VideoSourceInterface() = default; 123 124 virtual void AddOrUpdateSink(VideoSinkInterface<VideoFrameT>* sink, 125 const VideoSinkWants& wants) = 0; 126 // RemoveSink must guarantee that at the time the method returns, 127 // there is no current and no future calls to VideoSinkInterface::OnFrame. 128 virtual void RemoveSink(VideoSinkInterface<VideoFrameT>* sink) = 0; 129 130 // Request underlying source to capture a new frame. 131 // TODO(crbug/1255737): make pure virtual once downstream projects adapt. 132 virtual void RequestRefreshFrame() {} 133 }; 134 135 } // namespace webrtc 136 137 #endif // API_VIDEO_VIDEO_SOURCE_INTERFACE_H_