History

Merge "vp8 rc: support temporal layers" into main

Jerome Jiang committed 5 years ago

Commit f84650b2 parents b247f6e 0de415c5 files · +257 −32Browse files

Unified · Split

5 files
  1. test/vp8_ratectrl_rtc_test.cc +172 −9
  2. vp8/encoder/onyx_if.c +20 −20
  3. vp8/encoder/onyx_int.h +6 −0
  4. vp8/vp8_ratectrl_rtc.cc +58 −3
  5. vp8/vp8_ratectrl_rtc.h +1 −0
test/vp8_ratectrl_rtc_test.cc+172−9
@@ -61,20 +61,81 @@ class Vp8RcInterfaceTest · 60 unmodified lines
61 SetMode(::libvpx_test::kRealTime);61 SetMode(::libvpx_test::kRealTime);
62 }62 }
63 63
64 // From error_resilience_test.cc
65 int SetFrameFlags(int frame_num, int num_temp_layers) {
66 int frame_flags = 0;
67 if (num_temp_layers == 2) {
68 if (frame_num % 2 == 0) {
69 // Layer 0: predict from L and ARF, update L.
70 frame_flags =
71 VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
72 } else {
73 // Layer 1: predict from L, G and ARF, and update G.
74 frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
75 VP8_EFLAG_NO_UPD_ENTROPY;
76 }
77 } else if (num_temp_layers == 3) {
78 if (frame_num % 4 == 0) {
79 // Layer 0: predict from L, update L.
80 frame_flags = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
81 VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF;
82 } else if ((frame_num - 2) % 4 == 0) {
83 // Layer 1: predict from L, G, update G.
84 frame_flags =
85 VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_REF_ARF;
86 } else if ((frame_num - 1) % 2 == 0) {
87 // Layer 2: predict from L, G, ARF; update ARG.
88 frame_flags = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_LAST;
89 }
90 }
91 return frame_flags;
92 }
93
94 int SetLayerId(int frame_num, int num_temp_layers) {
95 int layer_id = 0;
96 if (num_temp_layers == 2) {
97 if (frame_num % 2 == 0) {
98 layer_id = 0;
99 } else {
100 layer_id = 1;
101 }
102 } else if (num_temp_layers == 3) {
103 if (frame_num % 4 == 0) {
104 layer_id = 0;
105 } else if ((frame_num - 2) % 4 == 0) {
106 layer_id = 1;
107 } else if ((frame_num - 1) % 2 == 0) {
108 layer_id = 2;
109 }
110 }
111 return layer_id;
112 }
113
64 virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,114 virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
65 ::libvpx_test::Encoder *encoder) {115 ::libvpx_test::Encoder *encoder) {
66 if (video->frame() == 0) {116 if (rc_cfg_.ts_number_layers > 1) {
67 encoder->Control(VP8E_SET_CPUUSED, -6);117 const int layer_id = SetLayerId(video->frame(), cfg_.ts_number_layers);
68 encoder->Control(VP8E_SET_RTC_EXTERNAL_RATECTRL, 1);118 const int frame_flags =
69 encoder->Control(VP8E_SET_MAX_INTRA_BITRATE_PCT, 1000);119 SetFrameFlags(video->frame(), cfg_.ts_number_layers);
120 frame_params_.temporal_layer_id = layer_id;
121 if (video->frame() > 0) {
122 encoder->Control(VP8E_SET_TEMPORAL_LAYER_ID, layer_id);
123 encoder->Control(VP8E_SET_FRAME_FLAGS, frame_flags);
124 }
125 } else {
126 if (video->frame() == 0) {
127 encoder->Control(VP8E_SET_CPUUSED, -6);
128 encoder->Control(VP8E_SET_RTC_EXTERNAL_RATECTRL, 1);
129 encoder->Control(VP8E_SET_MAX_INTRA_BITRATE_PCT, 1000);
130 }
131 if (frame_params_.frame_type == INTER_FRAME) {
132 // Disable golden frame update.
133 frame_flags_ |= VP8_EFLAG_NO_UPD_GF;
134 frame_flags_ |= VP8_EFLAG_NO_UPD_ARF;
135 }
70 }136 }
71 frame_params_.frame_type =137 frame_params_.frame_type =
72 video->frame() % key_interval_ == 0 ? KEY_FRAME : INTER_FRAME;138 video->frame() % key_interval_ == 0 ? KEY_FRAME : INTER_FRAME;
73 if (frame_params_.frame_type == INTER_FRAME) {
74 // Disable golden frame update.
75 frame_flags_ |= VP8_EFLAG_NO_UPD_GF;
76 frame_flags_ |= VP8_EFLAG_NO_UPD_ARF;
77 }
78 encoder_exit_ = video->frame() == test_video_.frames;139 encoder_exit_ = video->frame() == test_video_.frames;
79 }140 }
80 141
@@ -125,6 +186,38 @@ class Vp8RcInterfaceTest · 44 unmodified lines
125 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));186 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
126 }187 }
127 188
189 void RunTemporalLayers2TL() {
190 test_video_ = GET_PARAM(2);
191 target_bitrate_ = GET_PARAM(1);
192 if (test_video_.width == 1280 && target_bitrate_ == 200) return;
193 if (test_video_.width == 640 && target_bitrate_ == 1000) return;
194 SetConfigTemporalLayers(2);
195 rc_api_ = libvpx::VP8RateControlRTC::Create(rc_cfg_);
196 rc_api_->UpdateRateControl(rc_cfg_);
197
198 ::libvpx_test::I420VideoSource video(test_video_.name, test_video_.width,
199 test_video_.height, 30, 1, 0,
200 test_video_.frames);
201
202 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
203 }
204
205 void RunTemporalLayers3TL() {
206 test_video_ = GET_PARAM(2);
207 target_bitrate_ = GET_PARAM(1);
208 if (test_video_.width == 1280 && target_bitrate_ == 200) return;
209 if (test_video_.width == 640 && target_bitrate_ == 1000) return;
210 SetConfigTemporalLayers(3);
211 rc_api_ = libvpx::VP8RateControlRTC::Create(rc_cfg_);
212 rc_api_->UpdateRateControl(rc_cfg_);
213
214 ::libvpx_test::I420VideoSource video(test_video_.name, test_video_.width,
215 test_video_.height, 30, 1, 0,
216 test_video_.frames);
217
218 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
219 }
220
128 private:221 private:
129 void SetConfig() {222 void SetConfig() {
130 rc_cfg_.width = test_video_.width;223 rc_cfg_.width = test_video_.width;
@@ -160,6 +253,72 @@ class Vp8RcInterfaceTest · 29 unmodified lines
160 cfg_.kf_max_dist = key_interval_;253 cfg_.kf_max_dist = key_interval_;
161 }254 }
162 255
256 void SetConfigTemporalLayers(int temporal_layers) {
257 rc_cfg_.width = test_video_.width;
258 rc_cfg_.height = test_video_.height;
259 rc_cfg_.max_quantizer = 60;
260 rc_cfg_.min_quantizer = 2;
261 rc_cfg_.target_bandwidth = target_bitrate_;
262 rc_cfg_.buf_initial_sz = 600;
263 rc_cfg_.buf_optimal_sz = 600;
264 rc_cfg_.buf_sz = target_bitrate_;
265 rc_cfg_.undershoot_pct = 50;
266 rc_cfg_.overshoot_pct = 50;
267 rc_cfg_.max_intra_bitrate_pct = 1000;
268 rc_cfg_.framerate = 30.0;
269 if (temporal_layers == 2) {
270 rc_cfg_.layer_target_bitrate[0] = 60 * target_bitrate_ / 100;
271 rc_cfg_.layer_target_bitrate[1] = target_bitrate_;
272 rc_cfg_.ts_rate_decimator[0] = 2;
273 rc_cfg_.ts_rate_decimator[1] = 1;
274 } else if (temporal_layers == 3) {
275 rc_cfg_.layer_target_bitrate[0] = 40 * target_bitrate_ / 100;
276 rc_cfg_.layer_target_bitrate[1] = 60 * target_bitrate_ / 100;
277 rc_cfg_.layer_target_bitrate[2] = target_bitrate_;
278 rc_cfg_.ts_rate_decimator[0] = 4;
279 rc_cfg_.ts_rate_decimator[1] = 2;
280 rc_cfg_.ts_rate_decimator[2] = 1;
281 }
282
283 rc_cfg_.ts_number_layers = temporal_layers;
284
285 // Encoder settings for ground truth.
286 cfg_.g_w = test_video_.width;
287 cfg_.g_h = test_video_.height;
288 cfg_.rc_undershoot_pct = 50;
289 cfg_.rc_overshoot_pct = 50;
290 cfg_.rc_buf_initial_sz = 600;
291 cfg_.rc_buf_optimal_sz = 600;
292 cfg_.rc_buf_sz = target_bitrate_;
293 cfg_.rc_dropframe_thresh = 0;
294 cfg_.rc_min_quantizer = 2;
295 cfg_.rc_max_quantizer = 60;
296 cfg_.rc_end_usage = VPX_CBR;
297 cfg_.g_lag_in_frames = 0;
298 cfg_.g_error_resilient = 1;
299 cfg_.rc_target_bitrate = target_bitrate_;
300 cfg_.kf_min_dist = key_interval_;
301 cfg_.kf_max_dist = key_interval_;
302 // 2 Temporal layers, no spatial layers, CBR mode.
303 cfg_.ss_number_layers = 1;
304 cfg_.ts_number_layers = temporal_layers;
305 if (temporal_layers == 2) {
306 cfg_.ts_rate_decimator[0] = 2;
307 cfg_.ts_rate_decimator[1] = 1;
308 cfg_.ts_periodicity = 2;
309 cfg_.ts_target_bitrate[0] = 60 * cfg_.rc_target_bitrate / 100;
310 cfg_.ts_target_bitrate[1] = cfg_.rc_target_bitrate;
311 } else if (temporal_layers == 3) {
312 cfg_.ts_rate_decimator[0] = 4;
313 cfg_.ts_rate_decimator[1] = 2;
314 cfg_.ts_rate_decimator[2] = 1;
315 cfg_.ts_periodicity = 4;
316 cfg_.ts_target_bitrate[0] = 40 * cfg_.rc_target_bitrate / 100;
317 cfg_.ts_target_bitrate[1] = 60 * cfg_.rc_target_bitrate / 100;
318 cfg_.ts_target_bitrate[2] = cfg_.rc_target_bitrate;
319 }
320 }
321
163 std::unique_ptr<libvpx::VP8RateControlRTC> rc_api_;322 std::unique_ptr<libvpx::VP8RateControlRTC> rc_api_;
164 libvpx::VP8RateControlRtcConfig rc_cfg_;323 libvpx::VP8RateControlRtcConfig rc_cfg_;
165 int key_interval_;324 int key_interval_;
@@ -173,6 +332,10 @@ TEST_P(Vp8RcInterfaceTest, OneLayer) { RunOneLayer(); } · 7 unmodified lines
173 332
174TEST_P(Vp8RcInterfaceTest, OneLayerPeriodicKey) { RunPeriodicKey(); }333TEST_P(Vp8RcInterfaceTest, OneLayerPeriodicKey) { RunPeriodicKey(); }
175 334
335TEST_P(Vp8RcInterfaceTest, TemporalLayers2TL) { RunTemporalLayers2TL(); }
336
337TEST_P(Vp8RcInterfaceTest, TemporalLayers3TL) { RunTemporalLayers3TL(); }
338
176VP8_INSTANTIATE_TEST_SUITE(Vp8RcInterfaceTest,339VP8_INSTANTIATE_TEST_SUITE(Vp8RcInterfaceTest,
177 ::testing::Values(200, 400, 1000),340 ::testing::Values(200, 400, 1000),
178 ::testing::ValuesIn(kVp8RCTestVectors));341 ::testing::ValuesIn(kVp8RCTestVectors));
vp8/encoder/onyx_if.c+20−20
@@ -183,7 +183,7 @@ static const unsigned char inter_minq[QINDEX_RANGE] = { · 182 unmodified lines
183extern FILE *vpxlogc;183extern FILE *vpxlogc;
184#endif184#endif
185 185
186static void save_layer_context(VP8_COMP *cpi) {186void vp8_save_layer_context(VP8_COMP *cpi) {
187 LAYER_CONTEXT *lc = &cpi->layer_context[cpi->current_layer];187 LAYER_CONTEXT *lc = &cpi->layer_context[cpi->current_layer];
188 188
189 /* Save layer dependent coding state */189 /* Save layer dependent coding state */
@@ -222,7 +222,7 @@ static void save_layer_context(VP8_COMP *cpi) { · 32 unmodified lines
222 sizeof(cpi->mb.count_mb_ref_frame_usage));222 sizeof(cpi->mb.count_mb_ref_frame_usage));
223}223}
224 224
225static void restore_layer_context(VP8_COMP *cpi, const int layer) {225void vp8_restore_layer_context(VP8_COMP *cpi, const int layer) {
226 LAYER_CONTEXT *lc = &cpi->layer_context[layer];226 LAYER_CONTEXT *lc = &cpi->layer_context[layer];
227 227
228 /* Restore layer dependent coding state */228 /* Restore layer dependent coding state */
@@ -269,9 +269,9 @@ static int rescale(int val, int num, int denom) { · 40 unmodified lines
269 return (int)(llval * llnum / llden);269 return (int)(llval * llnum / llden);
270}270}
271 271
272static void init_temporal_layer_context(VP8_COMP *cpi, VP8_CONFIG *oxcf,272void vp8_init_temporal_layer_context(VP8_COMP *cpi, VP8_CONFIG *oxcf,
273 const int layer,273 const int layer,
274 double prev_layer_framerate) {274 double prev_layer_framerate) {
275 LAYER_CONTEXT *lc = &cpi->layer_context[layer];275 LAYER_CONTEXT *lc = &cpi->layer_context[layer];
276 276
277 lc->framerate = cpi->output_framerate / cpi->oxcf.rate_decimator[layer];277 lc->framerate = cpi->output_framerate / cpi->oxcf.rate_decimator[layer];
@@ -336,12 +336,12 @@ static void reset_temporal_layer_change(VP8_COMP *cpi, VP8_CONFIG *oxcf, · 58 unmodified lines
336 // We need this to set the layer context for the new layers below.336 // We need this to set the layer context for the new layers below.
337 if (prev_num_layers == 1) {337 if (prev_num_layers == 1) {
338 cpi->current_layer = 0;338 cpi->current_layer = 0;
339 save_layer_context(cpi);339 vp8_save_layer_context(cpi);
340 }340 }
341 for (i = 0; i < curr_num_layers; ++i) {341 for (i = 0; i < curr_num_layers; ++i) {
342 LAYER_CONTEXT *lc = &cpi->layer_context[i];342 LAYER_CONTEXT *lc = &cpi->layer_context[i];
343 if (i >= prev_num_layers) {343 if (i >= prev_num_layers) {
344 init_temporal_layer_context(cpi, oxcf, i, prev_layer_framerate);344 vp8_init_temporal_layer_context(cpi, oxcf, i, prev_layer_framerate);
345 }345 }
346 // The initial buffer levels are set based on their starting levels.346 // The initial buffer levels are set based on their starting levels.
347 // We could set the buffer levels based on the previous state (normalized347 // We could set the buffer levels based on the previous state (normalized
@@ -356,7 +356,7 @@ static void reset_temporal_layer_change(VP8_COMP *cpi, VP8_CONFIG *oxcf, · 8 unmodified lines
356 // state (to smooth-out quality dips/rate fluctuation at transition)?356 // state (to smooth-out quality dips/rate fluctuation at transition)?
357 357
358 // We need to treat the 1 layer case separately: oxcf.target_bitrate[i]358 // We need to treat the 1 layer case separately: oxcf.target_bitrate[i]
359 // is not set for 1 layer, and the restore_layer_context/save_context()359 // is not set for 1 layer, and the vp8_restore_layer_context/save_context()
360 // are not called in the encoding loop, so we need to call it here to360 // are not called in the encoding loop, so we need to call it here to
361 // pass the layer context state to |cpi|.361 // pass the layer context state to |cpi|.
362 if (curr_num_layers == 1) {362 if (curr_num_layers == 1) {
@@ -364,7 +364,7 @@ static void reset_temporal_layer_change(VP8_COMP *cpi, VP8_CONFIG *oxcf, · 1 unmodified line
364 lc->buffer_level =364 lc->buffer_level =
365 cpi->oxcf.starting_buffer_level_in_ms * lc->target_bandwidth / 1000;365 cpi->oxcf.starting_buffer_level_in_ms * lc->target_bandwidth / 1000;
366 lc->bits_off_target = lc->buffer_level;366 lc->bits_off_target = lc->buffer_level;
367 restore_layer_context(cpi, 0);367 vp8_restore_layer_context(cpi, 0);
368 }368 }
369 prev_layer_framerate = cpi->output_framerate / cpi->oxcf.rate_decimator[i];369 prev_layer_framerate = cpi->output_framerate / cpi->oxcf.rate_decimator[i];
370 }370 }
@@ -1274,7 +1274,7 @@ void vp8_new_framerate(VP8_COMP *cpi, double framerate) { · 903 unmodified lines
1274 cpi->framerate = framerate;1274 cpi->framerate = framerate;
1275 cpi->output_framerate = framerate;1275 cpi->output_framerate = framerate;
1276 cpi->per_frame_bandwidth =1276 cpi->per_frame_bandwidth =
1277 (int)(cpi->oxcf.target_bandwidth / cpi->output_framerate);1277 (int)round(cpi->oxcf.target_bandwidth / cpi->output_framerate);
1278 cpi->av_per_frame_bandwidth = cpi->per_frame_bandwidth;1278 cpi->av_per_frame_bandwidth = cpi->per_frame_bandwidth;
1279 cpi->min_frame_bandwidth = (int)(cpi->av_per_frame_bandwidth *1279 cpi->min_frame_bandwidth = (int)(cpi->av_per_frame_bandwidth *
1280 cpi->oxcf.two_pass_vbrmin_section / 100);1280 cpi->oxcf.two_pass_vbrmin_section / 100);
@@ -1365,7 +1365,7 @@ static void init_config(VP8_COMP *cpi, VP8_CONFIG *oxcf) { · 84 unmodified lines
1365 double prev_layer_framerate = 0;1365 double prev_layer_framerate = 0;
1366 1366
1367 for (i = 0; i < cpi->oxcf.number_of_layers; ++i) {1367 for (i = 0; i < cpi->oxcf.number_of_layers; ++i) {
1368 init_temporal_layer_context(cpi, oxcf, i, prev_layer_framerate);1368 vp8_init_temporal_layer_context(cpi, oxcf, i, prev_layer_framerate);
1369 prev_layer_framerate =1369 prev_layer_framerate =
1370 cpi->output_framerate / cpi->oxcf.rate_decimator[i];1370 cpi->output_framerate / cpi->oxcf.rate_decimator[i];
1371 }1371 }
@@ -1382,7 +1382,7 @@ static void init_config(VP8_COMP *cpi, VP8_CONFIG *oxcf) { · 10 unmodified lines
1382#endif1382#endif
1383}1383}
1384 1384
1385static void update_layer_contexts(VP8_COMP *cpi) {1385void vp8_update_layer_contexts(VP8_COMP *cpi) {
1386 VP8_CONFIG *oxcf = &cpi->oxcf;1386 VP8_CONFIG *oxcf = &cpi->oxcf;
1387 1387
1388 /* Update snapshots of the layer contexts to reflect new parameters */1388 /* Update snapshots of the layer contexts to reflect new parameters */
@@ -1417,8 +1417,8 @@ static void update_layer_contexts(VP8_COMP *cpi) { · 28 unmodified lines
1417 /* Work out the average size of a frame within this layer */1417 /* Work out the average size of a frame within this layer */
1418 if (i > 0) {1418 if (i > 0) {
1419 lc->avg_frame_size_for_layer =1419 lc->avg_frame_size_for_layer =
1420 (int)((oxcf->target_bitrate[i] - oxcf->target_bitrate[i - 1]) *1420 (int)round((oxcf->target_bitrate[i] - oxcf->target_bitrate[i - 1]) *
1421 1000 / (lc->framerate - prev_layer_framerate));1421 1000 / (lc->framerate - prev_layer_framerate));
1422 }1422 }
1423 1423
1424 prev_layer_framerate = lc->framerate;1424 prev_layer_framerate = lc->framerate;
@@ -3261,7 +3261,7 @@ static void encode_frame_to_data_rate(VP8_COMP *cpi, size_t *size, · 1836 unmodified lines
3261#endif // !CONFIG_REALTIME_ONLY3261#endif // !CONFIG_REALTIME_ONLY
3262 default:3262 default:
3263 cpi->per_frame_bandwidth =3263 cpi->per_frame_bandwidth =
3264 (int)(cpi->target_bandwidth / cpi->output_framerate);3264 (int)round(cpi->target_bandwidth / cpi->output_framerate);
3265 break;3265 break;
3266 }3266 }
3267 3267
@@ -4554,8 +4554,8 @@ static void encode_frame_to_data_rate(VP8_COMP *cpi, size_t *size, · 1286 unmodified lines
4554 4554
4555 for (i = cpi->current_layer + 1; i < cpi->oxcf.number_of_layers; ++i) {4555 for (i = cpi->current_layer + 1; i < cpi->oxcf.number_of_layers; ++i) {
4556 LAYER_CONTEXT *lc = &cpi->layer_context[i];4556 LAYER_CONTEXT *lc = &cpi->layer_context[i];
4557 int bits_off_for_this_layer = (int)(lc->target_bandwidth / lc->framerate -4557 int bits_off_for_this_layer = (int)round(
4558 cpi->projected_frame_size);4558 lc->target_bandwidth / lc->framerate - cpi->projected_frame_size);
4559 4559
4560 lc->bits_off_target += bits_off_for_this_layer;4560 lc->bits_off_target += bits_off_for_this_layer;
4561 4561
@@ -4992,7 +4992,7 @@ int vp8_get_compressed_data(VP8_COMP *cpi, unsigned int *frame_flags, · 430 unmodified lines
4992 if (cpi->oxcf.number_of_layers > 1) {4992 if (cpi->oxcf.number_of_layers > 1) {
4993 int layer;4993 int layer;
4994 4994
4995 update_layer_contexts(cpi);4995 vp8_update_layer_contexts(cpi);
4996 4996
4997 /* Restore layer specific context & set frame rate */4997 /* Restore layer specific context & set frame rate */
4998 if (cpi->temporal_layer_id >= 0) {4998 if (cpi->temporal_layer_id >= 0) {
@@ -5002,7 +5002,7 @@ int vp8_get_compressed_data(VP8_COMP *cpi, unsigned int *frame_flags, · 3 unmodified lines
5002 cpi->oxcf5002 cpi->oxcf
5003 .layer_id[cpi->temporal_pattern_counter % cpi->oxcf.periodicity];5003 .layer_id[cpi->temporal_pattern_counter % cpi->oxcf.periodicity];
5004 }5004 }
5005 restore_layer_context(cpi, layer);5005 vp8_restore_layer_context(cpi, layer);
5006 vp8_new_framerate(cpi, cpi->layer_context[layer].framerate);5006 vp8_new_framerate(cpi, cpi->layer_context[layer].framerate);
5007 }5007 }
5008 5008
@@ -5133,7 +5133,7 @@ int vp8_get_compressed_data(VP8_COMP *cpi, unsigned int *frame_flags, · 124 unmodified lines
5133 }5133 }
5134 5134
5135 /* Save layer specific state */5135 /* Save layer specific state */
5136 if (cpi->oxcf.number_of_layers > 1) save_layer_context(cpi);5136 if (cpi->oxcf.number_of_layers > 1) vp8_save_layer_context(cpi);
5137 5137
5138 vpx_usec_timer_mark(&cmptimer);5138 vpx_usec_timer_mark(&cmptimer);
5139 cpi->time_compress_data += vpx_usec_timer_elapsed(&cmptimer);5139 cpi->time_compress_data += vpx_usec_timer_elapsed(&cmptimer);
vp8/encoder/onyx_int.h+6−0
@@ -712,6 +712,12 @@ void vp8_initialize_enc(void); · 711 unmodified lines
712 712
713void vp8_alloc_compressor_data(VP8_COMP *cpi);713void vp8_alloc_compressor_data(VP8_COMP *cpi);
714int vp8_reverse_trans(int x);714int vp8_reverse_trans(int x);
715void vp8_init_temporal_layer_context(VP8_COMP *cpi, VP8_CONFIG *oxcf,
716 const int layer,
717 double prev_layer_framerate);
718void vp8_update_layer_contexts(VP8_COMP *cpi);
719void vp8_save_layer_context(VP8_COMP *cpi);
720void vp8_restore_layer_context(VP8_COMP *cpi, const int layer);
715void vp8_new_framerate(VP8_COMP *cpi, double framerate);721void vp8_new_framerate(VP8_COMP *cpi, double framerate);
716void vp8_loopfilter_frame(VP8_COMP *cpi, VP8_COMMON *cm);722void vp8_loopfilter_frame(VP8_COMP *cpi, VP8_COMMON *cm);
717 723
vp8/vp8_ratectrl_rtc.cc+58−3
@@ -8,9 +8,11 @@ · 7 unmodified lines
8 * be found in the AUTHORS file in the root of the source tree.8 * be found in the AUTHORS file in the root of the source tree.
9 */9 */
10 10
11#include <math.h>
11#include <new>12#include <new>
12#include "vp8/vp8_ratectrl_rtc.h"13#include "vp8/vp8_ratectrl_rtc.h"
13#include "vp8/encoder/ratectrl.h"14#include "vp8/encoder/ratectrl.h"
15#include "vpx_ports/system_state.h"
14 16
15namespace libvpx {17namespace libvpx {
16/* Quant MOD */18/* Quant MOD */
@@ -90,7 +92,7 @@ void VP8RateControlRTC::UpdateRateControl( · 73 unmodified lines
90 const VP8RateControlRtcConfig &rc_cfg) {92 const VP8RateControlRtcConfig &rc_cfg) {
91 VP8_COMMON *cm = &cpi_->common;93 VP8_COMMON *cm = &cpi_->common;
92 VP8_CONFIG *oxcf = &cpi_->oxcf;94 VP8_CONFIG *oxcf = &cpi_->oxcf;
93 95 vpx_clear_system_state();
94 cm->Width = rc_cfg.width;96 cm->Width = rc_cfg.width;
95 cm->Height = rc_cfg.height;97 cm->Height = rc_cfg.height;
96 oxcf->Width = rc_cfg.width;98 oxcf->Width = rc_cfg.width;
@@ -102,6 +104,7 @@ void VP8RateControlRTC::UpdateRateControl( · 5 unmodified lines
102 cpi_->output_framerate = rc_cfg.framerate;104 cpi_->output_framerate = rc_cfg.framerate;
103 oxcf->target_bandwidth =105 oxcf->target_bandwidth =
104 static_cast<unsigned int>(1000 * rc_cfg.target_bandwidth);106 static_cast<unsigned int>(1000 * rc_cfg.target_bandwidth);
107 cpi_->ref_framerate = cpi_->output_framerate;
105 oxcf->fixed_q = -1;108 oxcf->fixed_q = -1;
106 oxcf->error_resilient_mode = 1;109 oxcf->error_resilient_mode = 1;
107 oxcf->starting_buffer_level_in_ms = rc_cfg.buf_initial_sz;110 oxcf->starting_buffer_level_in_ms = rc_cfg.buf_initial_sz;
@@ -110,7 +113,7 @@ void VP8RateControlRTC::UpdateRateControl( · 2 unmodified lines
110 oxcf->starting_buffer_level = rc_cfg.buf_initial_sz;113 oxcf->starting_buffer_level = rc_cfg.buf_initial_sz;
111 oxcf->optimal_buffer_level = rc_cfg.buf_optimal_sz;114 oxcf->optimal_buffer_level = rc_cfg.buf_optimal_sz;
112 oxcf->maximum_buffer_size = rc_cfg.buf_sz;115 oxcf->maximum_buffer_size = rc_cfg.buf_sz;
113 oxcf->number_of_layers = 1;116 oxcf->number_of_layers = rc_cfg.ts_number_layers;
114 cpi_->buffered_mode = oxcf->optimal_buffer_level > 0;117 cpi_->buffered_mode = oxcf->optimal_buffer_level > 0;
115 oxcf->under_shoot_pct = rc_cfg.undershoot_pct;118 oxcf->under_shoot_pct = rc_cfg.undershoot_pct;
116 oxcf->over_shoot_pct = rc_cfg.overshoot_pct;119 oxcf->over_shoot_pct = rc_cfg.overshoot_pct;
@@ -121,6 +124,20 @@ void VP8RateControlRTC::UpdateRateControl( · 4 unmodified lines
121 static_cast<int>(cpi_->output_framerate);124 static_cast<int>(cpi_->output_framerate);
122 }125 }
123 126
127 if (oxcf->number_of_layers > 1) {
128 memcpy(oxcf->target_bitrate, rc_cfg.layer_target_bitrate,
129 sizeof(rc_cfg.layer_target_bitrate));
130 memcpy(oxcf->rate_decimator, rc_cfg.ts_rate_decimator,
131 sizeof(rc_cfg.ts_rate_decimator));
132 oxcf->periodicity = 2;
133
134 double prev_layer_framerate = 0;
135 for (unsigned int i = 0; i < oxcf->number_of_layers; ++i) {
136 vp8_init_temporal_layer_context(cpi_, oxcf, i, prev_layer_framerate);
137 prev_layer_framerate = cpi_->output_framerate / oxcf->rate_decimator[i];
138 }
139 }
140
124 cpi_->total_actual_bits = 0;141 cpi_->total_actual_bits = 0;
125 cpi_->total_target_vs_actual = 0;142 cpi_->total_target_vs_actual = 0;
126 143
@@ -155,6 +172,15 @@ void VP8RateControlRTC::UpdateRateControl( · 28 unmodified lines
155 172
156void VP8RateControlRTC::ComputeQP(const VP8FrameParamsQpRTC &frame_params) {173void VP8RateControlRTC::ComputeQP(const VP8FrameParamsQpRTC &frame_params) {
157 VP8_COMMON *const cm = &cpi_->common;174 VP8_COMMON *const cm = &cpi_->common;
175 vpx_clear_system_state();
176 if (cpi_->oxcf.number_of_layers > 1) {
177 cpi_->temporal_layer_id = frame_params.temporal_layer_id;
178 const int layer = frame_params.temporal_layer_id;
179 vp8_update_layer_contexts(cpi_);
180 /* Restore layer specific context & set frame rate */
181 vp8_restore_layer_context(cpi_, layer);
182 vp8_new_framerate(cpi_, cpi_->layer_context[layer].framerate);
183 }
158 cm->frame_type = frame_params.frame_type;184 cm->frame_type = frame_params.frame_type;
159 cm->refresh_golden_frame = (cm->frame_type == KEY_FRAME) ? 1 : 0;185 cm->refresh_golden_frame = (cm->frame_type == KEY_FRAME) ? 1 : 0;
160 cm->refresh_alt_ref_frame = (cm->frame_type == KEY_FRAME) ? 1 : 0;186 cm->refresh_alt_ref_frame = (cm->frame_type == KEY_FRAME) ? 1 : 0;
@@ -231,9 +257,15 @@ int VP8RateControlRTC::GetQP() const { return q_; } · 70 unmodified lines
231 257
232void VP8RateControlRTC::PostEncodeUpdate(uint64_t encoded_frame_size) {258void VP8RateControlRTC::PostEncodeUpdate(uint64_t encoded_frame_size) {
233 VP8_COMMON *const cm = &cpi_->common;259 VP8_COMMON *const cm = &cpi_->common;
234 260 vpx_clear_system_state();
235 cpi_->total_byte_count += encoded_frame_size;261 cpi_->total_byte_count += encoded_frame_size;
236 cpi_->projected_frame_size = static_cast<int>(encoded_frame_size << 3);262 cpi_->projected_frame_size = static_cast<int>(encoded_frame_size << 3);
263 if (cpi_->oxcf.number_of_layers > 1) {
264 for (unsigned int i = cpi_->current_layer + 1;
265 i < cpi_->oxcf.number_of_layers; ++i) {
266 cpi_->layer_context[i].total_byte_count += encoded_frame_size;
267 }
268 }
237 269
238 vp8_update_rate_correction_factors(cpi_, 2);270 vp8_update_rate_correction_factors(cpi_, 2);
239 271
@@ -283,7 +315,30 @@ void VP8RateControlRTC::PostEncodeUpdate(uint64_t encoded_frame_size) { · 43 unmodified lines
283 cpi_->total_actual_bits += cpi_->projected_frame_size;315 cpi_->total_actual_bits += cpi_->projected_frame_size;
284 cpi_->buffer_level = cpi_->bits_off_target;316 cpi_->buffer_level = cpi_->bits_off_target;
285 317
318 /* Propagate values to higher temporal layers */
319 if (cpi_->oxcf.number_of_layers > 1) {
320 for (unsigned int i = cpi_->current_layer + 1;
321 i < cpi_->oxcf.number_of_layers; ++i) {
322 LAYER_CONTEXT *lc = &cpi_->layer_context[i];
323 int bits_off_for_this_layer = (int)round(
324 lc->target_bandwidth / lc->framerate - cpi_->projected_frame_size);
325
326 lc->bits_off_target += bits_off_for_this_layer;
327
328 /* Clip buffer level to maximum buffer size for the layer */
329 if (lc->bits_off_target > lc->maximum_buffer_size) {
330 lc->bits_off_target = lc->maximum_buffer_size;
331 }
332
333 lc->total_actual_bits += cpi_->projected_frame_size;
334 lc->total_target_vs_actual += bits_off_for_this_layer;
335 lc->buffer_level = lc->bits_off_target;
336 }
337 }
338
286 cpi_->common.current_video_frame++;339 cpi_->common.current_video_frame++;
287 cpi_->frames_since_key++;340 cpi_->frames_since_key++;
341
342 if (cpi_->oxcf.number_of_layers > 1) vp8_save_layer_context(cpi_);
288}343}
289} // namespace libvpx344} // namespace libvpx
vp8/vp8_ratectrl_rtc.h+1−0
@@ -29,6 +29,7 @@ struct VP8RateControlRtcConfig : public VpxRateControlRtcConfig { · 28 unmodified lines
29 29
30struct VP8FrameParamsQpRTC {30struct VP8FrameParamsQpRTC {
31 FRAME_TYPE frame_type;31 FRAME_TYPE frame_type;
32 int temporal_layer_id;
32};33};
33 34
34class VP8RateControlRTC {35class VP8RateControlRTC {

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t