1 /* 2 * Copyright (c) 2011 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 11 #ifndef TEST_TESTSUPPORT_FRAME_READER_H_ 12 #define TEST_TESTSUPPORT_FRAME_READER_H_ 13 14 #include <stdio.h> 15 16 #include <string> 17 18 #include "absl/types/optional.h" 19 #include "api/scoped_refptr.h" 20 21 namespace webrtc { 22 class I420Buffer; 23 namespace test { 24 25 // Handles reading of I420 frames from video files. 26 class FrameReader { 27 public: ~FrameReader()28 virtual ~FrameReader() {} 29 30 // Initializes the frame reader, i.e. opens the input file. 31 // This must be called before reading of frames has started. 32 // Returns false if an error has occurred, in addition to printing to stderr. 33 virtual bool Init() = 0; 34 35 // Reads a frame from the input file. On success, returns the frame. 36 // Returns nullptr if encountering end of file or a read error. 37 virtual rtc::scoped_refptr<I420Buffer> ReadFrame() = 0; 38 39 // Closes the input file if open. Essentially makes this class impossible 40 // to use anymore. Will also be invoked by the destructor. 41 virtual void Close() = 0; 42 43 // Frame length in bytes of a single frame image. 44 virtual size_t FrameLength() = 0; 45 // Total number of frames in the input video source. 46 virtual int NumberOfFrames() = 0; 47 }; 48 49 class YuvFrameReaderImpl : public FrameReader { 50 public: 51 enum class RepeatMode { kSingle, kRepeat, kPingPong }; 52 class DropperUtil { 53 public: 54 DropperUtil(int source_fps, int target_fps); 55 56 enum class DropDecision { kDropframe, kKeepFrame }; 57 DropDecision UpdateLevel(); 58 59 private: 60 const double frame_size_buckets_; 61 double bucket_level_; 62 }; 63 64 // Creates a file handler. The input file is assumed to exist and be readable. 65 // Parameters: 66 // input_filename The file to read from. 67 // width, height Size of each frame to read. 68 YuvFrameReaderImpl(std::string input_filename, int width, int height); 69 YuvFrameReaderImpl(std::string input_filename, 70 int input_width, 71 int input_height, 72 int desired_width, 73 int desired_height, 74 RepeatMode repeat_mode, 75 absl::optional<int> clip_fps, 76 int target_fps); 77 ~YuvFrameReaderImpl() override; 78 bool Init() override; 79 rtc::scoped_refptr<I420Buffer> ReadFrame() override; 80 void Close() override; 81 size_t FrameLength() override; 82 int NumberOfFrames() override; 83 84 protected: 85 const std::string input_filename_; 86 // It is not const, so subclasses will be able to add frame header size. 87 size_t frame_length_in_bytes_; 88 const int input_width_; 89 const int input_height_; 90 const int desired_width_; 91 const int desired_height_; 92 const size_t frame_size_bytes_; 93 const RepeatMode repeat_mode_; 94 int number_of_frames_; 95 int current_frame_index_; 96 std::unique_ptr<DropperUtil> dropper_; 97 FILE* input_file_; 98 }; 99 100 class Y4mFrameReaderImpl : public YuvFrameReaderImpl { 101 public: 102 // Creates a file handler. The input file is assumed to exist and be readable. 103 // Parameters: 104 // input_filename The file to read from. 105 // width, height Size of each frame to read. 106 Y4mFrameReaderImpl(std::string input_filename, int width, int height); 107 ~Y4mFrameReaderImpl() override; 108 bool Init() override; 109 rtc::scoped_refptr<I420Buffer> ReadFrame() override; 110 111 private: 112 // Buffer that is used to read file and frame headers. 113 char* buffer_; 114 }; 115 116 } // namespace test 117 } // namespace webrtc 118 119 #endif // TEST_TESTSUPPORT_FRAME_READER_H_ 120