| @@ -16,6 +16,7 @@ · 15 unmodified lines |
| 16 | 16 | #include "third_party/googletest/src/include/gtest/gtest.h" |
| 17 | 17 | #include "test/codec_factory.h" |
| 18 | 18 | #include "test/encode_test_driver.h" |
| 19 | +#include "test/i420_video_source.h" |
| 19 | 20 | #include "test/util.h" |
| 20 | 21 | #include "test/video_source.h" |
| 21 | 22 | #include "vpx/vpx_codec.h" |
| @@ -23,188 +24,89 @@ · 1 unmodified line |
| 23 | 24 | |
| 24 | 25 | namespace { |
| 25 | 26 | |
| 26 | | −const size_t kNumFrame = 850; |
| 27 | +const size_t kNumFrames = 300; |
| 27 | 28 | |
| 28 | | −struct FrameInfo { |
| 29 | | − friend std::istream &operator>>(std::istream &is, FrameInfo &info) { |
| 30 | | − is >> info.frame_id >> info.spatial_id >> info.temporal_id >> info.base_q >> |
| 31 | | − info.target_bandwidth >> info.buffer_level >> info.filter_level_ >> |
| 32 | | − info.bytes_used; |
| 33 | | − return is; |
| 34 | | − } |
| 35 | | − |
| 36 | | − int frame_id; |
| 37 | | − int spatial_id; |
| 38 | | − int temporal_id; |
| 39 | | − // Base QP |
| 40 | | − int base_q; |
| 41 | | − size_t target_bandwidth; |
| 42 | | − size_t buffer_level; |
| 43 | | − // Loopfilter level |
| 44 | | − int filter_level_; |
| 45 | | − // Frame size for current frame, used for pose encode update |
| 46 | | − size_t bytes_used; |
| 47 | | −}; |
| 29 | +const int kTemporalId[4] = { 0, 2, 1, 2 }; |
| 48 | 30 | |
| 49 | | −// This test runs the rate control interface and compare against ground truth |
| 50 | | −// generated by encoders. |
| 51 | | −// Settings for the encoder: |
| 52 | | −// For 1 layer CBR: |
| 53 | | −// - AQ_Mode 0 |
| 54 | | −// - Disable golden refresh |
| 55 | | −// - Bitrate x 2 at frame/superframe 200 |
| 56 | | −// - Bitrate / 4 at frame/superframe 400 |
| 57 | | −// examples/vpx_temporal_svc_encoder gipsrec_motion1.1280_720.yuv out vp9 |
| 58 | | −// 1280 720 1 30 7 0 0 1 0 1000 |
| 59 | | −// |
| 60 | | −// For 1 layer VBR: |
| 61 | | −// - Set rc_end_usage to VPX_VBR |
| 62 | | −// - AQ Mode 0 |
| 63 | | −// - Disable vp9_compute_frame_low_motion in vp9_encoder.c |
| 64 | | −// - Set rc->constrain_gf_key_freq_onepass_vbr = 0 in vp9_rc_init |
| 65 | | −// examples/vpx_temporal_svc_encoder gipsrec_motion1.1280_720.yuv out vp9 |
| 66 | | −// 1280 720 1 30 7 0 0 1 0 1000 |
| 67 | | −// |
| 68 | | −// For SVC (3 temporal layers, 3 spatial layers): |
| 69 | | −// - AQ_Mode 0 |
| 70 | | −// - Disable golden refresh |
| 71 | | −// - Bitrate x 2 at frame/superframe 200 |
| 72 | | −// - Bitrate / 4 at frame/superframe 400 |
| 73 | | −// examples/vp9_spatial_svc_encoder -f 10000 -w 1280 -h 720 -t 1/30 -sl 3 |
| 74 | | −// -k 10000 -bl 100,140,200,250,350,500,450,630,900 -b 1600 --rc-end-usage=1 |
| 75 | | −// --lag-in-frames=0 --passes=1 --speed=7 --threads=1 |
| 76 | | −// --temporal-layering-mode=3 -aq 1 -rcstat 1 |
| 77 | | −// gipsrec_motion1.1280_720.yuv -o out.webm |
| 78 | | −// |
| 79 | | −// The generated file includes: |
| 80 | | −// frame number, spatial layer ID, temporal layer ID, base QP, target |
| 81 | | −// bandwidth, buffer level, loopfilter level, encoded frame size |
| 82 | | −// TODO(jianj): Remove golden files, and run actual encoding in this test. |
| 83 | | −class RcInterfaceTest : public ::testing::Test { |
| 31 | +class RcInterfaceTest |
| 32 | + : public ::libvpx_test::EncoderTest, |
| 33 | + public ::libvpx_test::CodecTestWith2Params<int, vpx_rc_mode> { |
| 84 | 34 | public: |
| 85 | | − explicit RcInterfaceTest() {} |
| 35 | + RcInterfaceTest() |
| 36 | + : EncoderTest(GET_PARAM(0)), aq_mode_(GET_PARAM(1)), key_interval_(3000), |
| 37 | + encoder_exit_(false) {} |
| 86 | 38 | |
| 87 | 39 | virtual ~RcInterfaceTest() {} |
| 88 | 40 | |
| 89 | 41 | protected: |
| 90 | | − void RunOneLayerCBR() { |
| 91 | | − SetConfigOneLayerCBR(); |
| 92 | | − rc_api_ = libvpx::VP9RateControlRTC::Create(rc_cfg_); |
| 93 | | − FrameInfo frame_info; |
| 94 | | − libvpx::VP9FrameParamsQpRTC frame_params; |
| 95 | | − frame_params.frame_type = KEY_FRAME; |
| 96 | | − frame_params.spatial_layer_id = 0; |
| 97 | | − frame_params.temporal_layer_id = 0; |
| 98 | | − std::ifstream one_layer_file; |
| 99 | | − one_layer_file.open(libvpx_test::GetDataPath() + |
| 100 | | − "/rc_interface_test_one_layer"); |
| 101 | | − ASSERT_TRUE(one_layer_file.good()); |
| 102 | | − for (size_t i = 0; i < kNumFrame; i++) { |
| 103 | | − one_layer_file >> frame_info; |
| 104 | | − if (frame_info.frame_id > 0) frame_params.frame_type = INTER_FRAME; |
| 105 | | − if (frame_info.frame_id == 200) { |
| 106 | | − rc_cfg_.target_bandwidth = rc_cfg_.target_bandwidth * 2; |
| 107 | | − rc_api_->UpdateRateControl(rc_cfg_); |
| 108 | | − } else if (frame_info.frame_id == 400) { |
| 109 | | − rc_cfg_.target_bandwidth = rc_cfg_.target_bandwidth / 4; |
| 110 | | − rc_api_->UpdateRateControl(rc_cfg_); |
| 111 | | − } |
| 112 | | − ASSERT_EQ(frame_info.spatial_id, 0); |
| 113 | | − ASSERT_EQ(frame_info.temporal_id, 0); |
| 114 | | − rc_api_->ComputeQP(frame_params); |
| 115 | | − ASSERT_EQ(rc_api_->GetQP(), frame_info.base_q); |
| 116 | | − ASSERT_EQ(rc_api_->GetLoopfilterLevel(), frame_info.filter_level_); |
| 117 | | − rc_api_->PostEncodeUpdate(frame_info.bytes_used); |
| 42 | + virtual void SetUp() { |
| 43 | + InitializeConfig(); |
| 44 | + SetMode(::libvpx_test::kRealTime); |
| 45 | + } |
| 46 | + |
| 47 | + virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video, |
| 48 | + libvpx_test::Encoder *encoder) { |
| 49 | + if (video->frame() == 0) { |
| 50 | + encoder->Control(VP8E_SET_CPUUSED, 7); |
| 51 | + encoder->Control(VP9E_SET_AQ_MODE, aq_mode_); |
| 52 | + encoder->Control(VP9E_SET_TUNE_CONTENT, 0); |
| 53 | + encoder->Control(VP8E_SET_MAX_INTRA_BITRATE_PCT, 1000); |
| 54 | + encoder->Control(VP9E_SET_RTC_EXTERNAL_RATECTRL, 1); |
| 118 | 55 | } |
| 56 | + frame_params_.frame_type = |
| 57 | + video->frame() % key_interval_ == 0 ? KEY_FRAME : INTER_FRAME; |
| 58 | + if (rc_cfg_.rc_mode == VPX_CBR && frame_params_.frame_type == INTER_FRAME) { |
| 59 | + // Disable golden frame update. |
| 60 | + frame_flags_ |= VP8_EFLAG_NO_UPD_GF; |
| 61 | + frame_flags_ |= VP8_EFLAG_NO_UPD_ARF; |
| 62 | + } |
| 63 | + encoder_exit_ = video->frame() == kNumFrames; |
| 119 | 64 | } |
| 120 | 65 | |
| 121 | | − void RunSVC() { |
| 122 | | − SetConfigSVC(); |
| 123 | | − rc_api_ = libvpx::VP9RateControlRTC::Create(rc_cfg_); |
| 124 | | − FrameInfo frame_info; |
| 125 | | − libvpx::VP9FrameParamsQpRTC frame_params; |
| 126 | | − frame_params.frame_type = KEY_FRAME; |
| 127 | | − std::ifstream svc_file; |
| 128 | | − svc_file.open(libvpx_test::GetDataPath() + "/rc_interface_test_svc"); |
| 129 | | − ASSERT_TRUE(svc_file.good()); |
| 130 | | − for (size_t i = 0; i < kNumFrame * rc_cfg_.ss_number_layers; i++) { |
| 131 | | − svc_file >> frame_info; |
| 132 | | − if (frame_info.frame_id > 0) frame_params.frame_type = INTER_FRAME; |
| 133 | | − if (frame_info.frame_id == 200 * rc_cfg_.ss_number_layers) { |
| 134 | | − for (int layer = 0; |
| 135 | | − layer < rc_cfg_.ss_number_layers * rc_cfg_.ts_number_layers; |
| 136 | | − layer++) |
| 137 | | − rc_cfg_.layer_target_bitrate[layer] *= 2; |
| 138 | | − rc_cfg_.target_bandwidth *= 2; |
| 139 | | − rc_api_->UpdateRateControl(rc_cfg_); |
| 140 | | − } else if (frame_info.frame_id == 400 * rc_cfg_.ss_number_layers) { |
| 141 | | − for (int layer = 0; |
| 142 | | − layer < rc_cfg_.ss_number_layers * rc_cfg_.ts_number_layers; |
| 143 | | − layer++) |
| 144 | | − rc_cfg_.layer_target_bitrate[layer] /= 4; |
| 145 | | − rc_cfg_.target_bandwidth /= 4; |
| 146 | | − rc_api_->UpdateRateControl(rc_cfg_); |
| 147 | | − } |
| 148 | | − frame_params.spatial_layer_id = frame_info.spatial_id; |
| 149 | | − frame_params.temporal_layer_id = frame_info.temporal_id; |
| 150 | | − rc_api_->ComputeQP(frame_params); |
| 151 | | − ASSERT_EQ(rc_api_->GetQP(), frame_info.base_q); |
| 152 | | − ASSERT_EQ(rc_api_->GetLoopfilterLevel(), frame_info.filter_level_); |
| 153 | | − rc_api_->PostEncodeUpdate(frame_info.bytes_used); |
| 66 | + virtual void PostEncodeFrameHook(::libvpx_test::Encoder *encoder) { |
| 67 | + if (encoder_exit_) { |
| 68 | + return; |
| 154 | 69 | } |
| 70 | + int loopfilter_level, qp; |
| 71 | + encoder->Control(VP9E_GET_LOOPFILTER_LEVEL, &loopfilter_level); |
| 72 | + encoder->Control(VP8E_GET_LAST_QUANTIZER, &qp); |
| 73 | + rc_api_->ComputeQP(frame_params_); |
| 74 | + ASSERT_EQ(rc_api_->GetQP(), qp); |
| 75 | + ASSERT_EQ(rc_api_->GetLoopfilterLevel(), loopfilter_level); |
| 155 | 76 | } |
| 156 | 77 | |
| 157 | | − void RunOneLayerVBR() { |
| 158 | | − SetConfigOneLayerVBR(); |
| 78 | + virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) { |
| 79 | + rc_api_->PostEncodeUpdate(pkt->data.frame.sz); |
| 80 | + } |
| 81 | + |
| 82 | + void RunOneLayer() { |
| 83 | + SetConfig(GET_PARAM(2)); |
| 159 | 84 | rc_api_ = libvpx::VP9RateControlRTC::Create(rc_cfg_); |
| 160 | | − FrameInfo frame_info; |
| 161 | | − libvpx::VP9FrameParamsQpRTC frame_params; |
| 162 | | − frame_params.frame_type = KEY_FRAME; |
| 163 | | − frame_params.spatial_layer_id = 0; |
| 164 | | − frame_params.temporal_layer_id = 0; |
| 165 | | − std::ifstream one_layer_file; |
| 166 | | − one_layer_file.open(libvpx_test::GetDataPath() + |
| 167 | | − "/rc_interface_test_one_layer_vbr"); |
| 168 | | − ASSERT_TRUE(one_layer_file.good()); |
| 169 | | − for (size_t i = 0; i < kNumFrame; i++) { |
| 170 | | − one_layer_file >> frame_info; |
| 171 | | − if (frame_info.frame_id > 0) frame_params.frame_type = INTER_FRAME; |
| 172 | | − ASSERT_EQ(frame_info.spatial_id, 0); |
| 173 | | − ASSERT_EQ(frame_info.temporal_id, 0); |
| 174 | | − rc_api_->ComputeQP(frame_params); |
| 175 | | − ASSERT_EQ(rc_api_->GetQP(), frame_info.base_q); |
| 176 | | − ASSERT_EQ(rc_api_->GetLoopfilterLevel(), frame_info.filter_level_); |
| 177 | | − rc_api_->PostEncodeUpdate(frame_info.bytes_used); |
| 178 | | − } |
| 85 | + frame_params_.spatial_layer_id = 0; |
| 86 | + frame_params_.temporal_layer_id = 0; |
| 87 | + |
| 88 | + ::libvpx_test::I420VideoSource video("desktop_office1.1280_720-020.yuv", |
| 89 | + 1280, 720, 30, 1, 0, kNumFrames); |
| 90 | + |
| 91 | + ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); |
| 179 | 92 | } |
| 180 | 93 | |
| 181 | 94 | void RunOneLayerVBRPeriodicKey() { |
| 182 | | − SetConfigOneLayerVBRPeriodicKey(); |
| 95 | + if (GET_PARAM(2) != VPX_VBR) return; |
| 96 | + key_interval_ = 100; |
| 97 | + SetConfig(VPX_VBR); |
| 183 | 98 | rc_api_ = libvpx::VP9RateControlRTC::Create(rc_cfg_); |
| 184 | | − FrameInfo frame_info; |
| 185 | | − libvpx::VP9FrameParamsQpRTC frame_params; |
| 186 | | − frame_params.frame_type = KEY_FRAME; |
| 187 | | − frame_params.spatial_layer_id = 0; |
| 188 | | − frame_params.temporal_layer_id = 0; |
| 189 | | − std::ifstream one_layer_file; |
| 190 | | − one_layer_file.open(libvpx_test::GetDataPath() + |
| 191 | | − "/rc_interface_test_one_layer_vbr_periodic_key"); |
| 192 | | − ASSERT_TRUE(one_layer_file.good()); |
| 193 | | − for (size_t i = 0; i < kNumFrame; i++) { |
| 194 | | − one_layer_file >> frame_info; |
| 195 | | − if (frame_info.frame_id > 0) frame_params.frame_type = INTER_FRAME; |
| 196 | | − if (frame_info.frame_id % 300 == 0) frame_params.frame_type = KEY_FRAME; |
| 197 | | − ASSERT_EQ(frame_info.spatial_id, 0); |
| 198 | | − ASSERT_EQ(frame_info.temporal_id, 0); |
| 199 | | − rc_api_->ComputeQP(frame_params); |
| 200 | | − ASSERT_EQ(rc_api_->GetQP(), frame_info.base_q); |
| 201 | | − ASSERT_EQ(rc_api_->GetLoopfilterLevel(), frame_info.filter_level_); |
| 202 | | − rc_api_->PostEncodeUpdate(frame_info.bytes_used); |
| 203 | | − } |
| 99 | + frame_params_.spatial_layer_id = 0; |
| 100 | + frame_params_.temporal_layer_id = 0; |
| 101 | + |
| 102 | + ::libvpx_test::I420VideoSource video("desktop_office1.1280_720-020.yuv", |
| 103 | + 1280, 720, 30, 1, 0, kNumFrames); |
| 104 | + |
| 105 | + ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); |
| 204 | 106 | } |
| 205 | 107 | |
| 206 | 108 | private: |
| 207 | | − void SetConfig() { |
| 109 | + void SetConfig(vpx_rc_mode rc_mode) { |
| 208 | 110 | rc_cfg_.width = 1280; |
| 209 | 111 | rc_cfg_.height = 720; |
| 210 | 112 | rc_cfg_.max_quantizer = 52; |
| @@ -224,24 +126,182 @@ class RcInterfaceTest : public ::testing::Test { · 13 unmodified lines |
| 224 | 126 | rc_cfg_.layer_target_bitrate[0] = 1000; |
| 225 | 127 | rc_cfg_.max_quantizers[0] = 52; |
| 226 | 128 | rc_cfg_.min_quantizers[0] = 2; |
| 129 | + rc_cfg_.rc_mode = rc_mode; |
| 130 | + |
| 131 | + // Encoder settings for ground truth. |
| 132 | + cfg_.g_w = 1280; |
| 133 | + cfg_.g_h = 720; |
| 134 | + cfg_.rc_undershoot_pct = 50; |
| 135 | + cfg_.rc_overshoot_pct = 50; |
| 136 | + cfg_.rc_buf_initial_sz = 600; |
| 137 | + cfg_.rc_buf_optimal_sz = 600; |
| 138 | + cfg_.rc_buf_sz = 1000; |
| 139 | + cfg_.rc_dropframe_thresh = 0; |
| 140 | + cfg_.rc_min_quantizer = 2; |
| 141 | + cfg_.rc_max_quantizer = 52; |
| 142 | + cfg_.rc_end_usage = rc_mode; |
| 143 | + cfg_.g_lag_in_frames = 0; |
| 144 | + cfg_.g_error_resilient = 0; |
| 145 | + cfg_.rc_target_bitrate = 1000; |
| 146 | + cfg_.kf_min_dist = key_interval_; |
| 147 | + cfg_.kf_max_dist = key_interval_; |
| 227 | 148 | } |
| 228 | 149 | |
| 229 | | − void SetConfigOneLayerCBR() { |
| 230 | | − SetConfig(); |
| 231 | | − rc_cfg_.rc_mode = VPX_CBR; |
| 150 | + std::unique_ptr<libvpx::VP9RateControlRTC> rc_api_; |
| 151 | + libvpx::VP9RateControlRtcConfig rc_cfg_; |
| 152 | + int aq_mode_; |
| 153 | + int key_interval_; |
| 154 | + libvpx::VP9FrameParamsQpRTC frame_params_; |
| 155 | + bool encoder_exit_; |
| 156 | +}; |
| 157 | + |
| 158 | +class RcInterfaceSvcTest : public ::libvpx_test::EncoderTest, |
| 159 | + public ::libvpx_test::CodecTestWithParam<int> { |
| 160 | + public: |
| 161 | + RcInterfaceSvcTest() : EncoderTest(GET_PARAM(0)), aq_mode_(GET_PARAM(1)) {} |
| 162 | + virtual ~RcInterfaceSvcTest() {} |
| 163 | + |
| 164 | + protected: |
| 165 | + virtual void SetUp() { |
| 166 | + InitializeConfig(); |
| 167 | + SetMode(::libvpx_test::kRealTime); |
| 232 | 168 | } |
| 233 | 169 | |
| 234 | | − void SetConfigOneLayerVBR() { |
| 235 | | − SetConfig(); |
| 236 | | − rc_cfg_.rc_mode = VPX_VBR; |
| 170 | + virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video, |
| 171 | + ::libvpx_test::Encoder *encoder) { |
| 172 | + if (video->frame() == 0) { |
| 173 | + encoder->Control(VP8E_SET_CPUUSED, 7); |
| 174 | + encoder->Control(VP9E_SET_AQ_MODE, aq_mode_); |
| 175 | + encoder->Control(VP9E_SET_TUNE_CONTENT, 0); |
| 176 | + encoder->Control(VP8E_SET_MAX_INTRA_BITRATE_PCT, 900); |
| 177 | + encoder->Control(VP9E_SET_RTC_EXTERNAL_RATECTRL, 1); |
| 178 | + encoder->Control(VP9E_SET_SVC, 1); |
| 179 | + encoder->Control(VP9E_SET_SVC_PARAMETERS, &svc_params_); |
| 180 | + } |
| 181 | + |
| 182 | + frame_params_.frame_type = video->frame() == 0 ? KEY_FRAME : INTER_FRAME; |
| 183 | + if (rc_cfg_.rc_mode == VPX_CBR && frame_params_.frame_type == INTER_FRAME) { |
| 184 | + // Disable golden frame update. |
| 185 | + frame_flags_ |= VP8_EFLAG_NO_UPD_GF; |
| 186 | + frame_flags_ |= VP8_EFLAG_NO_UPD_ARF; |
| 187 | + } |
| 188 | + encoder_exit_ = video->frame() == kNumFrames; |
| 189 | + current_superframe_ = video->frame(); |
| 237 | 190 | } |
| 238 | 191 | |
| 239 | | − void SetConfigOneLayerVBRPeriodicKey() { |
| 240 | | − SetConfig(); |
| 241 | | − rc_cfg_.rc_mode = VPX_VBR; |
| 192 | + virtual void PostEncodeFrameHook(::libvpx_test::Encoder *encoder) { |
| 193 | + ::libvpx_test::CxDataIterator iter = encoder->GetCxData(); |
| 194 | + while (const vpx_codec_cx_pkt_t *pkt = iter.Next()) { |
| 195 | + ParseSuperframeSizes(static_cast<const uint8_t *>(pkt->data.frame.buf), |
| 196 | + pkt->data.frame.sz); |
| 197 | + for (int sl = 0; sl < rc_cfg_.ss_number_layers; sl++) { |
| 198 | + frame_params_.spatial_layer_id = sl; |
| 199 | + frame_params_.temporal_layer_id = kTemporalId[current_superframe_ % 4]; |
| 200 | + rc_api_->ComputeQP(frame_params_); |
| 201 | + frame_params_.frame_type = INTER_FRAME; |
| 202 | + rc_api_->PostEncodeUpdate(sizes_[sl]); |
| 203 | + } |
| 204 | + } |
| 205 | + if (!encoder_exit_) { |
| 206 | + int loopfilter_level, qp; |
| 207 | + encoder->Control(VP9E_GET_LOOPFILTER_LEVEL, &loopfilter_level); |
| 208 | + encoder->Control(VP8E_GET_LAST_QUANTIZER, &qp); |
| 209 | + ASSERT_EQ(rc_api_->GetQP(), qp); |
| 210 | + ASSERT_EQ(rc_api_->GetLoopfilterLevel(), loopfilter_level); |
| 211 | + } |
| 212 | + } |
| 213 | + // This method needs to be overridden because non-reference frames are |
| 214 | + // expected to be mismatched frames as the encoder will avoid loopfilter on |
| 215 | + // these frames. |
| 216 | + virtual void MismatchHook(const vpx_image_t * /*img1*/, |
| 217 | + const vpx_image_t * /*img2*/) {} |
| 218 | + |
| 219 | + void RunSvc() { |
| 220 | + SetConfigSvc(); |
| 221 | + rc_api_ = libvpx::VP9RateControlRTC::Create(rc_cfg_); |
| 222 | + SetEncoderSvc(); |
| 223 | + |
| 224 | + ::libvpx_test::I420VideoSource video("desktop_office1.1280_720-020.yuv", |
| 225 | + 1280, 720, 30, 1, 0, kNumFrames); |
| 226 | + |
| 227 | + ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); |
| 228 | + } |
| 229 | + |
| 230 | + private: |
| 231 | + vpx_codec_err_t ParseSuperframeSizes(const uint8_t *data, size_t data_sz) { |
| 232 | + uint8_t marker = *(data + data_sz - 1); |
| 233 | + if ((marker & 0xe0) == 0xc0) { |
| 234 | + const uint32_t frames = (marker & 0x7) + 1; |
| 235 | + const uint32_t mag = ((marker >> 3) & 0x3) + 1; |
| 236 | + const size_t index_sz = 2 + mag * frames; |
| 237 | + // This chunk is marked as having a superframe index but doesn't have |
| 238 | + // enough data for it, thus it's an invalid superframe index. |
| 239 | + if (data_sz < index_sz) return VPX_CODEC_CORRUPT_FRAME; |
| 240 | + { |
| 241 | + const uint8_t marker2 = *(data + data_sz - index_sz); |
| 242 | + // This chunk is marked as having a superframe index but doesn't have |
| 243 | + // the matching marker byte at the front of the index therefore it's an |
| 244 | + // invalid chunk. |
| 245 | + if (marker != marker2) return VPX_CODEC_CORRUPT_FRAME; |
| 246 | + } |
| 247 | + const uint8_t *x = &data[data_sz - index_sz + 1]; |
| 248 | + for (uint32_t i = 0; i < frames; ++i) { |
| 249 | + uint32_t this_sz = 0; |
| 250 | + |
| 251 | + for (uint32_t j = 0; j < mag; ++j) this_sz |= (*x++) << (j * 8); |
| 252 | + sizes_[i] = this_sz; |
| 253 | + } |
| 254 | + } |
| 255 | + return VPX_CODEC_OK; |
| 256 | + } |
| 257 | + |
| 258 | + void SetEncoderSvc() { |
| 259 | + cfg_.ss_number_layers = 3; |
| 260 | + cfg_.ts_number_layers = 3; |
| 261 | + cfg_.g_timebase.num = 1; |
| 262 | + cfg_.g_timebase.den = 30; |
| 263 | + svc_params_.scaling_factor_num[0] = 72; |
| 264 | + svc_params_.scaling_factor_den[0] = 288; |
| 265 | + svc_params_.scaling_factor_num[1] = 144; |
| 266 | + svc_params_.scaling_factor_den[1] = 288; |
| 267 | + svc_params_.scaling_factor_num[2] = 288; |
| 268 | + svc_params_.scaling_factor_den[2] = 288; |
| 269 | + for (int i = 0; i < VPX_MAX_LAYERS; ++i) { |
| 270 | + svc_params_.max_quantizers[i] = 56; |
| 271 | + svc_params_.min_quantizers[i] = 2; |
| 272 | + } |
| 273 | + cfg_.rc_end_usage = VPX_CBR; |
| 274 | + cfg_.g_lag_in_frames = 0; |
| 275 | + cfg_.g_error_resilient = 0; |
| 276 | + // 3 temporal layers |
| 277 | + cfg_.ts_rate_decimator[0] = 4; |
| 278 | + cfg_.ts_rate_decimator[1] = 2; |
| 279 | + cfg_.ts_rate_decimator[2] = 1; |
| 280 | + cfg_.temporal_layering_mode = 3; |
| 281 | + |
| 282 | + cfg_.rc_buf_initial_sz = 500; |
| 283 | + cfg_.rc_buf_optimal_sz = 600; |
| 284 | + cfg_.rc_buf_sz = 1000; |
| 285 | + cfg_.rc_min_quantizer = 2; |
| 286 | + cfg_.rc_max_quantizer = 56; |
| 287 | + cfg_.g_threads = 1; |
| 288 | + cfg_.kf_max_dist = 9999; |
| 289 | + cfg_.rc_target_bitrate = 1600; |
| 290 | + cfg_.rc_overshoot_pct = 50; |
| 291 | + cfg_.rc_undershoot_pct = 50; |
| 292 | + |
| 293 | + cfg_.layer_target_bitrate[0] = 100; |
| 294 | + cfg_.layer_target_bitrate[1] = 140; |
| 295 | + cfg_.layer_target_bitrate[2] = 200; |
| 296 | + cfg_.layer_target_bitrate[3] = 250; |
| 297 | + cfg_.layer_target_bitrate[4] = 350; |
| 298 | + cfg_.layer_target_bitrate[5] = 500; |
| 299 | + cfg_.layer_target_bitrate[6] = 450; |
| 300 | + cfg_.layer_target_bitrate[7] = 630; |
| 301 | + cfg_.layer_target_bitrate[8] = 900; |
| 242 | 302 | } |
| 243 | 303 | |
| 244 | | − void SetConfigSVC() { |
| 304 | + void SetConfigSvc() { |
| 245 | 305 | rc_cfg_.width = 1280; |
| 246 | 306 | rc_cfg_.height = 720; |
| 247 | 307 | rc_cfg_.max_quantizer = 56; |
| @@ -288,17 +348,25 @@ class RcInterfaceTest : public ::testing::Test { · 40 unmodified lines |
| 288 | 348 | } |
| 289 | 349 | } |
| 290 | 350 | |
| 351 | + int aq_mode_; |
| 291 | 352 | std::unique_ptr<libvpx::VP9RateControlRTC> rc_api_; |
| 292 | 353 | libvpx::VP9RateControlRtcConfig rc_cfg_; |
| 354 | + vpx_svc_extra_cfg_t svc_params_; |
| 355 | + libvpx::VP9FrameParamsQpRTC frame_params_; |
| 356 | + bool encoder_exit_; |
| 357 | + int current_superframe_; |
| 358 | + uint32_t sizes_[8]; |
| 293 | 359 | }; |
| 294 | 360 | |
| 295 | | −TEST_F(RcInterfaceTest, OneLayerCBR) { RunOneLayerCBR(); } |
| 361 | +TEST_P(RcInterfaceTest, OneLayer) { RunOneLayer(); } |
| 296 | 362 | |
| 297 | | −TEST_F(RcInterfaceTest, OneLayerVBR) { RunOneLayerVBR(); } |
| 363 | +TEST_P(RcInterfaceTest, OneLayerVBRPeriodicKey) { RunOneLayerVBRPeriodicKey(); } |
| 298 | 364 | |
| 299 | | −TEST_F(RcInterfaceTest, OneLayerVBRPeriodicKey) { RunOneLayerVBRPeriodicKey(); } |
| 365 | +TEST_P(RcInterfaceSvcTest, Svc) { RunSvc(); } |
| 300 | 366 | |
| 301 | | −TEST_F(RcInterfaceTest, SVC) { RunSVC(); } |
| 367 | +VP9_INSTANTIATE_TEST_SUITE(RcInterfaceTest, ::testing::Values(0), |
| 368 | + ::testing::Values(VPX_CBR, VPX_VBR)); |
| 369 | +VP9_INSTANTIATE_TEST_SUITE(RcInterfaceSvcTest, ::testing::Values(0)); |
| 302 | 370 | } // namespace |
| 303 | 371 | |
| 304 | 372 | int main(int argc, char **argv) { |