11b362b15af34006e6a11974088a46d42b903418eJohann/*
2b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian *  Copyright (c) 2013 The WebM project authors. All Rights Reserved.
3b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian *
4b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian *  Use of this source code is governed by a BSD-style license
5b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian *  that can be found in the LICENSE file in the root of the source
6b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian *  tree. An additional intellectual property rights grant can be found
7b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian *  in the file PATENTS.  All contributing project authors may
8b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian *  be found in the AUTHORS file in the root of the source tree.
9b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian */
10ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
111b362b15af34006e6a11974088a46d42b903418eJohann#include "third_party/googletest/src/include/gtest/gtest.h"
12ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "test/codec_factory.h"
131b362b15af34006e6a11974088a46d42b903418eJohann#include "test/encode_test_driver.h"
141b362b15af34006e6a11974088a46d42b903418eJohann#include "test/i420_video_source.h"
15ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "test/util.h"
161b362b15af34006e6a11974088a46d42b903418eJohann
171b362b15af34006e6a11974088a46d42b903418eJohannnamespace {
181b362b15af34006e6a11974088a46d42b903418eJohann
19b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianconst int kMaxErrorFrames = 12;
20b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianconst int kMaxDroppableFrames = 12;
21ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
22a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanianclass ErrorResilienceTestLarge : public ::libvpx_test::EncoderTest,
23ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
241b362b15af34006e6a11974088a46d42b903418eJohann protected:
25a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian  ErrorResilienceTestLarge()
26a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian      : EncoderTest(GET_PARAM(0)),
27a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian        psnr_(0.0),
28a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian        nframes_(0),
29a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian        mismatch_psnr_(0.0),
30a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian        mismatch_nframes_(0),
31a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian        encoding_mode_(GET_PARAM(1)) {
32ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    Reset();
331b362b15af34006e6a11974088a46d42b903418eJohann  }
34ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
35a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian  virtual ~ErrorResilienceTestLarge() {}
361b362b15af34006e6a11974088a46d42b903418eJohann
37ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  void Reset() {
38ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    error_nframes_ = 0;
39ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    droppable_nframes_ = 0;
40ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
41ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
421b362b15af34006e6a11974088a46d42b903418eJohann  virtual void SetUp() {
431b362b15af34006e6a11974088a46d42b903418eJohann    InitializeConfig();
441b362b15af34006e6a11974088a46d42b903418eJohann    SetMode(encoding_mode_);
451b362b15af34006e6a11974088a46d42b903418eJohann  }
461b362b15af34006e6a11974088a46d42b903418eJohann
471b362b15af34006e6a11974088a46d42b903418eJohann  virtual void BeginPassHook(unsigned int /*pass*/) {
481b362b15af34006e6a11974088a46d42b903418eJohann    psnr_ = 0.0;
491b362b15af34006e6a11974088a46d42b903418eJohann    nframes_ = 0;
50ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    mismatch_psnr_ = 0.0;
51ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    mismatch_nframes_ = 0;
521b362b15af34006e6a11974088a46d42b903418eJohann  }
531b362b15af34006e6a11974088a46d42b903418eJohann
541b362b15af34006e6a11974088a46d42b903418eJohann  virtual void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) {
551b362b15af34006e6a11974088a46d42b903418eJohann    psnr_ += pkt->data.psnr.psnr[0];
561b362b15af34006e6a11974088a46d42b903418eJohann    nframes_++;
571b362b15af34006e6a11974088a46d42b903418eJohann  }
581b362b15af34006e6a11974088a46d42b903418eJohann
59ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video) {
60ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    frame_flags_ &= ~(VP8_EFLAG_NO_UPD_LAST |
61ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                      VP8_EFLAG_NO_UPD_GF |
62ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                      VP8_EFLAG_NO_UPD_ARF);
63ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (droppable_nframes_ > 0 &&
64ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        (cfg_.g_pass == VPX_RC_LAST_PASS || cfg_.g_pass == VPX_RC_ONE_PASS)) {
65ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      for (unsigned int i = 0; i < droppable_nframes_; ++i) {
663df0563f1b24dac6c0bd122fc922a48211269061hkuang        if (droppable_frames_[i] == video->frame()) {
67ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          std::cout << "             Encoding droppable frame: "
68ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                    << droppable_frames_[i] << "\n";
69ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          frame_flags_ |= (VP8_EFLAG_NO_UPD_LAST |
70ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                           VP8_EFLAG_NO_UPD_GF |
71ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                           VP8_EFLAG_NO_UPD_ARF);
72ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          return;
73ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
74ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
75ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
76ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
77ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
781b362b15af34006e6a11974088a46d42b903418eJohann  double GetAveragePsnr() const {
791b362b15af34006e6a11974088a46d42b903418eJohann    if (nframes_)
801b362b15af34006e6a11974088a46d42b903418eJohann      return psnr_ / nframes_;
811b362b15af34006e6a11974088a46d42b903418eJohann    return 0.0;
821b362b15af34006e6a11974088a46d42b903418eJohann  }
831b362b15af34006e6a11974088a46d42b903418eJohann
84ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  double GetAverageMismatchPsnr() const {
85ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (mismatch_nframes_)
86ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      return mismatch_psnr_ / mismatch_nframes_;
87ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    return 0.0;
88ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
89ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
90ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  virtual bool DoDecode() const {
91ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (error_nframes_ > 0 &&
92ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        (cfg_.g_pass == VPX_RC_LAST_PASS || cfg_.g_pass == VPX_RC_ONE_PASS)) {
93ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      for (unsigned int i = 0; i < error_nframes_; ++i) {
94ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        if (error_frames_[i] == nframes_ - 1) {
95ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          std::cout << "             Skipping decoding frame: "
96ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                    << error_frames_[i] << "\n";
97ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          return 0;
98ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
99ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
100ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
101ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    return 1;
102ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
103ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
104ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  virtual void MismatchHook(const vpx_image_t *img1,
105ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                            const vpx_image_t *img2) {
106ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    double mismatch_psnr = compute_psnr(img1, img2);
107ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    mismatch_psnr_ += mismatch_psnr;
108ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ++mismatch_nframes_;
109ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // std::cout << "Mismatch frame psnr: " << mismatch_psnr << "\n";
110ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
111ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
112ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  void SetErrorFrames(int num, unsigned int *list) {
113ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (num > kMaxErrorFrames)
114ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      num = kMaxErrorFrames;
115ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    else if (num < 0)
116ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      num = 0;
117ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    error_nframes_ = num;
118ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (unsigned int i = 0; i < error_nframes_; ++i)
119ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      error_frames_[i] = list[i];
120ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
121ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
122ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  void SetDroppableFrames(int num, unsigned int *list) {
123ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (num > kMaxDroppableFrames)
124ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      num = kMaxDroppableFrames;
125ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    else if (num < 0)
126ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      num = 0;
127ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    droppable_nframes_ = num;
128ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (unsigned int i = 0; i < droppable_nframes_; ++i)
129ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      droppable_frames_[i] = list[i];
130ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
131ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
132ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  unsigned int GetMismatchFrames() {
133ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    return mismatch_nframes_;
134ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
135ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1361b362b15af34006e6a11974088a46d42b903418eJohann private:
1371b362b15af34006e6a11974088a46d42b903418eJohann  double psnr_;
1381b362b15af34006e6a11974088a46d42b903418eJohann  unsigned int nframes_;
139ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  unsigned int error_nframes_;
140ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  unsigned int droppable_nframes_;
141ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  double mismatch_psnr_;
142ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  unsigned int mismatch_nframes_;
143ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  unsigned int error_frames_[kMaxErrorFrames];
144ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  unsigned int droppable_frames_[kMaxDroppableFrames];
1451b362b15af34006e6a11974088a46d42b903418eJohann  libvpx_test::TestMode encoding_mode_;
1461b362b15af34006e6a11974088a46d42b903418eJohann};
1471b362b15af34006e6a11974088a46d42b903418eJohann
148a72801d7d92ababb50eecf27a36bd222d031d2feVignesh VenkatasubramanianTEST_P(ErrorResilienceTestLarge, OnVersusOff) {
1491b362b15af34006e6a11974088a46d42b903418eJohann  const vpx_rational timebase = { 33333333, 1000000000 };
1501b362b15af34006e6a11974088a46d42b903418eJohann  cfg_.g_timebase = timebase;
1511b362b15af34006e6a11974088a46d42b903418eJohann  cfg_.rc_target_bitrate = 2000;
1523df0563f1b24dac6c0bd122fc922a48211269061hkuang  cfg_.g_lag_in_frames = 10;
1531b362b15af34006e6a11974088a46d42b903418eJohann
1541b362b15af34006e6a11974088a46d42b903418eJohann  init_flags_ = VPX_CODEC_USE_PSNR;
1551b362b15af34006e6a11974088a46d42b903418eJohann
1561b362b15af34006e6a11974088a46d42b903418eJohann  libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
1571b362b15af34006e6a11974088a46d42b903418eJohann                                     timebase.den, timebase.num, 0, 30);
1581b362b15af34006e6a11974088a46d42b903418eJohann
1591b362b15af34006e6a11974088a46d42b903418eJohann  // Error resilient mode OFF.
1601b362b15af34006e6a11974088a46d42b903418eJohann  cfg_.g_error_resilient = 0;
1611b362b15af34006e6a11974088a46d42b903418eJohann  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1621b362b15af34006e6a11974088a46d42b903418eJohann  const double psnr_resilience_off = GetAveragePsnr();
1631b362b15af34006e6a11974088a46d42b903418eJohann  EXPECT_GT(psnr_resilience_off, 25.0);
1641b362b15af34006e6a11974088a46d42b903418eJohann
1651b362b15af34006e6a11974088a46d42b903418eJohann  // Error resilient mode ON.
1661b362b15af34006e6a11974088a46d42b903418eJohann  cfg_.g_error_resilient = 1;
1671b362b15af34006e6a11974088a46d42b903418eJohann  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1681b362b15af34006e6a11974088a46d42b903418eJohann  const double psnr_resilience_on = GetAveragePsnr();
1691b362b15af34006e6a11974088a46d42b903418eJohann  EXPECT_GT(psnr_resilience_on, 25.0);
1701b362b15af34006e6a11974088a46d42b903418eJohann
1711b362b15af34006e6a11974088a46d42b903418eJohann  // Test that turning on error resilient mode hurts by 10% at most.
1721b362b15af34006e6a11974088a46d42b903418eJohann  if (psnr_resilience_off > 0.0) {
1731b362b15af34006e6a11974088a46d42b903418eJohann    const double psnr_ratio = psnr_resilience_on / psnr_resilience_off;
1741b362b15af34006e6a11974088a46d42b903418eJohann    EXPECT_GE(psnr_ratio, 0.9);
1751b362b15af34006e6a11974088a46d42b903418eJohann    EXPECT_LE(psnr_ratio, 1.1);
1761b362b15af34006e6a11974088a46d42b903418eJohann  }
1771b362b15af34006e6a11974088a46d42b903418eJohann}
1781b362b15af34006e6a11974088a46d42b903418eJohann
179b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// Check for successful decoding and no encoder/decoder mismatch
180b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// if we lose (i.e., drop before decoding) a set of droppable
181b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// frames (i.e., frames that don't update any reference buffers).
182b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// Check both isolated and consecutive loss.
183a72801d7d92ababb50eecf27a36bd222d031d2feVignesh VenkatasubramanianTEST_P(ErrorResilienceTestLarge, DropFramesWithoutRecovery) {
184ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const vpx_rational timebase = { 33333333, 1000000000 };
185ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  cfg_.g_timebase = timebase;
186ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  cfg_.rc_target_bitrate = 500;
1873df0563f1b24dac6c0bd122fc922a48211269061hkuang  // FIXME(debargha): Fix this to work for any lag.
1883df0563f1b24dac6c0bd122fc922a48211269061hkuang  // Currently this test only works for lag = 0
1893df0563f1b24dac6c0bd122fc922a48211269061hkuang  cfg_.g_lag_in_frames = 0;
190ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
191ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  init_flags_ = VPX_CODEC_USE_PSNR;
192ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
193ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
194b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                     timebase.den, timebase.num, 0, 40);
195ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
196ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Error resilient mode ON.
197ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  cfg_.g_error_resilient = 1;
198b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  cfg_.kf_mode = VPX_KF_DISABLED;
199b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
200b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  // Set an arbitrary set of error frames same as droppable frames.
201b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  // In addition to isolated loss/drop, add a long consecutive series
202b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  // (of size 9) of dropped frames.
203b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  unsigned int num_droppable_frames = 11;
204b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  unsigned int droppable_frame_list[] = {5, 16, 22, 23, 24, 25, 26, 27, 28,
205b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                         29, 30};
206ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  SetDroppableFrames(num_droppable_frames, droppable_frame_list);
207ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  SetErrorFrames(num_droppable_frames, droppable_frame_list);
208ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
209ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Test that no mismatches have been found
210ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  std::cout << "             Mismatch frames: "
211ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            << GetMismatchFrames() << "\n";
212ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  EXPECT_EQ(GetMismatchFrames(), (unsigned int) 0);
213ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
214b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  // Reset previously set of error/droppable frames.
215ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  Reset();
216ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
217ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#if 0
218ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // TODO(jkoleszar): This test is disabled for the time being as too
219ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // sensitive. It's not clear how to set a reasonable threshold for
220ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // this behavior.
221ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
222ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Now set an arbitrary set of error frames that are non-droppable
223ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  unsigned int num_error_frames = 3;
224ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  unsigned int error_frame_list[] = {3, 10, 20};
225ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  SetErrorFrames(num_error_frames, error_frame_list);
226ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
227ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
228ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Test that dropping an arbitrary set of inter frames does not hurt too much
229ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Note the Average Mismatch PSNR is the average of the PSNR between
230ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // decoded frame and encoder's version of the same frame for all frames
231ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // with mismatch.
232ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const double psnr_resilience_mismatch = GetAverageMismatchPsnr();
233ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  std::cout << "             Mismatch PSNR: "
234ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            << psnr_resilience_mismatch << "\n";
235ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  EXPECT_GT(psnr_resilience_mismatch, 20.0);
236ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#endif
237ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
238ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
239a72801d7d92ababb50eecf27a36bd222d031d2feVignesh VenkatasubramanianVP8_INSTANTIATE_TEST_CASE(ErrorResilienceTestLarge, ONE_PASS_TEST_MODES);
240a72801d7d92ababb50eecf27a36bd222d031d2feVignesh VenkatasubramanianVP9_INSTANTIATE_TEST_CASE(ErrorResilienceTestLarge, ONE_PASS_TEST_MODES);
241ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2421b362b15af34006e6a11974088a46d42b903418eJohann}  // namespace
243