1 /*
2 * Copyright(c) 2019 Netflix, Inc.
3 *
4 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at https://www.aomedia.org/license/software-license. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at https://www.aomedia.org/license/patent-license.
10 */
11 
12 /******************************************************************************
13  * @file E2eTestVectors.h
14  *
15  * @brief Defines test vectors for End to End test
16  *
17  * @author Cidana-Edmond
18  *
19  ******************************************************************************/
20 
21 #ifndef _E2E_TEST_VECTOR_
22 #define _E2E_TEST_VECTOR_
23 
24 #include <map>
25 #include "VideoSource.h"
26 #include "EbDefinitions.h"
27 #include "ConfigEncoder.h"
28 
29 /** @defgroup svt_av1_e2e_test_vector Test vectors for E2E test
30  *  Defines the test vectors of E2E test, with file-type, width, height and
31  * file-path
32  *  *** You need to get test vectors before run e2e test, we use CMaked
33  * generated makefile to download test vectors, you can use 'make TestVectors'
34  * to download them.
35  *  @{
36  */
37 namespace svt_av1_e2e_test_vector {
38 
39 /** TestVectorFormat is enumerate type of input video file format */
40 typedef enum TestVectorFormat {
41     YUV_VIDEO_FILE,
42     Y4M_VIDEO_FILE,
43     DUMMY_SOURCE
44 } TestVectorFormat;
45 
46 /** TestVideoVector is tuple of test params in a test case */
47 typedef std::tuple<std::string,      /**< file name */
48                    TestVectorFormat, /**< file format */
49                    VideoColorFormat, /**< color format */
50                    uint32_t,         /**< width */
51                    uint32_t,         /**< height */
52                    uint32_t,         /**< bit depth */
53                    bool,             /**< compressed 2-bit in 10-bit frame */
54                    uint32_t,         /**< start read position in frame */
55                    uint32_t> /**< frames to test, (0) means full-frames*/
56     TestVideoVector;
57 const std::vector<TestVideoVector> default_test_vectors = {
58     std::make_tuple("kirland_640_480_30.yuv", YUV_VIDEO_FILE, IMG_FMT_420, 640,
59                     480, 8, 0, 0, 60),
60     std::make_tuple("niklas_640_480_30.yuv", YUV_VIDEO_FILE, IMG_FMT_420, 640,
61                     480, 8, 0, 0, 60),
62 };
63 
64 const std::vector<TestVideoVector> incomplete_sb_test_vectors = {
65     std::make_tuple("park_joy_90p_8_420.y4m", Y4M_VIDEO_FILE, IMG_FMT_420, 160,
66                     90, 8, 0, 0, 0),
67     std::make_tuple("park_joy_90p_10_420.y4m", Y4M_VIDEO_FILE, IMG_FMT_420, 160,
68                     90, 10, 0, 0, 0),
69 };
70 
71 const std::vector<TestVideoVector> res_480p_test_vectors = {
72     std::make_tuple("kirland_640_480_30.yuv", YUV_VIDEO_FILE, IMG_FMT_420, 640,
73                     480, 8, 0, 0, 60),
74     std::make_tuple("screendata.y4m", Y4M_VIDEO_FILE, IMG_FMT_420, 640, 480, 8,
75                     0, 0, 0),
76 };
77 
78 const std::vector<TestVideoVector> screen_test_vectors = {
79     std::make_tuple("screendata.y4m", Y4M_VIDEO_FILE, IMG_FMT_420, 640, 480, 8,
80                     0, 0, 0),
81 };
82 
83 const std::vector<TestVideoVector> dummy_test_vectors = {
84     std::make_tuple("colorbar_480p_8_420", DUMMY_SOURCE, IMG_FMT_420, 640, 480,
85                     8, 0, 0, 100),
86     std::make_tuple("colorbar_1080p_8_420", DUMMY_SOURCE, IMG_FMT_420, 1920, 1080,
87                     8, 0, 0, 60),
88     std::make_tuple("colorbar_64x64_8_420", DUMMY_SOURCE, IMG_FMT_420, 64, 64,
89                     8, 0, 0, 60),
90     std::make_tuple("colorbar_480p_10_420", DUMMY_SOURCE, IMG_FMT_420, 640, 480,
91                     10, 0, 0, 100),
92     std::make_tuple("colorbar_1080p_10_420", DUMMY_SOURCE, IMG_FMT_420, 1920, 1080,
93                     10, 0, 0, 60),
94     std::make_tuple("colorbar_64x64_10_420", DUMMY_SOURCE, IMG_FMT_420, 64, 64,
95                     10, 0, 0, 60),
96 };
97 
98 const std::vector<TestVideoVector> dummy_422_test_vectors = {
99     std::make_tuple("colorbar_480p_8_422", DUMMY_SOURCE, IMG_FMT_422, 640, 480,
100                     8, 0, 0, 100),
101 };
102 
103 const std::vector<TestVideoVector> dummy_444_test_vectors = {
104     std::make_tuple("colorbar_480p_8_444", DUMMY_SOURCE, IMG_FMT_444, 640, 480,
105                     8, 0, 0, 100),
106 };
107 
108 using EncSetting = std::map<std::string, std::string>;
109 typedef struct EncTestSetting {
110     std::string name;    // description of the test cases
111     EncSetting setting;  // pairs of encoder setting, {name, value};
112     std::vector<TestVideoVector> test_vectors;
to_stringEncTestSetting113     std::string to_string(std::string& fn) const {
114         std::string str = get_setting_str();
115         str += "test vector: ";
116         str += fn;
117         return str;
118     }
119 
to_cliEncTestSetting120     std::string to_cli(TestVideoVector& vector) const {
121         std::string str = "SvtAv1EncApp";
122         str += get_vector_cli(vector);
123         str += get_setting_cli();
124         append_token(str, "StreamFile");
125         str += "output.ivf";
126         append_token(str, "ReconFile");
127         str += "recon.yuv";
128         return str;
129     }
130 
get_setting_strEncTestSetting131     std::string get_setting_str() const {
132         std::string str(name);
133         str += ": ";
134         for (auto x : setting) {
135             str += x.first;
136             str += "=";
137             str += x.second;
138             str += ", ";
139         }
140         return str;
141     }
142 
color_fmtEncTestSetting143     int color_fmt(VideoColorFormat fmt) const {
144         switch (fmt) {
145         case IMG_FMT_420:
146         case IMG_FMT_420P10_PACKED: return 420;
147         case IMG_FMT_422:
148         case IMG_FMT_422P10_PACKED: return 422;
149         case IMG_FMT_444:
150         case IMG_FMT_444P10_PACKED: return 444;
151         default: break;
152         }
153         return -1;
154     }
155 
get_vector_cliEncTestSetting156     std::string get_vector_cli(TestVideoVector& vector) const {
157         std::string str;
158         append_token(str, "InputFile");
159         str += std::get<0>(vector);
160         if (std::get<1>(vector) != Y4M_VIDEO_FILE) {
161             append_token(str, "SourceWidth");
162             str += std::to_string(std::get<3>(vector));
163             append_token(str, "SourceHeight");
164             str += std::to_string(std::get<4>(vector));
165             append_token(str, "EncoderBitDepth");
166             str += std::to_string(std::get<5>(vector));
167             append_token(str, "EncoderColorFormat");
168             str += std::to_string(color_fmt(std::get<2>(vector)));
169         }
170         return str;
171     }
172 
append_tokenEncTestSetting173     void append_token(std::string& str, const char* name) const {
174         str += " ";
175         str += get_enc_token(name);
176         str += " ";
177     }
178 
get_setting_cliEncTestSetting179     std::string get_setting_cli() const {
180         std::string str;
181         for (auto x : setting) {
182             append_token(str, x.first.c_str());
183             str += x.second;
184         }
185         return str;
186     }
187 
get_setting_nameEncTestSetting188     std::string get_setting_name() const {
189         return name;
190     }
191 
192     friend std::ostream& operator<<(std::ostream& os,
193                                     const EncTestSetting& setting) {
194         return os << setting.get_setting_str();
195     }
196     // used in INSTANTIATE_TEST_CASE_P to append the param info into the test
197     // name
GetSettingNameEncTestSetting198     static std::string GetSettingName(
199         const ::testing::TestParamInfo<EncTestSetting> setting) {
200         return setting.param.get_setting_name();
201     }
202 
203 } EncTestSetting;
204 
205 /**
206  * @brief      Generate test vectors from config file.
207  *
208  * @param[in]  config_file  The configuration file name. It will read tihs file
209  * from path which defined by system envrionment SVT_AV1_TEST_VECTOR_PATH.
210  *
211  * @return     A std::vector of test vectors.
212  */
generate_vector_from_config(const char * config_file)213 static inline const std::vector<EncTestSetting> generate_vector_from_config(
214     const char* config_file) {
215     std::vector<TestVideoVector> values;
216     std::vector<EncTestSetting> enc_test_cases;
217     std::string cfg_fn =
218         svt_av1_video_source::VideoFileSource::get_vector_dir();
219     cfg_fn = cfg_fn + '/' + config_file;
220 
221     FILE* file_handle;
222     FOPEN(file_handle, cfg_fn.c_str(), "rt");
223     if (file_handle != nullptr) {
224         char line[1024] = {0};
225         while (fgets(line, 1024, file_handle) != nullptr) {
226             if (line[0] == '#' || line[0] == '\r' ||
227                 line[0] == '\n')  // skip comment line and empty line
228                 continue;
229             char vector_fn[1024] = {0};
230             uint32_t y4m = 0;
231             TestVectorFormat file_type;
232             char color_fmt[10];
233             VideoColorFormat color_fmt_type;
234             uint32_t w;
235             uint32_t h;
236             uint32_t bit_depth;
237             uint32_t compressed_10bit;
238             uint32_t start_frame;
239             uint32_t frame_count;
240 
241             sscanf(line,
242                    "%s %d %s %d %d %d %d %d %d",
243                    vector_fn,
244                    &y4m,
245                    color_fmt,
246                    &w,
247                    &h,
248                    &bit_depth,
249                    &compressed_10bit,
250                    &start_frame,
251                    &frame_count);
252 
253             file_type = y4m ? Y4M_VIDEO_FILE : YUV_VIDEO_FILE;
254             if (strcmp(color_fmt, "420") == 0) {
255                 color_fmt_type = IMG_FMT_420;
256             } else if (strcmp(color_fmt, "420p10") == 0) {
257                 color_fmt_type = IMG_FMT_420P10_PACKED;
258             }
259             values.push_back(TestVideoVector(vector_fn,
260                                              file_type,
261                                              color_fmt_type,
262                                              w,
263                                              h,
264                                              (uint8_t)bit_depth,
265                                              compressed_10bit,
266                                              start_frame,
267                                              frame_count));
268         }
269         fclose(file_handle);
270     } else {
271         printf("test configuration file can not be opended: %s!\n",
272                cfg_fn.c_str());
273     }
274     enc_test_cases.push_back(EncTestSetting{
275         "default_setting", std::map<std::string, std::string>(), values});
276     return enc_test_cases;
277 }
278 
279 }  // namespace svt_av1_e2e_test_vector
280 /** @} */  // end of svt_av1_e2e_test_vector
281 
282 #endif  // _E2E_TEST_VECTOR_
283