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