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