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
6161 SetMode(::libvpx_test::kRealTime);
6262 }
6363
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+
64114 virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
65115 ::libvpx_test::Encoder *encoder) {
66− if (video->frame() == 0) {
67− encoder->Control(VP8E_SET_CPUUSED, -6);
68− encoder->Control(VP8E_SET_RTC_EXTERNAL_RATECTRL, 1);
69− encoder->Control(VP8E_SET_MAX_INTRA_BITRATE_PCT, 1000);
116+ if (rc_cfg_.ts_number_layers > 1) {
117+ const int layer_id = SetLayerId(video->frame(), cfg_.ts_number_layers);
118+ const int frame_flags =
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+ }
70136 }
71137 frame_params_.frame_type =
72138 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− }
78139 encoder_exit_ = video->frame() == test_video_.frames;
79140 }
80141
@@ -125,6 +186,38 @@ class Vp8RcInterfaceTest · 44 unmodified lines
125186 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
126187 }
127188
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+
128221 private:
129222 void SetConfig() {
130223 rc_cfg_.width = test_video_.width;
@@ -160,6 +253,72 @@ class Vp8RcInterfaceTest · 29 unmodified lines
160253 cfg_.kf_max_dist = key_interval_;
161254 }
162255
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+
163322 std::unique_ptr<libvpx::VP8RateControlRTC> rc_api_;
164323 libvpx::VP8RateControlRtcConfig rc_cfg_;
165324 int key_interval_;
@@ -173,6 +332,10 @@ TEST_P(Vp8RcInterfaceTest, OneLayer) { RunOneLayer(); } · 7 unmodified lines
173332
174333 TEST_P(Vp8RcInterfaceTest, OneLayerPeriodicKey) { RunPeriodicKey(); }
175334
335+TEST_P(Vp8RcInterfaceTest, TemporalLayers2TL) { RunTemporalLayers2TL(); }
336+
337+TEST_P(Vp8RcInterfaceTest, TemporalLayers3TL) { RunTemporalLayers3TL(); }
338+
176339 VP8_INSTANTIATE_TEST_SUITE(Vp8RcInterfaceTest,
177340 ::testing::Values(200, 400, 1000),
178341 ::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
183183 extern FILE *vpxlogc;
184184 #endif
185185
186−static void save_layer_context(VP8_COMP *cpi) {
186+void vp8_save_layer_context(VP8_COMP *cpi) {
187187 LAYER_CONTEXT *lc = &cpi->layer_context[cpi->current_layer];
188188
189189 /* Save layer dependent coding state */
@@ -222,7 +222,7 @@ static void save_layer_context(VP8_COMP *cpi) { · 32 unmodified lines
222222 sizeof(cpi->mb.count_mb_ref_frame_usage));
223223 }
224224
225−static void restore_layer_context(VP8_COMP *cpi, const int layer) {
225+void vp8_restore_layer_context(VP8_COMP *cpi, const int layer) {
226226 LAYER_CONTEXT *lc = &cpi->layer_context[layer];
227227
228228 /* Restore layer dependent coding state */
@@ -269,9 +269,9 @@ static int rescale(int val, int num, int denom) { · 40 unmodified lines
269269 return (int)(llval * llnum / llden);
270270 }
271271
272−static void init_temporal_layer_context(VP8_COMP *cpi, VP8_CONFIG *oxcf,
273− const int layer,
274− double prev_layer_framerate) {
272+void vp8_init_temporal_layer_context(VP8_COMP *cpi, VP8_CONFIG *oxcf,
273+ const int layer,
274+ double prev_layer_framerate) {
275275 LAYER_CONTEXT *lc = &cpi->layer_context[layer];
276276
277277 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
336336 // We need this to set the layer context for the new layers below.
337337 if (prev_num_layers == 1) {
338338 cpi->current_layer = 0;
339− save_layer_context(cpi);
339+ vp8_save_layer_context(cpi);
340340 }
341341 for (i = 0; i < curr_num_layers; ++i) {
342342 LAYER_CONTEXT *lc = &cpi->layer_context[i];
343343 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);
345345 }
346346 // The initial buffer levels are set based on their starting levels.
347347 // 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
356356 // state (to smooth-out quality dips/rate fluctuation at transition)?
357357
358358 // 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()
360360 // are not called in the encoding loop, so we need to call it here to
361361 // pass the layer context state to |cpi|.
362362 if (curr_num_layers == 1) {
@@ -364,7 +364,7 @@ static void reset_temporal_layer_change(VP8_COMP *cpi, VP8_CONFIG *oxcf, · 1 unmodified line
364364 lc->buffer_level =
365365 cpi->oxcf.starting_buffer_level_in_ms * lc->target_bandwidth / 1000;
366366 lc->bits_off_target = lc->buffer_level;
367− restore_layer_context(cpi, 0);
367+ vp8_restore_layer_context(cpi, 0);
368368 }
369369 prev_layer_framerate = cpi->output_framerate / cpi->oxcf.rate_decimator[i];
370370 }
@@ -1274,7 +1274,7 @@ void vp8_new_framerate(VP8_COMP *cpi, double framerate) { · 903 unmodified lines
12741274 cpi->framerate = framerate;
12751275 cpi->output_framerate = framerate;
12761276 cpi->per_frame_bandwidth =
1277− (int)(cpi->oxcf.target_bandwidth / cpi->output_framerate);
1277+ (int)round(cpi->oxcf.target_bandwidth / cpi->output_framerate);
12781278 cpi->av_per_frame_bandwidth = cpi->per_frame_bandwidth;
12791279 cpi->min_frame_bandwidth = (int)(cpi->av_per_frame_bandwidth *
12801280 cpi->oxcf.two_pass_vbrmin_section / 100);
@@ -1365,7 +1365,7 @@ static void init_config(VP8_COMP *cpi, VP8_CONFIG *oxcf) { · 84 unmodified lines
13651365 double prev_layer_framerate = 0;
13661366
13671367 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);
13691369 prev_layer_framerate =
13701370 cpi->output_framerate / cpi->oxcf.rate_decimator[i];
13711371 }
@@ -1382,7 +1382,7 @@ static void init_config(VP8_COMP *cpi, VP8_CONFIG *oxcf) { · 10 unmodified lines
13821382 #endif
13831383 }
13841384
1385−static void update_layer_contexts(VP8_COMP *cpi) {
1385+void vp8_update_layer_contexts(VP8_COMP *cpi) {
13861386 VP8_CONFIG *oxcf = &cpi->oxcf;
13871387
13881388 /* 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
14171417 /* Work out the average size of a frame within this layer */
14181418 if (i > 0) {
14191419 lc->avg_frame_size_for_layer =
1420− (int)((oxcf->target_bitrate[i] - oxcf->target_bitrate[i - 1]) *
1421− 1000 / (lc->framerate - prev_layer_framerate));
1420+ (int)round((oxcf->target_bitrate[i] - oxcf->target_bitrate[i - 1]) *
1421+ 1000 / (lc->framerate - prev_layer_framerate));
14221422 }
14231423
14241424 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
32613261 #endif // !CONFIG_REALTIME_ONLY
32623262 default:
32633263 cpi->per_frame_bandwidth =
3264− (int)(cpi->target_bandwidth / cpi->output_framerate);
3264+ (int)round(cpi->target_bandwidth / cpi->output_framerate);
32653265 break;
32663266 }
32673267
@@ -4554,8 +4554,8 @@ static void encode_frame_to_data_rate(VP8_COMP *cpi, size_t *size, · 1286 unmodified lines
45544554
45554555 for (i = cpi->current_layer + 1; i < cpi->oxcf.number_of_layers; ++i) {
45564556 LAYER_CONTEXT *lc = &cpi->layer_context[i];
4557− int bits_off_for_this_layer = (int)(lc->target_bandwidth / lc->framerate -
4558− cpi->projected_frame_size);
4557+ int bits_off_for_this_layer = (int)round(
4558+ lc->target_bandwidth / lc->framerate - cpi->projected_frame_size);
45594559
45604560 lc->bits_off_target += bits_off_for_this_layer;
45614561
@@ -4992,7 +4992,7 @@ int vp8_get_compressed_data(VP8_COMP *cpi, unsigned int *frame_flags, · 430 unmodified lines
49924992 if (cpi->oxcf.number_of_layers > 1) {
49934993 int layer;
49944994
4995− update_layer_contexts(cpi);
4995+ vp8_update_layer_contexts(cpi);
49964996
49974997 /* Restore layer specific context & set frame rate */
49984998 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
50025002 cpi->oxcf
50035003 .layer_id[cpi->temporal_pattern_counter % cpi->oxcf.periodicity];
50045004 }
5005− restore_layer_context(cpi, layer);
5005+ vp8_restore_layer_context(cpi, layer);
50065006 vp8_new_framerate(cpi, cpi->layer_context[layer].framerate);
50075007 }
50085008
@@ -5133,7 +5133,7 @@ int vp8_get_compressed_data(VP8_COMP *cpi, unsigned int *frame_flags, · 124 unmodified lines
51335133 }
51345134
51355135 /* 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);
51375137
51385138 vpx_usec_timer_mark(&cmptimer);
51395139 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
712712
713713 void vp8_alloc_compressor_data(VP8_COMP *cpi);
714714 int vp8_reverse_trans(int x);
715+void vp8_init_temporal_layer_context(VP8_COMP *cpi, VP8_CONFIG *oxcf,
716+ const int layer,
717+ double prev_layer_framerate);
718+void vp8_update_layer_contexts(VP8_COMP *cpi);
719+void vp8_save_layer_context(VP8_COMP *cpi);
720+void vp8_restore_layer_context(VP8_COMP *cpi, const int layer);
715721 void vp8_new_framerate(VP8_COMP *cpi, double framerate);
716722 void vp8_loopfilter_frame(VP8_COMP *cpi, VP8_COMMON *cm);
717723
vp8/vp8_ratectrl_rtc.cc+58−3
@@ -8,9 +8,11 @@ · 7 unmodified lines
88 * be found in the AUTHORS file in the root of the source tree.
99 */
1010
11+#include <math.h>
1112 #include <new>
1213 #include "vp8/vp8_ratectrl_rtc.h"
1314 #include "vp8/encoder/ratectrl.h"
15+#include "vpx_ports/system_state.h"
1416
1517 namespace libvpx {
1618 /* Quant MOD */
@@ -90,7 +92,7 @@ void VP8RateControlRTC::UpdateRateControl( · 73 unmodified lines
9092 const VP8RateControlRtcConfig &rc_cfg) {
9193 VP8_COMMON *cm = &cpi_->common;
9294 VP8_CONFIG *oxcf = &cpi_->oxcf;
93−
95+ vpx_clear_system_state();
9496 cm->Width = rc_cfg.width;
9597 cm->Height = rc_cfg.height;
9698 oxcf->Width = rc_cfg.width;
@@ -102,6 +104,7 @@ void VP8RateControlRTC::UpdateRateControl( · 5 unmodified lines
102104 cpi_->output_framerate = rc_cfg.framerate;
103105 oxcf->target_bandwidth =
104106 static_cast<unsigned int>(1000 * rc_cfg.target_bandwidth);
107+ cpi_->ref_framerate = cpi_->output_framerate;
105108 oxcf->fixed_q = -1;
106109 oxcf->error_resilient_mode = 1;
107110 oxcf->starting_buffer_level_in_ms = rc_cfg.buf_initial_sz;
@@ -110,7 +113,7 @@ void VP8RateControlRTC::UpdateRateControl( · 2 unmodified lines
110113 oxcf->starting_buffer_level = rc_cfg.buf_initial_sz;
111114 oxcf->optimal_buffer_level = rc_cfg.buf_optimal_sz;
112115 oxcf->maximum_buffer_size = rc_cfg.buf_sz;
113− oxcf->number_of_layers = 1;
116+ oxcf->number_of_layers = rc_cfg.ts_number_layers;
114117 cpi_->buffered_mode = oxcf->optimal_buffer_level > 0;
115118 oxcf->under_shoot_pct = rc_cfg.undershoot_pct;
116119 oxcf->over_shoot_pct = rc_cfg.overshoot_pct;
@@ -121,6 +124,20 @@ void VP8RateControlRTC::UpdateRateControl( · 4 unmodified lines
121124 static_cast<int>(cpi_->output_framerate);
122125 }
123126
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+
124141 cpi_->total_actual_bits = 0;
125142 cpi_->total_target_vs_actual = 0;
126143
@@ -155,6 +172,15 @@ void VP8RateControlRTC::UpdateRateControl( · 28 unmodified lines
155172
156173 void VP8RateControlRTC::ComputeQP(const VP8FrameParamsQpRTC &frame_params) {
157174 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+ }
158184 cm->frame_type = frame_params.frame_type;
159185 cm->refresh_golden_frame = (cm->frame_type == KEY_FRAME) ? 1 : 0;
160186 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
231257
232258 void VP8RateControlRTC::PostEncodeUpdate(uint64_t encoded_frame_size) {
233259 VP8_COMMON *const cm = &cpi_->common;
234−
260+ vpx_clear_system_state();
235261 cpi_->total_byte_count += encoded_frame_size;
236262 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+ }
237269
238270 vp8_update_rate_correction_factors(cpi_, 2);
239271
@@ -283,7 +315,30 @@ void VP8RateControlRTC::PostEncodeUpdate(uint64_t encoded_frame_size) { · 43 unmodified lines
283315 cpi_->total_actual_bits += cpi_->projected_frame_size;
284316 cpi_->buffer_level = cpi_->bits_off_target;
285317
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+
286339 cpi_->common.current_video_frame++;
287340 cpi_->frames_since_key++;
341+
342+ if (cpi_->oxcf.number_of_layers > 1) vp8_save_layer_context(cpi_);
288343 }
289344 } // namespace libvpx
vp8/vp8_ratectrl_rtc.h+1−0
@@ -29,6 +29,7 @@ struct VP8RateControlRtcConfig : public VpxRateControlRtcConfig { · 28 unmodified lines
2929
3030 struct VP8FrameParamsQpRTC {
3131 FRAME_TYPE frame_type;
32+ int temporal_layer_id;
3233 };
3334
3435 class 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