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 <string> 12#include "third_party/googletest/src/include/gtest/gtest.h" 13#include "test/codec_factory.h" 14#include "test/decode_test_driver.h" 15#include "test/i420_video_source.h" 16 17#include "vp9/decoder/vp9_decoder.h" 18 19#include "vpx/svc_context.h" 20#include "vpx/vp8cx.h" 21#include "vpx/vpx_encoder.h" 22 23namespace { 24 25using libvpx_test::CodecFactory; 26using libvpx_test::Decoder; 27using libvpx_test::DxDataIterator; 28using libvpx_test::VP9CodecFactory; 29 30class SvcTest : public ::testing::Test { 31 protected: 32 static const uint32_t kWidth = 352; 33 static const uint32_t kHeight = 288; 34 35 SvcTest() 36 : codec_iface_(0), test_file_name_("hantro_collage_w352h288.yuv"), 37 codec_initialized_(false), decoder_(0) { 38 memset(&svc_, 0, sizeof(svc_)); 39 memset(&codec_, 0, sizeof(codec_)); 40 memset(&codec_enc_, 0, sizeof(codec_enc_)); 41 } 42 43 virtual ~SvcTest() {} 44 45 virtual void SetUp() { 46 svc_.log_level = SVC_LOG_DEBUG; 47 svc_.log_print = 0; 48 49 codec_iface_ = vpx_codec_vp9_cx(); 50 const vpx_codec_err_t res = 51 vpx_codec_enc_config_default(codec_iface_, &codec_enc_, 0); 52 EXPECT_EQ(VPX_CODEC_OK, res); 53 54 codec_enc_.g_w = kWidth; 55 codec_enc_.g_h = kHeight; 56 codec_enc_.g_timebase.num = 1; 57 codec_enc_.g_timebase.den = 60; 58 codec_enc_.kf_min_dist = 100; 59 codec_enc_.kf_max_dist = 100; 60 61 vpx_codec_dec_cfg_t dec_cfg = vpx_codec_dec_cfg_t(); 62 VP9CodecFactory codec_factory; 63 decoder_ = codec_factory.CreateDecoder(dec_cfg, 0); 64 65 tile_columns_ = 0; 66 tile_rows_ = 0; 67 } 68 69 virtual void TearDown() { 70 ReleaseEncoder(); 71 delete (decoder_); 72 } 73 74 void InitializeEncoder() { 75 const vpx_codec_err_t res = 76 vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_); 77 EXPECT_EQ(VPX_CODEC_OK, res); 78 vpx_codec_control(&codec_, VP8E_SET_CPUUSED, 4); // Make the test faster 79 vpx_codec_control(&codec_, VP9E_SET_TILE_COLUMNS, tile_columns_); 80 vpx_codec_control(&codec_, VP9E_SET_TILE_ROWS, tile_rows_); 81 codec_initialized_ = true; 82 } 83 84 void ReleaseEncoder() { 85 vpx_svc_release(&svc_); 86 if (codec_initialized_) vpx_codec_destroy(&codec_); 87 codec_initialized_ = false; 88 } 89 90 void GetStatsData(std::string *const stats_buf) { 91 vpx_codec_iter_t iter = NULL; 92 const vpx_codec_cx_pkt_t *cx_pkt; 93 94 while ((cx_pkt = vpx_codec_get_cx_data(&codec_, &iter)) != NULL) { 95 if (cx_pkt->kind == VPX_CODEC_STATS_PKT) { 96 EXPECT_GT(cx_pkt->data.twopass_stats.sz, 0U); 97 ASSERT_TRUE(cx_pkt->data.twopass_stats.buf != NULL); 98 stats_buf->append(static_cast<char *>(cx_pkt->data.twopass_stats.buf), 99 cx_pkt->data.twopass_stats.sz); 100 } 101 } 102 } 103 104 void Pass1EncodeNFrames(const int n, const int layers, 105 std::string *const stats_buf) { 106 vpx_codec_err_t res; 107 108 ASSERT_GT(n, 0); 109 ASSERT_GT(layers, 0); 110 svc_.spatial_layers = layers; 111 codec_enc_.g_pass = VPX_RC_FIRST_PASS; 112 InitializeEncoder(); 113 114 libvpx_test::I420VideoSource video( 115 test_file_name_, codec_enc_.g_w, codec_enc_.g_h, 116 codec_enc_.g_timebase.den, codec_enc_.g_timebase.num, 0, 30); 117 video.Begin(); 118 119 for (int i = 0; i < n; ++i) { 120 res = vpx_svc_encode(&svc_, &codec_, video.img(), video.pts(), 121 video.duration(), VPX_DL_GOOD_QUALITY); 122 ASSERT_EQ(VPX_CODEC_OK, res); 123 GetStatsData(stats_buf); 124 video.Next(); 125 } 126 127 // Flush encoder and test EOS packet. 128 res = vpx_svc_encode(&svc_, &codec_, NULL, video.pts(), video.duration(), 129 VPX_DL_GOOD_QUALITY); 130 ASSERT_EQ(VPX_CODEC_OK, res); 131 GetStatsData(stats_buf); 132 133 ReleaseEncoder(); 134 } 135 136 void StoreFrames(const size_t max_frame_received, 137 struct vpx_fixed_buf *const outputs, 138 size_t *const frame_received) { 139 vpx_codec_iter_t iter = NULL; 140 const vpx_codec_cx_pkt_t *cx_pkt; 141 142 while ((cx_pkt = vpx_codec_get_cx_data(&codec_, &iter)) != NULL) { 143 if (cx_pkt->kind == VPX_CODEC_CX_FRAME_PKT) { 144 const size_t frame_size = cx_pkt->data.frame.sz; 145 146 EXPECT_GT(frame_size, 0U); 147 ASSERT_TRUE(cx_pkt->data.frame.buf != NULL); 148 ASSERT_LT(*frame_received, max_frame_received); 149 150 if (*frame_received == 0) 151 EXPECT_EQ(1, !!(cx_pkt->data.frame.flags & VPX_FRAME_IS_KEY)); 152 153 outputs[*frame_received].buf = malloc(frame_size + 16); 154 ASSERT_TRUE(outputs[*frame_received].buf != NULL); 155 memcpy(outputs[*frame_received].buf, cx_pkt->data.frame.buf, 156 frame_size); 157 outputs[*frame_received].sz = frame_size; 158 ++(*frame_received); 159 } 160 } 161 } 162 163 void Pass2EncodeNFrames(std::string *const stats_buf, const int n, 164 const int layers, 165 struct vpx_fixed_buf *const outputs) { 166 vpx_codec_err_t res; 167 size_t frame_received = 0; 168 169 ASSERT_TRUE(outputs != NULL); 170 ASSERT_GT(n, 0); 171 ASSERT_GT(layers, 0); 172 svc_.spatial_layers = layers; 173 codec_enc_.rc_target_bitrate = 500; 174 if (codec_enc_.g_pass == VPX_RC_LAST_PASS) { 175 ASSERT_TRUE(stats_buf != NULL); 176 ASSERT_GT(stats_buf->size(), 0U); 177 codec_enc_.rc_twopass_stats_in.buf = &(*stats_buf)[0]; 178 codec_enc_.rc_twopass_stats_in.sz = stats_buf->size(); 179 } 180 InitializeEncoder(); 181 182 libvpx_test::I420VideoSource video( 183 test_file_name_, codec_enc_.g_w, codec_enc_.g_h, 184 codec_enc_.g_timebase.den, codec_enc_.g_timebase.num, 0, 30); 185 video.Begin(); 186 187 for (int i = 0; i < n; ++i) { 188 res = vpx_svc_encode(&svc_, &codec_, video.img(), video.pts(), 189 video.duration(), VPX_DL_GOOD_QUALITY); 190 ASSERT_EQ(VPX_CODEC_OK, res); 191 StoreFrames(n, outputs, &frame_received); 192 video.Next(); 193 } 194 195 // Flush encoder. 196 res = vpx_svc_encode(&svc_, &codec_, NULL, 0, video.duration(), 197 VPX_DL_GOOD_QUALITY); 198 EXPECT_EQ(VPX_CODEC_OK, res); 199 StoreFrames(n, outputs, &frame_received); 200 201 EXPECT_EQ(frame_received, static_cast<size_t>(n)); 202 203 ReleaseEncoder(); 204 } 205 206 void DecodeNFrames(const struct vpx_fixed_buf *const inputs, const int n) { 207 int decoded_frames = 0; 208 int received_frames = 0; 209 210 ASSERT_TRUE(inputs != NULL); 211 ASSERT_GT(n, 0); 212 213 for (int i = 0; i < n; ++i) { 214 ASSERT_TRUE(inputs[i].buf != NULL); 215 ASSERT_GT(inputs[i].sz, 0U); 216 const vpx_codec_err_t res_dec = decoder_->DecodeFrame( 217 static_cast<const uint8_t *>(inputs[i].buf), inputs[i].sz); 218 ASSERT_EQ(VPX_CODEC_OK, res_dec) << decoder_->DecodeError(); 219 ++decoded_frames; 220 221 DxDataIterator dec_iter = decoder_->GetDxData(); 222 while (dec_iter.Next() != NULL) { 223 ++received_frames; 224 } 225 } 226 EXPECT_EQ(decoded_frames, n); 227 EXPECT_EQ(received_frames, n); 228 } 229 230 void DropEnhancementLayers(struct vpx_fixed_buf *const inputs, 231 const int num_super_frames, 232 const int remained_spatial_layers) { 233 ASSERT_TRUE(inputs != NULL); 234 ASSERT_GT(num_super_frames, 0); 235 ASSERT_GT(remained_spatial_layers, 0); 236 237 for (int i = 0; i < num_super_frames; ++i) { 238 uint32_t frame_sizes[8] = { 0 }; 239 int frame_count = 0; 240 int frames_found = 0; 241 int frame; 242 ASSERT_TRUE(inputs[i].buf != NULL); 243 ASSERT_GT(inputs[i].sz, 0U); 244 245 vpx_codec_err_t res = vp9_parse_superframe_index( 246 static_cast<const uint8_t *>(inputs[i].buf), inputs[i].sz, 247 frame_sizes, &frame_count, NULL, NULL); 248 ASSERT_EQ(VPX_CODEC_OK, res); 249 250 if (frame_count == 0) { 251 // There's no super frame but only a single frame. 252 ASSERT_EQ(1, remained_spatial_layers); 253 } else { 254 // Found a super frame. 255 uint8_t *frame_data = static_cast<uint8_t *>(inputs[i].buf); 256 uint8_t *frame_start = frame_data; 257 for (frame = 0; frame < frame_count; ++frame) { 258 // Looking for a visible frame. 259 if (frame_data[0] & 0x02) { 260 ++frames_found; 261 if (frames_found == remained_spatial_layers) break; 262 } 263 frame_data += frame_sizes[frame]; 264 } 265 ASSERT_LT(frame, frame_count) 266 << "Couldn't find a visible frame. " 267 << "remained_spatial_layers: " << remained_spatial_layers 268 << " super_frame: " << i; 269 if (frame == frame_count - 1) continue; 270 271 frame_data += frame_sizes[frame]; 272 273 // We need to add one more frame for multiple frame contexts. 274 uint8_t marker = 275 static_cast<const uint8_t *>(inputs[i].buf)[inputs[i].sz - 1]; 276 const uint32_t mag = ((marker >> 3) & 0x3) + 1; 277 const size_t index_sz = 2 + mag * frame_count; 278 const size_t new_index_sz = 2 + mag * (frame + 1); 279 marker &= 0x0f8; 280 marker |= frame; 281 282 // Copy existing frame sizes. 283 memmove(frame_data + 1, frame_start + inputs[i].sz - index_sz + 1, 284 new_index_sz - 2); 285 // New marker. 286 frame_data[0] = marker; 287 frame_data += (mag * (frame + 1) + 1); 288 289 *frame_data++ = marker; 290 inputs[i].sz = frame_data - frame_start; 291 } 292 } 293 } 294 295 void FreeBitstreamBuffers(struct vpx_fixed_buf *const inputs, const int n) { 296 ASSERT_TRUE(inputs != NULL); 297 ASSERT_GT(n, 0); 298 299 for (int i = 0; i < n; ++i) { 300 free(inputs[i].buf); 301 inputs[i].buf = NULL; 302 inputs[i].sz = 0; 303 } 304 } 305 306 SvcContext svc_; 307 vpx_codec_ctx_t codec_; 308 struct vpx_codec_enc_cfg codec_enc_; 309 vpx_codec_iface_t *codec_iface_; 310 std::string test_file_name_; 311 bool codec_initialized_; 312 Decoder *decoder_; 313 int tile_columns_; 314 int tile_rows_; 315}; 316 317TEST_F(SvcTest, SvcInit) { 318 // test missing parameters 319 vpx_codec_err_t res = vpx_svc_init(NULL, &codec_, codec_iface_, &codec_enc_); 320 EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res); 321 res = vpx_svc_init(&svc_, NULL, codec_iface_, &codec_enc_); 322 EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res); 323 res = vpx_svc_init(&svc_, &codec_, NULL, &codec_enc_); 324 EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res); 325 326 res = vpx_svc_init(&svc_, &codec_, codec_iface_, NULL); 327 EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res); 328 329 svc_.spatial_layers = 6; // too many layers 330 res = vpx_svc_init(&svc_, &codec_, codec_iface_, &codec_enc_); 331 EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res); 332 333 svc_.spatial_layers = 0; // use default layers 334 InitializeEncoder(); 335 EXPECT_EQ(VPX_SS_DEFAULT_LAYERS, svc_.spatial_layers); 336} 337 338TEST_F(SvcTest, InitTwoLayers) { 339 svc_.spatial_layers = 2; 340 InitializeEncoder(); 341} 342 343TEST_F(SvcTest, InvalidOptions) { 344 vpx_codec_err_t res = vpx_svc_set_options(&svc_, NULL); 345 EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res); 346 347 res = vpx_svc_set_options(&svc_, "not-an-option=1"); 348 EXPECT_EQ(VPX_CODEC_OK, res); 349 res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_); 350 EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res); 351} 352 353TEST_F(SvcTest, SetLayersOption) { 354 vpx_codec_err_t res = vpx_svc_set_options(&svc_, "spatial-layers=3"); 355 EXPECT_EQ(VPX_CODEC_OK, res); 356 InitializeEncoder(); 357 EXPECT_EQ(3, svc_.spatial_layers); 358} 359 360TEST_F(SvcTest, SetMultipleOptions) { 361 vpx_codec_err_t res = 362 vpx_svc_set_options(&svc_, "spatial-layers=2 scale-factors=1/3,2/3"); 363 EXPECT_EQ(VPX_CODEC_OK, res); 364 InitializeEncoder(); 365 EXPECT_EQ(2, svc_.spatial_layers); 366} 367 368TEST_F(SvcTest, SetScaleFactorsOption) { 369 svc_.spatial_layers = 2; 370 vpx_codec_err_t res = 371 vpx_svc_set_options(&svc_, "scale-factors=not-scale-factors"); 372 EXPECT_EQ(VPX_CODEC_OK, res); 373 res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_); 374 EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res); 375 376 res = vpx_svc_set_options(&svc_, "scale-factors=1/3, 3*3"); 377 EXPECT_EQ(VPX_CODEC_OK, res); 378 res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_); 379 EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res); 380 381 res = vpx_svc_set_options(&svc_, "scale-factors=1/3"); 382 EXPECT_EQ(VPX_CODEC_OK, res); 383 res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_); 384 EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res); 385 386 res = vpx_svc_set_options(&svc_, "scale-factors=1/3,2/3"); 387 EXPECT_EQ(VPX_CODEC_OK, res); 388 InitializeEncoder(); 389} 390 391TEST_F(SvcTest, SetQuantizersOption) { 392 svc_.spatial_layers = 2; 393 vpx_codec_err_t res = vpx_svc_set_options(&svc_, "max-quantizers=nothing"); 394 EXPECT_EQ(VPX_CODEC_OK, res); 395 res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_); 396 EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res); 397 398 res = vpx_svc_set_options(&svc_, "min-quantizers=nothing"); 399 EXPECT_EQ(VPX_CODEC_OK, res); 400 res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_); 401 EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res); 402 403 res = vpx_svc_set_options(&svc_, "max-quantizers=40"); 404 EXPECT_EQ(VPX_CODEC_OK, res); 405 res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_); 406 EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res); 407 408 res = vpx_svc_set_options(&svc_, "min-quantizers=40"); 409 EXPECT_EQ(VPX_CODEC_OK, res); 410 res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_); 411 EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res); 412 413 res = vpx_svc_set_options(&svc_, "max-quantizers=30,30 min-quantizers=40,40"); 414 EXPECT_EQ(VPX_CODEC_OK, res); 415 res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_); 416 EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res); 417 418 res = vpx_svc_set_options(&svc_, "max-quantizers=40,40 min-quantizers=30,30"); 419 InitializeEncoder(); 420} 421 422TEST_F(SvcTest, SetAutoAltRefOption) { 423 svc_.spatial_layers = 5; 424 vpx_codec_err_t res = vpx_svc_set_options(&svc_, "auto-alt-refs=none"); 425 EXPECT_EQ(VPX_CODEC_OK, res); 426 res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_); 427 EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res); 428 429 res = vpx_svc_set_options(&svc_, "auto-alt-refs=1,1,1,1,0"); 430 EXPECT_EQ(VPX_CODEC_OK, res); 431 res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_); 432 EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res); 433 434 vpx_svc_set_options(&svc_, "auto-alt-refs=0,1,1,1,0"); 435 InitializeEncoder(); 436} 437 438// Test that decoder can handle an SVC frame as the first frame in a sequence. 439TEST_F(SvcTest, OnePassEncodeOneFrame) { 440 codec_enc_.g_pass = VPX_RC_ONE_PASS; 441 vpx_fixed_buf output = vpx_fixed_buf(); 442 Pass2EncodeNFrames(NULL, 1, 2, &output); 443 DecodeNFrames(&output, 1); 444 FreeBitstreamBuffers(&output, 1); 445} 446 447TEST_F(SvcTest, OnePassEncodeThreeFrames) { 448 codec_enc_.g_pass = VPX_RC_ONE_PASS; 449 codec_enc_.g_lag_in_frames = 0; 450 vpx_fixed_buf outputs[3]; 451 memset(&outputs[0], 0, sizeof(outputs)); 452 Pass2EncodeNFrames(NULL, 3, 2, &outputs[0]); 453 DecodeNFrames(&outputs[0], 3); 454 FreeBitstreamBuffers(&outputs[0], 3); 455} 456 457TEST_F(SvcTest, TwoPassEncode10Frames) { 458 // First pass encode 459 std::string stats_buf; 460 Pass1EncodeNFrames(10, 2, &stats_buf); 461 462 // Second pass encode 463 codec_enc_.g_pass = VPX_RC_LAST_PASS; 464 vpx_fixed_buf outputs[10]; 465 memset(&outputs[0], 0, sizeof(outputs)); 466 Pass2EncodeNFrames(&stats_buf, 10, 2, &outputs[0]); 467 DecodeNFrames(&outputs[0], 10); 468 FreeBitstreamBuffers(&outputs[0], 10); 469} 470 471TEST_F(SvcTest, TwoPassEncode20FramesWithAltRef) { 472 // First pass encode 473 std::string stats_buf; 474 Pass1EncodeNFrames(20, 2, &stats_buf); 475 476 // Second pass encode 477 codec_enc_.g_pass = VPX_RC_LAST_PASS; 478 vpx_svc_set_options(&svc_, "auto-alt-refs=1,1"); 479 vpx_fixed_buf outputs[20]; 480 memset(&outputs[0], 0, sizeof(outputs)); 481 Pass2EncodeNFrames(&stats_buf, 20, 2, &outputs[0]); 482 DecodeNFrames(&outputs[0], 20); 483 FreeBitstreamBuffers(&outputs[0], 20); 484} 485 486TEST_F(SvcTest, TwoPassEncode2SpatialLayersDecodeBaseLayerOnly) { 487 // First pass encode 488 std::string stats_buf; 489 Pass1EncodeNFrames(10, 2, &stats_buf); 490 491 // Second pass encode 492 codec_enc_.g_pass = VPX_RC_LAST_PASS; 493 vpx_svc_set_options(&svc_, "auto-alt-refs=1,1"); 494 vpx_fixed_buf outputs[10]; 495 memset(&outputs[0], 0, sizeof(outputs)); 496 Pass2EncodeNFrames(&stats_buf, 10, 2, &outputs[0]); 497 DropEnhancementLayers(&outputs[0], 10, 1); 498 DecodeNFrames(&outputs[0], 10); 499 FreeBitstreamBuffers(&outputs[0], 10); 500} 501 502TEST_F(SvcTest, TwoPassEncode5SpatialLayersDecode54321Layers) { 503 // First pass encode 504 std::string stats_buf; 505 Pass1EncodeNFrames(10, 5, &stats_buf); 506 507 // Second pass encode 508 codec_enc_.g_pass = VPX_RC_LAST_PASS; 509 vpx_svc_set_options(&svc_, "auto-alt-refs=0,1,1,1,0"); 510 vpx_fixed_buf outputs[10]; 511 memset(&outputs[0], 0, sizeof(outputs)); 512 Pass2EncodeNFrames(&stats_buf, 10, 5, &outputs[0]); 513 514 DecodeNFrames(&outputs[0], 10); 515 DropEnhancementLayers(&outputs[0], 10, 4); 516 DecodeNFrames(&outputs[0], 10); 517 DropEnhancementLayers(&outputs[0], 10, 3); 518 DecodeNFrames(&outputs[0], 10); 519 DropEnhancementLayers(&outputs[0], 10, 2); 520 DecodeNFrames(&outputs[0], 10); 521 DropEnhancementLayers(&outputs[0], 10, 1); 522 DecodeNFrames(&outputs[0], 10); 523 524 FreeBitstreamBuffers(&outputs[0], 10); 525} 526 527TEST_F(SvcTest, TwoPassEncode2SNRLayers) { 528 // First pass encode 529 std::string stats_buf; 530 vpx_svc_set_options(&svc_, "scale-factors=1/1,1/1"); 531 Pass1EncodeNFrames(20, 2, &stats_buf); 532 533 // Second pass encode 534 codec_enc_.g_pass = VPX_RC_LAST_PASS; 535 vpx_svc_set_options(&svc_, "auto-alt-refs=1,1 scale-factors=1/1,1/1"); 536 vpx_fixed_buf outputs[20]; 537 memset(&outputs[0], 0, sizeof(outputs)); 538 Pass2EncodeNFrames(&stats_buf, 20, 2, &outputs[0]); 539 DecodeNFrames(&outputs[0], 20); 540 FreeBitstreamBuffers(&outputs[0], 20); 541} 542 543TEST_F(SvcTest, TwoPassEncode3SNRLayersDecode321Layers) { 544 // First pass encode 545 std::string stats_buf; 546 vpx_svc_set_options(&svc_, "scale-factors=1/1,1/1,1/1"); 547 Pass1EncodeNFrames(20, 3, &stats_buf); 548 549 // Second pass encode 550 codec_enc_.g_pass = VPX_RC_LAST_PASS; 551 vpx_svc_set_options(&svc_, "auto-alt-refs=1,1,1 scale-factors=1/1,1/1,1/1"); 552 vpx_fixed_buf outputs[20]; 553 memset(&outputs[0], 0, sizeof(outputs)); 554 Pass2EncodeNFrames(&stats_buf, 20, 3, &outputs[0]); 555 DecodeNFrames(&outputs[0], 20); 556 DropEnhancementLayers(&outputs[0], 20, 2); 557 DecodeNFrames(&outputs[0], 20); 558 DropEnhancementLayers(&outputs[0], 20, 1); 559 DecodeNFrames(&outputs[0], 20); 560 561 FreeBitstreamBuffers(&outputs[0], 20); 562} 563 564TEST_F(SvcTest, SetMultipleFrameContextsOption) { 565 svc_.spatial_layers = 5; 566 vpx_codec_err_t res = vpx_svc_set_options(&svc_, "multi-frame-contexts=1"); 567 EXPECT_EQ(VPX_CODEC_OK, res); 568 res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_); 569 EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res); 570 571 svc_.spatial_layers = 2; 572 res = vpx_svc_set_options(&svc_, "multi-frame-contexts=1"); 573 InitializeEncoder(); 574} 575 576TEST_F(SvcTest, TwoPassEncode2SpatialLayersWithMultipleFrameContexts) { 577 // First pass encode 578 std::string stats_buf; 579 Pass1EncodeNFrames(10, 2, &stats_buf); 580 581 // Second pass encode 582 codec_enc_.g_pass = VPX_RC_LAST_PASS; 583 codec_enc_.g_error_resilient = 0; 584 vpx_svc_set_options(&svc_, "auto-alt-refs=1,1 multi-frame-contexts=1"); 585 vpx_fixed_buf outputs[10]; 586 memset(&outputs[0], 0, sizeof(outputs)); 587 Pass2EncodeNFrames(&stats_buf, 10, 2, &outputs[0]); 588 DecodeNFrames(&outputs[0], 10); 589 FreeBitstreamBuffers(&outputs[0], 10); 590} 591 592TEST_F(SvcTest, 593 TwoPassEncode2SpatialLayersWithMultipleFrameContextsDecodeBaselayer) { 594 // First pass encode 595 std::string stats_buf; 596 Pass1EncodeNFrames(10, 2, &stats_buf); 597 598 // Second pass encode 599 codec_enc_.g_pass = VPX_RC_LAST_PASS; 600 codec_enc_.g_error_resilient = 0; 601 vpx_svc_set_options(&svc_, "auto-alt-refs=1,1 multi-frame-contexts=1"); 602 vpx_fixed_buf outputs[10]; 603 memset(&outputs[0], 0, sizeof(outputs)); 604 Pass2EncodeNFrames(&stats_buf, 10, 2, &outputs[0]); 605 DropEnhancementLayers(&outputs[0], 10, 1); 606 DecodeNFrames(&outputs[0], 10); 607 FreeBitstreamBuffers(&outputs[0], 10); 608} 609 610TEST_F(SvcTest, TwoPassEncode2SNRLayersWithMultipleFrameContexts) { 611 // First pass encode 612 std::string stats_buf; 613 vpx_svc_set_options(&svc_, "scale-factors=1/1,1/1"); 614 Pass1EncodeNFrames(10, 2, &stats_buf); 615 616 // Second pass encode 617 codec_enc_.g_pass = VPX_RC_LAST_PASS; 618 codec_enc_.g_error_resilient = 0; 619 vpx_svc_set_options(&svc_, 620 "auto-alt-refs=1,1 scale-factors=1/1,1/1 " 621 "multi-frame-contexts=1"); 622 vpx_fixed_buf outputs[10]; 623 memset(&outputs[0], 0, sizeof(outputs)); 624 Pass2EncodeNFrames(&stats_buf, 10, 2, &outputs[0]); 625 DecodeNFrames(&outputs[0], 10); 626 FreeBitstreamBuffers(&outputs[0], 10); 627} 628 629TEST_F(SvcTest, 630 TwoPassEncode3SNRLayersWithMultipleFrameContextsDecode321Layer) { 631 // First pass encode 632 std::string stats_buf; 633 vpx_svc_set_options(&svc_, "scale-factors=1/1,1/1,1/1"); 634 Pass1EncodeNFrames(10, 3, &stats_buf); 635 636 // Second pass encode 637 codec_enc_.g_pass = VPX_RC_LAST_PASS; 638 codec_enc_.g_error_resilient = 0; 639 vpx_svc_set_options(&svc_, 640 "auto-alt-refs=1,1,1 scale-factors=1/1,1/1,1/1 " 641 "multi-frame-contexts=1"); 642 vpx_fixed_buf outputs[10]; 643 memset(&outputs[0], 0, sizeof(outputs)); 644 Pass2EncodeNFrames(&stats_buf, 10, 3, &outputs[0]); 645 646 DecodeNFrames(&outputs[0], 10); 647 DropEnhancementLayers(&outputs[0], 10, 2); 648 DecodeNFrames(&outputs[0], 10); 649 DropEnhancementLayers(&outputs[0], 10, 1); 650 DecodeNFrames(&outputs[0], 10); 651 652 FreeBitstreamBuffers(&outputs[0], 10); 653} 654 655TEST_F(SvcTest, TwoPassEncode2TemporalLayers) { 656 // First pass encode 657 std::string stats_buf; 658 vpx_svc_set_options(&svc_, "scale-factors=1/1"); 659 svc_.temporal_layers = 2; 660 Pass1EncodeNFrames(10, 1, &stats_buf); 661 662 // Second pass encode 663 codec_enc_.g_pass = VPX_RC_LAST_PASS; 664 svc_.temporal_layers = 2; 665 vpx_svc_set_options(&svc_, "auto-alt-refs=1 scale-factors=1/1"); 666 vpx_fixed_buf outputs[10]; 667 memset(&outputs[0], 0, sizeof(outputs)); 668 Pass2EncodeNFrames(&stats_buf, 10, 1, &outputs[0]); 669 DecodeNFrames(&outputs[0], 10); 670 FreeBitstreamBuffers(&outputs[0], 10); 671} 672 673TEST_F(SvcTest, TwoPassEncode2TemporalLayersWithMultipleFrameContexts) { 674 // First pass encode 675 std::string stats_buf; 676 vpx_svc_set_options(&svc_, "scale-factors=1/1"); 677 svc_.temporal_layers = 2; 678 Pass1EncodeNFrames(10, 1, &stats_buf); 679 680 // Second pass encode 681 codec_enc_.g_pass = VPX_RC_LAST_PASS; 682 svc_.temporal_layers = 2; 683 codec_enc_.g_error_resilient = 0; 684 vpx_svc_set_options(&svc_, 685 "auto-alt-refs=1 scale-factors=1/1 " 686 "multi-frame-contexts=1"); 687 vpx_fixed_buf outputs[10]; 688 memset(&outputs[0], 0, sizeof(outputs)); 689 Pass2EncodeNFrames(&stats_buf, 10, 1, &outputs[0]); 690 DecodeNFrames(&outputs[0], 10); 691 FreeBitstreamBuffers(&outputs[0], 10); 692} 693 694TEST_F(SvcTest, TwoPassEncode2TemporalLayersDecodeBaseLayer) { 695 // First pass encode 696 std::string stats_buf; 697 vpx_svc_set_options(&svc_, "scale-factors=1/1"); 698 svc_.temporal_layers = 2; 699 Pass1EncodeNFrames(10, 1, &stats_buf); 700 701 // Second pass encode 702 codec_enc_.g_pass = VPX_RC_LAST_PASS; 703 svc_.temporal_layers = 2; 704 vpx_svc_set_options(&svc_, "auto-alt-refs=1 scale-factors=1/1"); 705 vpx_fixed_buf outputs[10]; 706 memset(&outputs[0], 0, sizeof(outputs)); 707 Pass2EncodeNFrames(&stats_buf, 10, 1, &outputs[0]); 708 709 vpx_fixed_buf base_layer[5]; 710 for (int i = 0; i < 5; ++i) base_layer[i] = outputs[i * 2]; 711 712 DecodeNFrames(&base_layer[0], 5); 713 FreeBitstreamBuffers(&outputs[0], 10); 714} 715 716TEST_F(SvcTest, 717 TwoPassEncode2TemporalLayersWithMultipleFrameContextsDecodeBaseLayer) { 718 // First pass encode 719 std::string stats_buf; 720 vpx_svc_set_options(&svc_, "scale-factors=1/1"); 721 svc_.temporal_layers = 2; 722 Pass1EncodeNFrames(10, 1, &stats_buf); 723 724 // Second pass encode 725 codec_enc_.g_pass = VPX_RC_LAST_PASS; 726 svc_.temporal_layers = 2; 727 codec_enc_.g_error_resilient = 0; 728 vpx_svc_set_options(&svc_, 729 "auto-alt-refs=1 scale-factors=1/1 " 730 "multi-frame-contexts=1"); 731 vpx_fixed_buf outputs[10]; 732 memset(&outputs[0], 0, sizeof(outputs)); 733 Pass2EncodeNFrames(&stats_buf, 10, 1, &outputs[0]); 734 735 vpx_fixed_buf base_layer[5]; 736 for (int i = 0; i < 5; ++i) base_layer[i] = outputs[i * 2]; 737 738 DecodeNFrames(&base_layer[0], 5); 739 FreeBitstreamBuffers(&outputs[0], 10); 740} 741 742TEST_F(SvcTest, TwoPassEncode2TemporalLayersWithTiles) { 743 // First pass encode 744 std::string stats_buf; 745 vpx_svc_set_options(&svc_, "scale-factors=1/1"); 746 svc_.temporal_layers = 2; 747 Pass1EncodeNFrames(10, 1, &stats_buf); 748 749 // Second pass encode 750 codec_enc_.g_pass = VPX_RC_LAST_PASS; 751 svc_.temporal_layers = 2; 752 vpx_svc_set_options(&svc_, "auto-alt-refs=1 scale-factors=1/1"); 753 codec_enc_.g_w = 704; 754 codec_enc_.g_h = 144; 755 tile_columns_ = 1; 756 tile_rows_ = 1; 757 vpx_fixed_buf outputs[10]; 758 memset(&outputs[0], 0, sizeof(outputs)); 759 Pass2EncodeNFrames(&stats_buf, 10, 1, &outputs[0]); 760 DecodeNFrames(&outputs[0], 10); 761 FreeBitstreamBuffers(&outputs[0], 10); 762} 763 764TEST_F(SvcTest, TwoPassEncode2TemporalLayersWithMultipleFrameContextsAndTiles) { 765 // First pass encode 766 std::string stats_buf; 767 vpx_svc_set_options(&svc_, "scale-factors=1/1"); 768 svc_.temporal_layers = 2; 769 Pass1EncodeNFrames(10, 1, &stats_buf); 770 771 // Second pass encode 772 codec_enc_.g_pass = VPX_RC_LAST_PASS; 773 svc_.temporal_layers = 2; 774 codec_enc_.g_error_resilient = 0; 775 codec_enc_.g_w = 704; 776 codec_enc_.g_h = 144; 777 tile_columns_ = 1; 778 tile_rows_ = 1; 779 vpx_svc_set_options(&svc_, 780 "auto-alt-refs=1 scale-factors=1/1 " 781 "multi-frame-contexts=1"); 782 vpx_fixed_buf outputs[10]; 783 memset(&outputs[0], 0, sizeof(outputs)); 784 Pass2EncodeNFrames(&stats_buf, 10, 1, &outputs[0]); 785 DecodeNFrames(&outputs[0], 10); 786 FreeBitstreamBuffers(&outputs[0], 10); 787} 788 789} // namespace 790