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