datarate_test.cc revision 2ec72e65689c948e92b826ae1e867bf369e72f13
1/* 2 * Copyright (c) 2012 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#include "./vpx_config.h" 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#include "test/y4m_video_source.h" 17 18namespace { 19 20class DatarateTestLarge : public ::libvpx_test::EncoderTest, 21 public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> { 22 public: 23 DatarateTestLarge() : EncoderTest(GET_PARAM(0)) {} 24 25 virtual ~DatarateTestLarge() {} 26 27 protected: 28 virtual void SetUp() { 29 InitializeConfig(); 30 SetMode(GET_PARAM(1)); 31 ResetModel(); 32 } 33 34 virtual void ResetModel() { 35 last_pts_ = 0; 36 bits_in_buffer_model_ = cfg_.rc_target_bitrate * cfg_.rc_buf_initial_sz; 37 frame_number_ = 0; 38 first_drop_ = 0; 39 bits_total_ = 0; 40 duration_ = 0.0; 41 } 42 43 virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video, 44 ::libvpx_test::Encoder *encoder) { 45 const vpx_rational_t tb = video->timebase(); 46 timebase_ = static_cast<double>(tb.num) / tb.den; 47 duration_ = 0; 48 } 49 50 virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) { 51 // Time since last timestamp = duration. 52 vpx_codec_pts_t duration = pkt->data.frame.pts - last_pts_; 53 54 // TODO(jimbankoski): Remove these lines when the issue: 55 // http://code.google.com/p/webm/issues/detail?id=496 is fixed. 56 // For now the codec assumes buffer starts at starting buffer rate 57 // plus one frame's time. 58 if (last_pts_ == 0) 59 duration = 1; 60 61 // Add to the buffer the bits we'd expect from a constant bitrate server. 62 bits_in_buffer_model_ += static_cast<int64_t>( 63 duration * timebase_ * cfg_.rc_target_bitrate * 1000); 64 65 /* Test the buffer model here before subtracting the frame. Do so because 66 * the way the leaky bucket model works in libvpx is to allow the buffer to 67 * empty - and then stop showing frames until we've got enough bits to 68 * show one. As noted in comment below (issue 495), this does not currently 69 * apply to key frames. For now exclude key frames in condition below. */ 70 const bool key_frame = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) 71 ? true: false; 72 if (!key_frame) { 73 ASSERT_GE(bits_in_buffer_model_, 0) << "Buffer Underrun at frame " 74 << pkt->data.frame.pts; 75 } 76 77 const size_t frame_size_in_bits = pkt->data.frame.sz * 8; 78 79 // Subtract from the buffer the bits associated with a played back frame. 80 bits_in_buffer_model_ -= frame_size_in_bits; 81 82 // Update the running total of bits for end of test datarate checks. 83 bits_total_ += frame_size_in_bits; 84 85 // If first drop not set and we have a drop set it to this time. 86 if (!first_drop_ && duration > 1) 87 first_drop_ = last_pts_ + 1; 88 89 // Update the most recent pts. 90 last_pts_ = pkt->data.frame.pts; 91 92 // We update this so that we can calculate the datarate minus the last 93 // frame encoded in the file. 94 bits_in_last_frame_ = frame_size_in_bits; 95 96 ++frame_number_; 97 } 98 99 virtual void EndPassHook(void) { 100 if (bits_total_) { 101 const double file_size_in_kb = bits_total_ / 1000.; // bits per kilobit 102 103 duration_ = (last_pts_ + 1) * timebase_; 104 105 // Effective file datarate includes the time spent prebuffering. 106 effective_datarate_ = (bits_total_ - bits_in_last_frame_) / 1000.0 107 / (cfg_.rc_buf_initial_sz / 1000.0 + duration_); 108 109 file_datarate_ = file_size_in_kb / duration_; 110 } 111 } 112 113 vpx_codec_pts_t last_pts_; 114 int64_t bits_in_buffer_model_; 115 double timebase_; 116 int frame_number_; 117 vpx_codec_pts_t first_drop_; 118 int64_t bits_total_; 119 double duration_; 120 double file_datarate_; 121 double effective_datarate_; 122 size_t bits_in_last_frame_; 123}; 124 125TEST_P(DatarateTestLarge, BasicBufferModel) { 126 cfg_.rc_buf_initial_sz = 500; 127 cfg_.rc_dropframe_thresh = 1; 128 cfg_.rc_max_quantizer = 56; 129 cfg_.rc_end_usage = VPX_CBR; 130 // 2 pass cbr datarate control has a bug hidden by the small # of 131 // frames selected in this encode. The problem is that even if the buffer is 132 // negative we produce a keyframe on a cutscene. Ignoring datarate 133 // constraints 134 // TODO(jimbankoski): ( Fix when issue 135 // http://code.google.com/p/webm/issues/detail?id=495 is addressed. ) 136 ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, 137 30, 1, 0, 140); 138 139 // There is an issue for low bitrates in real-time mode, where the 140 // effective_datarate slightly overshoots the target bitrate. 141 // This is same the issue as noted about (#495). 142 // TODO(jimbankoski/marpan): Update test to run for lower bitrates (< 100), 143 // when the issue is resolved. 144 for (int i = 100; i < 800; i += 200) { 145 cfg_.rc_target_bitrate = i; 146 ResetModel(); 147 ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); 148 ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_) 149 << " The datarate for the file exceeds the target!"; 150 151 ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.3) 152 << " The datarate for the file missed the target!"; 153 } 154} 155 156TEST_P(DatarateTestLarge, ChangingDropFrameThresh) { 157 cfg_.rc_buf_initial_sz = 500; 158 cfg_.rc_max_quantizer = 36; 159 cfg_.rc_end_usage = VPX_CBR; 160 cfg_.rc_target_bitrate = 200; 161 cfg_.kf_mode = VPX_KF_DISABLED; 162 163 const int frame_count = 40; 164 ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, 165 30, 1, 0, frame_count); 166 167 // Here we check that the first dropped frame gets earlier and earlier 168 // as the drop frame threshold is increased. 169 170 const int kDropFrameThreshTestStep = 30; 171 vpx_codec_pts_t last_drop = frame_count; 172 for (int i = 1; i < 91; i += kDropFrameThreshTestStep) { 173 cfg_.rc_dropframe_thresh = i; 174 ResetModel(); 175 ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); 176 ASSERT_LE(first_drop_, last_drop) 177 << " The first dropped frame for drop_thresh " << i 178 << " > first dropped frame for drop_thresh " 179 << i - kDropFrameThreshTestStep; 180 last_drop = first_drop_; 181 } 182} 183 184class DatarateTestVP9Large : public ::libvpx_test::EncoderTest, 185 public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> { 186 public: 187 DatarateTestVP9Large() : EncoderTest(GET_PARAM(0)) {} 188 189 protected: 190 virtual ~DatarateTestVP9Large() {} 191 192 virtual void SetUp() { 193 InitializeConfig(); 194 SetMode(GET_PARAM(1)); 195 set_cpu_used_ = GET_PARAM(2); 196 ResetModel(); 197 } 198 199 virtual void ResetModel() { 200 last_pts_ = 0; 201 bits_in_buffer_model_ = cfg_.rc_target_bitrate * cfg_.rc_buf_initial_sz; 202 frame_number_ = 0; 203 tot_frame_number_ = 0; 204 first_drop_ = 0; 205 num_drops_ = 0; 206 // For testing up to 3 layers. 207 for (int i = 0; i < 3; ++i) { 208 bits_total_[i] = 0; 209 } 210 } 211 212 // 213 // Frame flags and layer id for temporal layers. 214 // 215 216 // For two layers, test pattern is: 217 // 1 3 218 // 0 2 ..... 219 // For three layers, test pattern is: 220 // 1 3 5 7 221 // 2 6 222 // 0 4 .... 223 // LAST is always update on base/layer 0, GOLDEN is updated on layer 1. 224 // For this 3 layer example, the 2nd enhancement layer (layer 2) does not 225 // update any reference frames. 226 int SetFrameFlags(int frame_num, int num_temp_layers) { 227 int frame_flags = 0; 228 if (num_temp_layers == 2) { 229 if (frame_num % 2 == 0) { 230 // Layer 0: predict from L and ARF, update L. 231 frame_flags = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | 232 VP8_EFLAG_NO_UPD_ARF; 233 } else { 234 // Layer 1: predict from L, G and ARF, and update G. 235 frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST | 236 VP8_EFLAG_NO_UPD_ENTROPY; 237 } 238 } else if (num_temp_layers == 3) { 239 if (frame_num % 4 == 0) { 240 // Layer 0: predict from L and ARF; update L. 241 frame_flags = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | 242 VP8_EFLAG_NO_REF_GF; 243 } else if ((frame_num - 2) % 4 == 0) { 244 // Layer 1: predict from L, G, ARF; update G. 245 frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST; 246 } else if ((frame_num - 1) % 2 == 0) { 247 // Layer 2: predict from L, G, ARF; update none. 248 frame_flags = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | 249 VP8_EFLAG_NO_UPD_LAST; 250 } 251 } 252 return frame_flags; 253 } 254 255 int SetLayerId(int frame_num, int num_temp_layers) { 256 int layer_id = 0; 257 if (num_temp_layers == 2) { 258 if (frame_num % 2 == 0) { 259 layer_id = 0; 260 } else { 261 layer_id = 1; 262 } 263 } else if (num_temp_layers == 3) { 264 if (frame_num % 4 == 0) { 265 layer_id = 0; 266 } else if ((frame_num - 2) % 4 == 0) { 267 layer_id = 1; 268 } else if ((frame_num - 1) % 2 == 0) { 269 layer_id = 2; 270 } 271 } 272 return layer_id; 273 } 274 275 virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video, 276 ::libvpx_test::Encoder *encoder) { 277 if (video->frame() == 1) { 278 encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_); 279 } 280 if (cfg_.ts_number_layers > 1) { 281 if (video->frame() == 1) { 282 encoder->Control(VP9E_SET_SVC, 1); 283 } 284 vpx_svc_layer_id_t layer_id = {0, 0}; 285 layer_id.spatial_layer_id = 0; 286 frame_flags_ = SetFrameFlags(video->frame(), cfg_.ts_number_layers); 287 layer_id.temporal_layer_id = SetLayerId(video->frame(), 288 cfg_.ts_number_layers); 289 if (video->frame() > 0) { 290 encoder->Control(VP9E_SET_SVC_LAYER_ID, &layer_id); 291 } 292 } 293 const vpx_rational_t tb = video->timebase(); 294 timebase_ = static_cast<double>(tb.num) / tb.den; 295 duration_ = 0; 296 } 297 298 299 virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) { 300 // Time since last timestamp = duration. 301 vpx_codec_pts_t duration = pkt->data.frame.pts - last_pts_; 302 303 if (duration > 1) { 304 // If first drop not set and we have a drop set it to this time. 305 if (!first_drop_) 306 first_drop_ = last_pts_ + 1; 307 // Update the number of frame drops. 308 num_drops_ += static_cast<int>(duration - 1); 309 // Update counter for total number of frames (#frames input to encoder). 310 // Needed for setting the proper layer_id below. 311 tot_frame_number_ += static_cast<int>(duration - 1); 312 } 313 314 int layer = SetLayerId(tot_frame_number_, cfg_.ts_number_layers); 315 316 // Add to the buffer the bits we'd expect from a constant bitrate server. 317 bits_in_buffer_model_ += static_cast<int64_t>( 318 duration * timebase_ * cfg_.rc_target_bitrate * 1000); 319 320 // Buffer should not go negative. 321 ASSERT_GE(bits_in_buffer_model_, 0) << "Buffer Underrun at frame " 322 << pkt->data.frame.pts; 323 324 const size_t frame_size_in_bits = pkt->data.frame.sz * 8; 325 326 // Update the total encoded bits. For temporal layers, update the cumulative 327 // encoded bits per layer. 328 for (int i = layer; i < static_cast<int>(cfg_.ts_number_layers); ++i) { 329 bits_total_[i] += frame_size_in_bits; 330 } 331 332 // Update the most recent pts. 333 last_pts_ = pkt->data.frame.pts; 334 ++frame_number_; 335 ++tot_frame_number_; 336 } 337 338 virtual void EndPassHook(void) { 339 for (int layer = 0; layer < static_cast<int>(cfg_.ts_number_layers); 340 ++layer) { 341 duration_ = (last_pts_ + 1) * timebase_; 342 if (bits_total_[layer]) { 343 // Effective file datarate: 344 effective_datarate_[layer] = (bits_total_[layer] / 1000.0) / duration_; 345 } 346 } 347 } 348 349 vpx_codec_pts_t last_pts_; 350 double timebase_; 351 int frame_number_; // Counter for number of non-dropped/encoded frames. 352 int tot_frame_number_; // Counter for total number of input frames. 353 int64_t bits_total_[3]; 354 double duration_; 355 double effective_datarate_[3]; 356 int set_cpu_used_; 357 int64_t bits_in_buffer_model_; 358 vpx_codec_pts_t first_drop_; 359 int num_drops_; 360}; 361 362// Check basic rate targeting, 363TEST_P(DatarateTestVP9Large, BasicRateTargeting) { 364 cfg_.rc_buf_initial_sz = 500; 365 cfg_.rc_buf_optimal_sz = 500; 366 cfg_.rc_buf_sz = 1000; 367 cfg_.rc_dropframe_thresh = 1; 368 cfg_.rc_min_quantizer = 0; 369 cfg_.rc_max_quantizer = 63; 370 cfg_.rc_end_usage = VPX_CBR; 371 cfg_.g_lag_in_frames = 0; 372 373 ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, 374 30, 1, 0, 140); 375 for (int i = 150; i < 800; i += 200) { 376 cfg_.rc_target_bitrate = i; 377 ResetModel(); 378 ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); 379 ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85) 380 << " The datarate for the file is lower than target by too much!"; 381 ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15) 382 << " The datarate for the file is greater than target by too much!"; 383 } 384} 385 386// Check basic rate targeting, 387TEST_P(DatarateTestVP9Large, BasicRateTargeting444) { 388 ::libvpx_test::Y4mVideoSource video("rush_hour_444.y4m", 0, 140); 389 390 cfg_.g_profile = 1; 391 cfg_.g_timebase = video.timebase(); 392 393 cfg_.rc_buf_initial_sz = 500; 394 cfg_.rc_buf_optimal_sz = 500; 395 cfg_.rc_buf_sz = 1000; 396 cfg_.rc_dropframe_thresh = 1; 397 cfg_.rc_min_quantizer = 0; 398 cfg_.rc_max_quantizer = 63; 399 cfg_.rc_end_usage = VPX_CBR; 400 401 for (int i = 250; i < 900; i += 200) { 402 cfg_.rc_target_bitrate = i; 403 ResetModel(); 404 ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); 405 ASSERT_GE(static_cast<double>(cfg_.rc_target_bitrate), 406 effective_datarate_[0] * 0.85) 407 << " The datarate for the file exceeds the target by too much!"; 408 ASSERT_LE(static_cast<double>(cfg_.rc_target_bitrate), 409 effective_datarate_[0] * 1.15) 410 << " The datarate for the file missed the target!" 411 << cfg_.rc_target_bitrate << " "<< effective_datarate_; 412 } 413} 414 415// Check that (1) the first dropped frame gets earlier and earlier 416// as the drop frame threshold is increased, and (2) that the total number of 417// frame drops does not decrease as we increase frame drop threshold. 418// Use a lower qp-max to force some frame drops. 419TEST_P(DatarateTestVP9Large, ChangingDropFrameThresh) { 420 cfg_.rc_buf_initial_sz = 500; 421 cfg_.rc_buf_optimal_sz = 500; 422 cfg_.rc_buf_sz = 1000; 423 cfg_.rc_undershoot_pct = 20; 424 cfg_.rc_undershoot_pct = 20; 425 cfg_.rc_dropframe_thresh = 10; 426 cfg_.rc_min_quantizer = 0; 427 cfg_.rc_max_quantizer = 50; 428 cfg_.rc_end_usage = VPX_CBR; 429 cfg_.rc_target_bitrate = 200; 430 cfg_.g_lag_in_frames = 0; 431 432 ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, 433 30, 1, 0, 140); 434 435 const int kDropFrameThreshTestStep = 30; 436 vpx_codec_pts_t last_drop = 140; 437 int last_num_drops = 0; 438 for (int i = 10; i < 100; i += kDropFrameThreshTestStep) { 439 cfg_.rc_dropframe_thresh = i; 440 ResetModel(); 441 ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); 442 ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85) 443 << " The datarate for the file is lower than target by too much!"; 444 ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15) 445 << " The datarate for the file is greater than target by too much!"; 446 ASSERT_LE(first_drop_, last_drop) 447 << " The first dropped frame for drop_thresh " << i 448 << " > first dropped frame for drop_thresh " 449 << i - kDropFrameThreshTestStep; 450 ASSERT_GE(num_drops_, last_num_drops) 451 << " The number of dropped frames for drop_thresh " << i 452 << " < number of dropped frames for drop_thresh " 453 << i - kDropFrameThreshTestStep; 454 last_drop = first_drop_; 455 last_num_drops = num_drops_; 456 } 457} 458 459// Check basic rate targeting for 2 temporal layers. 460TEST_P(DatarateTestVP9Large, BasicRateTargeting2TemporalLayers) { 461 cfg_.rc_buf_initial_sz = 500; 462 cfg_.rc_buf_optimal_sz = 500; 463 cfg_.rc_buf_sz = 1000; 464 cfg_.rc_dropframe_thresh = 1; 465 cfg_.rc_min_quantizer = 0; 466 cfg_.rc_max_quantizer = 63; 467 cfg_.rc_end_usage = VPX_CBR; 468 cfg_.g_lag_in_frames = 0; 469 470 // 2 Temporal layers, no spatial layers: Framerate decimation (2, 1). 471 cfg_.ss_number_layers = 1; 472 cfg_.ts_number_layers = 2; 473 cfg_.ts_rate_decimator[0] = 2; 474 cfg_.ts_rate_decimator[1] = 1; 475 476 ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, 477 30, 1, 0, 200); 478 for (int i = 200; i <= 800; i += 200) { 479 cfg_.rc_target_bitrate = i; 480 ResetModel(); 481 // 60-40 bitrate allocation for 2 temporal layers. 482 cfg_.ts_target_bitrate[0] = 60 * cfg_.rc_target_bitrate / 100; 483 cfg_.ts_target_bitrate[1] = cfg_.rc_target_bitrate; 484 ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); 485 for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) { 486 ASSERT_GE(effective_datarate_[j], cfg_.ts_target_bitrate[j] * 0.85) 487 << " The datarate for the file is lower than target by too much, " 488 "for layer: " << j; 489 ASSERT_LE(effective_datarate_[j], cfg_.ts_target_bitrate[j] * 1.15) 490 << " The datarate for the file is greater than target by too much, " 491 "for layer: " << j; 492 } 493 } 494} 495 496// Check basic rate targeting for 3 temporal layers. 497TEST_P(DatarateTestVP9Large, BasicRateTargeting3TemporalLayers) { 498 cfg_.rc_buf_initial_sz = 500; 499 cfg_.rc_buf_optimal_sz = 500; 500 cfg_.rc_buf_sz = 1000; 501 cfg_.rc_dropframe_thresh = 1; 502 cfg_.rc_min_quantizer = 0; 503 cfg_.rc_max_quantizer = 63; 504 cfg_.rc_end_usage = VPX_CBR; 505 cfg_.g_lag_in_frames = 0; 506 507 // 3 Temporal layers, no spatial layers: Framerate decimation (4, 2, 1). 508 cfg_.ss_number_layers = 1; 509 cfg_.ts_number_layers = 3; 510 cfg_.ts_rate_decimator[0] = 4; 511 cfg_.ts_rate_decimator[1] = 2; 512 cfg_.ts_rate_decimator[2] = 1; 513 514 ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, 515 30, 1, 0, 200); 516 for (int i = 200; i <= 800; i += 200) { 517 cfg_.rc_target_bitrate = i; 518 ResetModel(); 519 // 40-20-40 bitrate allocation for 3 temporal layers. 520 cfg_.ts_target_bitrate[0] = 40 * cfg_.rc_target_bitrate / 100; 521 cfg_.ts_target_bitrate[1] = 60 * cfg_.rc_target_bitrate / 100; 522 cfg_.ts_target_bitrate[2] = cfg_.rc_target_bitrate; 523 ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); 524 for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) { 525 ASSERT_GE(effective_datarate_[j], cfg_.ts_target_bitrate[j] * 0.85) 526 << " The datarate for the file is lower than target by too much, " 527 "for layer: " << j; 528 ASSERT_LE(effective_datarate_[j], cfg_.ts_target_bitrate[j] * 1.15) 529 << " The datarate for the file is greater than target by too much, " 530 "for layer: " << j; 531 } 532 } 533} 534 535// Check basic rate targeting for 3 temporal layers, with frame dropping. 536// Only for one (low) bitrate with lower max_quantizer, and somewhat higher 537// frame drop threshold, to force frame dropping. 538TEST_P(DatarateTestVP9Large, BasicRateTargeting3TemporalLayersFrameDropping) { 539 cfg_.rc_buf_initial_sz = 500; 540 cfg_.rc_buf_optimal_sz = 500; 541 cfg_.rc_buf_sz = 1000; 542 // Set frame drop threshold and rc_max_quantizer to force some frame drops. 543 cfg_.rc_dropframe_thresh = 20; 544 cfg_.rc_max_quantizer = 45; 545 cfg_.rc_min_quantizer = 0; 546 cfg_.rc_end_usage = VPX_CBR; 547 cfg_.g_lag_in_frames = 0; 548 549 // 3 Temporal layers, no spatial layers: Framerate decimation (4, 2, 1). 550 cfg_.ss_number_layers = 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 556 ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, 557 30, 1, 0, 200); 558 cfg_.rc_target_bitrate = 200; 559 ResetModel(); 560 // 40-20-40 bitrate allocation for 3 temporal layers. 561 cfg_.ts_target_bitrate[0] = 40 * cfg_.rc_target_bitrate / 100; 562 cfg_.ts_target_bitrate[1] = 60 * cfg_.rc_target_bitrate / 100; 563 cfg_.ts_target_bitrate[2] = cfg_.rc_target_bitrate; 564 ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); 565 for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) { 566 ASSERT_GE(effective_datarate_[j], cfg_.ts_target_bitrate[j] * 0.85) 567 << " The datarate for the file is lower than target by too much, " 568 "for layer: " << j; 569 ASSERT_LE(effective_datarate_[j], cfg_.ts_target_bitrate[j] * 1.15) 570 << " The datarate for the file is greater than target by too much, " 571 "for layer: " << j; 572 // Expect some frame drops in this test: for this 200 frames test, 573 // expect at least 10% and not more than 50% drops. 574 ASSERT_GE(num_drops_, 20); 575 ASSERT_LE(num_drops_, 100); 576 } 577} 578 579VP8_INSTANTIATE_TEST_CASE(DatarateTestLarge, ALL_TEST_MODES); 580VP9_INSTANTIATE_TEST_CASE(DatarateTestVP9Large, 581 ::testing::Values(::libvpx_test::kOnePassGood, 582 ::libvpx_test::kRealTime), 583 ::testing::Range(2, 7)); 584// TODO(marpan): Speed 7 fails on one of these tests (likely just a threshold 585// needs to be changed), so for now test up to speed 6, and start at 2 (since 586// speed 0 and 1 are slow). Allow speed 7 (for real-time mode) after 587// looking into/fix failing issue. 588} // namespace 589