xref: /aosp_15_r20/external/webrtc/test/frame_generator.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright (c) 2013 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 #ifndef TEST_FRAME_GENERATOR_H_
11 #define TEST_FRAME_GENERATOR_H_
12 
13 #include <memory>
14 #include <string>
15 #include <vector>
16 
17 #include "api/scoped_refptr.h"
18 #include "api/test/frame_generator_interface.h"
19 #include "api/video/i420_buffer.h"
20 #include "api/video/nv12_buffer.h"
21 #include "api/video/video_frame.h"
22 #include "api/video/video_frame_buffer.h"
23 #include "api/video/video_source_interface.h"
24 #include "rtc_base/logging.h"
25 #include "rtc_base/random.h"
26 #include "rtc_base/synchronization/mutex.h"
27 #include "system_wrappers/include/clock.h"
28 
29 namespace webrtc {
30 namespace test {
31 
32 // SquareGenerator is a FrameGenerator that draws a given amount of randomly
33 // sized and colored squares. Between each new generated frame, the squares
34 // are moved slightly towards the lower right corner.
35 class SquareGenerator : public FrameGeneratorInterface {
36  public:
37   SquareGenerator(int width, int height, OutputType type, int num_squares);
38 
39   void ChangeResolution(size_t width, size_t height) override;
40   VideoFrameData NextFrame() override;
41 
42  private:
43   rtc::scoped_refptr<I420Buffer> CreateI420Buffer(int width, int height);
44 
45   class Square {
46    public:
47     Square(int width, int height, int seed);
48 
49     void Draw(const rtc::scoped_refptr<VideoFrameBuffer>& frame_buffer);
50 
51    private:
52     Random random_generator_;
53     int x_;
54     int y_;
55     const int length_;
56     const uint8_t yuv_y_;
57     const uint8_t yuv_u_;
58     const uint8_t yuv_v_;
59     const uint8_t yuv_a_;
60   };
61 
62   Mutex mutex_;
63   const OutputType type_;
64   int width_ RTC_GUARDED_BY(&mutex_);
65   int height_ RTC_GUARDED_BY(&mutex_);
66   std::vector<std::unique_ptr<Square>> squares_ RTC_GUARDED_BY(&mutex_);
67 };
68 
69 class YuvFileGenerator : public FrameGeneratorInterface {
70  public:
71   YuvFileGenerator(std::vector<FILE*> files,
72                    size_t width,
73                    size_t height,
74                    int frame_repeat_count);
75 
76   ~YuvFileGenerator();
77 
78   VideoFrameData NextFrame() override;
ChangeResolution(size_t width,size_t height)79   void ChangeResolution(size_t width, size_t height) override {
80     RTC_LOG(LS_WARNING) << "YuvFileGenerator::ChangeResolution not implemented";
81   }
82 
83  private:
84   // Returns true if the new frame was loaded.
85   // False only in case of a single file with a single frame in it.
86   bool ReadNextFrame();
87 
88   size_t file_index_;
89   size_t frame_index_;
90   const std::vector<FILE*> files_;
91   const size_t width_;
92   const size_t height_;
93   const size_t frame_size_;
94   const std::unique_ptr<uint8_t[]> frame_buffer_;
95   const int frame_display_count_;
96   int current_display_count_;
97   rtc::scoped_refptr<I420Buffer> last_read_buffer_;
98 };
99 
100 class NV12FileGenerator : public FrameGeneratorInterface {
101  public:
102   NV12FileGenerator(std::vector<FILE*> files,
103                     size_t width,
104                     size_t height,
105                     int frame_repeat_count);
106 
107   ~NV12FileGenerator();
108 
109   VideoFrameData NextFrame() override;
ChangeResolution(size_t width,size_t height)110   void ChangeResolution(size_t width, size_t height) override {
111     RTC_LOG(LS_WARNING)
112         << "NV12FileGenerator::ChangeResolution not implemented";
113   }
114 
115  private:
116   // Returns true if the new frame was loaded.
117   // False only in case of a single file with a single frame in it.
118   bool ReadNextFrame();
119 
120   size_t file_index_;
121   size_t frame_index_;
122   const std::vector<FILE*> files_;
123   const size_t width_;
124   const size_t height_;
125   const size_t frame_size_;
126   const std::unique_ptr<uint8_t[]> frame_buffer_;
127   const int frame_display_count_;
128   int current_display_count_;
129   rtc::scoped_refptr<NV12Buffer> last_read_buffer_;
130 };
131 
132 // SlideGenerator works similarly to YuvFileGenerator but it fills the frames
133 // with randomly sized and colored squares instead of reading their content
134 // from files.
135 class SlideGenerator : public FrameGeneratorInterface {
136  public:
137   SlideGenerator(int width, int height, int frame_repeat_count);
138 
139   VideoFrameData NextFrame() override;
ChangeResolution(size_t width,size_t height)140   void ChangeResolution(size_t width, size_t height) override {
141     RTC_LOG(LS_WARNING) << "SlideGenerator::ChangeResolution not implemented";
142   }
143 
144  private:
145   // Generates some randomly sized and colored squares scattered
146   // over the frame.
147   void GenerateNewFrame();
148 
149   const int width_;
150   const int height_;
151   const int frame_display_count_;
152   int current_display_count_;
153   Random random_generator_;
154   rtc::scoped_refptr<I420Buffer> buffer_;
155 };
156 
157 class ScrollingImageFrameGenerator : public FrameGeneratorInterface {
158  public:
159   ScrollingImageFrameGenerator(Clock* clock,
160                                const std::vector<FILE*>& files,
161                                size_t source_width,
162                                size_t source_height,
163                                size_t target_width,
164                                size_t target_height,
165                                int64_t scroll_time_ms,
166                                int64_t pause_time_ms);
167   ~ScrollingImageFrameGenerator() override = default;
168 
169   VideoFrameData NextFrame() override;
ChangeResolution(size_t width,size_t height)170   void ChangeResolution(size_t width, size_t height) override {
171     RTC_LOG(LS_WARNING)
172         << "ScrollingImageFrameGenerator::ChangeResolution not implemented";
173   }
174 
175  private:
176   void UpdateSourceFrame(size_t frame_num);
177   void CropSourceToScrolledImage(double scroll_factor);
178 
179   Clock* const clock_;
180   const int64_t start_time_;
181   const int64_t scroll_time_;
182   const int64_t pause_time_;
183   const size_t num_frames_;
184   const int target_width_;
185   const int target_height_;
186 
187   size_t current_frame_num_;
188   bool prev_frame_not_scrolled_;
189   VideoFrameData current_source_frame_;
190   VideoFrameData current_frame_;
191   YuvFileGenerator file_generator_;
192 };
193 
194 }  // namespace test
195 }  // namespace webrtc
196 
197 #endif  // TEST_FRAME_GENERATOR_H_
198