Marco Paniconi | 5b1e473 | 2019-08-08 18:57:53 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2019, Alliance for Open Media. 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 | #ifndef AOM_AV1_ENCODER_SVC_LAYERCONTEXT_H_ |
| 12 | #define AOM_AV1_ENCODER_SVC_LAYERCONTEXT_H_ |
| 13 | |
Marco Paniconi | 6dfcab2 | 2022-10-31 00:41:42 -0700 | [diff] [blame] | 14 | #include "aom_scale/yv12config.h" |
Marco Paniconi | 5b1e473 | 2019-08-08 18:57:53 -0700 | [diff] [blame] | 15 | #include "av1/encoder/aq_cyclicrefresh.h" |
| 16 | #include "av1/encoder/encoder.h" |
| 17 | #include "av1/encoder/ratectrl.h" |
| 18 | |
| 19 | #ifdef __cplusplus |
| 20 | extern "C" { |
| 21 | #endif |
| 22 | |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 23 | /*! |
| 24 | * \brief The stucture of quantities related to each spatial and temporal layer. |
| 25 | * \ingroup SVC |
| 26 | */ |
Marco Paniconi | 5b1e473 | 2019-08-08 18:57:53 -0700 | [diff] [blame] | 27 | typedef struct { |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 28 | /*!\cond */ |
Marco Paniconi | 5b1e473 | 2019-08-08 18:57:53 -0700 | [diff] [blame] | 29 | RATE_CONTROL rc; |
Mufaddal Chakera | 94ee9bf | 2021-04-12 01:02:22 +0530 | [diff] [blame] | 30 | PRIMARY_RATE_CONTROL p_rc; |
Marco Paniconi | 5b1e473 | 2019-08-08 18:57:53 -0700 | [diff] [blame] | 31 | int framerate_factor; |
Wan-Teh Chang | 122be35 | 2023-02-15 14:08:19 -0800 | [diff] [blame] | 32 | int64_t layer_target_bitrate; // In bits per second. |
Marco Paniconi | 5b1e473 | 2019-08-08 18:57:53 -0700 | [diff] [blame] | 33 | int scaling_factor_num; |
| 34 | int scaling_factor_den; |
Jerome Jiang | f54337a | 2019-08-15 09:28:58 -0700 | [diff] [blame] | 35 | int64_t target_bandwidth; |
| 36 | int64_t spatial_layer_target_bandwidth; |
Marco Paniconi | 5b1e473 | 2019-08-08 18:57:53 -0700 | [diff] [blame] | 37 | double framerate; |
| 38 | int avg_frame_size; |
| 39 | int max_q; |
| 40 | int min_q; |
| 41 | int frames_from_key_frame; |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 42 | /*!\endcond */ |
| 43 | |
| 44 | /*! |
| 45 | * Cyclic refresh parameters (aq-mode=3), that need to be updated per-frame. |
| 46 | */ |
Marco Paniconi | 5b1e473 | 2019-08-08 18:57:53 -0700 | [diff] [blame] | 47 | int sb_index; |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 48 | /*! |
| 49 | * Segmentation map |
| 50 | */ |
Marco Paniconi | 5b1e473 | 2019-08-08 18:57:53 -0700 | [diff] [blame] | 51 | int8_t *map; |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 52 | /*! |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 53 | * Number of blocks on segment 1 |
| 54 | */ |
Marco Paniconi | 5b1e473 | 2019-08-08 18:57:53 -0700 | [diff] [blame] | 55 | int actual_num_seg1_blocks; |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 56 | |
| 57 | /*! |
| 58 | * Number of blocks on segment 2 |
| 59 | */ |
Marco Paniconi | 5b1e473 | 2019-08-08 18:57:53 -0700 | [diff] [blame] | 60 | int actual_num_seg2_blocks; |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 61 | /*! |
| 62 | * Counter used to detect scene change. |
| 63 | */ |
Marco Paniconi | 5b1e473 | 2019-08-08 18:57:53 -0700 | [diff] [blame] | 64 | int counter_encode_maxq_scene_change; |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 65 | |
| 66 | /*! |
| 67 | * Speed settings for each layer. |
| 68 | */ |
Marco Paniconi | 5b1e473 | 2019-08-08 18:57:53 -0700 | [diff] [blame] | 69 | uint8_t speed; |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 70 | /*! |
| 71 | * GF group index. |
| 72 | */ |
Marco Paniconi | efac449 | 2019-08-26 21:03:14 -0700 | [diff] [blame] | 73 | unsigned char group_index; |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 74 | /*! |
| 75 | * If current layer is key frame. |
| 76 | */ |
Marco Paniconi | 2b22a1f | 2020-06-22 21:55:02 -0700 | [diff] [blame] | 77 | int is_key_frame; |
Marco Paniconi | dbc2946 | 2020-07-29 09:13:25 -0700 | [diff] [blame] | 78 | /*! |
| 79 | * Maximum motion magnitude of previous encoded layer. |
| 80 | */ |
| 81 | int max_mv_magnitude; |
Marco Paniconi | 5b1e473 | 2019-08-08 18:57:53 -0700 | [diff] [blame] | 82 | } LAYER_CONTEXT; |
| 83 | |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 84 | /*! |
| 85 | * \brief The stucture of SVC. |
| 86 | * \ingroup SVC |
| 87 | */ |
Marco Paniconi | 5b1e473 | 2019-08-08 18:57:53 -0700 | [diff] [blame] | 88 | typedef struct SVC { |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 89 | /*!\cond */ |
Marco Paniconi | 5b1e473 | 2019-08-08 18:57:53 -0700 | [diff] [blame] | 90 | int spatial_layer_id; |
| 91 | int temporal_layer_id; |
| 92 | int number_spatial_layers; |
| 93 | int number_temporal_layers; |
Marco Paniconi | d8bcf2a | 2023-01-03 15:10:27 -0800 | [diff] [blame] | 94 | int prev_number_spatial_layers; |
Marco Paniconi | e5de332 | 2021-03-22 22:03:17 -0700 | [diff] [blame] | 95 | int use_flexible_mode; |
| 96 | int ksvc_fixed_mode; |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 97 | /*!\endcond */ |
| 98 | |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 99 | /*!\cond */ |
Marco Paniconi | 6397132 | 2019-08-15 21:32:05 -0700 | [diff] [blame] | 100 | double base_framerate; |
Marco Paniconi | ddd5666 | 2019-08-28 15:46:56 -0700 | [diff] [blame] | 101 | unsigned int current_superframe; |
Marco Paniconi | 84cb8b3 | 2021-01-19 14:02:19 -0800 | [diff] [blame] | 102 | int skip_mvsearch_last; |
| 103 | int skip_mvsearch_gf; |
chiyotsai | fda9d9d | 2022-05-18 11:56:02 -0700 | [diff] [blame] | 104 | int skip_mvsearch_altref; |
Marco Paniconi | 42e1bdd | 2020-06-10 16:47:39 -0700 | [diff] [blame] | 105 | int spatial_layer_fb[REF_FRAMES]; |
| 106 | int temporal_layer_fb[REF_FRAMES]; |
Fyodor Kyslov | 34b591f | 2020-06-24 20:13:58 -0700 | [diff] [blame] | 107 | int num_encoded_top_layer; |
Fyodor Kyslov | b790c9c | 2021-01-12 15:33:36 -0800 | [diff] [blame] | 108 | int first_layer_denoise; |
Marco Paniconi | 6dfcab2 | 2022-10-31 00:41:42 -0700 | [diff] [blame] | 109 | YV12_BUFFER_CONFIG source_last_TL0; |
| 110 | int mi_cols_full_resoln; |
| 111 | int mi_rows_full_resoln; |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 112 | /*!\endcond */ |
| 113 | |
| 114 | /*! |
| 115 | * Layer context used for rate control in CBR mode. |
Wan-Teh Chang | 122be35 | 2023-02-15 14:08:19 -0800 | [diff] [blame] | 116 | * An array. The index for spatial layer `sl` and temporal layer `tl` is |
| 117 | * sl * number_temporal_layers + tl. |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 118 | */ |
Deepa K G | 5c61149 | 2022-08-21 17:39:43 +0530 | [diff] [blame] | 119 | LAYER_CONTEXT *layer_context; |
| 120 | |
| 121 | /*! |
Wan-Teh Chang | 122be35 | 2023-02-15 14:08:19 -0800 | [diff] [blame] | 122 | * Number of layers allocated for layer_context. If nonzero, must be greater |
| 123 | * than or equal to number_spatial_layers * number_temporal_layers. |
Deepa K G | 5c61149 | 2022-08-21 17:39:43 +0530 | [diff] [blame] | 124 | */ |
| 125 | int num_allocated_layers; |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 126 | |
| 127 | /*! |
| 128 | * EIGHTTAP_SMOOTH or BILINEAR |
| 129 | */ |
Jerome Jiang | 790190e | 2020-06-12 16:47:45 -0700 | [diff] [blame] | 130 | InterpFilter downsample_filter_type[AOM_MAX_SS_LAYERS]; |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 131 | |
| 132 | /*! |
| 133 | * Downsample_filter_phase: = 0 will do sub-sampling (no weighted average), |
| 134 | * = 8 will center the target pixel and get a symmetric averaging filter. |
| 135 | */ |
Jerome Jiang | 790190e | 2020-06-12 16:47:45 -0700 | [diff] [blame] | 136 | int downsample_filter_phase[AOM_MAX_SS_LAYERS]; |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 137 | |
| 138 | /*! |
| 139 | * Force zero-mv in mode search for the spatial/inter-layer reference. |
| 140 | */ |
Marco Paniconi | 2b22a1f | 2020-06-22 21:55:02 -0700 | [diff] [blame] | 141 | int force_zero_mode_spatial_ref; |
Marco Paniconi | 5b1e473 | 2019-08-08 18:57:53 -0700 | [diff] [blame] | 142 | } SVC; |
| 143 | |
| 144 | struct AV1_COMP; |
Marco Paniconi | 6dfcab2 | 2022-10-31 00:41:42 -0700 | [diff] [blame] | 145 | struct EncodeFrameInput; |
Marco Paniconi | 5b1e473 | 2019-08-08 18:57:53 -0700 | [diff] [blame] | 146 | |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 147 | /*!\brief Initialize layer context data from init_config(). |
| 148 | * |
| 149 | * \ingroup SVC |
| 150 | * \callgraph |
| 151 | * \callergraph |
| 152 | * |
| 153 | * \param[in] cpi Top level encoder structure |
| 154 | * |
Wan-Teh Chang | 0defff8 | 2022-08-23 14:17:01 -0700 | [diff] [blame] | 155 | * \remark Nothing returned. Set cpi->svc. |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 156 | */ |
Marco Paniconi | 5b1e473 | 2019-08-08 18:57:53 -0700 | [diff] [blame] | 157 | void av1_init_layer_context(struct AV1_COMP *const cpi); |
| 158 | |
Deepa K G | 5c61149 | 2022-08-21 17:39:43 +0530 | [diff] [blame] | 159 | /*!\brief Allocate layer context data. |
| 160 | * |
| 161 | * \ingroup SVC |
| 162 | * \callgraph |
| 163 | * \callergraph |
| 164 | * |
| 165 | * \param[in] cpi Top level encoder structure |
| 166 | * \param[in] num_layers Number of layers to be allocated |
| 167 | * |
James Zern | ff135dc | 2022-12-06 15:23:51 -0800 | [diff] [blame] | 168 | * \remark Allocates memory for cpi->svc.layer_context. |
| 169 | * \return True on success, false on allocation failure. |
Deepa K G | 5c61149 | 2022-08-21 17:39:43 +0530 | [diff] [blame] | 170 | */ |
James Zern | ff135dc | 2022-12-06 15:23:51 -0800 | [diff] [blame] | 171 | bool av1_alloc_layer_context(struct AV1_COMP *cpi, int num_layers); |
Deepa K G | 5c61149 | 2022-08-21 17:39:43 +0530 | [diff] [blame] | 172 | |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 173 | /*!\brief Update the layer context from a change_config() call. |
| 174 | * |
| 175 | * \ingroup SVC |
| 176 | * \callgraph |
| 177 | * \callergraph |
| 178 | * |
| 179 | * \param[in] cpi Top level encoder structure |
| 180 | * \param[in] target_bandwidth Total target bandwidth |
| 181 | * |
Wan-Teh Chang | 0defff8 | 2022-08-23 14:17:01 -0700 | [diff] [blame] | 182 | * \remark Nothing returned. Buffer level for each layer is set. |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 183 | */ |
Marco Paniconi | 5b1e473 | 2019-08-08 18:57:53 -0700 | [diff] [blame] | 184 | void av1_update_layer_context_change_config(struct AV1_COMP *const cpi, |
Jerome Jiang | f54337a | 2019-08-15 09:28:58 -0700 | [diff] [blame] | 185 | const int64_t target_bandwidth); |
Marco Paniconi | 5b1e473 | 2019-08-08 18:57:53 -0700 | [diff] [blame] | 186 | |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 187 | /*!\brief Prior to encoding the frame, update framerate-related quantities |
| 188 | for the current temporal layer. |
| 189 | * |
| 190 | * \ingroup SVC |
| 191 | * \callgraph |
| 192 | * \callergraph |
| 193 | * |
| 194 | * \param[in] cpi Top level encoder structure |
| 195 | * |
Wan-Teh Chang | 0defff8 | 2022-08-23 14:17:01 -0700 | [diff] [blame] | 196 | * \remark Nothing returned. Frame related quantities for current temporal |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 197 | layer are updated. |
| 198 | */ |
Marco Paniconi | 5b1e473 | 2019-08-08 18:57:53 -0700 | [diff] [blame] | 199 | void av1_update_temporal_layer_framerate(struct AV1_COMP *const cpi); |
| 200 | |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 201 | /*!\brief Prior to encoding the frame, set the layer context, for the current |
| 202 | layer to be encoded, to the cpi struct. |
| 203 | * |
| 204 | * \ingroup SVC |
| 205 | * \callgraph |
| 206 | * \callergraph |
| 207 | * |
| 208 | * \param[in] cpi Top level encoder structure |
| 209 | * |
Wan-Teh Chang | 0defff8 | 2022-08-23 14:17:01 -0700 | [diff] [blame] | 210 | * \remark Nothing returned. Layer context for current layer is set. |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 211 | */ |
Marco Paniconi | 5b1e473 | 2019-08-08 18:57:53 -0700 | [diff] [blame] | 212 | void av1_restore_layer_context(struct AV1_COMP *const cpi); |
| 213 | |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 214 | /*!\brief Save the layer context after encoding the frame. |
| 215 | * |
| 216 | * \ingroup SVC |
| 217 | * \callgraph |
| 218 | * \callergraph |
| 219 | * |
| 220 | * \param[in] cpi Top level encoder structure |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 221 | */ |
Marco Paniconi | 5b1e473 | 2019-08-08 18:57:53 -0700 | [diff] [blame] | 222 | void av1_save_layer_context(struct AV1_COMP *const cpi); |
| 223 | |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 224 | /*!\brief Free the memory used for cyclic refresh in layer context. |
| 225 | * |
| 226 | * \ingroup SVC |
| 227 | * \callgraph |
| 228 | * \callergraph |
| 229 | * |
| 230 | * \param[in] cpi Top level encoder structure |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 231 | */ |
Marco Paniconi | 5b1e473 | 2019-08-08 18:57:53 -0700 | [diff] [blame] | 232 | void av1_free_svc_cyclic_refresh(struct AV1_COMP *const cpi); |
| 233 | |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 234 | /*!\brief Reset on key frame: reset counters, references and buffer updates. |
| 235 | * |
| 236 | * \ingroup SVC |
| 237 | * \callgraph |
| 238 | * \callergraph |
| 239 | * |
| 240 | * \param[in] cpi Top level encoder structure |
| 241 | * \param[in] is_key Whether current layer is key frame |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 242 | */ |
Marco Paniconi | 5b1e473 | 2019-08-08 18:57:53 -0700 | [diff] [blame] | 243 | void av1_svc_reset_temporal_layers(struct AV1_COMP *const cpi, int is_key); |
| 244 | |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 245 | /*!\brief Before encoding, set resolutions and allocate compressor data. |
| 246 | * |
| 247 | * \ingroup SVC |
| 248 | * \callgraph |
| 249 | * \callergraph |
| 250 | * |
| 251 | * \param[in] cpi Top level encoder structure |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 252 | */ |
Marco Paniconi | 6397132 | 2019-08-15 21:32:05 -0700 | [diff] [blame] | 253 | void av1_one_pass_cbr_svc_start_layer(struct AV1_COMP *const cpi); |
| 254 | |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 255 | /*!\brief Get primary reference frame for current layer |
| 256 | * |
| 257 | * \ingroup SVC |
| 258 | * \callgraph |
| 259 | * \callergraph |
| 260 | * |
| 261 | * \param[in] cpi Top level encoder structure |
| 262 | * |
| 263 | * \return The primary reference frame for current layer. |
| 264 | */ |
Marco Paniconi | 42e1bdd | 2020-06-10 16:47:39 -0700 | [diff] [blame] | 265 | int av1_svc_primary_ref_frame(const struct AV1_COMP *const cpi); |
| 266 | |
Fyodor Kyslov | b790c9c | 2021-01-12 15:33:36 -0800 | [diff] [blame] | 267 | /*!\brief Get resolution for current layer. |
| 268 | * |
| 269 | * \ingroup SVC |
| 270 | * \param[in] width_org Original width, unscaled |
| 271 | * \param[in] height_org Original height, unscaled |
| 272 | * \param[in] num Numerator for the scale ratio |
| 273 | * \param[in] den Denominator for the scale ratio |
| 274 | * \param[in] width_out Output width, scaled for current layer |
| 275 | * \param[in] height_out Output height, scaled for current layer |
| 276 | * |
Wan-Teh Chang | 0defff8 | 2022-08-23 14:17:01 -0700 | [diff] [blame] | 277 | * \remark Nothing is returned. Instead the scaled width and height are set. |
Fyodor Kyslov | b790c9c | 2021-01-12 15:33:36 -0800 | [diff] [blame] | 278 | */ |
| 279 | void av1_get_layer_resolution(const int width_org, const int height_org, |
| 280 | const int num, const int den, int *width_out, |
| 281 | int *height_out); |
Marco Paniconi | e5de332 | 2021-03-22 22:03:17 -0700 | [diff] [blame] | 282 | |
| 283 | void av1_set_svc_fixed_mode(struct AV1_COMP *const cpi); |
| 284 | |
Marco Paniconi | 2b52ff1 | 2021-04-29 11:29:37 -0700 | [diff] [blame] | 285 | void av1_svc_check_reset_layer_rc_flag(struct AV1_COMP *const cpi); |
| 286 | |
Marco Paniconi | 6dfcab2 | 2022-10-31 00:41:42 -0700 | [diff] [blame] | 287 | void av1_svc_set_last_source(struct AV1_COMP *const cpi, |
| 288 | struct EncodeFrameInput *frame_input, |
| 289 | YV12_BUFFER_CONFIG *prev_source); |
Marco Paniconi | b5b1be8 | 2022-10-22 23:37:42 -0700 | [diff] [blame] | 290 | |
Marco Paniconi | 42b9273 | 2023-02-07 00:07:13 -0800 | [diff] [blame^] | 291 | void av1_svc_update_buffer_slot_refreshed(struct AV1_COMP *const cpi); |
| 292 | |
| 293 | int av1_svc_get_min_ref_dist(const struct AV1_COMP *cpi); |
| 294 | |
| 295 | void av1_svc_set_reference_was_previous(struct AV1_COMP *cpi); |
Marco Paniconi | 5b1e473 | 2019-08-08 18:57:53 -0700 | [diff] [blame] | 296 | #ifdef __cplusplus |
| 297 | } // extern "C" |
| 298 | #endif |
| 299 | |
| 300 | #endif // AOM_AV1_ENCODER_SVC_LAYERCONTEXT_H_ |