xref: /aosp_15_r20/external/webrtc/test/frame_generator_capturer.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright (c) 2013 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 #ifndef TEST_FRAME_GENERATOR_CAPTURER_H_
11*d9f75844SAndroid Build Coastguard Worker #define TEST_FRAME_GENERATOR_CAPTURER_H_
12*d9f75844SAndroid Build Coastguard Worker 
13*d9f75844SAndroid Build Coastguard Worker #include <memory>
14*d9f75844SAndroid Build Coastguard Worker #include <string>
15*d9f75844SAndroid Build Coastguard Worker 
16*d9f75844SAndroid Build Coastguard Worker #include "api/task_queue/task_queue_factory.h"
17*d9f75844SAndroid Build Coastguard Worker #include "api/test/frame_generator_interface.h"
18*d9f75844SAndroid Build Coastguard Worker #include "api/video/video_frame.h"
19*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/synchronization/mutex.h"
20*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/task_queue.h"
21*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/task_utils/repeating_task.h"
22*d9f75844SAndroid Build Coastguard Worker #include "system_wrappers/include/clock.h"
23*d9f75844SAndroid Build Coastguard Worker #include "test/test_video_capturer.h"
24*d9f75844SAndroid Build Coastguard Worker 
25*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
26*d9f75844SAndroid Build Coastguard Worker 
27*d9f75844SAndroid Build Coastguard Worker namespace test {
28*d9f75844SAndroid Build Coastguard Worker namespace frame_gen_cap_impl {
29*d9f75844SAndroid Build Coastguard Worker template <typename T>
30*d9f75844SAndroid Build Coastguard Worker class AutoOpt : public absl::optional<T> {
31*d9f75844SAndroid Build Coastguard Worker  public:
32*d9f75844SAndroid Build Coastguard Worker   using absl::optional<T>::optional;
33*d9f75844SAndroid Build Coastguard Worker   T* operator->() {
34*d9f75844SAndroid Build Coastguard Worker     if (!absl::optional<T>::has_value())
35*d9f75844SAndroid Build Coastguard Worker       this->emplace(T());
36*d9f75844SAndroid Build Coastguard Worker     return absl::optional<T>::operator->();
37*d9f75844SAndroid Build Coastguard Worker   }
38*d9f75844SAndroid Build Coastguard Worker };
39*d9f75844SAndroid Build Coastguard Worker }  // namespace frame_gen_cap_impl
40*d9f75844SAndroid Build Coastguard Worker struct FrameGeneratorCapturerConfig {
41*d9f75844SAndroid Build Coastguard Worker   struct SquaresVideo {
42*d9f75844SAndroid Build Coastguard Worker     int framerate = 30;
43*d9f75844SAndroid Build Coastguard Worker     FrameGeneratorInterface::OutputType pixel_format =
44*d9f75844SAndroid Build Coastguard Worker         FrameGeneratorInterface::OutputType::kI420;
45*d9f75844SAndroid Build Coastguard Worker     int width = 320;
46*d9f75844SAndroid Build Coastguard Worker     int height = 180;
47*d9f75844SAndroid Build Coastguard Worker     int num_squares = 10;
48*d9f75844SAndroid Build Coastguard Worker   };
49*d9f75844SAndroid Build Coastguard Worker 
50*d9f75844SAndroid Build Coastguard Worker   struct SquareSlides {
51*d9f75844SAndroid Build Coastguard Worker     int framerate = 30;
52*d9f75844SAndroid Build Coastguard Worker     TimeDelta change_interval = TimeDelta::Seconds(10);
53*d9f75844SAndroid Build Coastguard Worker     int width = 1600;
54*d9f75844SAndroid Build Coastguard Worker     int height = 1200;
55*d9f75844SAndroid Build Coastguard Worker   };
56*d9f75844SAndroid Build Coastguard Worker 
57*d9f75844SAndroid Build Coastguard Worker   struct VideoFile {
58*d9f75844SAndroid Build Coastguard Worker     int framerate = 30;
59*d9f75844SAndroid Build Coastguard Worker     std::string name;
60*d9f75844SAndroid Build Coastguard Worker     // Must be set to width and height of the source video file.
61*d9f75844SAndroid Build Coastguard Worker     int width = 0;
62*d9f75844SAndroid Build Coastguard Worker     int height = 0;
63*d9f75844SAndroid Build Coastguard Worker   };
64*d9f75844SAndroid Build Coastguard Worker 
65*d9f75844SAndroid Build Coastguard Worker   struct ImageSlides {
66*d9f75844SAndroid Build Coastguard Worker     int framerate = 30;
67*d9f75844SAndroid Build Coastguard Worker     TimeDelta change_interval = TimeDelta::Seconds(10);
68*d9f75844SAndroid Build Coastguard Worker     struct Crop {
69*d9f75844SAndroid Build Coastguard Worker       TimeDelta scroll_duration = TimeDelta::Seconds(0);
70*d9f75844SAndroid Build Coastguard Worker       absl::optional<int> width;
71*d9f75844SAndroid Build Coastguard Worker       absl::optional<int> height;
72*d9f75844SAndroid Build Coastguard Worker     } crop;
73*d9f75844SAndroid Build Coastguard Worker     int width = 1850;
74*d9f75844SAndroid Build Coastguard Worker     int height = 1110;
75*d9f75844SAndroid Build Coastguard Worker     std::vector<std::string> paths = {
76*d9f75844SAndroid Build Coastguard Worker         "web_screenshot_1850_1110",
77*d9f75844SAndroid Build Coastguard Worker         "presentation_1850_1110",
78*d9f75844SAndroid Build Coastguard Worker         "photo_1850_1110",
79*d9f75844SAndroid Build Coastguard Worker         "difficult_photo_1850_1110",
80*d9f75844SAndroid Build Coastguard Worker     };
81*d9f75844SAndroid Build Coastguard Worker   };
82*d9f75844SAndroid Build Coastguard Worker 
83*d9f75844SAndroid Build Coastguard Worker   frame_gen_cap_impl::AutoOpt<SquaresVideo> squares_video;
84*d9f75844SAndroid Build Coastguard Worker   frame_gen_cap_impl::AutoOpt<SquareSlides> squares_slides;
85*d9f75844SAndroid Build Coastguard Worker   frame_gen_cap_impl::AutoOpt<VideoFile> video_file;
86*d9f75844SAndroid Build Coastguard Worker   frame_gen_cap_impl::AutoOpt<ImageSlides> image_slides;
87*d9f75844SAndroid Build Coastguard Worker };
88*d9f75844SAndroid Build Coastguard Worker 
89*d9f75844SAndroid Build Coastguard Worker class FrameGeneratorCapturer : public TestVideoCapturer {
90*d9f75844SAndroid Build Coastguard Worker  public:
91*d9f75844SAndroid Build Coastguard Worker   class SinkWantsObserver {
92*d9f75844SAndroid Build Coastguard Worker    public:
93*d9f75844SAndroid Build Coastguard Worker     // OnSinkWantsChanged is called when FrameGeneratorCapturer::AddOrUpdateSink
94*d9f75844SAndroid Build Coastguard Worker     // is called.
95*d9f75844SAndroid Build Coastguard Worker     virtual void OnSinkWantsChanged(rtc::VideoSinkInterface<VideoFrame>* sink,
96*d9f75844SAndroid Build Coastguard Worker                                     const rtc::VideoSinkWants& wants) = 0;
97*d9f75844SAndroid Build Coastguard Worker 
98*d9f75844SAndroid Build Coastguard Worker    protected:
~SinkWantsObserver()99*d9f75844SAndroid Build Coastguard Worker     virtual ~SinkWantsObserver() {}
100*d9f75844SAndroid Build Coastguard Worker   };
101*d9f75844SAndroid Build Coastguard Worker 
102*d9f75844SAndroid Build Coastguard Worker   FrameGeneratorCapturer(
103*d9f75844SAndroid Build Coastguard Worker       Clock* clock,
104*d9f75844SAndroid Build Coastguard Worker       std::unique_ptr<FrameGeneratorInterface> frame_generator,
105*d9f75844SAndroid Build Coastguard Worker       int target_fps,
106*d9f75844SAndroid Build Coastguard Worker       TaskQueueFactory& task_queue_factory);
107*d9f75844SAndroid Build Coastguard Worker   virtual ~FrameGeneratorCapturer();
108*d9f75844SAndroid Build Coastguard Worker 
109*d9f75844SAndroid Build Coastguard Worker   static std::unique_ptr<FrameGeneratorCapturer> Create(
110*d9f75844SAndroid Build Coastguard Worker       Clock* clock,
111*d9f75844SAndroid Build Coastguard Worker       TaskQueueFactory& task_queue_factory,
112*d9f75844SAndroid Build Coastguard Worker       FrameGeneratorCapturerConfig::SquaresVideo config);
113*d9f75844SAndroid Build Coastguard Worker   static std::unique_ptr<FrameGeneratorCapturer> Create(
114*d9f75844SAndroid Build Coastguard Worker       Clock* clock,
115*d9f75844SAndroid Build Coastguard Worker       TaskQueueFactory& task_queue_factory,
116*d9f75844SAndroid Build Coastguard Worker       FrameGeneratorCapturerConfig::SquareSlides config);
117*d9f75844SAndroid Build Coastguard Worker   static std::unique_ptr<FrameGeneratorCapturer> Create(
118*d9f75844SAndroid Build Coastguard Worker       Clock* clock,
119*d9f75844SAndroid Build Coastguard Worker       TaskQueueFactory& task_queue_factory,
120*d9f75844SAndroid Build Coastguard Worker       FrameGeneratorCapturerConfig::VideoFile config);
121*d9f75844SAndroid Build Coastguard Worker   static std::unique_ptr<FrameGeneratorCapturer> Create(
122*d9f75844SAndroid Build Coastguard Worker       Clock* clock,
123*d9f75844SAndroid Build Coastguard Worker       TaskQueueFactory& task_queue_factory,
124*d9f75844SAndroid Build Coastguard Worker       FrameGeneratorCapturerConfig::ImageSlides config);
125*d9f75844SAndroid Build Coastguard Worker   static std::unique_ptr<FrameGeneratorCapturer> Create(
126*d9f75844SAndroid Build Coastguard Worker       Clock* clock,
127*d9f75844SAndroid Build Coastguard Worker       TaskQueueFactory& task_queue_factory,
128*d9f75844SAndroid Build Coastguard Worker       const FrameGeneratorCapturerConfig& config);
129*d9f75844SAndroid Build Coastguard Worker 
130*d9f75844SAndroid Build Coastguard Worker   void Start();
131*d9f75844SAndroid Build Coastguard Worker   void Stop();
132*d9f75844SAndroid Build Coastguard Worker   void ChangeResolution(size_t width, size_t height);
133*d9f75844SAndroid Build Coastguard Worker   void ChangeFramerate(int target_framerate);
134*d9f75844SAndroid Build Coastguard Worker 
135*d9f75844SAndroid Build Coastguard Worker   struct Resolution {
136*d9f75844SAndroid Build Coastguard Worker     int width;
137*d9f75844SAndroid Build Coastguard Worker     int height;
138*d9f75844SAndroid Build Coastguard Worker   };
139*d9f75844SAndroid Build Coastguard Worker   absl::optional<Resolution> GetResolution();
140*d9f75844SAndroid Build Coastguard Worker 
141*d9f75844SAndroid Build Coastguard Worker   void OnOutputFormatRequest(int width,
142*d9f75844SAndroid Build Coastguard Worker                              int height,
143*d9f75844SAndroid Build Coastguard Worker                              const absl::optional<int>& max_fps);
144*d9f75844SAndroid Build Coastguard Worker 
145*d9f75844SAndroid Build Coastguard Worker   void SetSinkWantsObserver(SinkWantsObserver* observer);
146*d9f75844SAndroid Build Coastguard Worker 
147*d9f75844SAndroid Build Coastguard Worker   void AddOrUpdateSink(rtc::VideoSinkInterface<VideoFrame>* sink,
148*d9f75844SAndroid Build Coastguard Worker                        const rtc::VideoSinkWants& wants) override;
149*d9f75844SAndroid Build Coastguard Worker   void RemoveSink(rtc::VideoSinkInterface<VideoFrame>* sink) override;
150*d9f75844SAndroid Build Coastguard Worker 
151*d9f75844SAndroid Build Coastguard Worker   void ForceFrame();
152*d9f75844SAndroid Build Coastguard Worker   void SetFakeRotation(VideoRotation rotation);
153*d9f75844SAndroid Build Coastguard Worker   void SetFakeColorSpace(absl::optional<ColorSpace> color_space);
154*d9f75844SAndroid Build Coastguard Worker 
first_frame_capture_time()155*d9f75844SAndroid Build Coastguard Worker   int64_t first_frame_capture_time() const { return first_frame_capture_time_; }
156*d9f75844SAndroid Build Coastguard Worker 
157*d9f75844SAndroid Build Coastguard Worker   bool Init();
158*d9f75844SAndroid Build Coastguard Worker 
159*d9f75844SAndroid Build Coastguard Worker  private:
160*d9f75844SAndroid Build Coastguard Worker   void InsertFrame();
161*d9f75844SAndroid Build Coastguard Worker   static bool Run(void* obj);
162*d9f75844SAndroid Build Coastguard Worker   int GetCurrentConfiguredFramerate();
163*d9f75844SAndroid Build Coastguard Worker   void UpdateFps(int max_fps) RTC_EXCLUSIVE_LOCKS_REQUIRED(&lock_);
164*d9f75844SAndroid Build Coastguard Worker 
165*d9f75844SAndroid Build Coastguard Worker   Clock* const clock_;
166*d9f75844SAndroid Build Coastguard Worker   RepeatingTaskHandle frame_task_;
167*d9f75844SAndroid Build Coastguard Worker   bool sending_;
168*d9f75844SAndroid Build Coastguard Worker   SinkWantsObserver* sink_wants_observer_ RTC_GUARDED_BY(&lock_);
169*d9f75844SAndroid Build Coastguard Worker 
170*d9f75844SAndroid Build Coastguard Worker   Mutex lock_;
171*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<FrameGeneratorInterface> frame_generator_;
172*d9f75844SAndroid Build Coastguard Worker 
173*d9f75844SAndroid Build Coastguard Worker   int source_fps_ RTC_GUARDED_BY(&lock_);
174*d9f75844SAndroid Build Coastguard Worker   int target_capture_fps_ RTC_GUARDED_BY(&lock_);
175*d9f75844SAndroid Build Coastguard Worker   absl::optional<int> wanted_fps_ RTC_GUARDED_BY(&lock_);
176*d9f75844SAndroid Build Coastguard Worker   VideoRotation fake_rotation_ = kVideoRotation_0;
177*d9f75844SAndroid Build Coastguard Worker   absl::optional<ColorSpace> fake_color_space_ RTC_GUARDED_BY(&lock_);
178*d9f75844SAndroid Build Coastguard Worker 
179*d9f75844SAndroid Build Coastguard Worker   int64_t first_frame_capture_time_;
180*d9f75844SAndroid Build Coastguard Worker 
181*d9f75844SAndroid Build Coastguard Worker   Mutex stats_lock_;
182*d9f75844SAndroid Build Coastguard Worker   absl::optional<Resolution> source_resolution_ RTC_GUARDED_BY(&stats_lock_);
183*d9f75844SAndroid Build Coastguard Worker 
184*d9f75844SAndroid Build Coastguard Worker   // Must be the last field, so it will be deconstructed first as tasks
185*d9f75844SAndroid Build Coastguard Worker   // in the TaskQueue access other fields of the instance of this class.
186*d9f75844SAndroid Build Coastguard Worker   rtc::TaskQueue task_queue_;
187*d9f75844SAndroid Build Coastguard Worker };
188*d9f75844SAndroid Build Coastguard Worker }  // namespace test
189*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc
190*d9f75844SAndroid Build Coastguard Worker 
191*d9f75844SAndroid Build Coastguard Worker #endif  // TEST_FRAME_GENERATOR_CAPTURER_H_
192