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