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