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