xref: /aosp_15_r20/external/libvpx/vp8/vp8_ratectrl_rtc.cc (revision fb1b10ab9aebc7c7068eedab379b749d7e3900be)
1 /*
2  *  Copyright (c) 2021 The WebM project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "vp8/vp8_ratectrl_rtc.h"
12 
13 #include <math.h>
14 
15 #include <new>
16 
17 #include "vp8/common/common.h"
18 #include "vp8/encoder/onyx_int.h"
19 #include "vp8/encoder/ratectrl.h"
20 #include "vpx_ports/system_state.h"
21 
22 namespace libvpx {
23 /* Quant MOD */
24 static const int kQTrans[] = {
25   0,  1,  2,  3,  4,  5,  7,   8,   9,   10,  12,  13,  15,  17,  18,  19,
26   20, 21, 23, 24, 25, 26, 27,  28,  29,  30,  31,  33,  35,  37,  39,  41,
27   43, 45, 47, 49, 51, 53, 55,  57,  59,  61,  64,  67,  70,  73,  76,  79,
28   82, 85, 88, 91, 94, 97, 100, 103, 106, 109, 112, 115, 118, 121, 124, 127,
29 };
30 
31 static const unsigned char kf_high_motion_minq[QINDEX_RANGE] = {
32   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
33   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  1,
34   1,  1,  2,  2,  2,  2,  3,  3,  3,  3,  3,  3,  3,  3,  4,  4,  4,  4,  5,
35   5,  5,  5,  5,  5,  6,  6,  6,  6,  7,  7,  8,  8,  8,  8,  9,  9,  10, 10,
36   10, 10, 11, 11, 11, 11, 12, 12, 13, 13, 13, 13, 14, 14, 15, 15, 15, 15, 16,
37   16, 16, 16, 17, 17, 18, 18, 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21,
38   22, 22, 23, 23, 24, 25, 25, 26, 26, 27, 28, 28, 29, 30
39 };
40 
41 static const unsigned char inter_minq[QINDEX_RANGE] = {
42   0,  0,  1,  1,  2,  3,  3,  4,  4,  5,  6,  6,  7,  8,  8,  9,  9,  10, 11,
43   11, 12, 13, 13, 14, 15, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22, 22, 23, 24,
44   24, 25, 26, 27, 27, 28, 29, 30, 30, 31, 32, 33, 33, 34, 35, 36, 36, 37, 38,
45   39, 39, 40, 41, 42, 42, 43, 44, 45, 46, 46, 47, 48, 49, 50, 50, 51, 52, 53,
46   54, 55, 55, 56, 57, 58, 59, 60, 60, 61, 62, 63, 64, 65, 66, 67, 67, 68, 69,
47   70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 86,
48   87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100
49 };
50 
rescale(int val,int num,int denom)51 static int rescale(int val, int num, int denom) {
52   int64_t llnum = num;
53   int64_t llden = denom;
54   int64_t llval = val;
55 
56   return (int)(llval * llnum / llden);
57 }
58 
Create(const VP8RateControlRtcConfig & cfg)59 std::unique_ptr<VP8RateControlRTC> VP8RateControlRTC::Create(
60     const VP8RateControlRtcConfig &cfg) {
61   std::unique_ptr<VP8RateControlRTC> rc_api(new (std::nothrow)
62                                                 VP8RateControlRTC());
63   if (!rc_api) return nullptr;
64   rc_api->cpi_ = static_cast<VP8_COMP *>(vpx_memalign(32, sizeof(*cpi_)));
65   if (!rc_api->cpi_) return nullptr;
66   vp8_zero(*rc_api->cpi_);
67 
68   if (!rc_api->InitRateControl(cfg)) return nullptr;
69 
70   return rc_api;
71 }
72 
~VP8RateControlRTC()73 VP8RateControlRTC::~VP8RateControlRTC() {
74   if (cpi_) {
75     vpx_free(cpi_->gf_active_flags);
76     vpx_free(cpi_);
77   }
78 }
79 
InitRateControl(const VP8RateControlRtcConfig & rc_cfg)80 bool VP8RateControlRTC::InitRateControl(const VP8RateControlRtcConfig &rc_cfg) {
81   VP8_COMMON *cm = &cpi_->common;
82   VP8_CONFIG *oxcf = &cpi_->oxcf;
83   oxcf->end_usage = USAGE_STREAM_FROM_SERVER;
84   cpi_->pass = 0;
85   cm->show_frame = 1;
86   oxcf->drop_frames_water_mark = 0;
87   cm->current_video_frame = 0;
88   cpi_->auto_gold = 1;
89   cpi_->key_frame_count = 1;
90   cpi_->rate_correction_factor = 1.0;
91   cpi_->key_frame_rate_correction_factor = 1.0;
92   cpi_->cyclic_refresh_mode_enabled = 0;
93   cpi_->auto_worst_q = 1;
94   cpi_->kf_overspend_bits = 0;
95   cpi_->kf_bitrate_adjustment = 0;
96   cpi_->gf_overspend_bits = 0;
97   cpi_->non_gf_bitrate_adjustment = 0;
98   if (!UpdateRateControl(rc_cfg)) return false;
99   cpi_->buffer_level = oxcf->starting_buffer_level;
100   cpi_->bits_off_target = oxcf->starting_buffer_level;
101   return true;
102 }
103 
UpdateRateControl(const VP8RateControlRtcConfig & rc_cfg)104 bool VP8RateControlRTC::UpdateRateControl(
105     const VP8RateControlRtcConfig &rc_cfg) {
106   if (rc_cfg.ts_number_layers < 1 ||
107       rc_cfg.ts_number_layers > VPX_TS_MAX_LAYERS) {
108     return false;
109   }
110 
111   VP8_COMMON *cm = &cpi_->common;
112   VP8_CONFIG *oxcf = &cpi_->oxcf;
113   const unsigned int prev_number_of_layers = oxcf->number_of_layers;
114   vpx_clear_system_state();
115   cm->Width = rc_cfg.width;
116   cm->Height = rc_cfg.height;
117   oxcf->Width = rc_cfg.width;
118   oxcf->Height = rc_cfg.height;
119   oxcf->worst_allowed_q = kQTrans[rc_cfg.max_quantizer];
120   oxcf->best_allowed_q = kQTrans[rc_cfg.min_quantizer];
121   cpi_->worst_quality = oxcf->worst_allowed_q;
122   cpi_->best_quality = oxcf->best_allowed_q;
123   cpi_->output_framerate = rc_cfg.framerate;
124   oxcf->target_bandwidth =
125       static_cast<unsigned int>(1000 * rc_cfg.target_bandwidth);
126   cpi_->ref_framerate = cpi_->output_framerate;
127   oxcf->fixed_q = -1;
128   oxcf->error_resilient_mode = 1;
129   oxcf->starting_buffer_level_in_ms = rc_cfg.buf_initial_sz;
130   oxcf->optimal_buffer_level_in_ms = rc_cfg.buf_optimal_sz;
131   oxcf->maximum_buffer_size_in_ms = rc_cfg.buf_sz;
132   oxcf->starting_buffer_level = rc_cfg.buf_initial_sz;
133   oxcf->optimal_buffer_level = rc_cfg.buf_optimal_sz;
134   oxcf->maximum_buffer_size = rc_cfg.buf_sz;
135   oxcf->number_of_layers = rc_cfg.ts_number_layers;
136   cpi_->buffered_mode = oxcf->optimal_buffer_level > 0;
137   oxcf->under_shoot_pct = rc_cfg.undershoot_pct;
138   oxcf->over_shoot_pct = rc_cfg.overshoot_pct;
139   oxcf->drop_frames_water_mark = rc_cfg.frame_drop_thresh;
140   if (oxcf->drop_frames_water_mark > 0) cpi_->drop_frames_allowed = 1;
141   cpi_->oxcf.rc_max_intra_bitrate_pct = rc_cfg.max_intra_bitrate_pct;
142   cpi_->framerate = rc_cfg.framerate;
143   for (int i = 0; i < KEY_FRAME_CONTEXT; ++i) {
144     cpi_->prior_key_frame_distance[i] =
145         static_cast<int>(cpi_->output_framerate);
146   }
147   oxcf->screen_content_mode = rc_cfg.is_screen;
148   if (oxcf->number_of_layers > 1 || prev_number_of_layers > 1) {
149     memcpy(oxcf->target_bitrate, rc_cfg.layer_target_bitrate,
150            sizeof(rc_cfg.layer_target_bitrate));
151     memcpy(oxcf->rate_decimator, rc_cfg.ts_rate_decimator,
152            sizeof(rc_cfg.ts_rate_decimator));
153     if (cm->current_video_frame == 0) {
154       double prev_layer_framerate = 0;
155       for (unsigned int i = 0; i < oxcf->number_of_layers; ++i) {
156         vp8_init_temporal_layer_context(cpi_, oxcf, i, prev_layer_framerate);
157         prev_layer_framerate = cpi_->output_framerate / oxcf->rate_decimator[i];
158       }
159     } else if (oxcf->number_of_layers != prev_number_of_layers) {
160       // The number of temporal layers has changed, so reset/initialize the
161       // temporal layer context for the new layer configuration: this means
162       // calling vp8_reset_temporal_layer_change() below.
163 
164       // Start at the base of the pattern cycle, so set the layer id to 0 and
165       // reset the temporal pattern counter.
166       // TODO(marpan/jianj): don't think lines 148-151 are needed (user controls
167       // the layer_id) so remove.
168       if (cpi_->temporal_layer_id > 0) {
169         cpi_->temporal_layer_id = 0;
170       }
171       cpi_->temporal_pattern_counter = 0;
172 
173       vp8_reset_temporal_layer_change(cpi_, oxcf,
174                                       static_cast<int>(prev_number_of_layers));
175     }
176   }
177 
178   cpi_->total_actual_bits = 0;
179   cpi_->total_target_vs_actual = 0;
180 
181   cm->mb_rows = cm->Height >> 4;
182   cm->mb_cols = cm->Width >> 4;
183   cm->MBs = cm->mb_rows * cm->mb_cols;
184   cm->mode_info_stride = cm->mb_cols + 1;
185 
186   // For temporal layers: starting/maximum/optimal_buffer_level is already set
187   // via vp8_init_temporal_layer_context() or vp8_reset_temporal_layer_change().
188   if (oxcf->number_of_layers <= 1 && prev_number_of_layers <= 1) {
189     oxcf->starting_buffer_level =
190         rescale((int)oxcf->starting_buffer_level, oxcf->target_bandwidth, 1000);
191     /* Set or reset optimal and maximum buffer levels. */
192     if (oxcf->optimal_buffer_level == 0) {
193       oxcf->optimal_buffer_level = oxcf->target_bandwidth / 8;
194     } else {
195       oxcf->optimal_buffer_level = rescale((int)oxcf->optimal_buffer_level,
196                                            oxcf->target_bandwidth, 1000);
197     }
198     if (oxcf->maximum_buffer_size == 0) {
199       oxcf->maximum_buffer_size = oxcf->target_bandwidth / 8;
200     } else {
201       oxcf->maximum_buffer_size =
202           rescale((int)oxcf->maximum_buffer_size, oxcf->target_bandwidth, 1000);
203     }
204   }
205 
206   if (cpi_->bits_off_target > oxcf->maximum_buffer_size) {
207     cpi_->bits_off_target = oxcf->maximum_buffer_size;
208     cpi_->buffer_level = cpi_->bits_off_target;
209   }
210 
211   vp8_new_framerate(cpi_, cpi_->framerate);
212   vpx_clear_system_state();
213   return true;
214 }
215 
ComputeQP(const VP8FrameParamsQpRTC & frame_params)216 FrameDropDecision VP8RateControlRTC::ComputeQP(
217     const VP8FrameParamsQpRTC &frame_params) {
218   VP8_COMMON *const cm = &cpi_->common;
219   vpx_clear_system_state();
220   if (cpi_->oxcf.number_of_layers > 1) {
221     cpi_->temporal_layer_id = frame_params.temporal_layer_id;
222     const int layer = frame_params.temporal_layer_id;
223     vp8_update_layer_contexts(cpi_);
224     /* Restore layer specific context & set frame rate */
225     vp8_restore_layer_context(cpi_, layer);
226     vp8_new_framerate(cpi_, cpi_->layer_context[layer].framerate);
227   }
228   cm->frame_type = static_cast<FRAME_TYPE>(frame_params.frame_type);
229   cm->refresh_golden_frame = (cm->frame_type == KEY_FRAME) ? 1 : 0;
230   cm->refresh_alt_ref_frame = (cm->frame_type == KEY_FRAME) ? 1 : 0;
231   if (cm->frame_type == KEY_FRAME && cpi_->common.current_video_frame > 0) {
232     cpi_->common.frame_flags |= FRAMEFLAGS_KEY;
233   }
234 
235   cpi_->per_frame_bandwidth = static_cast<int>(
236       round(cpi_->oxcf.target_bandwidth / cpi_->output_framerate));
237   if (vp8_check_drop_buffer(cpi_)) {
238     if (cpi_->oxcf.number_of_layers > 1) vp8_save_layer_context(cpi_);
239     return FrameDropDecision::kDrop;
240   }
241 
242   if (!vp8_pick_frame_size(cpi_)) {
243     cm->current_video_frame++;
244     cpi_->frames_since_key++;
245     cpi_->ext_refresh_frame_flags_pending = 0;
246     if (cpi_->oxcf.number_of_layers > 1) vp8_save_layer_context(cpi_);
247     return FrameDropDecision::kDrop;
248   }
249 
250   if (cpi_->buffer_level >= cpi_->oxcf.optimal_buffer_level &&
251       cpi_->buffered_mode) {
252     /* Max adjustment is 1/4 */
253     int Adjustment = cpi_->active_worst_quality / 4;
254     if (Adjustment) {
255       int buff_lvl_step;
256       if (cpi_->buffer_level < cpi_->oxcf.maximum_buffer_size) {
257         buff_lvl_step = (int)((cpi_->oxcf.maximum_buffer_size -
258                                cpi_->oxcf.optimal_buffer_level) /
259                               Adjustment);
260         if (buff_lvl_step) {
261           Adjustment =
262               (int)((cpi_->buffer_level - cpi_->oxcf.optimal_buffer_level) /
263                     buff_lvl_step);
264         } else {
265           Adjustment = 0;
266         }
267       }
268       cpi_->active_worst_quality -= Adjustment;
269       if (cpi_->active_worst_quality < cpi_->active_best_quality) {
270         cpi_->active_worst_quality = cpi_->active_best_quality;
271       }
272     }
273   }
274 
275   if (cpi_->ni_frames > 150) {
276     int q = cpi_->active_worst_quality;
277     if (cm->frame_type == KEY_FRAME) {
278       cpi_->active_best_quality = kf_high_motion_minq[q];
279     } else {
280       cpi_->active_best_quality = inter_minq[q];
281     }
282 
283     if (cpi_->buffer_level >= cpi_->oxcf.maximum_buffer_size) {
284       cpi_->active_best_quality = cpi_->best_quality;
285 
286     } else if (cpi_->buffer_level > cpi_->oxcf.optimal_buffer_level) {
287       int Fraction =
288           (int)(((cpi_->buffer_level - cpi_->oxcf.optimal_buffer_level) * 128) /
289                 (cpi_->oxcf.maximum_buffer_size -
290                  cpi_->oxcf.optimal_buffer_level));
291       int min_qadjustment =
292           ((cpi_->active_best_quality - cpi_->best_quality) * Fraction) / 128;
293 
294       cpi_->active_best_quality -= min_qadjustment;
295     }
296   }
297 
298   /* Clip the active best and worst quality values to limits */
299   if (cpi_->active_worst_quality > cpi_->worst_quality) {
300     cpi_->active_worst_quality = cpi_->worst_quality;
301   }
302   if (cpi_->active_best_quality < cpi_->best_quality) {
303     cpi_->active_best_quality = cpi_->best_quality;
304   }
305   if (cpi_->active_worst_quality < cpi_->active_best_quality) {
306     cpi_->active_worst_quality = cpi_->active_best_quality;
307   }
308 
309   q_ = vp8_regulate_q(cpi_, cpi_->this_frame_target);
310   vp8_set_quantizer(cpi_, q_);
311   vpx_clear_system_state();
312   return FrameDropDecision::kOk;
313 }
314 
GetQP() const315 int VP8RateControlRTC::GetQP() const { return q_; }
316 
GetUVDeltaQP() const317 UVDeltaQP VP8RateControlRTC::GetUVDeltaQP() const {
318   VP8_COMMON *cm = &cpi_->common;
319   UVDeltaQP uv_delta_q;
320   uv_delta_q.uvdc_delta_q = cm->uvdc_delta_q;
321   uv_delta_q.uvac_delta_q = cm->uvac_delta_q;
322   return uv_delta_q;
323 }
324 
GetLoopfilterLevel() const325 int VP8RateControlRTC::GetLoopfilterLevel() const {
326   VP8_COMMON *cm = &cpi_->common;
327   const double qp = q_;
328 
329   // This model is from linear regression
330   if (cm->Width * cm->Height <= 320 * 240) {
331     cm->filter_level = static_cast<int>(0.352685 * qp + 2.957774);
332   } else if (cm->Width * cm->Height <= 640 * 480) {
333     cm->filter_level = static_cast<int>(0.485069 * qp - 0.534462);
334   } else {
335     cm->filter_level = static_cast<int>(0.314875 * qp + 7.959003);
336   }
337 
338   int min_filter_level = 0;
339   // This logic is from get_min_filter_level() in picklpf.c
340   if (q_ > 6 && q_ <= 16) {
341     min_filter_level = 1;
342   } else {
343     min_filter_level = (q_ / 8);
344   }
345 
346   const int max_filter_level = 63;
347   if (cm->filter_level < min_filter_level) cm->filter_level = min_filter_level;
348   if (cm->filter_level > max_filter_level) cm->filter_level = max_filter_level;
349 
350   return cm->filter_level;
351 }
352 
PostEncodeUpdate(uint64_t encoded_frame_size)353 void VP8RateControlRTC::PostEncodeUpdate(uint64_t encoded_frame_size) {
354   VP8_COMMON *const cm = &cpi_->common;
355   vpx_clear_system_state();
356   cpi_->total_byte_count += encoded_frame_size;
357   cpi_->projected_frame_size = static_cast<int>(encoded_frame_size << 3);
358   if (cpi_->oxcf.number_of_layers > 1) {
359     for (unsigned int i = cpi_->current_layer + 1;
360          i < cpi_->oxcf.number_of_layers; ++i) {
361       cpi_->layer_context[i].total_byte_count += encoded_frame_size;
362     }
363   }
364 
365   vp8_update_rate_correction_factors(cpi_, 2);
366 
367   cpi_->last_q[cm->frame_type] = cm->base_qindex;
368 
369   if (cm->frame_type == KEY_FRAME) {
370     vp8_adjust_key_frame_context(cpi_);
371   }
372 
373   /* Keep a record of ambient average Q. */
374   if (cm->frame_type != KEY_FRAME) {
375     cpi_->avg_frame_qindex =
376         (2 + 3 * cpi_->avg_frame_qindex + cm->base_qindex) >> 2;
377   }
378   /* Keep a record from which we can calculate the average Q excluding
379    * key frames.
380    */
381   if (cm->frame_type != KEY_FRAME) {
382     cpi_->ni_frames++;
383     /* Damp value for first few frames */
384     if (cpi_->ni_frames > 150) {
385       cpi_->ni_tot_qi += q_;
386       cpi_->ni_av_qi = (cpi_->ni_tot_qi / cpi_->ni_frames);
387     } else {
388       cpi_->ni_tot_qi += q_;
389       cpi_->ni_av_qi =
390           ((cpi_->ni_tot_qi / cpi_->ni_frames) + cpi_->worst_quality + 1) / 2;
391     }
392 
393     /* If the average Q is higher than what was used in the last
394      * frame (after going through the recode loop to keep the frame
395      * size within range) then use the last frame value - 1. The -1
396      * is designed to stop Q and hence the data rate, from
397      * progressively falling away during difficult sections, but at
398      * the same time reduce the number of itterations around the
399      * recode loop.
400      */
401     if (q_ > cpi_->ni_av_qi) cpi_->ni_av_qi = q_ - 1;
402   }
403 
404   cpi_->bits_off_target +=
405       cpi_->av_per_frame_bandwidth - cpi_->projected_frame_size;
406   if (cpi_->bits_off_target > cpi_->oxcf.maximum_buffer_size) {
407     cpi_->bits_off_target = cpi_->oxcf.maximum_buffer_size;
408   }
409 
410   cpi_->total_actual_bits += cpi_->projected_frame_size;
411   cpi_->buffer_level = cpi_->bits_off_target;
412 
413   /* Propagate values to higher temporal layers */
414   if (cpi_->oxcf.number_of_layers > 1) {
415     for (unsigned int i = cpi_->current_layer + 1;
416          i < cpi_->oxcf.number_of_layers; ++i) {
417       LAYER_CONTEXT *lc = &cpi_->layer_context[i];
418       int bits_off_for_this_layer = (int)round(
419           lc->target_bandwidth / lc->framerate - cpi_->projected_frame_size);
420 
421       lc->bits_off_target += bits_off_for_this_layer;
422 
423       /* Clip buffer level to maximum buffer size for the layer */
424       if (lc->bits_off_target > lc->maximum_buffer_size) {
425         lc->bits_off_target = lc->maximum_buffer_size;
426       }
427 
428       lc->total_actual_bits += cpi_->projected_frame_size;
429       lc->total_target_vs_actual += bits_off_for_this_layer;
430       lc->buffer_level = lc->bits_off_target;
431     }
432   }
433 
434   cpi_->common.current_video_frame++;
435   cpi_->frames_since_key++;
436 
437   if (cpi_->oxcf.number_of_layers > 1) vp8_save_layer_context(cpi_);
438   vpx_clear_system_state();
439 }
440 }  // namespace libvpx
441