OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2013 The WebM project authors. All Rights Reserved. | 2 * Copyright (c) 2013 The WebM project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 19 matching lines...) Expand all Loading... |
30 mismatch_nframes_(0), | 30 mismatch_nframes_(0), |
31 encoding_mode_(GET_PARAM(1)) { | 31 encoding_mode_(GET_PARAM(1)) { |
32 Reset(); | 32 Reset(); |
33 } | 33 } |
34 | 34 |
35 virtual ~ErrorResilienceTestLarge() {} | 35 virtual ~ErrorResilienceTestLarge() {} |
36 | 36 |
37 void Reset() { | 37 void Reset() { |
38 error_nframes_ = 0; | 38 error_nframes_ = 0; |
39 droppable_nframes_ = 0; | 39 droppable_nframes_ = 0; |
| 40 pattern_switch_ = 0; |
40 } | 41 } |
41 | 42 |
42 virtual void SetUp() { | 43 virtual void SetUp() { |
43 InitializeConfig(); | 44 InitializeConfig(); |
44 SetMode(encoding_mode_); | 45 SetMode(encoding_mode_); |
45 } | 46 } |
46 | 47 |
47 virtual void BeginPassHook(unsigned int /*pass*/) { | 48 virtual void BeginPassHook(unsigned int /*pass*/) { |
48 psnr_ = 0.0; | 49 psnr_ = 0.0; |
49 nframes_ = 0; | 50 nframes_ = 0; |
50 mismatch_psnr_ = 0.0; | 51 mismatch_psnr_ = 0.0; |
51 mismatch_nframes_ = 0; | 52 mismatch_nframes_ = 0; |
52 } | 53 } |
53 | 54 |
54 virtual void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) { | 55 virtual void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) { |
55 psnr_ += pkt->data.psnr.psnr[0]; | 56 psnr_ += pkt->data.psnr.psnr[0]; |
56 nframes_++; | 57 nframes_++; |
57 } | 58 } |
58 | 59 |
59 // | 60 // |
60 // Frame flags and layer id for temporal layers. | 61 // Frame flags and layer id for temporal layers. |
61 // For two layers, test pattern is: | 62 // For two layers, test pattern is: |
62 // 1 3 | 63 // 1 3 |
63 // 0 2 ..... | 64 // 0 2 ..... |
64 // LAST is updated on base/layer 0, GOLDEN updated on layer 1. | 65 // LAST is updated on base/layer 0, GOLDEN updated on layer 1. |
65 int SetFrameFlags(int frame_num, int num_temp_layers) { | 66 // Non-zero pattern_switch parameter means pattern will switch to |
| 67 // not using LAST for frame_num >= pattern_switch. |
| 68 int SetFrameFlags(int frame_num, |
| 69 int num_temp_layers, |
| 70 int pattern_switch) { |
66 int frame_flags = 0; | 71 int frame_flags = 0; |
67 if (num_temp_layers == 2) { | 72 if (num_temp_layers == 2) { |
68 if (frame_num % 2 == 0) { | 73 if (frame_num % 2 == 0) { |
69 // Layer 0: predict from L and ARF, update L. | 74 if (frame_num < pattern_switch || pattern_switch == 0) { |
70 frame_flags = VP8_EFLAG_NO_REF_GF | | 75 // Layer 0: predict from LAST and ARF, update LAST. |
71 VP8_EFLAG_NO_UPD_GF | | 76 frame_flags = VP8_EFLAG_NO_REF_GF | |
72 VP8_EFLAG_NO_UPD_ARF; | 77 VP8_EFLAG_NO_UPD_GF | |
73 } else { | 78 VP8_EFLAG_NO_UPD_ARF; |
74 // Layer 1: predict from L, GF, and ARF, and update GF. | 79 } else { |
75 frame_flags = VP8_EFLAG_NO_UPD_ARF | | 80 // Layer 0: predict from GF and ARF, update GF. |
76 VP8_EFLAG_NO_UPD_LAST; | 81 frame_flags = VP8_EFLAG_NO_REF_LAST | |
77 } | 82 VP8_EFLAG_NO_UPD_LAST | |
| 83 VP8_EFLAG_NO_UPD_ARF; |
| 84 } |
| 85 } else { |
| 86 if (frame_num < pattern_switch || pattern_switch == 0) { |
| 87 // Layer 1: predict from L, GF, and ARF, update GF. |
| 88 frame_flags = VP8_EFLAG_NO_UPD_ARF | |
| 89 VP8_EFLAG_NO_UPD_LAST; |
| 90 } else { |
| 91 // Layer 1: predict from GF and ARF, update GF. |
| 92 frame_flags = VP8_EFLAG_NO_REF_LAST | |
| 93 VP8_EFLAG_NO_UPD_LAST | |
| 94 VP8_EFLAG_NO_UPD_ARF; |
| 95 } |
| 96 } |
78 } | 97 } |
79 return frame_flags; | 98 return frame_flags; |
80 } | 99 } |
81 | 100 |
82 virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video, | 101 virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video, |
83 ::libvpx_test::Encoder *encoder) { | 102 ::libvpx_test::Encoder *encoder) { |
84 frame_flags_ &= ~(VP8_EFLAG_NO_UPD_LAST | | 103 frame_flags_ &= ~(VP8_EFLAG_NO_UPD_LAST | |
85 VP8_EFLAG_NO_UPD_GF | | 104 VP8_EFLAG_NO_UPD_GF | |
86 VP8_EFLAG_NO_UPD_ARF); | 105 VP8_EFLAG_NO_UPD_ARF); |
87 // For temporal layer case. | 106 // For temporal layer case. |
88 if (cfg_.ts_number_layers > 1) { | 107 if (cfg_.ts_number_layers > 1) { |
89 frame_flags_ = SetFrameFlags(video->frame(), cfg_.ts_number_layers); | 108 frame_flags_ = SetFrameFlags(video->frame(), |
| 109 cfg_.ts_number_layers, |
| 110 pattern_switch_); |
90 for (unsigned int i = 0; i < droppable_nframes_; ++i) { | 111 for (unsigned int i = 0; i < droppable_nframes_; ++i) { |
91 if (droppable_frames_[i] == video->frame()) { | 112 if (droppable_frames_[i] == video->frame()) { |
92 std::cout << "Encoding droppable frame: " | 113 std::cout << "Encoding droppable frame: " |
93 << droppable_frames_[i] << "\n"; | 114 << droppable_frames_[i] << "\n"; |
94 } | 115 } |
95 } | 116 } |
96 } else { | 117 } else { |
97 if (droppable_nframes_ > 0 && | 118 if (droppable_nframes_ > 0 && |
98 (cfg_.g_pass == VPX_RC_LAST_PASS || cfg_.g_pass == VPX_RC_ONE_PASS)) { | 119 (cfg_.g_pass == VPX_RC_LAST_PASS || cfg_.g_pass == VPX_RC_ONE_PASS)) { |
99 for (unsigned int i = 0; i < droppable_nframes_; ++i) { | 120 for (unsigned int i = 0; i < droppable_nframes_; ++i) { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
161 num = 0; | 182 num = 0; |
162 droppable_nframes_ = num; | 183 droppable_nframes_ = num; |
163 for (unsigned int i = 0; i < droppable_nframes_; ++i) | 184 for (unsigned int i = 0; i < droppable_nframes_; ++i) |
164 droppable_frames_[i] = list[i]; | 185 droppable_frames_[i] = list[i]; |
165 } | 186 } |
166 | 187 |
167 unsigned int GetMismatchFrames() { | 188 unsigned int GetMismatchFrames() { |
168 return mismatch_nframes_; | 189 return mismatch_nframes_; |
169 } | 190 } |
170 | 191 |
| 192 void SetPatternSwitch(int frame_switch) { |
| 193 pattern_switch_ = frame_switch; |
| 194 } |
| 195 |
171 private: | 196 private: |
172 double psnr_; | 197 double psnr_; |
173 unsigned int nframes_; | 198 unsigned int nframes_; |
174 unsigned int error_nframes_; | 199 unsigned int error_nframes_; |
175 unsigned int droppable_nframes_; | 200 unsigned int droppable_nframes_; |
| 201 unsigned int pattern_switch_; |
176 double mismatch_psnr_; | 202 double mismatch_psnr_; |
177 unsigned int mismatch_nframes_; | 203 unsigned int mismatch_nframes_; |
178 unsigned int error_frames_[kMaxErrorFrames]; | 204 unsigned int error_frames_[kMaxErrorFrames]; |
179 unsigned int droppable_frames_[kMaxDroppableFrames]; | 205 unsigned int droppable_frames_[kMaxDroppableFrames]; |
180 libvpx_test::TestMode encoding_mode_; | 206 libvpx_test::TestMode encoding_mode_; |
181 }; | 207 }; |
182 | 208 |
183 TEST_P(ErrorResilienceTestLarge, OnVersusOff) { | 209 TEST_P(ErrorResilienceTestLarge, OnVersusOff) { |
184 const vpx_rational timebase = { 33333333, 1000000000 }; | 210 const vpx_rational timebase = { 33333333, 1000000000 }; |
185 cfg_.g_timebase = timebase; | 211 cfg_.g_timebase = timebase; |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 cfg_.ts_target_bitrate[1] = cfg_.rc_target_bitrate; | 318 cfg_.ts_target_bitrate[1] = cfg_.rc_target_bitrate; |
293 | 319 |
294 init_flags_ = VPX_CODEC_USE_PSNR; | 320 init_flags_ = VPX_CODEC_USE_PSNR; |
295 | 321 |
296 libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, | 322 libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, |
297 timebase.den, timebase.num, 0, 40); | 323 timebase.den, timebase.num, 0, 40); |
298 | 324 |
299 // Error resilient mode ON. | 325 // Error resilient mode ON. |
300 cfg_.g_error_resilient = 1; | 326 cfg_.g_error_resilient = 1; |
301 cfg_.kf_mode = VPX_KF_DISABLED; | 327 cfg_.kf_mode = VPX_KF_DISABLED; |
| 328 SetPatternSwitch(0); |
302 | 329 |
303 // The odd frames are the enhancement layer for 2 layer pattern, so set | 330 // The odd frames are the enhancement layer for 2 layer pattern, so set |
304 // those frames as droppable. Drop the last 7 frames. | 331 // those frames as droppable. Drop the last 7 frames. |
305 unsigned int num_droppable_frames = 7; | 332 unsigned int num_droppable_frames = 7; |
306 unsigned int droppable_frame_list[] = {27, 29, 31, 33, 35, 37, 39}; | 333 unsigned int droppable_frame_list[] = {27, 29, 31, 33, 35, 37, 39}; |
307 SetDroppableFrames(num_droppable_frames, droppable_frame_list); | 334 SetDroppableFrames(num_droppable_frames, droppable_frame_list); |
308 SetErrorFrames(num_droppable_frames, droppable_frame_list); | 335 SetErrorFrames(num_droppable_frames, droppable_frame_list); |
309 ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); | 336 ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); |
310 // Test that no mismatches have been found | 337 // Test that no mismatches have been found |
311 std::cout << " Mismatch frames: " | 338 std::cout << " Mismatch frames: " |
312 << GetMismatchFrames() << "\n"; | 339 << GetMismatchFrames() << "\n"; |
313 EXPECT_EQ(GetMismatchFrames(), (unsigned int) 0); | 340 EXPECT_EQ(GetMismatchFrames(), (unsigned int) 0); |
314 | 341 |
315 // Reset previously set of error/droppable frames. | 342 // Reset previously set of error/droppable frames. |
316 Reset(); | 343 Reset(); |
317 } | 344 } |
318 | 345 |
| 346 // Check for successful decoding and no encoder/decoder mismatch |
| 347 // for a two layer temporal pattern, where at some point in the |
| 348 // sequence, the LAST ref is not used anymore. |
| 349 TEST_P(ErrorResilienceTestLarge, 2LayersNoRefLast) { |
| 350 const vpx_rational timebase = { 33333333, 1000000000 }; |
| 351 cfg_.g_timebase = timebase; |
| 352 cfg_.rc_target_bitrate = 500; |
| 353 cfg_.g_lag_in_frames = 0; |
| 354 |
| 355 cfg_.rc_end_usage = VPX_CBR; |
| 356 // 2 Temporal layers, no spatial layers, CBR mode. |
| 357 cfg_.ss_number_layers = 1; |
| 358 cfg_.ts_number_layers = 2; |
| 359 cfg_.ts_rate_decimator[0] = 2; |
| 360 cfg_.ts_rate_decimator[1] = 1; |
| 361 cfg_.ts_periodicity = 2; |
| 362 cfg_.ts_target_bitrate[0] = 60 * cfg_.rc_target_bitrate / 100; |
| 363 cfg_.ts_target_bitrate[1] = cfg_.rc_target_bitrate; |
| 364 |
| 365 init_flags_ = VPX_CODEC_USE_PSNR; |
| 366 |
| 367 libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, |
| 368 timebase.den, timebase.num, 0, 100); |
| 369 |
| 370 // Error resilient mode ON. |
| 371 cfg_.g_error_resilient = 1; |
| 372 cfg_.kf_mode = VPX_KF_DISABLED; |
| 373 SetPatternSwitch(60); |
| 374 |
| 375 ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); |
| 376 // Test that no mismatches have been found |
| 377 std::cout << " Mismatch frames: " |
| 378 << GetMismatchFrames() << "\n"; |
| 379 EXPECT_EQ(GetMismatchFrames(), (unsigned int) 0); |
| 380 |
| 381 // Reset previously set of error/droppable frames. |
| 382 Reset(); |
| 383 } |
| 384 |
319 class ErrorResilienceTestLargeCodecControls : public ::libvpx_test::EncoderTest, | 385 class ErrorResilienceTestLargeCodecControls : public ::libvpx_test::EncoderTest, |
320 public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> { | 386 public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> { |
321 protected: | 387 protected: |
322 ErrorResilienceTestLargeCodecControls() | 388 ErrorResilienceTestLargeCodecControls() |
323 : EncoderTest(GET_PARAM(0)), | 389 : EncoderTest(GET_PARAM(0)), |
324 encoding_mode_(GET_PARAM(1)) { | 390 encoding_mode_(GET_PARAM(1)) { |
325 Reset(); | 391 Reset(); |
326 } | 392 } |
327 | 393 |
328 virtual ~ErrorResilienceTestLargeCodecControls() {} | 394 virtual ~ErrorResilienceTestLargeCodecControls() {} |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
511 "for layer: " << j; | 577 "for layer: " << j; |
512 } | 578 } |
513 } | 579 } |
514 } | 580 } |
515 | 581 |
516 VP8_INSTANTIATE_TEST_CASE(ErrorResilienceTestLarge, ONE_PASS_TEST_MODES); | 582 VP8_INSTANTIATE_TEST_CASE(ErrorResilienceTestLarge, ONE_PASS_TEST_MODES); |
517 VP8_INSTANTIATE_TEST_CASE(ErrorResilienceTestLargeCodecControls, | 583 VP8_INSTANTIATE_TEST_CASE(ErrorResilienceTestLargeCodecControls, |
518 ONE_PASS_TEST_MODES); | 584 ONE_PASS_TEST_MODES); |
519 VP9_INSTANTIATE_TEST_CASE(ErrorResilienceTestLarge, ONE_PASS_TEST_MODES); | 585 VP9_INSTANTIATE_TEST_CASE(ErrorResilienceTestLarge, ONE_PASS_TEST_MODES); |
520 } // namespace | 586 } // namespace |
OLD | NEW |