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 | 0d59418 | 2023-09-27 12:17:52 -0700 | [diff] [blame] | 142 | |
| 143 | /*! |
| 144 | * Flag to indicate that current spatial layer has a lower quality layer |
| 145 | * (at the same timestamp) that can be used as a reference. |
| 146 | * Lower quality layer refers to the same resolution but encoded at |
| 147 | * different/lower bitrate. |
| 148 | */ |
| 149 | int has_lower_quality_layer; |
Marco Paniconi | 5b1e473 | 2019-08-08 18:57:53 -0700 | [diff] [blame] | 150 | } SVC; |
| 151 | |
| 152 | struct AV1_COMP; |
Marco Paniconi | 6dfcab2 | 2022-10-31 00:41:42 -0700 | [diff] [blame] | 153 | struct EncodeFrameInput; |
Marco Paniconi | 5b1e473 | 2019-08-08 18:57:53 -0700 | [diff] [blame] | 154 | |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 155 | /*!\brief Initialize layer context data from init_config(). |
| 156 | * |
| 157 | * \ingroup SVC |
| 158 | * \callgraph |
| 159 | * \callergraph |
| 160 | * |
| 161 | * \param[in] cpi Top level encoder structure |
| 162 | * |
Wan-Teh Chang | 0defff8 | 2022-08-23 14:17:01 -0700 | [diff] [blame] | 163 | * \remark Nothing returned. Set cpi->svc. |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 164 | */ |
Marco Paniconi | 5b1e473 | 2019-08-08 18:57:53 -0700 | [diff] [blame] | 165 | void av1_init_layer_context(struct AV1_COMP *const cpi); |
| 166 | |
Deepa K G | 5c61149 | 2022-08-21 17:39:43 +0530 | [diff] [blame] | 167 | /*!\brief Allocate layer context data. |
| 168 | * |
| 169 | * \ingroup SVC |
| 170 | * \callgraph |
| 171 | * \callergraph |
| 172 | * |
| 173 | * \param[in] cpi Top level encoder structure |
| 174 | * \param[in] num_layers Number of layers to be allocated |
| 175 | * |
James Zern | ff135dc | 2022-12-06 15:23:51 -0800 | [diff] [blame] | 176 | * \remark Allocates memory for cpi->svc.layer_context. |
| 177 | * \return True on success, false on allocation failure. |
Deepa K G | 5c61149 | 2022-08-21 17:39:43 +0530 | [diff] [blame] | 178 | */ |
James Zern | ff135dc | 2022-12-06 15:23:51 -0800 | [diff] [blame] | 179 | 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] | 180 | |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 181 | /*!\brief Update the layer context from a change_config() call. |
| 182 | * |
| 183 | * \ingroup SVC |
| 184 | * \callgraph |
| 185 | * \callergraph |
| 186 | * |
| 187 | * \param[in] cpi Top level encoder structure |
| 188 | * \param[in] target_bandwidth Total target bandwidth |
| 189 | * |
Wan-Teh Chang | 0defff8 | 2022-08-23 14:17:01 -0700 | [diff] [blame] | 190 | * \remark Nothing returned. Buffer level for each layer is set. |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 191 | */ |
Marco Paniconi | 5b1e473 | 2019-08-08 18:57:53 -0700 | [diff] [blame] | 192 | void av1_update_layer_context_change_config(struct AV1_COMP *const cpi, |
Jerome Jiang | f54337a | 2019-08-15 09:28:58 -0700 | [diff] [blame] | 193 | const int64_t target_bandwidth); |
Marco Paniconi | 5b1e473 | 2019-08-08 18:57:53 -0700 | [diff] [blame] | 194 | |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 195 | /*!\brief Prior to encoding the frame, update framerate-related quantities |
| 196 | for the current temporal layer. |
| 197 | * |
| 198 | * \ingroup SVC |
| 199 | * \callgraph |
| 200 | * \callergraph |
| 201 | * |
| 202 | * \param[in] cpi Top level encoder structure |
| 203 | * |
Wan-Teh Chang | 0defff8 | 2022-08-23 14:17:01 -0700 | [diff] [blame] | 204 | * \remark Nothing returned. Frame related quantities for current temporal |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 205 | layer are updated. |
| 206 | */ |
Marco Paniconi | 5b1e473 | 2019-08-08 18:57:53 -0700 | [diff] [blame] | 207 | void av1_update_temporal_layer_framerate(struct AV1_COMP *const cpi); |
| 208 | |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 209 | /*!\brief Prior to encoding the frame, set the layer context, for the current |
| 210 | layer to be encoded, to the cpi struct. |
| 211 | * |
| 212 | * \ingroup SVC |
| 213 | * \callgraph |
| 214 | * \callergraph |
| 215 | * |
| 216 | * \param[in] cpi Top level encoder structure |
| 217 | * |
Wan-Teh Chang | 0defff8 | 2022-08-23 14:17:01 -0700 | [diff] [blame] | 218 | * \remark Nothing returned. Layer context for current layer is set. |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 219 | */ |
Marco Paniconi | 5b1e473 | 2019-08-08 18:57:53 -0700 | [diff] [blame] | 220 | void av1_restore_layer_context(struct AV1_COMP *const cpi); |
| 221 | |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 222 | /*!\brief Save the layer context after encoding the frame. |
| 223 | * |
| 224 | * \ingroup SVC |
| 225 | * \callgraph |
| 226 | * \callergraph |
| 227 | * |
| 228 | * \param[in] cpi Top level encoder structure |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 229 | */ |
Marco Paniconi | 5b1e473 | 2019-08-08 18:57:53 -0700 | [diff] [blame] | 230 | void av1_save_layer_context(struct AV1_COMP *const cpi); |
| 231 | |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 232 | /*!\brief Free the memory used for cyclic refresh in layer context. |
| 233 | * |
| 234 | * \ingroup SVC |
| 235 | * \callgraph |
| 236 | * \callergraph |
| 237 | * |
| 238 | * \param[in] cpi Top level encoder structure |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 239 | */ |
Marco Paniconi | 5b1e473 | 2019-08-08 18:57:53 -0700 | [diff] [blame] | 240 | void av1_free_svc_cyclic_refresh(struct AV1_COMP *const cpi); |
| 241 | |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 242 | /*!\brief Reset on key frame: reset counters, references and buffer updates. |
| 243 | * |
| 244 | * \ingroup SVC |
| 245 | * \callgraph |
| 246 | * \callergraph |
| 247 | * |
| 248 | * \param[in] cpi Top level encoder structure |
| 249 | * \param[in] is_key Whether current layer is key frame |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 250 | */ |
Marco Paniconi | 5b1e473 | 2019-08-08 18:57:53 -0700 | [diff] [blame] | 251 | void av1_svc_reset_temporal_layers(struct AV1_COMP *const cpi, int is_key); |
| 252 | |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 253 | /*!\brief Before encoding, set resolutions and allocate compressor data. |
| 254 | * |
| 255 | * \ingroup SVC |
| 256 | * \callgraph |
| 257 | * \callergraph |
| 258 | * |
| 259 | * \param[in] cpi Top level encoder structure |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 260 | */ |
Marco Paniconi | 6397132 | 2019-08-15 21:32:05 -0700 | [diff] [blame] | 261 | void av1_one_pass_cbr_svc_start_layer(struct AV1_COMP *const cpi); |
| 262 | |
Jerome Jiang | 66e7624 | 2020-07-09 11:38:19 -0700 | [diff] [blame] | 263 | /*!\brief Get primary reference frame for current layer |
| 264 | * |
| 265 | * \ingroup SVC |
| 266 | * \callgraph |
| 267 | * \callergraph |
| 268 | * |
| 269 | * \param[in] cpi Top level encoder structure |
| 270 | * |
| 271 | * \return The primary reference frame for current layer. |
| 272 | */ |
Marco Paniconi | 42e1bdd | 2020-06-10 16:47:39 -0700 | [diff] [blame] | 273 | int av1_svc_primary_ref_frame(const struct AV1_COMP *const cpi); |
| 274 | |
Fyodor Kyslov | b790c9c | 2021-01-12 15:33:36 -0800 | [diff] [blame] | 275 | /*!\brief Get resolution for current layer. |
| 276 | * |
| 277 | * \ingroup SVC |
| 278 | * \param[in] width_org Original width, unscaled |
| 279 | * \param[in] height_org Original height, unscaled |
| 280 | * \param[in] num Numerator for the scale ratio |
| 281 | * \param[in] den Denominator for the scale ratio |
| 282 | * \param[in] width_out Output width, scaled for current layer |
| 283 | * \param[in] height_out Output height, scaled for current layer |
| 284 | * |
Wan-Teh Chang | 0defff8 | 2022-08-23 14:17:01 -0700 | [diff] [blame] | 285 | * \remark Nothing is returned. Instead the scaled width and height are set. |
Fyodor Kyslov | b790c9c | 2021-01-12 15:33:36 -0800 | [diff] [blame] | 286 | */ |
| 287 | void av1_get_layer_resolution(const int width_org, const int height_org, |
| 288 | const int num, const int den, int *width_out, |
| 289 | int *height_out); |
Marco Paniconi | e5de332 | 2021-03-22 22:03:17 -0700 | [diff] [blame] | 290 | |
| 291 | void av1_set_svc_fixed_mode(struct AV1_COMP *const cpi); |
| 292 | |
Marco Paniconi | 2b52ff1 | 2021-04-29 11:29:37 -0700 | [diff] [blame] | 293 | void av1_svc_check_reset_layer_rc_flag(struct AV1_COMP *const cpi); |
| 294 | |
Marco Paniconi | 6dfcab2 | 2022-10-31 00:41:42 -0700 | [diff] [blame] | 295 | void av1_svc_set_last_source(struct AV1_COMP *const cpi, |
| 296 | struct EncodeFrameInput *frame_input, |
| 297 | YV12_BUFFER_CONFIG *prev_source); |
Marco Paniconi | b5b1be8 | 2022-10-22 23:37:42 -0700 | [diff] [blame] | 298 | |
Marco Paniconi | 42b9273 | 2023-02-07 00:07:13 -0800 | [diff] [blame] | 299 | void av1_svc_update_buffer_slot_refreshed(struct AV1_COMP *const cpi); |
| 300 | |
| 301 | int av1_svc_get_min_ref_dist(const struct AV1_COMP *cpi); |
| 302 | |
| 303 | void av1_svc_set_reference_was_previous(struct AV1_COMP *cpi); |
Marco Paniconi | 5b1e473 | 2019-08-08 18:57:53 -0700 | [diff] [blame] | 304 | #ifdef __cplusplus |
| 305 | } // extern "C" |
| 306 | #endif |
| 307 | |
| 308 | #endif // AOM_AV1_ENCODER_SVC_LAYERCONTEXT_H_ |