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