| 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 |