| @@ -16,6 +16,7 @@ · 15 unmodified lines |
| 16 | #include "third_party/googletest/src/include/gtest/gtest.h" | 16 | #include "third_party/googletest/src/include/gtest/gtest.h" |
| 17 | #include "test/codec_factory.h" | 17 | #include "test/codec_factory.h" |
| 18 | #include "test/encode_test_driver.h" | 18 | #include "test/encode_test_driver.h" |
| | 19 | #include "test/i420_video_source.h" |
| 19 | #include "test/util.h" | 20 | #include "test/util.h" |
| 20 | #include "test/video_source.h" | 21 | #include "test/video_source.h" |
| 21 | #include "vpx/vpx_codec.h" | 22 | #include "vpx/vpx_codec.h" |
| @@ -23,188 +24,89 @@ · 1 unmodified line |
| 23 | | 24 | |
| 24 | namespace { | 25 | namespace { |
| 25 | | 26 | |
| 26 | const size_t kNumFrame = 850; | 27 | const size_t kNumFrames = 300; |
| 27 | | 28 | |
| 28 | struct FrameInfo { | 29 | const int kTemporalId[4] = { 0, 2, 1, 2 }; |
| 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 | }; | | |
| 48 | | 30 | |
| 49 | // This test runs the rate control interface and compare against ground truth | 31 | class RcInterfaceTest |
| 50 | // generated by encoders. | 32 | : public ::libvpx_test::EncoderTest, |
| 51 | // Settings for the encoder: | 33 | public ::libvpx_test::CodecTestWith2Params<int, vpx_rc_mode> { |
| 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 { | | |
| 84 | public: | 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 | virtual ~RcInterfaceTest() {} | 39 | virtual ~RcInterfaceTest() {} |
| 88 | | 40 | |
| 89 | protected: | 41 | protected: |
| 90 | void RunOneLayerCBR() { | 42 | virtual void SetUp() { |
| 91 | SetConfigOneLayerCBR(); | 43 | InitializeConfig(); |
| 92 | rc_api_ = libvpx::VP9RateControlRTC::Create(rc_cfg_); | 44 | SetMode(::libvpx_test::kRealTime); |
| 93 | FrameInfo frame_info; | 45 | } |
| 94 | libvpx::VP9FrameParamsQpRTC frame_params; | 46 | |
| 95 | frame_params.frame_type = KEY_FRAME; | 47 | virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video, |
| 96 | frame_params.spatial_layer_id = 0; | 48 | libvpx_test::Encoder *encoder) { |
| 97 | frame_params.temporal_layer_id = 0; | 49 | if (video->frame() == 0) { |
| 98 | std::ifstream one_layer_file; | 50 | encoder->Control(VP8E_SET_CPUUSED, 7); |
| 99 | one_layer_file.open(libvpx_test::GetDataPath() + | 51 | encoder->Control(VP9E_SET_AQ_MODE, aq_mode_); |
| 100 | "/rc_interface_test_one_layer"); | 52 | encoder->Control(VP9E_SET_TUNE_CONTENT, 0); |
| 101 | ASSERT_TRUE(one_layer_file.good()); | 53 | encoder->Control(VP8E_SET_MAX_INTRA_BITRATE_PCT, 1000); |
| 102 | for (size_t i = 0; i < kNumFrame; i++) { | 54 | encoder->Control(VP9E_SET_RTC_EXTERNAL_RATECTRL, 1); |
| 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); | | |
| 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() { | 66 | virtual void PostEncodeFrameHook(::libvpx_test::Encoder *encoder) { |
| 122 | SetConfigSVC(); | 67 | if (encoder_exit_) { |
| 123 | rc_api_ = libvpx::VP9RateControlRTC::Create(rc_cfg_); | 68 | return; |
| 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); | | |
| 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() { | 78 | virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) { |
| 158 | SetConfigOneLayerVBR(); | 79 | rc_api_->PostEncodeUpdate(pkt->data.frame.sz); |
| | 80 | } |
| | 81 | |
| | 82 | void RunOneLayer() { |
| | 83 | SetConfig(GET_PARAM(2)); |
| 159 | rc_api_ = libvpx::VP9RateControlRTC::Create(rc_cfg_); | 84 | rc_api_ = libvpx::VP9RateControlRTC::Create(rc_cfg_); |
| 160 | FrameInfo frame_info; | 85 | frame_params_.spatial_layer_id = 0; |
| 161 | libvpx::VP9FrameParamsQpRTC frame_params; | 86 | frame_params_.temporal_layer_id = 0; |
| 162 | frame_params.frame_type = KEY_FRAME; | 87 | |
| 163 | frame_params.spatial_layer_id = 0; | 88 | ::libvpx_test::I420VideoSource video("desktop_office1.1280_720-020.yuv", |
| 164 | frame_params.temporal_layer_id = 0; | 89 | 1280, 720, 30, 1, 0, kNumFrames); |
| 165 | std::ifstream one_layer_file; | 90 | |
| 166 | one_layer_file.open(libvpx_test::GetDataPath() + | 91 | ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); |
| 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 | } | | |
| 179 | } | 92 | } |
| 180 | | 93 | |
| 181 | void RunOneLayerVBRPeriodicKey() { | 94 | void RunOneLayerVBRPeriodicKey() { |
| 182 | SetConfigOneLayerVBRPeriodicKey(); | 95 | if (GET_PARAM(2) != VPX_VBR) return; |
| | 96 | key_interval_ = 100; |
| | 97 | SetConfig(VPX_VBR); |
| 183 | rc_api_ = libvpx::VP9RateControlRTC::Create(rc_cfg_); | 98 | rc_api_ = libvpx::VP9RateControlRTC::Create(rc_cfg_); |
| 184 | FrameInfo frame_info; | 99 | frame_params_.spatial_layer_id = 0; |
| 185 | libvpx::VP9FrameParamsQpRTC frame_params; | 100 | frame_params_.temporal_layer_id = 0; |
| 186 | frame_params.frame_type = KEY_FRAME; | 101 | |
| 187 | frame_params.spatial_layer_id = 0; | 102 | ::libvpx_test::I420VideoSource video("desktop_office1.1280_720-020.yuv", |
| 188 | frame_params.temporal_layer_id = 0; | 103 | 1280, 720, 30, 1, 0, kNumFrames); |
| 189 | std::ifstream one_layer_file; | 104 | |
| 190 | one_layer_file.open(libvpx_test::GetDataPath() + | 105 | ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); |
| 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 | } | | |
| 204 | } | 106 | } |
| 205 | | 107 | |
| 206 | private: | 108 | private: |
| 207 | void SetConfig() { | 109 | void SetConfig(vpx_rc_mode rc_mode) { |
| 208 | rc_cfg_.width = 1280; | 110 | rc_cfg_.width = 1280; |
| 209 | rc_cfg_.height = 720; | 111 | rc_cfg_.height = 720; |
| 210 | rc_cfg_.max_quantizer = 52; | 112 | rc_cfg_.max_quantizer = 52; |
| @@ -224,24 +126,182 @@ class RcInterfaceTest : public ::testing::Test { · 13 unmodified lines |
| 224 | rc_cfg_.layer_target_bitrate[0] = 1000; | 126 | rc_cfg_.layer_target_bitrate[0] = 1000; |
| 225 | rc_cfg_.max_quantizers[0] = 52; | 127 | rc_cfg_.max_quantizers[0] = 52; |
| 226 | rc_cfg_.min_quantizers[0] = 2; | 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() { | 150 | std::unique_ptr<libvpx::VP9RateControlRTC> rc_api_; |
| 230 | SetConfig(); | 151 | libvpx::VP9RateControlRtcConfig rc_cfg_; |
| 231 | rc_cfg_.rc_mode = VPX_CBR; | 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() { | 170 | virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video, |
| 235 | SetConfig(); | 171 | ::libvpx_test::Encoder *encoder) { |
| 236 | rc_cfg_.rc_mode = VPX_VBR; | 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() { | 192 | virtual void PostEncodeFrameHook(::libvpx_test::Encoder *encoder) { |
| 240 | SetConfig(); | 193 | ::libvpx_test::CxDataIterator iter = encoder->GetCxData(); |
| 241 | rc_cfg_.rc_mode = VPX_VBR; | 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 | rc_cfg_.width = 1280; | 305 | rc_cfg_.width = 1280; |
| 246 | rc_cfg_.height = 720; | 306 | rc_cfg_.height = 720; |
| 247 | rc_cfg_.max_quantizer = 56; | 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 | std::unique_ptr<libvpx::VP9RateControlRTC> rc_api_; | 352 | std::unique_ptr<libvpx::VP9RateControlRTC> rc_api_; |
| 292 | libvpx::VP9RateControlRtcConfig rc_cfg_; | 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 | } // namespace | 370 | } // namespace |
| 303 | | 371 | |
| 304 | int main(int argc, char **argv) { | 372 | int main(int argc, char **argv) { |