1 /*
2 * Copyright (c) 2019 The WebM 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 #include <math.h>
12 #include <memory>
13 #include <string>
14 #include <vector>
15 #include "gtest/gtest.h"
16 #include "test/video_source.h"
17 #include "vp9/simple_encode.h"
18
19 namespace vp9 {
20 namespace {
21
GetBitrateInKbps(size_t bit_size,int num_frames,int frame_rate_num,int frame_rate_den)22 double GetBitrateInKbps(size_t bit_size, int num_frames, int frame_rate_num,
23 int frame_rate_den) {
24 return static_cast<double>(bit_size) / num_frames * frame_rate_num /
25 frame_rate_den / 1000.0;
26 }
27
28 // Returns the number of unit in size of 4.
29 // For example, if size is 7, return 2.
GetNumUnit4x4(int size)30 int GetNumUnit4x4(int size) { return (size + 3) >> 2; }
31
32 class SimpleEncodeTest : public ::testing::Test {
33 protected:
34 const int width_ = 352;
35 const int height_ = 288;
36 const int frame_rate_num_ = 30;
37 const int frame_rate_den_ = 1;
38 const int target_bitrate_ = 1000;
39 const int num_frames_ = 17;
40 const int target_level_ = LEVEL_UNKNOWN;
41 const std::string in_file_path_str_ =
42 libvpx_test::GetDataPath() + "/bus_352x288_420_f20_b8.yuv";
43 };
44
TEST_F(SimpleEncodeTest,ComputeFirstPassStats)45 TEST_F(SimpleEncodeTest, ComputeFirstPassStats) {
46 SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_,
47 target_bitrate_, num_frames_, target_level_,
48 in_file_path_str_.c_str());
49 simple_encode.ComputeFirstPassStats();
50 std::vector<std::vector<double>> frame_stats =
51 simple_encode.ObserveFirstPassStats();
52 EXPECT_EQ(frame_stats.size(), static_cast<size_t>(num_frames_));
53 const size_t data_num = frame_stats[0].size();
54 // Read ObserveFirstPassStats before changing FIRSTPASS_STATS.
55 EXPECT_EQ(data_num, static_cast<size_t>(25));
56 for (size_t i = 0; i < frame_stats.size(); ++i) {
57 EXPECT_EQ(frame_stats[i].size(), data_num);
58 // FIRSTPASS_STATS's first element is frame
59 EXPECT_EQ(frame_stats[i][0], i);
60 // FIRSTPASS_STATS's last element is count, and the count is 1 for single
61 // frame stats
62 EXPECT_EQ(frame_stats[i][data_num - 1], 1);
63 }
64 }
65
TEST_F(SimpleEncodeTest,ObserveFirstPassMotionVectors)66 TEST_F(SimpleEncodeTest, ObserveFirstPassMotionVectors) {
67 SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_,
68 target_bitrate_, num_frames_, target_level_,
69 in_file_path_str_.c_str());
70 simple_encode.ComputeFirstPassStats();
71 std::vector<std::vector<MotionVectorInfo>> fps_motion_vectors =
72 simple_encode.ObserveFirstPassMotionVectors();
73 EXPECT_EQ(fps_motion_vectors.size(), static_cast<size_t>(num_frames_));
74 const size_t num_blocks = ((width_ + 15) >> 4) * ((height_ + 15) >> 4);
75 EXPECT_EQ(num_blocks, fps_motion_vectors[0].size());
76 for (size_t i = 0; i < fps_motion_vectors.size(); ++i) {
77 EXPECT_EQ(num_blocks, fps_motion_vectors[i].size());
78 for (size_t j = 0; j < num_blocks; ++j) {
79 const int mv_count = fps_motion_vectors[i][j].mv_count;
80 const int ref_count =
81 (fps_motion_vectors[i][j].ref_frame[0] != kRefFrameTypeNone) +
82 (fps_motion_vectors[i][j].ref_frame[1] != kRefFrameTypeNone);
83 EXPECT_EQ(mv_count, ref_count);
84 }
85 }
86 }
87
TEST_F(SimpleEncodeTest,GetCodingFrameNum)88 TEST_F(SimpleEncodeTest, GetCodingFrameNum) {
89 SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_,
90 target_bitrate_, num_frames_, target_level_,
91 in_file_path_str_.c_str());
92 simple_encode.ComputeFirstPassStats();
93 const int num_coding_frames = simple_encode.GetCodingFrameNum();
94 EXPECT_EQ(num_coding_frames, 19);
95 }
96
TEST_F(SimpleEncodeTest,EncodeFrame)97 TEST_F(SimpleEncodeTest, EncodeFrame) {
98 SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_,
99 target_bitrate_, num_frames_, target_level_,
100 in_file_path_str_.c_str());
101 simple_encode.ComputeFirstPassStats();
102 int num_coding_frames = simple_encode.GetCodingFrameNum();
103 EXPECT_GE(num_coding_frames, num_frames_);
104 simple_encode.StartEncode();
105 size_t total_data_bit_size = 0;
106 int coded_show_frame_count = 0;
107 int frame_coding_index = 0;
108 while (coded_show_frame_count < num_frames_) {
109 const GroupOfPicture group_of_picture =
110 simple_encode.ObserveGroupOfPicture();
111 const std::vector<EncodeFrameInfo> &encode_frame_list =
112 group_of_picture.encode_frame_list;
113 for (size_t group_index = 0; group_index < encode_frame_list.size();
114 ++group_index) {
115 EncodeFrameResult encode_frame_result;
116 simple_encode.EncodeFrame(&encode_frame_result);
117 EXPECT_EQ(encode_frame_result.show_idx,
118 encode_frame_list[group_index].show_idx);
119 EXPECT_EQ(encode_frame_result.frame_type,
120 encode_frame_list[group_index].frame_type);
121 EXPECT_EQ(encode_frame_list[group_index].coding_index,
122 frame_coding_index);
123 EXPECT_GE(encode_frame_result.psnr, 34)
124 << "The psnr is supposed to be greater than 34 given the "
125 "target_bitrate 1000 kbps";
126 EXPECT_EQ(encode_frame_result.ref_frame_info,
127 encode_frame_list[group_index].ref_frame_info);
128 total_data_bit_size += encode_frame_result.coding_data_bit_size;
129 ++frame_coding_index;
130 }
131 coded_show_frame_count += group_of_picture.show_frame_count;
132 }
133 const double bitrate = GetBitrateInKbps(total_data_bit_size, num_frames_,
134 frame_rate_num_, frame_rate_den_);
135 const double off_target_threshold = 150;
136 EXPECT_LE(fabs(target_bitrate_ - bitrate), off_target_threshold);
137 simple_encode.EndEncode();
138 }
139
TEST_F(SimpleEncodeTest,ObserveKeyFrameMap)140 TEST_F(SimpleEncodeTest, ObserveKeyFrameMap) {
141 SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_,
142 target_bitrate_, num_frames_, target_level_,
143 in_file_path_str_.c_str());
144 simple_encode.ComputeFirstPassStats();
145 std::vector<int> key_frame_map = simple_encode.ObserveKeyFrameMap();
146 EXPECT_EQ(key_frame_map.size(), static_cast<size_t>(num_frames_));
147 simple_encode.StartEncode();
148 int coded_show_frame_count = 0;
149 while (coded_show_frame_count < num_frames_) {
150 const GroupOfPicture group_of_picture =
151 simple_encode.ObserveGroupOfPicture();
152 const std::vector<EncodeFrameInfo> &encode_frame_list =
153 group_of_picture.encode_frame_list;
154 for (size_t group_index = 0; group_index < encode_frame_list.size();
155 ++group_index) {
156 EncodeFrameResult encode_frame_result;
157 simple_encode.EncodeFrame(&encode_frame_result);
158 if (encode_frame_result.frame_type == kFrameTypeKey) {
159 EXPECT_EQ(key_frame_map[encode_frame_result.show_idx], 1);
160 } else {
161 EXPECT_EQ(key_frame_map[encode_frame_result.show_idx], 0);
162 }
163 }
164 coded_show_frame_count += group_of_picture.show_frame_count;
165 }
166 simple_encode.EndEncode();
167 }
168
TEST_F(SimpleEncodeTest,EncodeFrameWithTargetFrameBits)169 TEST_F(SimpleEncodeTest, EncodeFrameWithTargetFrameBits) {
170 SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_,
171 target_bitrate_, num_frames_, target_level_,
172 in_file_path_str_.c_str());
173 simple_encode.ComputeFirstPassStats();
174 const int num_coding_frames = simple_encode.GetCodingFrameNum();
175 simple_encode.StartEncode();
176 for (int i = 0; i < num_coding_frames; ++i) {
177 EncodeFrameInfo encode_frame_info = simple_encode.GetNextEncodeFrameInfo();
178 int target_frame_bits;
179 switch (encode_frame_info.frame_type) {
180 case kFrameTypeInter: target_frame_bits = 20000; break;
181 case kFrameTypeKey:
182 case kFrameTypeAltRef:
183 case kFrameTypeGolden: target_frame_bits = 100000; break;
184 case kFrameTypeOverlay: target_frame_bits = 2000; break;
185 default: target_frame_bits = 20000;
186 }
187
188 double percent_diff = 15;
189 if (encode_frame_info.frame_type == kFrameTypeOverlay) {
190 percent_diff = 100;
191 }
192 EncodeFrameResult encode_frame_result;
193 simple_encode.EncodeFrameWithTargetFrameBits(
194 &encode_frame_result, target_frame_bits, percent_diff);
195 const int recode_count = encode_frame_result.recode_count;
196 // TODO(angiebird): Replace 7 by RATE_CTRL_MAX_RECODE_NUM
197 EXPECT_LE(recode_count, 7);
198 EXPECT_GE(recode_count, 1);
199
200 const double diff = fabs((double)encode_frame_result.coding_data_bit_size -
201 target_frame_bits);
202 EXPECT_LE(diff * 100 / target_frame_bits, percent_diff);
203 }
204 simple_encode.EndEncode();
205 }
206
TEST_F(SimpleEncodeTest,EncodeFrameWithQuantizeIndex)207 TEST_F(SimpleEncodeTest, EncodeFrameWithQuantizeIndex) {
208 SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_,
209 target_bitrate_, num_frames_, target_level_,
210 in_file_path_str_.c_str());
211 simple_encode.ComputeFirstPassStats();
212 const int num_coding_frames = simple_encode.GetCodingFrameNum();
213 simple_encode.StartEncode();
214 for (int i = 0; i < num_coding_frames; ++i) {
215 const int assigned_quantize_index = 100 + i;
216 EncodeFrameResult encode_frame_result;
217 simple_encode.EncodeFrameWithQuantizeIndex(&encode_frame_result,
218 assigned_quantize_index);
219 EXPECT_EQ(encode_frame_result.quantize_index, assigned_quantize_index);
220 }
221 simple_encode.EndEncode();
222 }
223
224 // This test encodes the video using EncodeFrame(), where quantize indexes
225 // are selected by vp9 rate control.
226 // Encode stats and the quantize_indexes are collected.
227 // Then the test encodes the video again using EncodeFrameWithQuantizeIndex()
228 // using the quantize indexes collected from the first run.
229 // Then test whether the encode stats of the two encoding runs match.
TEST_F(SimpleEncodeTest,EncodeConsistencyTest)230 TEST_F(SimpleEncodeTest, EncodeConsistencyTest) {
231 std::vector<int> quantize_index_list;
232 std::vector<uint64_t> ref_sse_list;
233 std::vector<double> ref_psnr_list;
234 std::vector<size_t> ref_bit_size_list;
235 std::vector<FrameType> ref_frame_type_list;
236 std::vector<int> ref_show_idx_list;
237 {
238 // The first encode.
239 SimpleEncode simple_encode(width_, height_, frame_rate_num_,
240 frame_rate_den_, target_bitrate_, num_frames_,
241 target_level_, in_file_path_str_.c_str());
242 simple_encode.ComputeFirstPassStats();
243 const int num_coding_frames = simple_encode.GetCodingFrameNum();
244 simple_encode.StartEncode();
245 for (int i = 0; i < num_coding_frames; ++i) {
246 EncodeFrameResult encode_frame_result;
247 simple_encode.EncodeFrame(&encode_frame_result);
248 quantize_index_list.push_back(encode_frame_result.quantize_index);
249 ref_sse_list.push_back(encode_frame_result.sse);
250 ref_psnr_list.push_back(encode_frame_result.psnr);
251 ref_bit_size_list.push_back(encode_frame_result.coding_data_bit_size);
252 ref_frame_type_list.push_back(encode_frame_result.frame_type);
253 ref_show_idx_list.push_back(encode_frame_result.show_idx);
254 }
255 simple_encode.EndEncode();
256 }
257 {
258 // The second encode with quantize index got from the first encode.
259 SimpleEncode simple_encode(width_, height_, frame_rate_num_,
260 frame_rate_den_, target_bitrate_, num_frames_,
261 target_level_, in_file_path_str_.c_str());
262 simple_encode.ComputeFirstPassStats();
263 const int num_coding_frames = simple_encode.GetCodingFrameNum();
264 EXPECT_EQ(static_cast<size_t>(num_coding_frames),
265 quantize_index_list.size());
266 simple_encode.StartEncode();
267 for (int i = 0; i < num_coding_frames; ++i) {
268 EncodeFrameResult encode_frame_result;
269 simple_encode.EncodeFrameWithQuantizeIndex(&encode_frame_result,
270 quantize_index_list[i]);
271 EXPECT_EQ(encode_frame_result.quantize_index, quantize_index_list[i]);
272 EXPECT_EQ(encode_frame_result.sse, ref_sse_list[i]);
273 EXPECT_DOUBLE_EQ(encode_frame_result.psnr, ref_psnr_list[i]);
274 EXPECT_EQ(encode_frame_result.coding_data_bit_size, ref_bit_size_list[i]);
275 EXPECT_EQ(encode_frame_result.frame_type, ref_frame_type_list[i]);
276 EXPECT_EQ(encode_frame_result.show_idx, ref_show_idx_list[i]);
277 }
278 simple_encode.EndEncode();
279 }
280 }
281
282 // Test the information (partition info and motion vector info) stored in
283 // encoder is the same between two encode runs.
TEST_F(SimpleEncodeTest,EncodeConsistencyTest2)284 TEST_F(SimpleEncodeTest, EncodeConsistencyTest2) {
285 const int num_rows_4x4 = GetNumUnit4x4(width_);
286 const int num_cols_4x4 = GetNumUnit4x4(height_);
287 const int num_units_4x4 = num_rows_4x4 * num_cols_4x4;
288 // The first encode.
289 SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_,
290 target_bitrate_, num_frames_, target_level_,
291 in_file_path_str_.c_str());
292 simple_encode.ComputeFirstPassStats();
293 const int num_coding_frames = simple_encode.GetCodingFrameNum();
294 std::vector<PartitionInfo> partition_info_list(num_units_4x4 *
295 num_coding_frames);
296 std::vector<MotionVectorInfo> motion_vector_info_list(num_units_4x4 *
297 num_coding_frames);
298 simple_encode.StartEncode();
299 for (int i = 0; i < num_coding_frames; ++i) {
300 EncodeFrameResult encode_frame_result;
301 simple_encode.EncodeFrame(&encode_frame_result);
302 for (int j = 0; j < num_rows_4x4 * num_cols_4x4; ++j) {
303 partition_info_list[i * num_units_4x4 + j] =
304 encode_frame_result.partition_info[j];
305 motion_vector_info_list[i * num_units_4x4 + j] =
306 encode_frame_result.motion_vector_info[j];
307 }
308 }
309 simple_encode.EndEncode();
310 // The second encode.
311 SimpleEncode simple_encode_2(width_, height_, frame_rate_num_,
312 frame_rate_den_, target_bitrate_, num_frames_,
313 target_level_, in_file_path_str_.c_str());
314 simple_encode_2.ComputeFirstPassStats();
315 const int num_coding_frames_2 = simple_encode_2.GetCodingFrameNum();
316 simple_encode_2.StartEncode();
317 for (int i = 0; i < num_coding_frames_2; ++i) {
318 EncodeFrameResult encode_frame_result;
319 simple_encode_2.EncodeFrame(&encode_frame_result);
320 for (int j = 0; j < num_rows_4x4 * num_cols_4x4; ++j) {
321 EXPECT_EQ(encode_frame_result.partition_info[j].row,
322 partition_info_list[i * num_units_4x4 + j].row);
323 EXPECT_EQ(encode_frame_result.partition_info[j].column,
324 partition_info_list[i * num_units_4x4 + j].column);
325 EXPECT_EQ(encode_frame_result.partition_info[j].row_start,
326 partition_info_list[i * num_units_4x4 + j].row_start);
327 EXPECT_EQ(encode_frame_result.partition_info[j].column_start,
328 partition_info_list[i * num_units_4x4 + j].column_start);
329 EXPECT_EQ(encode_frame_result.partition_info[j].width,
330 partition_info_list[i * num_units_4x4 + j].width);
331 EXPECT_EQ(encode_frame_result.partition_info[j].height,
332 partition_info_list[i * num_units_4x4 + j].height);
333
334 EXPECT_EQ(encode_frame_result.motion_vector_info[j].mv_count,
335 motion_vector_info_list[i * num_units_4x4 + j].mv_count);
336 EXPECT_EQ(encode_frame_result.motion_vector_info[j].ref_frame[0],
337 motion_vector_info_list[i * num_units_4x4 + j].ref_frame[0]);
338 EXPECT_EQ(encode_frame_result.motion_vector_info[j].ref_frame[1],
339 motion_vector_info_list[i * num_units_4x4 + j].ref_frame[1]);
340 EXPECT_EQ(encode_frame_result.motion_vector_info[j].mv_row[0],
341 motion_vector_info_list[i * num_units_4x4 + j].mv_row[0]);
342 EXPECT_EQ(encode_frame_result.motion_vector_info[j].mv_column[0],
343 motion_vector_info_list[i * num_units_4x4 + j].mv_column[0]);
344 EXPECT_EQ(encode_frame_result.motion_vector_info[j].mv_row[1],
345 motion_vector_info_list[i * num_units_4x4 + j].mv_row[1]);
346 EXPECT_EQ(encode_frame_result.motion_vector_info[j].mv_column[1],
347 motion_vector_info_list[i * num_units_4x4 + j].mv_column[1]);
348 }
349 }
350 simple_encode_2.EndEncode();
351 }
352
353 // Test the information stored in encoder is the same between two encode runs.
TEST_F(SimpleEncodeTest,EncodeConsistencyTest3)354 TEST_F(SimpleEncodeTest, EncodeConsistencyTest3) {
355 std::vector<int> quantize_index_list;
356 const int num_rows_4x4 = GetNumUnit4x4(width_);
357 const int num_cols_4x4 = GetNumUnit4x4(height_);
358 const int num_units_4x4 = num_rows_4x4 * num_cols_4x4;
359 // The first encode.
360 SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_,
361 target_bitrate_, num_frames_, target_level_,
362 in_file_path_str_.c_str());
363 simple_encode.ComputeFirstPassStats();
364 const int num_coding_frames = simple_encode.GetCodingFrameNum();
365 std::vector<PartitionInfo> partition_info_list(num_units_4x4 *
366 num_coding_frames);
367 simple_encode.StartEncode();
368 for (int i = 0; i < num_coding_frames; ++i) {
369 EncodeFrameResult encode_frame_result;
370 simple_encode.EncodeFrame(&encode_frame_result);
371 quantize_index_list.push_back(encode_frame_result.quantize_index);
372 for (int j = 0; j < num_rows_4x4 * num_cols_4x4; ++j) {
373 partition_info_list[i * num_units_4x4 + j] =
374 encode_frame_result.partition_info[j];
375 }
376 }
377 simple_encode.EndEncode();
378 // The second encode.
379 SimpleEncode simple_encode_2(width_, height_, frame_rate_num_,
380 frame_rate_den_, target_bitrate_, num_frames_,
381 target_level_, in_file_path_str_.c_str());
382 simple_encode_2.ComputeFirstPassStats();
383 const int num_coding_frames_2 = simple_encode_2.GetCodingFrameNum();
384 simple_encode_2.StartEncode();
385 for (int i = 0; i < num_coding_frames_2; ++i) {
386 EncodeFrameResult encode_frame_result;
387 simple_encode_2.EncodeFrameWithQuantizeIndex(&encode_frame_result,
388 quantize_index_list[i]);
389 for (int j = 0; j < num_rows_4x4 * num_cols_4x4; ++j) {
390 EXPECT_EQ(encode_frame_result.partition_info[j].row,
391 partition_info_list[i * num_units_4x4 + j].row);
392 EXPECT_EQ(encode_frame_result.partition_info[j].column,
393 partition_info_list[i * num_units_4x4 + j].column);
394 EXPECT_EQ(encode_frame_result.partition_info[j].row_start,
395 partition_info_list[i * num_units_4x4 + j].row_start);
396 EXPECT_EQ(encode_frame_result.partition_info[j].column_start,
397 partition_info_list[i * num_units_4x4 + j].column_start);
398 EXPECT_EQ(encode_frame_result.partition_info[j].width,
399 partition_info_list[i * num_units_4x4 + j].width);
400 EXPECT_EQ(encode_frame_result.partition_info[j].height,
401 partition_info_list[i * num_units_4x4 + j].height);
402 }
403 }
404 simple_encode_2.EndEncode();
405 }
406
407 // Encode with default VP9 decision first.
408 // Get QPs and arf locations from the first encode.
409 // Set external arfs and QPs for the second encode.
410 // Expect to get matched results.
TEST_F(SimpleEncodeTest,EncodeConsistencySetExternalGroupOfPicturesMap)411 TEST_F(SimpleEncodeTest, EncodeConsistencySetExternalGroupOfPicturesMap) {
412 std::vector<int> quantize_index_list;
413 std::vector<uint64_t> ref_sse_list;
414 std::vector<double> ref_psnr_list;
415 std::vector<size_t> ref_bit_size_list;
416 std::vector<int> gop_map(num_frames_, 0);
417 {
418 // The first encode.
419 SimpleEncode simple_encode(width_, height_, frame_rate_num_,
420 frame_rate_den_, target_bitrate_, num_frames_,
421 target_level_, in_file_path_str_.c_str());
422 simple_encode.ComputeFirstPassStats();
423 simple_encode.StartEncode();
424
425 int coded_show_frame_count = 0;
426 while (coded_show_frame_count < num_frames_) {
427 const GroupOfPicture group_of_picture =
428 simple_encode.ObserveGroupOfPicture();
429 gop_map[coded_show_frame_count] |= kGopMapFlagStart;
430 if (group_of_picture.use_alt_ref) {
431 gop_map[coded_show_frame_count] |= kGopMapFlagUseAltRef;
432 }
433 const std::vector<EncodeFrameInfo> &encode_frame_list =
434 group_of_picture.encode_frame_list;
435 for (size_t group_index = 0; group_index < encode_frame_list.size();
436 ++group_index) {
437 EncodeFrameResult encode_frame_result;
438 simple_encode.EncodeFrame(&encode_frame_result);
439 quantize_index_list.push_back(encode_frame_result.quantize_index);
440 ref_sse_list.push_back(encode_frame_result.sse);
441 ref_psnr_list.push_back(encode_frame_result.psnr);
442 ref_bit_size_list.push_back(encode_frame_result.coding_data_bit_size);
443 }
444 coded_show_frame_count += group_of_picture.show_frame_count;
445 }
446 simple_encode.EndEncode();
447 }
448 {
449 // The second encode with quantize index got from the first encode.
450 // The external arfs are the same as the first encode.
451 SimpleEncode simple_encode(width_, height_, frame_rate_num_,
452 frame_rate_den_, target_bitrate_, num_frames_,
453 target_level_, in_file_path_str_.c_str());
454 simple_encode.ComputeFirstPassStats();
455 simple_encode.SetExternalGroupOfPicturesMap(gop_map.data(), gop_map.size());
456 const int num_coding_frames = simple_encode.GetCodingFrameNum();
457 EXPECT_EQ(static_cast<size_t>(num_coding_frames),
458 quantize_index_list.size());
459 simple_encode.StartEncode();
460 for (int i = 0; i < num_coding_frames; ++i) {
461 EncodeFrameResult encode_frame_result;
462 simple_encode.EncodeFrameWithQuantizeIndex(&encode_frame_result,
463 quantize_index_list[i]);
464 EXPECT_EQ(encode_frame_result.quantize_index, quantize_index_list[i]);
465 EXPECT_EQ(encode_frame_result.sse, ref_sse_list[i]);
466 EXPECT_DOUBLE_EQ(encode_frame_result.psnr, ref_psnr_list[i]);
467 EXPECT_EQ(encode_frame_result.coding_data_bit_size, ref_bit_size_list[i]);
468 }
469 simple_encode.EndEncode();
470 }
471 }
472
TEST_F(SimpleEncodeTest,SetExternalGroupOfPicturesMap)473 TEST_F(SimpleEncodeTest, SetExternalGroupOfPicturesMap) {
474 SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_,
475 target_bitrate_, num_frames_, target_level_,
476 in_file_path_str_.c_str());
477 simple_encode.ComputeFirstPassStats();
478
479 std::vector<int> gop_map(num_frames_, 0);
480
481 // Should be the first gop group.
482 gop_map[0] = 0;
483
484 // Second gop group with an alt ref.
485 gop_map[5] |= kGopMapFlagStart | kGopMapFlagUseAltRef;
486
487 // Third gop group without an alt ref.
488 gop_map[10] |= kGopMapFlagStart;
489
490 // Last gop group.
491 gop_map[14] |= kGopMapFlagStart | kGopMapFlagUseAltRef;
492
493 simple_encode.SetExternalGroupOfPicturesMap(gop_map.data(), gop_map.size());
494
495 std::vector<int> observed_gop_map =
496 simple_encode.ObserveExternalGroupOfPicturesMap();
497
498 // First gop group.
499 // There is always a key frame at show_idx 0 and key frame should always be
500 // the start of a gop. We expect ObserveExternalGroupOfPicturesMap() will
501 // insert an extra gop start here.
502 EXPECT_EQ(observed_gop_map[0], kGopMapFlagStart | kGopMapFlagUseAltRef);
503
504 // Second gop group with an alt ref.
505 EXPECT_EQ(observed_gop_map[5], kGopMapFlagStart | kGopMapFlagUseAltRef);
506
507 // Third gop group without an alt ref.
508 EXPECT_EQ(observed_gop_map[10], kGopMapFlagStart);
509
510 // Last gop group. The last gop is not supposed to use an alt ref. We expect
511 // ObserveExternalGroupOfPicturesMap() will remove the alt ref flag here.
512 EXPECT_EQ(observed_gop_map[14], kGopMapFlagStart);
513
514 int ref_gop_show_frame_count_list[4] = { 5, 5, 4, 3 };
515 size_t ref_gop_coded_frame_count_list[4] = { 6, 6, 4, 3 };
516 int gop_count = 0;
517
518 simple_encode.StartEncode();
519 int coded_show_frame_count = 0;
520 while (coded_show_frame_count < num_frames_) {
521 const GroupOfPicture group_of_picture =
522 simple_encode.ObserveGroupOfPicture();
523 const std::vector<EncodeFrameInfo> &encode_frame_list =
524 group_of_picture.encode_frame_list;
525 EXPECT_EQ(encode_frame_list.size(),
526 ref_gop_coded_frame_count_list[gop_count]);
527 EXPECT_EQ(group_of_picture.show_frame_count,
528 ref_gop_show_frame_count_list[gop_count]);
529 for (size_t group_index = 0; group_index < encode_frame_list.size();
530 ++group_index) {
531 EncodeFrameResult encode_frame_result;
532 simple_encode.EncodeFrame(&encode_frame_result);
533 }
534 coded_show_frame_count += group_of_picture.show_frame_count;
535 ++gop_count;
536 }
537 EXPECT_EQ(gop_count, 4);
538 simple_encode.EndEncode();
539 }
540
TEST_F(SimpleEncodeTest,GetEncodeFrameInfo)541 TEST_F(SimpleEncodeTest, GetEncodeFrameInfo) {
542 // Makes sure that the encode_frame_info obtained from GetEncodeFrameInfo()
543 // matches the counterpart in encode_frame_result obtained from EncodeFrame()
544 SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_,
545 target_bitrate_, num_frames_, target_level_,
546 in_file_path_str_.c_str());
547 simple_encode.ComputeFirstPassStats();
548 const int num_coding_frames = simple_encode.GetCodingFrameNum();
549 simple_encode.StartEncode();
550 for (int i = 0; i < num_coding_frames; ++i) {
551 EncodeFrameInfo encode_frame_info = simple_encode.GetNextEncodeFrameInfo();
552 EncodeFrameResult encode_frame_result;
553 simple_encode.EncodeFrame(&encode_frame_result);
554 EXPECT_EQ(encode_frame_info.show_idx, encode_frame_result.show_idx);
555 EXPECT_EQ(encode_frame_info.frame_type, encode_frame_result.frame_type);
556 }
557 simple_encode.EndEncode();
558 }
559
TEST_F(SimpleEncodeTest,GetFramePixelCount)560 TEST_F(SimpleEncodeTest, GetFramePixelCount) {
561 SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_,
562 target_bitrate_, num_frames_, target_level_,
563 in_file_path_str_.c_str());
564 EXPECT_EQ(simple_encode.GetFramePixelCount(),
565 static_cast<uint64_t>(width_ * height_ * 3 / 2));
566 }
567
568 } // namespace
569 } // namespace vp9
570
main(int argc,char ** argv)571 int main(int argc, char **argv) {
572 ::testing::InitGoogleTest(&argc, argv);
573 return RUN_ALL_TESTS();
574 }
575