Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1 | /* |
Yaowu Xu | 2ab7ff0 | 2016-09-02 12:04:54 -0700 | [diff] [blame] | 2 | * Copyright (c) 2016, Alliance for Open Media. All rights reserved |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 3 | * |
Yaowu Xu | 2ab7ff0 | 2016-09-02 12:04:54 -0700 | [diff] [blame] | 4 | * This source code is subject to the terms of the BSD 2 Clause License and |
| 5 | * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License |
| 6 | * was not distributed with this source code in the LICENSE file, you can |
| 7 | * obtain it at www.aomedia.org/license/software. If the Alliance for Open |
| 8 | * Media Patent License 1.0 was not distributed with this source code in the |
| 9 | * PATENTS file, you can obtain it at www.aomedia.org/license/patent. |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 10 | */ |
| 11 | |
James Zern | e1cbb13 | 2018-08-22 14:10:36 -0700 | [diff] [blame] | 12 | #ifndef AOM_AV1_ENCODER_FIRSTPASS_H_ |
| 13 | #define AOM_AV1_ENCODER_FIRSTPASS_H_ |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 14 | |
Wan-Teh Chang | f2d15ee | 2020-03-10 09:24:43 -0700 | [diff] [blame] | 15 | #include "av1/common/av1_common_int.h" |
Zoe Liu | 43486e7 | 2017-09-04 03:44:27 -0700 | [diff] [blame] | 16 | #include "av1/common/enums.h" |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 17 | #include "av1/encoder/lookahead.h" |
| 18 | #include "av1/encoder/ratectrl.h" |
| 19 | |
| 20 | #ifdef __cplusplus |
| 21 | extern "C" { |
| 22 | #endif |
| 23 | |
David Turner | 0fa8c49 | 2019-02-06 16:38:13 +0000 | [diff] [blame] | 24 | #define DOUBLE_DIVIDE_CHECK(x) ((x) < 0 ? (x)-0.000001 : (x) + 0.000001) |
| 25 | |
Di Chen | 53a04f6 | 2017-06-23 13:47:56 -0700 | [diff] [blame] | 26 | #define MIN_ZERO_MOTION 0.95 |
| 27 | #define MAX_SR_CODED_ERROR 40 |
| 28 | #define MAX_RAW_ERR_VAR 2000 |
| 29 | #define MIN_MV_IN_OUT 0.4 |
Di Chen | 53a04f6 | 2017-06-23 13:47:56 -0700 | [diff] [blame] | 30 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 31 | #define VLOW_MOTION_THRESHOLD 950 |
| 32 | |
Cheng Chen | a7fd6f1 | 2020-06-08 10:46:30 -0700 | [diff] [blame] | 33 | /*! |
| 34 | * \brief The stucture of acummulated frame stats in the first pass. |
Bohan Li | 063e4e5 | 2021-06-18 13:59:38 -0700 | [diff] [blame] | 35 | * |
| 36 | * Errors (coded_error, intra_error, etc.) and counters (new_mv_count) are |
| 37 | * normalized to each MB. MV related stats (MVc, MVr, etc.) are normalized to |
| 38 | * the frame width and height. See function normalize_firstpass_stats. |
Cheng Chen | a7fd6f1 | 2020-06-08 10:46:30 -0700 | [diff] [blame] | 39 | */ |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 40 | typedef struct { |
Cheng Chen | a7fd6f1 | 2020-06-08 10:46:30 -0700 | [diff] [blame] | 41 | /*! |
| 42 | * Frame number in display order, if stats are for a single frame. |
| 43 | * No real meaning for a collection of frames. |
| 44 | */ |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 45 | double frame; |
Cheng Chen | a7fd6f1 | 2020-06-08 10:46:30 -0700 | [diff] [blame] | 46 | /*! |
| 47 | * Weight assigned to this frame (or total weight for the collection of |
| 48 | * frames) currently based on intra factor and brightness factor. This is used |
| 49 | * to distribute bits betweeen easier and harder frames. |
| 50 | */ |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 51 | double weight; |
Cheng Chen | a7fd6f1 | 2020-06-08 10:46:30 -0700 | [diff] [blame] | 52 | /*! |
| 53 | * Intra prediction error. |
| 54 | */ |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 55 | double intra_error; |
Cheng Chen | a7fd6f1 | 2020-06-08 10:46:30 -0700 | [diff] [blame] | 56 | /*! |
| 57 | * Average wavelet energy computed using Discrete Wavelet Transform (DWT). |
| 58 | */ |
Yue Chen | 2dbdbc9 | 2018-05-24 09:54:01 -0700 | [diff] [blame] | 59 | double frame_avg_wavelet_energy; |
Cheng Chen | a7fd6f1 | 2020-06-08 10:46:30 -0700 | [diff] [blame] | 60 | /*! |
| 61 | * Best of intra pred error and inter pred error using last frame as ref. |
| 62 | */ |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 63 | double coded_error; |
Cheng Chen | a7fd6f1 | 2020-06-08 10:46:30 -0700 | [diff] [blame] | 64 | /*! |
| 65 | * Best of intra pred error and inter pred error using golden frame as ref. |
| 66 | */ |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 67 | double sr_coded_error; |
Cheng Chen | a7fd6f1 | 2020-06-08 10:46:30 -0700 | [diff] [blame] | 68 | /*! |
Cheng Chen | a7fd6f1 | 2020-06-08 10:46:30 -0700 | [diff] [blame] | 69 | * Percentage of blocks with inter pred error < intra pred error. |
| 70 | */ |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 71 | double pcnt_inter; |
Cheng Chen | a7fd6f1 | 2020-06-08 10:46:30 -0700 | [diff] [blame] | 72 | /*! |
| 73 | * Percentage of blocks using (inter prediction and) non-zero motion vectors. |
| 74 | */ |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 75 | double pcnt_motion; |
Cheng Chen | a7fd6f1 | 2020-06-08 10:46:30 -0700 | [diff] [blame] | 76 | /*! |
| 77 | * Percentage of blocks where golden frame was better than last or intra: |
| 78 | * inter pred error using golden frame < inter pred error using last frame and |
| 79 | * inter pred error using golden frame < intra pred error |
| 80 | */ |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 81 | double pcnt_second_ref; |
Cheng Chen | a7fd6f1 | 2020-06-08 10:46:30 -0700 | [diff] [blame] | 82 | /*! |
Cheng Chen | a7fd6f1 | 2020-06-08 10:46:30 -0700 | [diff] [blame] | 83 | * Percentage of blocks where intra and inter prediction errors were very |
| 84 | * close. Note that this is a 'weighted count', that is, the so blocks may be |
| 85 | * weighted by how close the two errors were. |
| 86 | */ |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 87 | double pcnt_neutral; |
Cheng Chen | a7fd6f1 | 2020-06-08 10:46:30 -0700 | [diff] [blame] | 88 | /*! |
| 89 | * Percentage of blocks that have almost no intra error residual |
| 90 | * (i.e. are in effect completely flat and untextured in the intra |
| 91 | * domain). In natural videos this is uncommon, but it is much more |
| 92 | * common in animations, graphics and screen content, so may be used |
| 93 | * as a signal to detect these types of content. |
| 94 | */ |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 95 | double intra_skip_pct; |
Cheng Chen | a7fd6f1 | 2020-06-08 10:46:30 -0700 | [diff] [blame] | 96 | /*! |
| 97 | * Image mask rows top and bottom. |
| 98 | */ |
Urvang Joshi | 87a8394 | 2019-03-28 12:35:25 -0700 | [diff] [blame] | 99 | double inactive_zone_rows; |
Cheng Chen | a7fd6f1 | 2020-06-08 10:46:30 -0700 | [diff] [blame] | 100 | /*! |
| 101 | * Image mask columns at left and right edges. |
| 102 | */ |
Urvang Joshi | 87a8394 | 2019-03-28 12:35:25 -0700 | [diff] [blame] | 103 | double inactive_zone_cols; |
Cheng Chen | a7fd6f1 | 2020-06-08 10:46:30 -0700 | [diff] [blame] | 104 | /*! |
| 105 | * Average of row motion vectors. |
| 106 | */ |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 107 | double MVr; |
Cheng Chen | a7fd6f1 | 2020-06-08 10:46:30 -0700 | [diff] [blame] | 108 | /*! |
| 109 | * Mean of absolute value of row motion vectors. |
| 110 | */ |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 111 | double mvr_abs; |
Cheng Chen | a7fd6f1 | 2020-06-08 10:46:30 -0700 | [diff] [blame] | 112 | /*! |
| 113 | * Mean of column motion vectors. |
| 114 | */ |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 115 | double MVc; |
Cheng Chen | a7fd6f1 | 2020-06-08 10:46:30 -0700 | [diff] [blame] | 116 | /*! |
| 117 | * Mean of absolute value of column motion vectors. |
| 118 | */ |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 119 | double mvc_abs; |
Cheng Chen | a7fd6f1 | 2020-06-08 10:46:30 -0700 | [diff] [blame] | 120 | /*! |
| 121 | * Variance of row motion vectors. |
| 122 | */ |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 123 | double MVrv; |
Cheng Chen | a7fd6f1 | 2020-06-08 10:46:30 -0700 | [diff] [blame] | 124 | /*! |
| 125 | * Variance of column motion vectors. |
| 126 | */ |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 127 | double MVcv; |
Cheng Chen | a7fd6f1 | 2020-06-08 10:46:30 -0700 | [diff] [blame] | 128 | /*! |
| 129 | * Value in range [-1,1] indicating fraction of row and column motion vectors |
| 130 | * that point inwards (negative MV value) or outwards (positive MV value). |
| 131 | * For example, value of 1 indicates, all row/column MVs are inwards. |
| 132 | */ |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 133 | double mv_in_out_count; |
Cheng Chen | a7fd6f1 | 2020-06-08 10:46:30 -0700 | [diff] [blame] | 134 | /*! |
| 135 | * Count of unique non-zero motion vectors. |
| 136 | */ |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 137 | double new_mv_count; |
Cheng Chen | a7fd6f1 | 2020-06-08 10:46:30 -0700 | [diff] [blame] | 138 | /*! |
| 139 | * Duration of the frame / collection of frames. |
| 140 | */ |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 141 | double duration; |
Cheng Chen | a7fd6f1 | 2020-06-08 10:46:30 -0700 | [diff] [blame] | 142 | /*! |
| 143 | * 1.0 if stats are for a single frame, OR |
| 144 | * Number of frames in this collection for which the stats are accumulated. |
| 145 | */ |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 146 | double count; |
Cheng Chen | a7fd6f1 | 2020-06-08 10:46:30 -0700 | [diff] [blame] | 147 | /*! |
| 148 | * standard deviation for (0, 0) motion prediction error |
| 149 | */ |
Di Chen | 53a04f6 | 2017-06-23 13:47:56 -0700 | [diff] [blame] | 150 | double raw_error_stdev; |
Bohan Li | dc1c16c | 2021-04-07 13:29:00 -0700 | [diff] [blame] | 151 | /*! |
| 152 | * Whether the frame contains a flash |
| 153 | */ |
| 154 | int64_t is_flash; |
| 155 | /*! |
| 156 | * Estimated noise variance |
| 157 | */ |
| 158 | double noise_var; |
| 159 | /*! |
| 160 | * Correlation coefficient with the previous frame |
| 161 | */ |
| 162 | double cor_coeff; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 163 | } FIRSTPASS_STATS; |
| 164 | |
Cheng Chen | a7fd6f1 | 2020-06-08 10:46:30 -0700 | [diff] [blame] | 165 | /*!\cond */ |
Angie Chiang | c798da5 | 2021-07-22 18:07:06 -0700 | [diff] [blame] | 166 | typedef struct { |
| 167 | /*! |
| 168 | * An static buffer that will be used when no ext_stats_buf is assigned. |
| 169 | * The ext_stats_buf is assigned through av1_firstpass_info_init() when |
| 170 | * user already has an pre-existing firstpass stats that store in an |
| 171 | * external buffer. The ext_stats_buf is usually use in two pass mode. |
| 172 | * When using one pass mode, we generate "firstpass" stats and |
| 173 | * encode the video in the same pass. In this scenario, the stats will |
| 174 | * be pushed and popped from static_stats_buf. |
| 175 | */ |
| 176 | FIRSTPASS_STATS static_stats_buf[MAX_LAP_BUFFERS]; |
| 177 | /*! |
| 178 | * A pointer point to first pass stats. |
| 179 | * Note that this buffer will be used as ring buffer. |
| 180 | */ |
| 181 | FIRSTPASS_STATS *stats_buf; |
| 182 | /*! |
| 183 | * size of stats_buf |
| 184 | */ |
| 185 | int stats_buf_size; |
| 186 | /*! |
| 187 | * start_index of the current frame's stats |
| 188 | */ |
| 189 | int start_index; |
| 190 | /*! |
| 191 | * count available stats stored in stats_buf |
| 192 | */ |
| 193 | int stats_count; |
| 194 | } FIRSTPASS_INFO; |
| 195 | |
| 196 | /*!\brief Init firstpass_info |
| 197 | * |
| 198 | * If using ext_stats_buf, the buffer needs to stay available during encoding |
| 199 | * process. |
| 200 | * |
| 201 | * \ingroup rate_control |
| 202 | * \param[out] firstpass_info struct of firstpass_info. |
| 203 | * \param[in] ext_stats_buf external stats buffer. Pass in NULL if |
| 204 | * choose to use internal static_stats_buf. |
| 205 | * \param[in] ext_stats_buf_size external stats buffer size. Pass in 0 if |
| 206 | * choose to use internal static_stats_buf. \return status |
| 207 | */ |
| 208 | aom_codec_err_t av1_firstpass_info_init(FIRSTPASS_INFO *firstpass_info, |
| 209 | FIRSTPASS_STATS *ext_stats_buf, |
| 210 | int ext_stats_buf_size); |
| 211 | |
| 212 | /*!\brief Pop a stats from firstpass_info |
| 213 | * |
| 214 | * \ingroup rate_control |
| 215 | * \param[out] firstpass_info struct of firstpass_info. |
| 216 | * \param[out] output_stats output stats |
| 217 | * \return status |
| 218 | */ |
| 219 | aom_codec_err_t av1_firstpass_info_pop(FIRSTPASS_INFO *firstpass_info, |
| 220 | FIRSTPASS_STATS *output_stats); |
| 221 | |
| 222 | /*!\brief Push a stats from firstpass_info |
| 223 | * |
| 224 | * Note that he input stats will be coppied into firstpass_copy. |
| 225 | * \ingroup rate_control |
| 226 | * \param[out] firstpass_info struct of firstpass_info. |
| 227 | * \param[in] input_stats input stats |
| 228 | * \return status |
| 229 | */ |
| 230 | aom_codec_err_t av1_firstpass_info_push(FIRSTPASS_INFO *firstpass_info, |
| 231 | const FIRSTPASS_STATS *input_stats); |
| 232 | |
| 233 | /*!\brief Peak a stats from firstpass_info |
| 234 | * |
| 235 | * Note that he input stats will be coppied into firstpass_copy. |
| 236 | * \ingroup rate_control |
| 237 | * \param[in] firstpass_info struct of firstpass_info. |
| 238 | * \param[in] stats_index_offset index offset. |
| 239 | * \param[out] out_stats input stats. |
| 240 | * \return status |
| 241 | */ |
| 242 | aom_codec_err_t av1_firstpass_info_peak(const FIRSTPASS_INFO *firstpass_info, |
| 243 | int stats_index_offset, |
| 244 | FIRSTPASS_STATS *output_stats); |
Cheng Chen | a7fd6f1 | 2020-06-08 10:46:30 -0700 | [diff] [blame] | 245 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 246 | #define FC_ANIMATION_THRESH 0.15 |
Satish Kumar Suman | 4667aa1 | 2018-12-14 18:28:19 +0530 | [diff] [blame] | 247 | enum { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 248 | FC_NORMAL = 0, |
| 249 | FC_GRAPHICS_ANIMATION = 1, |
| 250 | FRAME_CONTENT_TYPES = 2 |
Satish Kumar Suman | 4667aa1 | 2018-12-14 18:28:19 +0530 | [diff] [blame] | 251 | } UENUM1BYTE(FRAME_CONTENT_TYPE); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 252 | |
Paul Wilkins | e8c76eb | 2020-06-30 17:24:11 +0100 | [diff] [blame] | 253 | /*!\endcond */ |
| 254 | /*! |
Wan-Teh Chang | 247dd54 | 2020-10-08 12:37:47 -0700 | [diff] [blame] | 255 | * \brief Data related to the current GF/ARF group and the |
Paul Wilkins | e8c76eb | 2020-06-30 17:24:11 +0100 | [diff] [blame] | 256 | * individual frames within the group |
| 257 | */ |
Kavi Ramamurthy | 291ef25 | 2021-06-09 17:07:30 +0000 | [diff] [blame] | 258 | typedef struct GF_GROUP { |
Paul Wilkins | e8c76eb | 2020-06-30 17:24:11 +0100 | [diff] [blame] | 259 | /*!\cond */ |
Wan-Teh Chang | 1287d35 | 2020-10-08 09:40:17 -0700 | [diff] [blame] | 260 | // Frame update type, e.g. ARF/GF/LF/Overlay |
Urvang Joshi | 2e4aaf2 | 2019-05-08 11:38:00 -0700 | [diff] [blame] | 261 | FRAME_UPDATE_TYPE update_type[MAX_STATIC_GF_GROUP_LENGTH]; |
| 262 | unsigned char arf_src_offset[MAX_STATIC_GF_GROUP_LENGTH]; |
Jingning Han | 9b8051e | 2020-02-24 22:06:52 -0800 | [diff] [blame] | 263 | // The number of frames displayed so far within the GOP at a given coding |
| 264 | // frame. |
| 265 | unsigned char cur_frame_idx[MAX_STATIC_GF_GROUP_LENGTH]; |
Jingning Han | 7a20235 | 2019-07-02 14:40:53 -0700 | [diff] [blame] | 266 | int layer_depth[MAX_STATIC_GF_GROUP_LENGTH]; |
Jingning Han | 3f9c45d | 2019-07-26 10:38:38 -0700 | [diff] [blame] | 267 | int arf_boost[MAX_STATIC_GF_GROUP_LENGTH]; |
Jingning Han | 237d46f | 2019-08-16 13:22:09 -0700 | [diff] [blame] | 268 | int max_layer_depth; |
| 269 | int max_layer_depth_allowed; |
Sarah Parker | fce5014 | 2019-06-03 16:52:07 -0700 | [diff] [blame] | 270 | // This is currently only populated for AOM_Q mode |
Angie Chiang | bb20160 | 2021-07-13 18:50:15 -0700 | [diff] [blame] | 271 | int q_val[MAX_STATIC_GF_GROUP_LENGTH]; |
Urvang Joshi | 2e4aaf2 | 2019-05-08 11:38:00 -0700 | [diff] [blame] | 272 | int bit_allocation[MAX_STATIC_GF_GROUP_LENGTH]; |
Wan-Teh Chang | 1287d35 | 2020-10-08 09:40:17 -0700 | [diff] [blame] | 273 | // The frame coding type - inter/intra frame |
Jingning Han | f842039 | 2020-08-20 14:42:08 -0700 | [diff] [blame] | 274 | FRAME_TYPE frame_type[MAX_STATIC_GF_GROUP_LENGTH]; |
Wan-Teh Chang | 1287d35 | 2020-10-08 09:40:17 -0700 | [diff] [blame] | 275 | // The reference frame buffer control - update or reset |
Jingning Han | f842039 | 2020-08-20 14:42:08 -0700 | [diff] [blame] | 276 | REFBUF_STATE refbuf_state[MAX_STATIC_GF_GROUP_LENGTH]; |
bohanli | 1629a4b | 2020-06-11 16:15:14 -0700 | [diff] [blame] | 277 | int arf_index; // the index in the gf group of ARF, if no arf, then -1 |
Wan-Teh Chang | 1287d35 | 2020-10-08 09:40:17 -0700 | [diff] [blame] | 278 | int size; // The total length of a GOP |
Remya Prakasan | 9f54e5c | 2021-04-21 15:27:34 +0530 | [diff] [blame] | 279 | #if CONFIG_FRAME_PARALLEL_ENCODE |
| 280 | // Indicates the level of parallelism in frame parallel encodes. |
| 281 | // 0 : frame is independently encoded (not part of parallel encodes). |
| 282 | // 1 : frame is the first in encode order in a given parallel encode set. |
| 283 | // 2 : frame occurs later in encode order in a given parallel encode set. |
| 284 | int frame_parallel_level[MAX_STATIC_GF_GROUP_LENGTH]; |
| 285 | // Indicates whether a frame should act as non-reference frame. |
| 286 | // 0 : frame is a reference frame. |
| 287 | // 1 : frame is a non-reference frame. |
| 288 | int is_frame_non_ref[MAX_STATIC_GF_GROUP_LENGTH]; |
Mufaddal Chakera | 97f9271 | 2021-05-21 15:10:33 +0530 | [diff] [blame] | 289 | |
| 290 | // The offset into lookahead_ctx for choosing |
| 291 | // source of frame parallel encodes. |
| 292 | int src_offset[MAX_STATIC_GF_GROUP_LENGTH]; |
Remya Prakasan | e90f8de | 2021-06-08 18:31:59 +0530 | [diff] [blame] | 293 | #if CONFIG_FRAME_PARALLEL_ENCODE_2 |
| 294 | // Stores the display order hint of each frame in the current GF_GROUP. |
| 295 | int display_idx[MAX_STATIC_GF_GROUP_LENGTH]; |
Remya Prakasan | a05ccde | 2021-06-07 21:24:11 +0530 | [diff] [blame] | 296 | // Stores the display order hint of the frames not to be |
| 297 | // refreshed by the current frame. |
| 298 | int skip_frame_refresh[MAX_STATIC_GF_GROUP_LENGTH][REF_FRAMES]; |
Remya Prakasan | fa7262a | 2021-05-29 16:00:30 +0530 | [diff] [blame] | 299 | // Stores the display order hint of the frame to be excluded during reference |
| 300 | // assignment. |
| 301 | int skip_frame_as_ref[MAX_STATIC_GF_GROUP_LENGTH]; |
Remya Prakasan | e90f8de | 2021-06-08 18:31:59 +0530 | [diff] [blame] | 302 | #endif // CONFIG_FRAME_PARALLEL_ENCODE_2 |
Remya Prakasan | 9f54e5c | 2021-04-21 15:27:34 +0530 | [diff] [blame] | 303 | #endif // CONFIG_FRAME_PARALLEL_ENCODE |
Paul Wilkins | e8c76eb | 2020-06-30 17:24:11 +0100 | [diff] [blame] | 304 | /*!\endcond */ |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 305 | } GF_GROUP; |
Paul Wilkins | e8c76eb | 2020-06-30 17:24:11 +0100 | [diff] [blame] | 306 | /*!\cond */ |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 307 | |
| 308 | typedef struct { |
Jingning Han | 9af02fa | 2020-08-20 23:01:01 -0700 | [diff] [blame] | 309 | // Track if the last frame in a GOP has higher quality. |
| 310 | int arf_gf_boost_lst; |
| 311 | } GF_STATE; |
| 312 | |
| 313 | typedef struct { |
Akshata Jadhav | a49be17 | 2019-12-18 00:03:53 +0530 | [diff] [blame] | 314 | FIRSTPASS_STATS *stats_in_start; |
| 315 | FIRSTPASS_STATS *stats_in_end; |
| 316 | FIRSTPASS_STATS *stats_in_buf_end; |
Aasaipriya | eb417c1 | 2020-04-07 12:08:24 +0530 | [diff] [blame] | 317 | FIRSTPASS_STATS *total_stats; |
| 318 | FIRSTPASS_STATS *total_left_stats; |
Akshata Jadhav | a49be17 | 2019-12-18 00:03:53 +0530 | [diff] [blame] | 319 | } STATS_BUFFER_CTX; |
| 320 | |
Paul Wilkins | 83cfad4 | 2020-06-26 12:38:07 +0100 | [diff] [blame] | 321 | /*!\endcond */ |
| 322 | |
| 323 | /*! |
| 324 | * \brief Two pass status and control data. |
| 325 | */ |
Akshata Jadhav | a49be17 | 2019-12-18 00:03:53 +0530 | [diff] [blame] | 326 | typedef struct { |
Paul Wilkins | 83cfad4 | 2020-06-26 12:38:07 +0100 | [diff] [blame] | 327 | /*!\cond */ |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 328 | unsigned int section_intra_rating; |
Urvang Joshi | 38b7e84 | 2019-05-01 11:27:47 -0700 | [diff] [blame] | 329 | // Circular queue of first pass stats stored for most recent frames. |
| 330 | // cpi->output_pkt_list[i].data.twopass_stats.buf points to actual data stored |
| 331 | // here. |
Akshata Jadhav | 4be6511 | 2019-12-18 00:26:25 +0530 | [diff] [blame] | 332 | FIRSTPASS_STATS *frame_stats_arr[MAX_LAP_BUFFERS + 1]; |
Urvang Joshi | 38b7e84 | 2019-05-01 11:27:47 -0700 | [diff] [blame] | 333 | int frame_stats_next_idx; // Index to next unused element in frame_stats_arr. |
Akshata Jadhav | a49be17 | 2019-12-18 00:03:53 +0530 | [diff] [blame] | 334 | STATS_BUFFER_CTX *stats_buf_ctx; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 335 | int first_pass_done; |
| 336 | int64_t bits_left; |
Debargha Mukherjee | d0b9bf7 | 2018-05-14 17:45:27 +0000 | [diff] [blame] | 337 | double modified_error_min; |
| 338 | double modified_error_max; |
| 339 | double modified_error_left; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 340 | |
| 341 | // Projected total bits available for a key frame group of frames |
| 342 | int64_t kf_group_bits; |
| 343 | |
| 344 | // Error score of frames still to be coded in kf group |
Bohan Li | 063e4e5 | 2021-06-18 13:59:38 -0700 | [diff] [blame] | 345 | double kf_group_error_left; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 346 | |
Paul Wilkins | 88fdf64 | 2019-07-31 12:29:48 +0100 | [diff] [blame] | 347 | // Over time correction for bits per macro block estimation |
| 348 | double bpm_factor; |
| 349 | |
| 350 | // Record of target and actual bits spent in current ARF group |
| 351 | int rolling_arf_group_target_bits; |
| 352 | int rolling_arf_group_actual_bits; |
| 353 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 354 | int sr_update_lag; |
| 355 | |
| 356 | int kf_zeromotion_pct; |
| 357 | int last_kfgroup_zeromotion_pct; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 358 | int extend_minq; |
| 359 | int extend_maxq; |
| 360 | int extend_minq_fast; |
Paul Wilkins | 83cfad4 | 2020-06-26 12:38:07 +0100 | [diff] [blame] | 361 | /*!\endcond */ |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 362 | } TWO_PASS; |
| 363 | |
Mufaddal Chakera | 55ea39b | 2021-07-07 15:25:37 +0530 | [diff] [blame] | 364 | /*! |
| 365 | * \brief Frame level Two pass status and control data. |
| 366 | */ |
| 367 | typedef struct { |
| 368 | /*!\cond */ |
| 369 | const FIRSTPASS_STATS *stats_in; |
Remya Prakasan | f54c2b9 | 2021-07-21 15:40:07 +0530 | [diff] [blame] | 370 | // Pointer to the stats of the current frame. |
| 371 | const FIRSTPASS_STATS *this_frame; |
Mufaddal Chakera | 55ea39b | 2021-07-07 15:25:37 +0530 | [diff] [blame] | 372 | double mb_av_energy; |
| 373 | // An indication of the content type of the current frame |
| 374 | FRAME_CONTENT_TYPE fr_content_type; |
| 375 | double frame_avg_haar_energy; |
| 376 | /*!\endcond */ |
| 377 | } TWO_PASS_FRAME; |
| 378 | |
Paul Wilkins | 83cfad4 | 2020-06-26 12:38:07 +0100 | [diff] [blame] | 379 | /*!\cond */ |
| 380 | |
Mufaddal Chakera | 6c3b6de | 2020-04-29 12:27:42 +0530 | [diff] [blame] | 381 | // This structure contains several key parameters to be accumulated for this |
| 382 | // frame. |
| 383 | typedef struct { |
| 384 | // Intra prediction error. |
| 385 | int64_t intra_error; |
| 386 | // Average wavelet energy computed using Discrete Wavelet Transform (DWT). |
| 387 | int64_t frame_avg_wavelet_energy; |
| 388 | // Best of intra pred error and inter pred error using last frame as ref. |
| 389 | int64_t coded_error; |
| 390 | // Best of intra pred error and inter pred error using golden frame as ref. |
| 391 | int64_t sr_coded_error; |
Mufaddal Chakera | 6c3b6de | 2020-04-29 12:27:42 +0530 | [diff] [blame] | 392 | // Count of motion vector. |
| 393 | int mv_count; |
| 394 | // Count of blocks that pick inter prediction (inter pred error is smaller |
| 395 | // than intra pred error). |
| 396 | int inter_count; |
| 397 | // Count of blocks that pick second ref (golden frame). |
| 398 | int second_ref_count; |
Mufaddal Chakera | 6c3b6de | 2020-04-29 12:27:42 +0530 | [diff] [blame] | 399 | // Count of blocks where the inter and intra are very close and very low. |
| 400 | double neutral_count; |
| 401 | // Count of blocks where intra error is very small. |
| 402 | int intra_skip_count; |
| 403 | // Start row. |
| 404 | int image_data_start_row; |
| 405 | // Count of unique non-zero motion vectors. |
| 406 | int new_mv_count; |
| 407 | // Sum of inward motion vectors. |
| 408 | int sum_in_vectors; |
| 409 | // Sum of motion vector row. |
| 410 | int sum_mvr; |
| 411 | // Sum of motion vector column. |
| 412 | int sum_mvc; |
| 413 | // Sum of absolute value of motion vector row. |
| 414 | int sum_mvr_abs; |
| 415 | // Sum of absolute value of motion vector column. |
| 416 | int sum_mvc_abs; |
| 417 | // Sum of the square of motion vector row. |
| 418 | int64_t sum_mvrs; |
| 419 | // Sum of the square of motion vector column. |
| 420 | int64_t sum_mvcs; |
| 421 | // A factor calculated using intra pred error. |
| 422 | double intra_factor; |
| 423 | // A factor that measures brightness. |
| 424 | double brightness_factor; |
| 425 | } FRAME_STATS; |
| 426 | |
| 427 | // This structure contains first pass data. |
| 428 | typedef struct { |
| 429 | // Buffer holding frame stats for all MACROBLOCKs. |
| 430 | // mb_stats[i] stores the FRAME_STATS of the ith |
| 431 | // MB in raster scan order. |
| 432 | FRAME_STATS *mb_stats; |
| 433 | // Buffer to store the prediction error of the (0,0) motion |
| 434 | // vector using the last source frame as the reference. |
| 435 | // raw_motion_err_list[i] stores the raw_motion_err of |
| 436 | // the ith MB in raster scan order. |
| 437 | int *raw_motion_err_list; |
| 438 | } FirstPassData; |
| 439 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 440 | struct AV1_COMP; |
David Turner | 475a313 | 2019-01-18 15:17:17 +0000 | [diff] [blame] | 441 | struct EncodeFrameParams; |
David Turner | 0fa8c49 | 2019-02-06 16:38:13 +0000 | [diff] [blame] | 442 | struct AV1EncoderConfig; |
Mufaddal Chakera | a7ff433 | 2020-04-28 15:10:49 +0530 | [diff] [blame] | 443 | struct TileDataEnc; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 444 | |
Mudassir Galagnath | 32e5416 | 2021-07-09 10:32:33 +0530 | [diff] [blame] | 445 | static INLINE int is_fp_wavelet_energy_invalid( |
| 446 | const FIRSTPASS_STATS *fp_stats) { |
Mufaddal Chakera | 55ea39b | 2021-07-07 15:25:37 +0530 | [diff] [blame] | 447 | assert(fp_stats != NULL); |
Mudassir Galagnath | 32e5416 | 2021-07-09 10:32:33 +0530 | [diff] [blame] | 448 | return (fp_stats->frame_avg_wavelet_energy < 0); |
| 449 | } |
| 450 | |
Deepa K G | c29630a | 2021-05-31 13:19:41 +0530 | [diff] [blame] | 451 | static INLINE BLOCK_SIZE get_fp_block_size(int is_screen_content_type) { |
| 452 | return (is_screen_content_type ? BLOCK_8X8 : BLOCK_16X16); |
| 453 | } |
| 454 | |
Cheng Chen | fd2c0cf | 2020-11-30 16:28:37 -0800 | [diff] [blame] | 455 | int av1_get_unit_rows_in_tile(TileInfo tile, const BLOCK_SIZE fp_block_size); |
| 456 | int av1_get_unit_cols_in_tile(TileInfo tile, const BLOCK_SIZE fp_block_size); |
Mufaddal Chakera | 65b6910 | 2020-05-01 04:07:13 +0530 | [diff] [blame] | 457 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 458 | void av1_rc_get_first_pass_params(struct AV1_COMP *cpi); |
Mufaddal Chakera | a7ff433 | 2020-04-28 15:10:49 +0530 | [diff] [blame] | 459 | void av1_first_pass_row(struct AV1_COMP *cpi, struct ThreadData *td, |
Cheng Chen | fd2c0cf | 2020-11-30 16:28:37 -0800 | [diff] [blame] | 460 | struct TileDataEnc *tile_data, const int mb_row, |
| 461 | const BLOCK_SIZE fp_block_size); |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 462 | void av1_end_first_pass(struct AV1_COMP *cpi); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 463 | |
David Turner | 0fa8c49 | 2019-02-06 16:38:13 +0000 | [diff] [blame] | 464 | void av1_twopass_zero_stats(FIRSTPASS_STATS *section); |
Aasaipriya | 240671e | 2020-04-16 16:50:21 +0530 | [diff] [blame] | 465 | void av1_accumulate_stats(FIRSTPASS_STATS *section, |
| 466 | const FIRSTPASS_STATS *frame); |
Cheng Chen | 7c26f2e | 2020-05-20 16:25:21 -0700 | [diff] [blame] | 467 | /*!\endcond */ |
| 468 | |
| 469 | /*!\brief AV1 first pass encoding. |
| 470 | * |
| 471 | * \ingroup rate_control |
| 472 | * This function is the first encoding pass for the two pass encoding mode. |
| 473 | * It encodes the whole video and collect essential information. |
| 474 | * Two pass encoding is an encoding mode in the reference software (libaom) |
| 475 | * of AV1 for high performance encoding. The first pass is a fast encoding |
| 476 | * process to collect essential information to help the second pass make |
| 477 | * encoding decisions and improve coding quality. The collected stats is used |
| 478 | * in rate control, for example, to determine frame cut, the position of |
| 479 | * alternative reference frame (ARF), etc. |
| 480 | * |
| 481 | * \param[in] cpi Top-level encoder structure |
| 482 | * \param[in] ts_duration Duration of the frame / collection of frames |
| 483 | * |
| 484 | * \return Nothing is returned. Instead, the "TWO_PASS" structure inside "cpi" |
| 485 | * is modified to store information computed in this function. |
| 486 | */ |
| 487 | void av1_first_pass(struct AV1_COMP *cpi, const int64_t ts_duration); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 488 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 489 | #ifdef __cplusplus |
| 490 | } // extern "C" |
| 491 | #endif |
| 492 | |
James Zern | e1cbb13 | 2018-08-22 14:10:36 -0700 | [diff] [blame] | 493 | #endif // AOM_AV1_ENCODER_FIRSTPASS_H_ |