1/*
2 *  Copyright (c) 2013 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 "third_party/googletest/src/include/gtest/gtest.h"
12#include "test/codec_factory.h"
13#include "test/encode_test_driver.h"
14#include "test/i420_video_source.h"
15#include "test/util.h"
16
17namespace {
18
19const int kMaxErrorFrames = 12;
20const int kMaxDroppableFrames = 12;
21
22class ErrorResilienceTestLarge
23    : public ::libvpx_test::EncoderTest,
24      public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, bool> {
25 protected:
26  ErrorResilienceTestLarge()
27      : EncoderTest(GET_PARAM(0)), svc_support_(GET_PARAM(2)), psnr_(0.0),
28        nframes_(0), mismatch_psnr_(0.0), mismatch_nframes_(0),
29        encoding_mode_(GET_PARAM(1)) {
30    Reset();
31  }
32
33  virtual ~ErrorResilienceTestLarge() {}
34
35  void Reset() {
36    error_nframes_ = 0;
37    droppable_nframes_ = 0;
38    pattern_switch_ = 0;
39  }
40
41  virtual void SetUp() {
42    InitializeConfig();
43    SetMode(encoding_mode_);
44  }
45
46  virtual void BeginPassHook(unsigned int /*pass*/) {
47    psnr_ = 0.0;
48    nframes_ = 0;
49    mismatch_psnr_ = 0.0;
50    mismatch_nframes_ = 0;
51  }
52
53  virtual void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) {
54    psnr_ += pkt->data.psnr.psnr[0];
55    nframes_++;
56  }
57
58  //
59  // Frame flags and layer id for temporal layers.
60  // For two layers, test pattern is:
61  //   1     3
62  // 0    2     .....
63  // LAST is updated on base/layer 0, GOLDEN  updated on layer 1.
64  // Non-zero pattern_switch parameter means pattern will switch to
65  // not using LAST for frame_num >= pattern_switch.
66  int SetFrameFlags(int frame_num, int num_temp_layers, int pattern_switch) {
67    int frame_flags = 0;
68    if (num_temp_layers == 2) {
69      if (frame_num % 2 == 0) {
70        if (frame_num < pattern_switch || pattern_switch == 0) {
71          // Layer 0: predict from LAST and ARF, update LAST.
72          frame_flags =
73              VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
74        } else {
75          // Layer 0: predict from GF and ARF, update GF.
76          frame_flags = VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_UPD_LAST |
77                        VP8_EFLAG_NO_UPD_ARF;
78        }
79      } else {
80        if (frame_num < pattern_switch || pattern_switch == 0) {
81          // Layer 1: predict from L, GF, and ARF, update GF.
82          frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
83        } else {
84          // Layer 1: predict from GF and ARF, update GF.
85          frame_flags = VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_UPD_LAST |
86                        VP8_EFLAG_NO_UPD_ARF;
87        }
88      }
89    }
90    return frame_flags;
91  }
92
93  virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video) {
94    frame_flags_ &=
95        ~(VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF);
96    // For temporal layer case.
97    if (cfg_.ts_number_layers > 1) {
98      frame_flags_ =
99          SetFrameFlags(video->frame(), cfg_.ts_number_layers, pattern_switch_);
100      for (unsigned int i = 0; i < droppable_nframes_; ++i) {
101        if (droppable_frames_[i] == video->frame()) {
102          std::cout << "Encoding droppable frame: " << droppable_frames_[i]
103                    << "\n";
104        }
105      }
106    } else {
107      if (droppable_nframes_ > 0 &&
108          (cfg_.g_pass == VPX_RC_LAST_PASS || cfg_.g_pass == VPX_RC_ONE_PASS)) {
109        for (unsigned int i = 0; i < droppable_nframes_; ++i) {
110          if (droppable_frames_[i] == video->frame()) {
111            std::cout << "Encoding droppable frame: " << droppable_frames_[i]
112                      << "\n";
113            frame_flags_ |= (VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF |
114                             VP8_EFLAG_NO_UPD_ARF);
115            return;
116          }
117        }
118      }
119    }
120  }
121
122  double GetAveragePsnr() const {
123    if (nframes_) return psnr_ / nframes_;
124    return 0.0;
125  }
126
127  double GetAverageMismatchPsnr() const {
128    if (mismatch_nframes_) return mismatch_psnr_ / mismatch_nframes_;
129    return 0.0;
130  }
131
132  virtual bool DoDecode() const {
133    if (error_nframes_ > 0 &&
134        (cfg_.g_pass == VPX_RC_LAST_PASS || cfg_.g_pass == VPX_RC_ONE_PASS)) {
135      for (unsigned int i = 0; i < error_nframes_; ++i) {
136        if (error_frames_[i] == nframes_ - 1) {
137          std::cout << "             Skipping decoding frame: "
138                    << error_frames_[i] << "\n";
139          return 0;
140        }
141      }
142    }
143    return 1;
144  }
145
146  virtual void MismatchHook(const vpx_image_t *img1, const vpx_image_t *img2) {
147    double mismatch_psnr = compute_psnr(img1, img2);
148    mismatch_psnr_ += mismatch_psnr;
149    ++mismatch_nframes_;
150    // std::cout << "Mismatch frame psnr: " << mismatch_psnr << "\n";
151  }
152
153  void SetErrorFrames(int num, unsigned int *list) {
154    if (num > kMaxErrorFrames) {
155      num = kMaxErrorFrames;
156    } else if (num < 0) {
157      num = 0;
158    }
159    error_nframes_ = num;
160    for (unsigned int i = 0; i < error_nframes_; ++i) {
161      error_frames_[i] = list[i];
162    }
163  }
164
165  void SetDroppableFrames(int num, unsigned int *list) {
166    if (num > kMaxDroppableFrames) {
167      num = kMaxDroppableFrames;
168    } else if (num < 0) {
169      num = 0;
170    }
171    droppable_nframes_ = num;
172    for (unsigned int i = 0; i < droppable_nframes_; ++i) {
173      droppable_frames_[i] = list[i];
174    }
175  }
176
177  unsigned int GetMismatchFrames() { return mismatch_nframes_; }
178
179  void SetPatternSwitch(int frame_switch) { pattern_switch_ = frame_switch; }
180
181  bool svc_support_;
182
183 private:
184  double psnr_;
185  unsigned int nframes_;
186  unsigned int error_nframes_;
187  unsigned int droppable_nframes_;
188  unsigned int pattern_switch_;
189  double mismatch_psnr_;
190  unsigned int mismatch_nframes_;
191  unsigned int error_frames_[kMaxErrorFrames];
192  unsigned int droppable_frames_[kMaxDroppableFrames];
193  libvpx_test::TestMode encoding_mode_;
194};
195
196TEST_P(ErrorResilienceTestLarge, OnVersusOff) {
197  const vpx_rational timebase = { 33333333, 1000000000 };
198  cfg_.g_timebase = timebase;
199  cfg_.rc_target_bitrate = 2000;
200  cfg_.g_lag_in_frames = 10;
201
202  init_flags_ = VPX_CODEC_USE_PSNR;
203
204  libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
205                                     timebase.den, timebase.num, 0, 30);
206
207  // Error resilient mode OFF.
208  cfg_.g_error_resilient = 0;
209  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
210  const double psnr_resilience_off = GetAveragePsnr();
211  EXPECT_GT(psnr_resilience_off, 25.0);
212
213  // Error resilient mode ON.
214  cfg_.g_error_resilient = 1;
215  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
216  const double psnr_resilience_on = GetAveragePsnr();
217  EXPECT_GT(psnr_resilience_on, 25.0);
218
219  // Test that turning on error resilient mode hurts by 10% at most.
220  if (psnr_resilience_off > 0.0) {
221    const double psnr_ratio = psnr_resilience_on / psnr_resilience_off;
222    EXPECT_GE(psnr_ratio, 0.9);
223    EXPECT_LE(psnr_ratio, 1.1);
224  }
225}
226
227// Check for successful decoding and no encoder/decoder mismatch
228// if we lose (i.e., drop before decoding) a set of droppable
229// frames (i.e., frames that don't update any reference buffers).
230// Check both isolated and consecutive loss.
231TEST_P(ErrorResilienceTestLarge, DropFramesWithoutRecovery) {
232  const vpx_rational timebase = { 33333333, 1000000000 };
233  cfg_.g_timebase = timebase;
234  cfg_.rc_target_bitrate = 500;
235  // FIXME(debargha): Fix this to work for any lag.
236  // Currently this test only works for lag = 0
237  cfg_.g_lag_in_frames = 0;
238
239  init_flags_ = VPX_CODEC_USE_PSNR;
240
241  libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
242                                     timebase.den, timebase.num, 0, 40);
243
244  // Error resilient mode ON.
245  cfg_.g_error_resilient = 1;
246  cfg_.kf_mode = VPX_KF_DISABLED;
247
248  // Set an arbitrary set of error frames same as droppable frames.
249  // In addition to isolated loss/drop, add a long consecutive series
250  // (of size 9) of dropped frames.
251  unsigned int num_droppable_frames = 11;
252  unsigned int droppable_frame_list[] = { 5,  16, 22, 23, 24, 25,
253                                          26, 27, 28, 29, 30 };
254  SetDroppableFrames(num_droppable_frames, droppable_frame_list);
255  SetErrorFrames(num_droppable_frames, droppable_frame_list);
256  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
257  // Test that no mismatches have been found
258  std::cout << "             Mismatch frames: " << GetMismatchFrames() << "\n";
259  EXPECT_EQ(GetMismatchFrames(), (unsigned int)0);
260
261  // Reset previously set of error/droppable frames.
262  Reset();
263
264#if 0
265  // TODO(jkoleszar): This test is disabled for the time being as too
266  // sensitive. It's not clear how to set a reasonable threshold for
267  // this behavior.
268
269  // Now set an arbitrary set of error frames that are non-droppable
270  unsigned int num_error_frames = 3;
271  unsigned int error_frame_list[] = {3, 10, 20};
272  SetErrorFrames(num_error_frames, error_frame_list);
273  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
274
275  // Test that dropping an arbitrary set of inter frames does not hurt too much
276  // Note the Average Mismatch PSNR is the average of the PSNR between
277  // decoded frame and encoder's version of the same frame for all frames
278  // with mismatch.
279  const double psnr_resilience_mismatch = GetAverageMismatchPsnr();
280  std::cout << "             Mismatch PSNR: "
281            << psnr_resilience_mismatch << "\n";
282  EXPECT_GT(psnr_resilience_mismatch, 20.0);
283#endif
284}
285
286// Check for successful decoding and no encoder/decoder mismatch
287// if we lose (i.e., drop before decoding) the enhancement layer frames for a
288// two layer temporal pattern. The base layer does not predict from the top
289// layer, so successful decoding is expected.
290TEST_P(ErrorResilienceTestLarge, 2LayersDropEnhancement) {
291  // This test doesn't run if SVC is not supported.
292  if (!svc_support_) return;
293
294  const vpx_rational timebase = { 33333333, 1000000000 };
295  cfg_.g_timebase = timebase;
296  cfg_.rc_target_bitrate = 500;
297  cfg_.g_lag_in_frames = 0;
298
299  cfg_.rc_end_usage = VPX_CBR;
300  // 2 Temporal layers, no spatial layers, CBR mode.
301  cfg_.ss_number_layers = 1;
302  cfg_.ts_number_layers = 2;
303  cfg_.ts_rate_decimator[0] = 2;
304  cfg_.ts_rate_decimator[1] = 1;
305  cfg_.ts_periodicity = 2;
306  cfg_.ts_target_bitrate[0] = 60 * cfg_.rc_target_bitrate / 100;
307  cfg_.ts_target_bitrate[1] = cfg_.rc_target_bitrate;
308
309  init_flags_ = VPX_CODEC_USE_PSNR;
310
311  libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
312                                     timebase.den, timebase.num, 0, 40);
313
314  // Error resilient mode ON.
315  cfg_.g_error_resilient = 1;
316  cfg_.kf_mode = VPX_KF_DISABLED;
317  SetPatternSwitch(0);
318
319  // The odd frames are the enhancement layer for 2 layer pattern, so set
320  // those frames as droppable. Drop the last 7 frames.
321  unsigned int num_droppable_frames = 7;
322  unsigned int droppable_frame_list[] = { 27, 29, 31, 33, 35, 37, 39 };
323  SetDroppableFrames(num_droppable_frames, droppable_frame_list);
324  SetErrorFrames(num_droppable_frames, droppable_frame_list);
325  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
326  // Test that no mismatches have been found
327  std::cout << "             Mismatch frames: " << GetMismatchFrames() << "\n";
328  EXPECT_EQ(GetMismatchFrames(), (unsigned int)0);
329
330  // Reset previously set of error/droppable frames.
331  Reset();
332}
333
334// Check for successful decoding and no encoder/decoder mismatch
335// for a two layer temporal pattern, where at some point in the
336// sequence, the LAST ref is not used anymore.
337TEST_P(ErrorResilienceTestLarge, 2LayersNoRefLast) {
338  // This test doesn't run if SVC is not supported.
339  if (!svc_support_) return;
340
341  const vpx_rational timebase = { 33333333, 1000000000 };
342  cfg_.g_timebase = timebase;
343  cfg_.rc_target_bitrate = 500;
344  cfg_.g_lag_in_frames = 0;
345
346  cfg_.rc_end_usage = VPX_CBR;
347  // 2 Temporal layers, no spatial layers, CBR mode.
348  cfg_.ss_number_layers = 1;
349  cfg_.ts_number_layers = 2;
350  cfg_.ts_rate_decimator[0] = 2;
351  cfg_.ts_rate_decimator[1] = 1;
352  cfg_.ts_periodicity = 2;
353  cfg_.ts_target_bitrate[0] = 60 * cfg_.rc_target_bitrate / 100;
354  cfg_.ts_target_bitrate[1] = cfg_.rc_target_bitrate;
355
356  init_flags_ = VPX_CODEC_USE_PSNR;
357
358  libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
359                                     timebase.den, timebase.num, 0, 100);
360
361  // Error resilient mode ON.
362  cfg_.g_error_resilient = 1;
363  cfg_.kf_mode = VPX_KF_DISABLED;
364  SetPatternSwitch(60);
365
366  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
367  // Test that no mismatches have been found
368  std::cout << "             Mismatch frames: " << GetMismatchFrames() << "\n";
369  EXPECT_EQ(GetMismatchFrames(), (unsigned int)0);
370
371  // Reset previously set of error/droppable frames.
372  Reset();
373}
374
375class ErrorResilienceTestLargeCodecControls
376    : public ::libvpx_test::EncoderTest,
377      public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
378 protected:
379  ErrorResilienceTestLargeCodecControls()
380      : EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)) {
381    Reset();
382  }
383
384  virtual ~ErrorResilienceTestLargeCodecControls() {}
385
386  void Reset() {
387    last_pts_ = 0;
388    tot_frame_number_ = 0;
389    // For testing up to 3 layers.
390    for (int i = 0; i < 3; ++i) {
391      bits_total_[i] = 0;
392    }
393    duration_ = 0.0;
394  }
395
396  virtual void SetUp() {
397    InitializeConfig();
398    SetMode(encoding_mode_);
399  }
400
401  //
402  // Frame flags and layer id for temporal layers.
403  //
404
405  // For two layers, test pattern is:
406  //   1     3
407  // 0    2     .....
408  // For three layers, test pattern is:
409  //   1      3    5      7
410  //      2           6
411  // 0          4            ....
412  // LAST is always update on base/layer 0, GOLDEN is updated on layer 1,
413  // and ALTREF is updated on top layer for 3 layer pattern.
414  int SetFrameFlags(int frame_num, int num_temp_layers) {
415    int frame_flags = 0;
416    if (num_temp_layers == 2) {
417      if (frame_num % 2 == 0) {
418        // Layer 0: predict from L and ARF, update L.
419        frame_flags =
420            VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
421      } else {
422        // Layer 1: predict from L, G and ARF, and update G.
423        frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
424                      VP8_EFLAG_NO_UPD_ENTROPY;
425      }
426    } else if (num_temp_layers == 3) {
427      if (frame_num % 4 == 0) {
428        // Layer 0: predict from L, update L.
429        frame_flags = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
430                      VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF;
431      } else if ((frame_num - 2) % 4 == 0) {
432        // Layer 1: predict from L, G,  update G.
433        frame_flags =
434            VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_REF_ARF;
435      } else if ((frame_num - 1) % 2 == 0) {
436        // Layer 2: predict from L, G, ARF; update ARG.
437        frame_flags = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_LAST;
438      }
439    }
440    return frame_flags;
441  }
442
443  int SetLayerId(int frame_num, int num_temp_layers) {
444    int layer_id = 0;
445    if (num_temp_layers == 2) {
446      if (frame_num % 2 == 0) {
447        layer_id = 0;
448      } else {
449        layer_id = 1;
450      }
451    } else if (num_temp_layers == 3) {
452      if (frame_num % 4 == 0) {
453        layer_id = 0;
454      } else if ((frame_num - 2) % 4 == 0) {
455        layer_id = 1;
456      } else if ((frame_num - 1) % 2 == 0) {
457        layer_id = 2;
458      }
459    }
460    return layer_id;
461  }
462
463  virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
464                                  libvpx_test::Encoder *encoder) {
465    if (cfg_.ts_number_layers > 1) {
466      int layer_id = SetLayerId(video->frame(), cfg_.ts_number_layers);
467      int frame_flags = SetFrameFlags(video->frame(), cfg_.ts_number_layers);
468      if (video->frame() > 0) {
469        encoder->Control(VP8E_SET_TEMPORAL_LAYER_ID, layer_id);
470        encoder->Control(VP8E_SET_FRAME_FLAGS, frame_flags);
471      }
472      const vpx_rational_t tb = video->timebase();
473      timebase_ = static_cast<double>(tb.num) / tb.den;
474      duration_ = 0;
475      return;
476    }
477  }
478
479  virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
480    // Time since last timestamp = duration.
481    vpx_codec_pts_t duration = pkt->data.frame.pts - last_pts_;
482    if (duration > 1) {
483      // Update counter for total number of frames (#frames input to encoder).
484      // Needed for setting the proper layer_id below.
485      tot_frame_number_ += static_cast<int>(duration - 1);
486    }
487    int layer = SetLayerId(tot_frame_number_, cfg_.ts_number_layers);
488    const size_t frame_size_in_bits = pkt->data.frame.sz * 8;
489    // Update the total encoded bits. For temporal layers, update the cumulative
490    // encoded bits per layer.
491    for (int i = layer; i < static_cast<int>(cfg_.ts_number_layers); ++i) {
492      bits_total_[i] += frame_size_in_bits;
493    }
494    // Update the most recent pts.
495    last_pts_ = pkt->data.frame.pts;
496    ++tot_frame_number_;
497  }
498
499  virtual void EndPassHook(void) {
500    duration_ = (last_pts_ + 1) * timebase_;
501    if (cfg_.ts_number_layers > 1) {
502      for (int layer = 0; layer < static_cast<int>(cfg_.ts_number_layers);
503           ++layer) {
504        if (bits_total_[layer]) {
505          // Effective file datarate:
506          effective_datarate_[layer] =
507              (bits_total_[layer] / 1000.0) / duration_;
508        }
509      }
510    }
511  }
512
513  double effective_datarate_[3];
514
515 private:
516  libvpx_test::TestMode encoding_mode_;
517  vpx_codec_pts_t last_pts_;
518  double timebase_;
519  int64_t bits_total_[3];
520  double duration_;
521  int tot_frame_number_;
522};
523
524// Check two codec controls used for:
525// (1) for setting temporal layer id, and (2) for settings encoder flags.
526// This test invokes those controls for each frame, and verifies encoder/decoder
527// mismatch and basic rate control response.
528// TODO(marpan): Maybe move this test to datarate_test.cc.
529TEST_P(ErrorResilienceTestLargeCodecControls, CodecControl3TemporalLayers) {
530  cfg_.rc_buf_initial_sz = 500;
531  cfg_.rc_buf_optimal_sz = 500;
532  cfg_.rc_buf_sz = 1000;
533  cfg_.rc_dropframe_thresh = 1;
534  cfg_.rc_min_quantizer = 2;
535  cfg_.rc_max_quantizer = 56;
536  cfg_.rc_end_usage = VPX_CBR;
537  cfg_.rc_dropframe_thresh = 1;
538  cfg_.g_lag_in_frames = 0;
539  cfg_.kf_mode = VPX_KF_DISABLED;
540  cfg_.g_error_resilient = 1;
541
542  // 3 Temporal layers. Framerate decimation (4, 2, 1).
543  cfg_.ts_number_layers = 3;
544  cfg_.ts_rate_decimator[0] = 4;
545  cfg_.ts_rate_decimator[1] = 2;
546  cfg_.ts_rate_decimator[2] = 1;
547  cfg_.ts_periodicity = 4;
548  cfg_.ts_layer_id[0] = 0;
549  cfg_.ts_layer_id[1] = 2;
550  cfg_.ts_layer_id[2] = 1;
551  cfg_.ts_layer_id[3] = 2;
552
553  ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
554                                       30, 1, 0, 200);
555  for (int i = 200; i <= 800; i += 200) {
556    cfg_.rc_target_bitrate = i;
557    Reset();
558    // 40-20-40 bitrate allocation for 3 temporal layers.
559    cfg_.ts_target_bitrate[0] = 40 * cfg_.rc_target_bitrate / 100;
560    cfg_.ts_target_bitrate[1] = 60 * cfg_.rc_target_bitrate / 100;
561    cfg_.ts_target_bitrate[2] = cfg_.rc_target_bitrate;
562    ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
563    for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
564      ASSERT_GE(effective_datarate_[j], cfg_.ts_target_bitrate[j] * 0.75)
565          << " The datarate for the file is lower than target by too much, "
566             "for layer: "
567          << j;
568      ASSERT_LE(effective_datarate_[j], cfg_.ts_target_bitrate[j] * 1.25)
569          << " The datarate for the file is greater than target by too much, "
570             "for layer: "
571          << j;
572    }
573  }
574}
575
576VP8_INSTANTIATE_TEST_CASE(ErrorResilienceTestLarge, ONE_PASS_TEST_MODES,
577                          ::testing::Values(true));
578VP8_INSTANTIATE_TEST_CASE(ErrorResilienceTestLargeCodecControls,
579                          ONE_PASS_TEST_MODES);
580VP9_INSTANTIATE_TEST_CASE(ErrorResilienceTestLarge, ONE_PASS_TEST_MODES,
581                          ::testing::Values(true));
582}  // namespace
583