| Index: source/libvpx/test/error_resilience_test.cc
|
| ===================================================================
|
| --- source/libvpx/test/error_resilience_test.cc (revision 293081)
|
| +++ source/libvpx/test/error_resilience_test.cc (working copy)
|
| @@ -56,22 +56,57 @@
|
| nframes_++;
|
| }
|
|
|
| - virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video) {
|
| + //
|
| + // Frame flags and layer id for temporal layers.
|
| + // For two layers, test pattern is:
|
| + // 1 3
|
| + // 0 2 .....
|
| + // LAST is updated on base/layer 0, GOLDEN updated on layer 1.
|
| + int SetFrameFlags(int frame_num, int num_temp_layers) {
|
| + int frame_flags = 0;
|
| + if (num_temp_layers == 2) {
|
| + if (frame_num % 2 == 0) {
|
| + // Layer 0: predict from L and ARF, update L.
|
| + frame_flags = VP8_EFLAG_NO_REF_GF |
|
| + VP8_EFLAG_NO_UPD_GF |
|
| + VP8_EFLAG_NO_UPD_ARF;
|
| + } else {
|
| + // Layer 1: predict from L, GF, and ARF, and update GF.
|
| + frame_flags = VP8_EFLAG_NO_UPD_ARF |
|
| + VP8_EFLAG_NO_UPD_LAST;
|
| + }
|
| + }
|
| + return frame_flags;
|
| + }
|
| +
|
| + virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
|
| + ::libvpx_test::Encoder *encoder) {
|
| frame_flags_ &= ~(VP8_EFLAG_NO_UPD_LAST |
|
| VP8_EFLAG_NO_UPD_GF |
|
| VP8_EFLAG_NO_UPD_ARF);
|
| - if (droppable_nframes_ > 0 &&
|
| - (cfg_.g_pass == VPX_RC_LAST_PASS || cfg_.g_pass == VPX_RC_ONE_PASS)) {
|
| + // For temporal layer case.
|
| + if (cfg_.ts_number_layers > 1) {
|
| + frame_flags_ = SetFrameFlags(video->frame(), cfg_.ts_number_layers);
|
| for (unsigned int i = 0; i < droppable_nframes_; ++i) {
|
| if (droppable_frames_[i] == video->frame()) {
|
| - std::cout << " Encoding droppable frame: "
|
| + std::cout << "Encoding droppable frame: "
|
| << droppable_frames_[i] << "\n";
|
| - frame_flags_ |= (VP8_EFLAG_NO_UPD_LAST |
|
| - VP8_EFLAG_NO_UPD_GF |
|
| - VP8_EFLAG_NO_UPD_ARF);
|
| - return;
|
| }
|
| }
|
| + } else {
|
| + if (droppable_nframes_ > 0 &&
|
| + (cfg_.g_pass == VPX_RC_LAST_PASS || cfg_.g_pass == VPX_RC_ONE_PASS)) {
|
| + for (unsigned int i = 0; i < droppable_nframes_; ++i) {
|
| + if (droppable_frames_[i] == video->frame()) {
|
| + std::cout << "Encoding droppable frame: "
|
| + << droppable_frames_[i] << "\n";
|
| + frame_flags_ |= (VP8_EFLAG_NO_UPD_LAST |
|
| + VP8_EFLAG_NO_UPD_GF |
|
| + VP8_EFLAG_NO_UPD_ARF);
|
| + return;
|
| + }
|
| + }
|
| + }
|
| }
|
| }
|
|
|
| @@ -236,6 +271,51 @@
|
| #endif
|
| }
|
|
|
| +// Check for successful decoding and no encoder/decoder mismatch
|
| +// if we lose (i.e., drop before decoding) the enhancement layer frames for a
|
| +// two layer temporal pattern. The base layer does not predict from the top
|
| +// layer, so successful decoding is expected.
|
| +TEST_P(ErrorResilienceTestLarge, 2LayersDropEnhancement) {
|
| + const vpx_rational timebase = { 33333333, 1000000000 };
|
| + cfg_.g_timebase = timebase;
|
| + cfg_.rc_target_bitrate = 500;
|
| + cfg_.g_lag_in_frames = 0;
|
| +
|
| + cfg_.rc_end_usage = VPX_CBR;
|
| + // 2 Temporal layers, no spatial layers, CBR mode.
|
| + cfg_.ss_number_layers = 1;
|
| + cfg_.ts_number_layers = 2;
|
| + cfg_.ts_rate_decimator[0] = 2;
|
| + cfg_.ts_rate_decimator[1] = 1;
|
| + cfg_.ts_periodicity = 2;
|
| + cfg_.ts_target_bitrate[0] = 60 * cfg_.rc_target_bitrate / 100;
|
| + cfg_.ts_target_bitrate[1] = cfg_.rc_target_bitrate;
|
| +
|
| + init_flags_ = VPX_CODEC_USE_PSNR;
|
| +
|
| + libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
| + timebase.den, timebase.num, 0, 40);
|
| +
|
| + // Error resilient mode ON.
|
| + cfg_.g_error_resilient = 1;
|
| + cfg_.kf_mode = VPX_KF_DISABLED;
|
| +
|
| + // The odd frames are the enhancement layer for 2 layer pattern, so set
|
| + // those frames as droppable. Drop the last 7 frames.
|
| + unsigned int num_droppable_frames = 7;
|
| + unsigned int droppable_frame_list[] = {27, 29, 31, 33, 35, 37, 39};
|
| + SetDroppableFrames(num_droppable_frames, droppable_frame_list);
|
| + SetErrorFrames(num_droppable_frames, droppable_frame_list);
|
| + ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
| + // Test that no mismatches have been found
|
| + std::cout << " Mismatch frames: "
|
| + << GetMismatchFrames() << "\n";
|
| + EXPECT_EQ(GetMismatchFrames(), (unsigned int) 0);
|
| +
|
| + // Reset previously set of error/droppable frames.
|
| + Reset();
|
| +}
|
| +
|
| VP8_INSTANTIATE_TEST_CASE(ErrorResilienceTestLarge, ONE_PASS_TEST_MODES);
|
| VP9_INSTANTIATE_TEST_CASE(ErrorResilienceTestLarge, ONE_PASS_TEST_MODES);
|
|
|
|
|