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