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 227bc9febe8749e98a3812a0dc4380ceae75c29450Johannclass ErrorResilienceTestLarge 237bc9febe8749e98a3812a0dc4380ceae75c29450Johann : public ::libvpx_test::EncoderTest, 247bc9febe8749e98a3812a0dc4380ceae75c29450Johann public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, bool> { 251b362b15af34006e6a11974088a46d42b903418eJohann protected: 26a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian ErrorResilienceTestLarge() 277bc9febe8749e98a3812a0dc4380ceae75c29450Johann : EncoderTest(GET_PARAM(0)), svc_support_(GET_PARAM(2)), psnr_(0.0), 287bc9febe8749e98a3812a0dc4380ceae75c29450Johann nframes_(0), mismatch_psnr_(0.0), mismatch_nframes_(0), 29a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian encoding_mode_(GET_PARAM(1)) { 30ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Reset(); 311b362b15af34006e6a11974088a46d42b903418eJohann } 32ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 33a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian virtual ~ErrorResilienceTestLarge() {} 341b362b15af34006e6a11974088a46d42b903418eJohann 35ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang void Reset() { 36ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error_nframes_ = 0; 37ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang droppable_nframes_ = 0; 387ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian pattern_switch_ = 0; 39ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 40ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 411b362b15af34006e6a11974088a46d42b903418eJohann virtual void SetUp() { 421b362b15af34006e6a11974088a46d42b903418eJohann InitializeConfig(); 431b362b15af34006e6a11974088a46d42b903418eJohann SetMode(encoding_mode_); 441b362b15af34006e6a11974088a46d42b903418eJohann } 451b362b15af34006e6a11974088a46d42b903418eJohann 461b362b15af34006e6a11974088a46d42b903418eJohann virtual void BeginPassHook(unsigned int /*pass*/) { 471b362b15af34006e6a11974088a46d42b903418eJohann psnr_ = 0.0; 481b362b15af34006e6a11974088a46d42b903418eJohann nframes_ = 0; 49ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang mismatch_psnr_ = 0.0; 50ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang mismatch_nframes_ = 0; 511b362b15af34006e6a11974088a46d42b903418eJohann } 521b362b15af34006e6a11974088a46d42b903418eJohann 531b362b15af34006e6a11974088a46d42b903418eJohann virtual void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) { 541b362b15af34006e6a11974088a46d42b903418eJohann psnr_ += pkt->data.psnr.psnr[0]; 551b362b15af34006e6a11974088a46d42b903418eJohann nframes_++; 561b362b15af34006e6a11974088a46d42b903418eJohann } 571b362b15af34006e6a11974088a46d42b903418eJohann 587ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // 597ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // Frame flags and layer id for temporal layers. 607ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // For two layers, test pattern is: 617ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // 1 3 627ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // 0 2 ..... 637ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // LAST is updated on base/layer 0, GOLDEN updated on layer 1. 647ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // Non-zero pattern_switch parameter means pattern will switch to 657ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // not using LAST for frame_num >= pattern_switch. 667bc9febe8749e98a3812a0dc4380ceae75c29450Johann int SetFrameFlags(int frame_num, int num_temp_layers, int pattern_switch) { 677ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian int frame_flags = 0; 687ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (num_temp_layers == 2) { 697bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (frame_num % 2 == 0) { 707bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (frame_num < pattern_switch || pattern_switch == 0) { 717bc9febe8749e98a3812a0dc4380ceae75c29450Johann // Layer 0: predict from LAST and ARF, update LAST. 727bc9febe8749e98a3812a0dc4380ceae75c29450Johann frame_flags = 737bc9febe8749e98a3812a0dc4380ceae75c29450Johann VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF; 747ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } else { 757bc9febe8749e98a3812a0dc4380ceae75c29450Johann // Layer 0: predict from GF and ARF, update GF. 767bc9febe8749e98a3812a0dc4380ceae75c29450Johann frame_flags = VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_UPD_LAST | 777bc9febe8749e98a3812a0dc4380ceae75c29450Johann VP8_EFLAG_NO_UPD_ARF; 787ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 797bc9febe8749e98a3812a0dc4380ceae75c29450Johann } else { 807bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (frame_num < pattern_switch || pattern_switch == 0) { 817bc9febe8749e98a3812a0dc4380ceae75c29450Johann // Layer 1: predict from L, GF, and ARF, update GF. 827bc9febe8749e98a3812a0dc4380ceae75c29450Johann frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST; 837bc9febe8749e98a3812a0dc4380ceae75c29450Johann } else { 847bc9febe8749e98a3812a0dc4380ceae75c29450Johann // Layer 1: predict from GF and ARF, update GF. 857bc9febe8749e98a3812a0dc4380ceae75c29450Johann frame_flags = VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_UPD_LAST | 867bc9febe8749e98a3812a0dc4380ceae75c29450Johann VP8_EFLAG_NO_UPD_ARF; 877bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 887bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 897ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 907ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return frame_flags; 917ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 927ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 937bc9febe8749e98a3812a0dc4380ceae75c29450Johann virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video) { 947bc9febe8749e98a3812a0dc4380ceae75c29450Johann frame_flags_ &= 957bc9febe8749e98a3812a0dc4380ceae75c29450Johann ~(VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF); 967ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // For temporal layer case. 977ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (cfg_.ts_number_layers > 1) { 987bc9febe8749e98a3812a0dc4380ceae75c29450Johann frame_flags_ = 997bc9febe8749e98a3812a0dc4380ceae75c29450Johann SetFrameFlags(video->frame(), cfg_.ts_number_layers, pattern_switch_); 100ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for (unsigned int i = 0; i < droppable_nframes_; ++i) { 1013df0563f1b24dac6c0bd122fc922a48211269061hkuang if (droppable_frames_[i] == video->frame()) { 1027bc9febe8749e98a3812a0dc4380ceae75c29450Johann std::cout << "Encoding droppable frame: " << droppable_frames_[i] 1037bc9febe8749e98a3812a0dc4380ceae75c29450Johann << "\n"; 104ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 105ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 1067ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } else { 1077bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (droppable_nframes_ > 0 && 1087bc9febe8749e98a3812a0dc4380ceae75c29450Johann (cfg_.g_pass == VPX_RC_LAST_PASS || cfg_.g_pass == VPX_RC_ONE_PASS)) { 1097bc9febe8749e98a3812a0dc4380ceae75c29450Johann for (unsigned int i = 0; i < droppable_nframes_; ++i) { 1107bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (droppable_frames_[i] == video->frame()) { 1117bc9febe8749e98a3812a0dc4380ceae75c29450Johann std::cout << "Encoding droppable frame: " << droppable_frames_[i] 1127bc9febe8749e98a3812a0dc4380ceae75c29450Johann << "\n"; 1137bc9febe8749e98a3812a0dc4380ceae75c29450Johann frame_flags_ |= (VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF | 1147bc9febe8749e98a3812a0dc4380ceae75c29450Johann VP8_EFLAG_NO_UPD_ARF); 1157bc9febe8749e98a3812a0dc4380ceae75c29450Johann return; 1167bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 1177bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 1187bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 119ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 120ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 121ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1221b362b15af34006e6a11974088a46d42b903418eJohann double GetAveragePsnr() const { 1237bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (nframes_) return psnr_ / nframes_; 1241b362b15af34006e6a11974088a46d42b903418eJohann return 0.0; 1251b362b15af34006e6a11974088a46d42b903418eJohann } 1261b362b15af34006e6a11974088a46d42b903418eJohann 127ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang double GetAverageMismatchPsnr() const { 1287bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (mismatch_nframes_) return mismatch_psnr_ / mismatch_nframes_; 129ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return 0.0; 130ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 131ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 132ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang virtual bool DoDecode() const { 133ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (error_nframes_ > 0 && 134ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (cfg_.g_pass == VPX_RC_LAST_PASS || cfg_.g_pass == VPX_RC_ONE_PASS)) { 135ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for (unsigned int i = 0; i < error_nframes_; ++i) { 136ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (error_frames_[i] == nframes_ - 1) { 137ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang std::cout << " Skipping decoding frame: " 138ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang << error_frames_[i] << "\n"; 139ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return 0; 140ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 141ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 142ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 143ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return 1; 144ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 145ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1467bc9febe8749e98a3812a0dc4380ceae75c29450Johann virtual void MismatchHook(const vpx_image_t *img1, const vpx_image_t *img2) { 147ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang double mismatch_psnr = compute_psnr(img1, img2); 148ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang mismatch_psnr_ += mismatch_psnr; 149ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ++mismatch_nframes_; 150ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang // std::cout << "Mismatch frame psnr: " << mismatch_psnr << "\n"; 151ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 152ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 153ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang void SetErrorFrames(int num, unsigned int *list) { 1547bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (num > kMaxErrorFrames) { 155ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang num = kMaxErrorFrames; 1567bc9febe8749e98a3812a0dc4380ceae75c29450Johann } else if (num < 0) { 157ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang num = 0; 1587bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 159ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error_nframes_ = num; 1607bc9febe8749e98a3812a0dc4380ceae75c29450Johann for (unsigned int i = 0; i < error_nframes_; ++i) { 161ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error_frames_[i] = list[i]; 1627bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 163ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 164ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 165ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang void SetDroppableFrames(int num, unsigned int *list) { 1667bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (num > kMaxDroppableFrames) { 167ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang num = kMaxDroppableFrames; 1687bc9febe8749e98a3812a0dc4380ceae75c29450Johann } else if (num < 0) { 169ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang num = 0; 1707bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 171ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang droppable_nframes_ = num; 1727bc9febe8749e98a3812a0dc4380ceae75c29450Johann for (unsigned int i = 0; i < droppable_nframes_; ++i) { 173ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang droppable_frames_[i] = list[i]; 1747bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 175ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 176ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1777bc9febe8749e98a3812a0dc4380ceae75c29450Johann unsigned int GetMismatchFrames() { return mismatch_nframes_; } 178ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1797bc9febe8749e98a3812a0dc4380ceae75c29450Johann void SetPatternSwitch(int frame_switch) { pattern_switch_ = frame_switch; } 1807ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 181c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann bool svc_support_; 182c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 1831b362b15af34006e6a11974088a46d42b903418eJohann private: 1841b362b15af34006e6a11974088a46d42b903418eJohann double psnr_; 1851b362b15af34006e6a11974088a46d42b903418eJohann unsigned int nframes_; 186ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int error_nframes_; 187ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int droppable_nframes_; 1887ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian unsigned int pattern_switch_; 189ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang double mismatch_psnr_; 190ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int mismatch_nframes_; 191ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int error_frames_[kMaxErrorFrames]; 192ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int droppable_frames_[kMaxDroppableFrames]; 1931b362b15af34006e6a11974088a46d42b903418eJohann libvpx_test::TestMode encoding_mode_; 1941b362b15af34006e6a11974088a46d42b903418eJohann}; 1951b362b15af34006e6a11974088a46d42b903418eJohann 196a72801d7d92ababb50eecf27a36bd222d031d2feVignesh VenkatasubramanianTEST_P(ErrorResilienceTestLarge, OnVersusOff) { 1971b362b15af34006e6a11974088a46d42b903418eJohann const vpx_rational timebase = { 33333333, 1000000000 }; 1981b362b15af34006e6a11974088a46d42b903418eJohann cfg_.g_timebase = timebase; 1991b362b15af34006e6a11974088a46d42b903418eJohann cfg_.rc_target_bitrate = 2000; 2003df0563f1b24dac6c0bd122fc922a48211269061hkuang cfg_.g_lag_in_frames = 10; 2011b362b15af34006e6a11974088a46d42b903418eJohann 2021b362b15af34006e6a11974088a46d42b903418eJohann init_flags_ = VPX_CODEC_USE_PSNR; 2031b362b15af34006e6a11974088a46d42b903418eJohann 2041b362b15af34006e6a11974088a46d42b903418eJohann libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, 2051b362b15af34006e6a11974088a46d42b903418eJohann timebase.den, timebase.num, 0, 30); 2061b362b15af34006e6a11974088a46d42b903418eJohann 2071b362b15af34006e6a11974088a46d42b903418eJohann // Error resilient mode OFF. 2081b362b15af34006e6a11974088a46d42b903418eJohann cfg_.g_error_resilient = 0; 2091b362b15af34006e6a11974088a46d42b903418eJohann ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); 2101b362b15af34006e6a11974088a46d42b903418eJohann const double psnr_resilience_off = GetAveragePsnr(); 2111b362b15af34006e6a11974088a46d42b903418eJohann EXPECT_GT(psnr_resilience_off, 25.0); 2121b362b15af34006e6a11974088a46d42b903418eJohann 2131b362b15af34006e6a11974088a46d42b903418eJohann // Error resilient mode ON. 2141b362b15af34006e6a11974088a46d42b903418eJohann cfg_.g_error_resilient = 1; 2151b362b15af34006e6a11974088a46d42b903418eJohann ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); 2161b362b15af34006e6a11974088a46d42b903418eJohann const double psnr_resilience_on = GetAveragePsnr(); 2171b362b15af34006e6a11974088a46d42b903418eJohann EXPECT_GT(psnr_resilience_on, 25.0); 2181b362b15af34006e6a11974088a46d42b903418eJohann 2191b362b15af34006e6a11974088a46d42b903418eJohann // Test that turning on error resilient mode hurts by 10% at most. 2201b362b15af34006e6a11974088a46d42b903418eJohann if (psnr_resilience_off > 0.0) { 2211b362b15af34006e6a11974088a46d42b903418eJohann const double psnr_ratio = psnr_resilience_on / psnr_resilience_off; 2221b362b15af34006e6a11974088a46d42b903418eJohann EXPECT_GE(psnr_ratio, 0.9); 2231b362b15af34006e6a11974088a46d42b903418eJohann EXPECT_LE(psnr_ratio, 1.1); 2241b362b15af34006e6a11974088a46d42b903418eJohann } 2251b362b15af34006e6a11974088a46d42b903418eJohann} 2261b362b15af34006e6a11974088a46d42b903418eJohann 227b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// Check for successful decoding and no encoder/decoder mismatch 228b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// if we lose (i.e., drop before decoding) a set of droppable 229b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// frames (i.e., frames that don't update any reference buffers). 230b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// Check both isolated and consecutive loss. 231a72801d7d92ababb50eecf27a36bd222d031d2feVignesh VenkatasubramanianTEST_P(ErrorResilienceTestLarge, DropFramesWithoutRecovery) { 232ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang const vpx_rational timebase = { 33333333, 1000000000 }; 233ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang cfg_.g_timebase = timebase; 234ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang cfg_.rc_target_bitrate = 500; 2353df0563f1b24dac6c0bd122fc922a48211269061hkuang // FIXME(debargha): Fix this to work for any lag. 2363df0563f1b24dac6c0bd122fc922a48211269061hkuang // Currently this test only works for lag = 0 2373df0563f1b24dac6c0bd122fc922a48211269061hkuang cfg_.g_lag_in_frames = 0; 238ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 239ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang init_flags_ = VPX_CODEC_USE_PSNR; 240ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 241ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, 242b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian timebase.den, timebase.num, 0, 40); 243ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 244ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang // Error resilient mode ON. 245ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang cfg_.g_error_resilient = 1; 246b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg_.kf_mode = VPX_KF_DISABLED; 247b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 248b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Set an arbitrary set of error frames same as droppable frames. 249b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // In addition to isolated loss/drop, add a long consecutive series 250b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // (of size 9) of dropped frames. 251b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian unsigned int num_droppable_frames = 11; 2527bc9febe8749e98a3812a0dc4380ceae75c29450Johann unsigned int droppable_frame_list[] = { 5, 16, 22, 23, 24, 25, 2537bc9febe8749e98a3812a0dc4380ceae75c29450Johann 26, 27, 28, 29, 30 }; 254ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang SetDroppableFrames(num_droppable_frames, droppable_frame_list); 255ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang SetErrorFrames(num_droppable_frames, droppable_frame_list); 256ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); 257ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang // Test that no mismatches have been found 2587bc9febe8749e98a3812a0dc4380ceae75c29450Johann std::cout << " Mismatch frames: " << GetMismatchFrames() << "\n"; 2597bc9febe8749e98a3812a0dc4380ceae75c29450Johann EXPECT_EQ(GetMismatchFrames(), (unsigned int)0); 260ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 261b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Reset previously set of error/droppable frames. 262ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Reset(); 263ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 264ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#if 0 265ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang // TODO(jkoleszar): This test is disabled for the time being as too 266ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang // sensitive. It's not clear how to set a reasonable threshold for 267ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang // this behavior. 268ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 269ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang // Now set an arbitrary set of error frames that are non-droppable 270ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int num_error_frames = 3; 271ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int error_frame_list[] = {3, 10, 20}; 272ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang SetErrorFrames(num_error_frames, error_frame_list); 273ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); 274ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 275ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang // Test that dropping an arbitrary set of inter frames does not hurt too much 276ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang // Note the Average Mismatch PSNR is the average of the PSNR between 277ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang // decoded frame and encoder's version of the same frame for all frames 278ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang // with mismatch. 279ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang const double psnr_resilience_mismatch = GetAverageMismatchPsnr(); 280ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang std::cout << " Mismatch PSNR: " 281ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang << psnr_resilience_mismatch << "\n"; 282ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang EXPECT_GT(psnr_resilience_mismatch, 20.0); 283ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#endif 284ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 285ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2867ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian// Check for successful decoding and no encoder/decoder mismatch 2877ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian// if we lose (i.e., drop before decoding) the enhancement layer frames for a 2887ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian// two layer temporal pattern. The base layer does not predict from the top 2897ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian// layer, so successful decoding is expected. 2907ce0a1d1337c01056ba24006efab21f00e179e04Vignesh VenkatasubramanianTEST_P(ErrorResilienceTestLarge, 2LayersDropEnhancement) { 291c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann // This test doesn't run if SVC is not supported. 2927bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!svc_support_) return; 293c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 2947ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian const vpx_rational timebase = { 33333333, 1000000000 }; 2957ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.g_timebase = timebase; 2967ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.rc_target_bitrate = 500; 2977ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.g_lag_in_frames = 0; 2987ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 2997ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.rc_end_usage = VPX_CBR; 3007ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // 2 Temporal layers, no spatial layers, CBR mode. 3017ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.ss_number_layers = 1; 3027ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.ts_number_layers = 2; 3037ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.ts_rate_decimator[0] = 2; 3047ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.ts_rate_decimator[1] = 1; 3057ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.ts_periodicity = 2; 3067ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.ts_target_bitrate[0] = 60 * cfg_.rc_target_bitrate / 100; 3077ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.ts_target_bitrate[1] = cfg_.rc_target_bitrate; 3087ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 3097ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian init_flags_ = VPX_CODEC_USE_PSNR; 3107ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 3117ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, 3127ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian timebase.den, timebase.num, 0, 40); 3137ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 3147ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // Error resilient mode ON. 3157ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.g_error_resilient = 1; 3167ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.kf_mode = VPX_KF_DISABLED; 3177ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian SetPatternSwitch(0); 3187ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 3197ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // The odd frames are the enhancement layer for 2 layer pattern, so set 3207ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // those frames as droppable. Drop the last 7 frames. 3217ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian unsigned int num_droppable_frames = 7; 3227bc9febe8749e98a3812a0dc4380ceae75c29450Johann unsigned int droppable_frame_list[] = { 27, 29, 31, 33, 35, 37, 39 }; 3237ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian SetDroppableFrames(num_droppable_frames, droppable_frame_list); 3247ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian SetErrorFrames(num_droppable_frames, droppable_frame_list); 3257ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); 3267ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // Test that no mismatches have been found 3277bc9febe8749e98a3812a0dc4380ceae75c29450Johann std::cout << " Mismatch frames: " << GetMismatchFrames() << "\n"; 3287bc9febe8749e98a3812a0dc4380ceae75c29450Johann EXPECT_EQ(GetMismatchFrames(), (unsigned int)0); 3297ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 3307ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // Reset previously set of error/droppable frames. 3317ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian Reset(); 3327ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 3337ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 3347ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian// Check for successful decoding and no encoder/decoder mismatch 3357ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian// for a two layer temporal pattern, where at some point in the 3367ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian// sequence, the LAST ref is not used anymore. 3377ce0a1d1337c01056ba24006efab21f00e179e04Vignesh VenkatasubramanianTEST_P(ErrorResilienceTestLarge, 2LayersNoRefLast) { 338c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann // This test doesn't run if SVC is not supported. 3397bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!svc_support_) return; 340c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 3417ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian const vpx_rational timebase = { 33333333, 1000000000 }; 3427ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.g_timebase = timebase; 3437ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.rc_target_bitrate = 500; 3447ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.g_lag_in_frames = 0; 3457ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 3467ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.rc_end_usage = VPX_CBR; 3477ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // 2 Temporal layers, no spatial layers, CBR mode. 3487ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.ss_number_layers = 1; 3497ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.ts_number_layers = 2; 3507ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.ts_rate_decimator[0] = 2; 3517ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.ts_rate_decimator[1] = 1; 3527ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.ts_periodicity = 2; 3537ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.ts_target_bitrate[0] = 60 * cfg_.rc_target_bitrate / 100; 3547ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.ts_target_bitrate[1] = cfg_.rc_target_bitrate; 3557ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 3567ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian init_flags_ = VPX_CODEC_USE_PSNR; 3577ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 3587ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, 3597ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian timebase.den, timebase.num, 0, 100); 3607ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 3617ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // Error resilient mode ON. 3627ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.g_error_resilient = 1; 3637ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.kf_mode = VPX_KF_DISABLED; 3647ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian SetPatternSwitch(60); 3657ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 3667ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); 3677ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // Test that no mismatches have been found 3687bc9febe8749e98a3812a0dc4380ceae75c29450Johann std::cout << " Mismatch frames: " << GetMismatchFrames() << "\n"; 3697bc9febe8749e98a3812a0dc4380ceae75c29450Johann EXPECT_EQ(GetMismatchFrames(), (unsigned int)0); 3707ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 3717ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // Reset previously set of error/droppable frames. 3727ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian Reset(); 3737ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 3747ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 3757bc9febe8749e98a3812a0dc4380ceae75c29450Johannclass ErrorResilienceTestLargeCodecControls 3767bc9febe8749e98a3812a0dc4380ceae75c29450Johann : public ::libvpx_test::EncoderTest, 3777bc9febe8749e98a3812a0dc4380ceae75c29450Johann public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> { 3787ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian protected: 3797ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian ErrorResilienceTestLargeCodecControls() 3807bc9febe8749e98a3812a0dc4380ceae75c29450Johann : EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)) { 3817ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian Reset(); 3827ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 3837ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 3847ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian virtual ~ErrorResilienceTestLargeCodecControls() {} 3857ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 3867ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian void Reset() { 3877ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian last_pts_ = 0; 3887ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian tot_frame_number_ = 0; 3897ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // For testing up to 3 layers. 3907ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian for (int i = 0; i < 3; ++i) { 3917ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian bits_total_[i] = 0; 3927ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 3937ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian duration_ = 0.0; 3947ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 3957ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 3967ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian virtual void SetUp() { 3977ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian InitializeConfig(); 3987ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian SetMode(encoding_mode_); 3997ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 4007ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 4017ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // 4027ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // Frame flags and layer id for temporal layers. 4037ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // 4047ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 4057ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // For two layers, test pattern is: 4067ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // 1 3 4077ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // 0 2 ..... 4087ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // For three layers, test pattern is: 4097ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // 1 3 5 7 4107ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // 2 6 4117ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // 0 4 .... 4127ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // LAST is always update on base/layer 0, GOLDEN is updated on layer 1, 4137ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // and ALTREF is updated on top layer for 3 layer pattern. 4147ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian int SetFrameFlags(int frame_num, int num_temp_layers) { 4157ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian int frame_flags = 0; 4167ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (num_temp_layers == 2) { 4177ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (frame_num % 2 == 0) { 4187ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // Layer 0: predict from L and ARF, update L. 4197bc9febe8749e98a3812a0dc4380ceae75c29450Johann frame_flags = 4207bc9febe8749e98a3812a0dc4380ceae75c29450Johann VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF; 4217ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } else { 4227ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // Layer 1: predict from L, G and ARF, and update G. 4237ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST | 4247ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian VP8_EFLAG_NO_UPD_ENTROPY; 4257ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 4267ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } else if (num_temp_layers == 3) { 4277ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (frame_num % 4 == 0) { 4287ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // Layer 0: predict from L, update L. 4297ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frame_flags = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | 4307ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF; 4317ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } else if ((frame_num - 2) % 4 == 0) { 4327ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // Layer 1: predict from L, G, update G. 4337bc9febe8749e98a3812a0dc4380ceae75c29450Johann frame_flags = 4347bc9febe8749e98a3812a0dc4380ceae75c29450Johann VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_REF_ARF; 4357bc9febe8749e98a3812a0dc4380ceae75c29450Johann } else if ((frame_num - 1) % 2 == 0) { 4367ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // Layer 2: predict from L, G, ARF; update ARG. 4377ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frame_flags = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_LAST; 4387ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 4397ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 4407ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return frame_flags; 4417ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 4427ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 4437ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian int SetLayerId(int frame_num, int num_temp_layers) { 4447ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian int layer_id = 0; 4457ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (num_temp_layers == 2) { 4467ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (frame_num % 2 == 0) { 4477ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian layer_id = 0; 4487ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } else { 4497bc9febe8749e98a3812a0dc4380ceae75c29450Johann layer_id = 1; 4507ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 4517ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } else if (num_temp_layers == 3) { 4527ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (frame_num % 4 == 0) { 4537ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian layer_id = 0; 4547ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } else if ((frame_num - 2) % 4 == 0) { 4557ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian layer_id = 1; 4567ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } else if ((frame_num - 1) % 2 == 0) { 4577ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian layer_id = 2; 4587ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 4597ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 4607ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return layer_id; 4617ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 4627ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 4637ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video, 4647ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian libvpx_test::Encoder *encoder) { 4657ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (cfg_.ts_number_layers > 1) { 4667bc9febe8749e98a3812a0dc4380ceae75c29450Johann int layer_id = SetLayerId(video->frame(), cfg_.ts_number_layers); 4677bc9febe8749e98a3812a0dc4380ceae75c29450Johann int frame_flags = SetFrameFlags(video->frame(), cfg_.ts_number_layers); 4687bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (video->frame() > 0) { 4697bc9febe8749e98a3812a0dc4380ceae75c29450Johann encoder->Control(VP8E_SET_TEMPORAL_LAYER_ID, layer_id); 4707bc9febe8749e98a3812a0dc4380ceae75c29450Johann encoder->Control(VP8E_SET_FRAME_FLAGS, frame_flags); 4717bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 4727bc9febe8749e98a3812a0dc4380ceae75c29450Johann const vpx_rational_t tb = video->timebase(); 4737bc9febe8749e98a3812a0dc4380ceae75c29450Johann timebase_ = static_cast<double>(tb.num) / tb.den; 4747bc9febe8749e98a3812a0dc4380ceae75c29450Johann duration_ = 0; 4757bc9febe8749e98a3812a0dc4380ceae75c29450Johann return; 4767ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 4777ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 4787ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 4797ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) { 4807ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // Time since last timestamp = duration. 4817ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian vpx_codec_pts_t duration = pkt->data.frame.pts - last_pts_; 4827ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (duration > 1) { 4837ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // Update counter for total number of frames (#frames input to encoder). 4847ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // Needed for setting the proper layer_id below. 4857ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian tot_frame_number_ += static_cast<int>(duration - 1); 4867ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 4877ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian int layer = SetLayerId(tot_frame_number_, cfg_.ts_number_layers); 4887ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian const size_t frame_size_in_bits = pkt->data.frame.sz * 8; 4897ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // Update the total encoded bits. For temporal layers, update the cumulative 4907ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // encoded bits per layer. 4917ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian for (int i = layer; i < static_cast<int>(cfg_.ts_number_layers); ++i) { 4927ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian bits_total_[i] += frame_size_in_bits; 4937ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 4947ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // Update the most recent pts. 4957ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian last_pts_ = pkt->data.frame.pts; 4967ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian ++tot_frame_number_; 4977ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 4987ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 4997ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian virtual void EndPassHook(void) { 5007ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian duration_ = (last_pts_ + 1) * timebase_; 5017bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (cfg_.ts_number_layers > 1) { 5027ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian for (int layer = 0; layer < static_cast<int>(cfg_.ts_number_layers); 5037bc9febe8749e98a3812a0dc4380ceae75c29450Johann ++layer) { 5047ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (bits_total_[layer]) { 5057ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // Effective file datarate: 5067bc9febe8749e98a3812a0dc4380ceae75c29450Johann effective_datarate_[layer] = 5077bc9febe8749e98a3812a0dc4380ceae75c29450Johann (bits_total_[layer] / 1000.0) / duration_; 5087ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 5097ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 5107ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 5117ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 5127ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 5137ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian double effective_datarate_[3]; 5147bc9febe8749e98a3812a0dc4380ceae75c29450Johann 5157bc9febe8749e98a3812a0dc4380ceae75c29450Johann private: 5167bc9febe8749e98a3812a0dc4380ceae75c29450Johann libvpx_test::TestMode encoding_mode_; 5177bc9febe8749e98a3812a0dc4380ceae75c29450Johann vpx_codec_pts_t last_pts_; 5187bc9febe8749e98a3812a0dc4380ceae75c29450Johann double timebase_; 5197bc9febe8749e98a3812a0dc4380ceae75c29450Johann int64_t bits_total_[3]; 5207bc9febe8749e98a3812a0dc4380ceae75c29450Johann double duration_; 5217bc9febe8749e98a3812a0dc4380ceae75c29450Johann int tot_frame_number_; 5227bc9febe8749e98a3812a0dc4380ceae75c29450Johann}; 5237ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 5247ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian// Check two codec controls used for: 5257ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian// (1) for setting temporal layer id, and (2) for settings encoder flags. 5267ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian// This test invokes those controls for each frame, and verifies encoder/decoder 5277ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian// mismatch and basic rate control response. 5287ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian// TODO(marpan): Maybe move this test to datarate_test.cc. 5297ce0a1d1337c01056ba24006efab21f00e179e04Vignesh VenkatasubramanianTEST_P(ErrorResilienceTestLargeCodecControls, CodecControl3TemporalLayers) { 5307ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.rc_buf_initial_sz = 500; 5317ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.rc_buf_optimal_sz = 500; 5327ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.rc_buf_sz = 1000; 5337ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.rc_dropframe_thresh = 1; 5347ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.rc_min_quantizer = 2; 5357ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.rc_max_quantizer = 56; 5367ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.rc_end_usage = VPX_CBR; 5377ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.rc_dropframe_thresh = 1; 5387ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.g_lag_in_frames = 0; 5397ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.kf_mode = VPX_KF_DISABLED; 5407ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.g_error_resilient = 1; 5417ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 5427ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // 3 Temporal layers. Framerate decimation (4, 2, 1). 5437ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.ts_number_layers = 3; 5447ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.ts_rate_decimator[0] = 4; 5457ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.ts_rate_decimator[1] = 2; 5467ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.ts_rate_decimator[2] = 1; 5477ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.ts_periodicity = 4; 5487ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.ts_layer_id[0] = 0; 5497ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.ts_layer_id[1] = 2; 5507ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.ts_layer_id[2] = 1; 5517ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.ts_layer_id[3] = 2; 5527ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 5537ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, 5547ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 30, 1, 0, 200); 5557ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian for (int i = 200; i <= 800; i += 200) { 5567ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.rc_target_bitrate = i; 5577ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian Reset(); 5587ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // 40-20-40 bitrate allocation for 3 temporal layers. 5597ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.ts_target_bitrate[0] = 40 * cfg_.rc_target_bitrate / 100; 5607ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.ts_target_bitrate[1] = 60 * cfg_.rc_target_bitrate / 100; 5617ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cfg_.ts_target_bitrate[2] = cfg_.rc_target_bitrate; 5627ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); 5637ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) { 5647ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian ASSERT_GE(effective_datarate_[j], cfg_.ts_target_bitrate[j] * 0.75) 5657ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian << " The datarate for the file is lower than target by too much, " 5667bc9febe8749e98a3812a0dc4380ceae75c29450Johann "for layer: " 5677bc9febe8749e98a3812a0dc4380ceae75c29450Johann << j; 5687ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian ASSERT_LE(effective_datarate_[j], cfg_.ts_target_bitrate[j] * 1.25) 5697ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian << " The datarate for the file is greater than target by too much, " 5707bc9febe8749e98a3812a0dc4380ceae75c29450Johann "for layer: " 5717bc9febe8749e98a3812a0dc4380ceae75c29450Johann << j; 5727ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 5737ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 5747ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 5757ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 576c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohannVP8_INSTANTIATE_TEST_CASE(ErrorResilienceTestLarge, ONE_PASS_TEST_MODES, 577c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann ::testing::Values(true)); 5787ce0a1d1337c01056ba24006efab21f00e179e04Vignesh VenkatasubramanianVP8_INSTANTIATE_TEST_CASE(ErrorResilienceTestLargeCodecControls, 5797ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian ONE_PASS_TEST_MODES); 580c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohannVP9_INSTANTIATE_TEST_CASE(ErrorResilienceTestLarge, ONE_PASS_TEST_MODES, 581c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann ::testing::Values(true)); 5821b362b15af34006e6a11974088a46d42b903418eJohann} // namespace 583