1 // Copyright 2018 The Chromium OS Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef C2_E2E_TEST_COMMON_H_ 6 #define C2_E2E_TEST_COMMON_H_ 7 8 #include <fstream> 9 #include <ios> 10 #include <memory> 11 #include <string> 12 #include <vector> 13 14 namespace android { 15 16 // The enumeration of video codec profile. This would be better to align with 17 // VideoCodecProfile enum in Chromium so we could use the identical test stream 18 // data arguments for both ARC end-to-end and Chromium tests. 19 enum VideoCodecProfile { 20 VIDEO_CODEC_PROFILE_UNKNOWN = -1, 21 VIDEO_CODEC_PROFILE_MIN = VIDEO_CODEC_PROFILE_UNKNOWN, 22 H264PROFILE_MIN = 0, 23 H264PROFILE_BASELINE = H264PROFILE_MIN, 24 H264PROFILE_MAIN = 1, 25 H264PROFILE_EXTENDED = 2, 26 H264PROFILE_HIGH = 3, 27 H264PROFILE_HIGH10PROFILE = 4, 28 H264PROFILE_HIGH422PROFILE = 5, 29 H264PROFILE_HIGH444PREDICTIVEPROFILE = 6, 30 H264PROFILE_SCALABLEBASELINE = 7, 31 H264PROFILE_SCALABLEHIGH = 8, 32 H264PROFILE_STEREOHIGH = 9, 33 H264PROFILE_MULTIVIEWHIGH = 10, 34 H264PROFILE_MAX = H264PROFILE_MULTIVIEWHIGH, 35 VP8PROFILE_MIN = 11, 36 VP8PROFILE_ANY = VP8PROFILE_MIN, 37 VP8PROFILE_MAX = VP8PROFILE_ANY, 38 VP9PROFILE_MIN = 12, 39 VP9PROFILE_PROFILE0 = VP9PROFILE_MIN, 40 VP9PROFILE_PROFILE1 = 13, 41 VP9PROFILE_PROFILE2 = 14, 42 VP9PROFILE_PROFILE3 = 15, 43 VP9PROFILE_MAX = VP9PROFILE_PROFILE3, 44 }; 45 46 // The enum class of video codec type. 47 enum class VideoCodecType { 48 UNKNOWN, 49 H264, 50 VP8, 51 VP9, 52 }; 53 54 // Structure to store resolution. 55 struct Size { SizeSize56 Size() : width(0), height(0) {} SizeSize57 Size(int w, int h) : width(w), height(h) {} IsEmptySize58 bool IsEmpty() const { return width <= 0 || height <= 0; } 59 60 int width; 61 int height; 62 }; 63 64 class InputFile { 65 public: 66 explicit InputFile(std::string file_path); 67 InputFile(std::string file_path, std::ios_base::openmode openmode); 68 69 // Check if the file is valid. 70 bool IsValid() const; 71 // Get the size of the file. 72 size_t GetLength(); 73 // Set position to the beginning of the file. 74 virtual void Rewind(); 75 76 protected: 77 std::ifstream file_; 78 }; 79 80 // Wrapper of std::ifstream for reading binary file. 81 class CachedInputFileStream : public InputFile { 82 public: 83 explicit CachedInputFileStream(std::string file_path); 84 85 // Read the given number of bytes to the buffer. Return the number of bytes 86 // read or -1 on error. 87 size_t Read(char* buffer, size_t size); 88 89 void Rewind() override; 90 91 private: 92 std::vector<char> data_; 93 size_t position_ = 0; 94 }; 95 96 // Wrapper of std::ifstream for reading ASCII file. 97 class InputFileASCII : public InputFile { 98 public: 99 explicit InputFileASCII(std::string file_path); 100 101 // Read one line from the file. Return false if EOF. 102 bool ReadLine(std::string* line); 103 }; 104 105 // IVF file writer, can be used to write an encoded VP8/9 video to disk. 106 class IVFWriter { 107 public: 108 IVFWriter(std::ofstream* output_file, VideoCodecType codec); 109 110 // Write the IVF file header. 111 bool WriteHeader(const Size& resolution, uint32_t frame_rate, uint32_t num_frames); 112 // Append the specified frame data to the IVF file. 113 bool WriteFrame(const uint8_t* data, uint32_t data_size, uint64_t timestamp); 114 // Set the number of video frames in the IVF file header. 115 bool SetNumFrames(uint32_t num_frames); 116 117 private: 118 std::ofstream* output_file_; 119 VideoCodecType codec_ = VideoCodecType::UNKNOWN; 120 }; 121 122 class OutputFile { 123 public: 124 bool Open(const std::string& file_path, VideoCodecType codec); 125 void Close(); 126 bool IsOpen(); 127 128 // Write the video file header. 129 bool WriteHeader(const Size& resolution, uint32_t frame_rate, uint32_t num_frames); 130 // Append the specified frame data to the video file. 131 bool WriteFrame(uint32_t data_size, const uint8_t* data); 132 133 private: 134 std::ofstream output_file_; 135 std::unique_ptr<IVFWriter> ivf_writer_; 136 uint64_t frame_index_ = 0; 137 }; 138 139 // The helper class to calculate FPS. 140 class FPSCalculator { 141 public: 142 // Record the time interval of output buffers. Return false if is invalid. 143 // This should be called per output buffer ready callback. 144 bool RecordFrameTimeDiff(); 145 146 // Calucalate FPS value. 147 double CalculateFPS() const; 148 149 private: 150 static constexpr double kMovingAvgWindowUs = 1000000; 151 static constexpr double kRegardedPercentile = 95; 152 153 // Return the statistics for the moving average over a window over the 154 // cumulative sum. Basically, moves a window from: [0, window] to 155 // [sum - window, sum] over the cumulative sum, over ((sum - window)/average) 156 // steps, and returns the average value over each window. 157 // This method is used to average time-diff data over a window of a constant 158 // time. 159 std::vector<double> MovingAvgOverSum() const; 160 161 std::vector<double> frame_time_diffs_us_; 162 int64_t last_frame_time_us_ = 0; 163 }; 164 165 // Helper function to get VideoCodecType from |profile|. 166 VideoCodecType VideoCodecProfileToType(VideoCodecProfile profile); 167 168 // Split the string |src| by the delimiter |delim|. 169 std::vector<std::string> SplitString(const std::string& src, char delim); 170 171 // Get monotonic timestamp for now in microseconds. 172 int64_t GetNowUs(); 173 174 // Get Mime type name from video codec type. 175 const char* GetMimeType(VideoCodecType type); 176 177 } // namespace android 178 #endif // C2_E2E_TEST_COMMON_H_ 179