• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2016, Alliance for Open Media. All rights reserved
3  *
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.
10  */
11 
12 #include <limits.h>
13 #include <float.h>
14 #include <math.h>
15 #include <stdio.h>
16 #include <time.h>
17 #include <stdlib.h>
18 
19 #include "config/aom_config.h"
20 #include "config/aom_dsp_rtcd.h"
21 
22 #include "aom/aomcx.h"
23 
24 #if CONFIG_DENOISE
25 #include "aom_dsp/grain_table.h"
26 #include "aom_dsp/noise_util.h"
27 #include "aom_dsp/noise_model.h"
28 #endif
29 #include "aom_dsp/psnr.h"
30 #if CONFIG_INTERNAL_STATS
31 #include "aom_dsp/ssim.h"
32 #endif
33 #include "aom_ports/aom_timer.h"
34 #include "aom_ports/mem.h"
35 #include "aom_scale/aom_scale.h"
36 #if CONFIG_BITSTREAM_DEBUG
37 #include "aom_util/debug_util.h"
38 #endif  // CONFIG_BITSTREAM_DEBUG
39 
40 #include "av1/common/alloccommon.h"
41 #include "av1/common/filter.h"
42 #include "av1/common/idct.h"
43 #include "av1/common/reconinter.h"
44 #include "av1/common/reconintra.h"
45 #include "av1/common/resize.h"
46 #include "av1/common/tile_common.h"
47 
48 #include "av1/encoder/allintra_vis.h"
49 #include "av1/encoder/aq_complexity.h"
50 #include "av1/encoder/aq_cyclicrefresh.h"
51 #include "av1/encoder/aq_variance.h"
52 #include "av1/encoder/bitstream.h"
53 #include "av1/encoder/context_tree.h"
54 #include "av1/encoder/dwt.h"
55 #include "av1/encoder/encodeframe.h"
56 #include "av1/encoder/encodemv.h"
57 #include "av1/encoder/encode_strategy.h"
58 #include "av1/encoder/encoder.h"
59 #include "av1/encoder/encoder_alloc.h"
60 #include "av1/encoder/encoder_utils.h"
61 #include "av1/encoder/encodetxb.h"
62 #include "av1/encoder/ethread.h"
63 #include "av1/encoder/firstpass.h"
64 #include "av1/encoder/hash_motion.h"
65 #include "av1/encoder/hybrid_fwd_txfm.h"
66 #include "av1/encoder/intra_mode_search.h"
67 #include "av1/encoder/mv_prec.h"
68 #include "av1/encoder/pass2_strategy.h"
69 #include "av1/encoder/pickcdef.h"
70 #include "av1/encoder/picklpf.h"
71 #include "av1/encoder/pickrst.h"
72 #include "av1/encoder/random.h"
73 #include "av1/encoder/ratectrl.h"
74 #include "av1/encoder/rc_utils.h"
75 #include "av1/encoder/rd.h"
76 #include "av1/encoder/rdopt.h"
77 #include "av1/encoder/segmentation.h"
78 #include "av1/encoder/speed_features.h"
79 #include "av1/encoder/superres_scale.h"
80 #include "av1/encoder/thirdpass.h"
81 #include "av1/encoder/tpl_model.h"
82 #include "av1/encoder/reconinter_enc.h"
83 #include "av1/encoder/var_based_part.h"
84 
85 #define DEFAULT_EXPLICIT_ORDER_HINT_BITS 7
86 
87 // #define OUTPUT_YUV_REC
88 #ifdef OUTPUT_YUV_REC
89 FILE *yuv_rec_file;
90 #define FILE_NAME_LEN 100
91 #endif
92 
93 #ifdef OUTPUT_YUV_DENOISED
94 FILE *yuv_denoised_file = NULL;
95 #endif
96 
Scale2Ratio(AOM_SCALING mode,int * hr,int * hs)97 static INLINE void Scale2Ratio(AOM_SCALING mode, int *hr, int *hs) {
98   switch (mode) {
99     case NORMAL:
100       *hr = 1;
101       *hs = 1;
102       break;
103     case FOURFIVE:
104       *hr = 4;
105       *hs = 5;
106       break;
107     case THREEFIVE:
108       *hr = 3;
109       *hs = 5;
110       break;
111     case THREEFOUR:
112       *hr = 3;
113       *hs = 4;
114       break;
115     case ONEFOUR:
116       *hr = 1;
117       *hs = 4;
118       break;
119     case ONEEIGHT:
120       *hr = 1;
121       *hs = 8;
122       break;
123     case ONETWO:
124       *hr = 1;
125       *hs = 2;
126       break;
127     default:
128       *hr = 1;
129       *hs = 1;
130       assert(0);
131       break;
132   }
133 }
134 
av1_set_active_map(AV1_COMP * cpi,unsigned char * new_map_16x16,int rows,int cols)135 int av1_set_active_map(AV1_COMP *cpi, unsigned char *new_map_16x16, int rows,
136                        int cols) {
137   const CommonModeInfoParams *const mi_params = &cpi->common.mi_params;
138   if (rows == mi_params->mb_rows && cols == mi_params->mb_cols) {
139     unsigned char *const active_map_8x8 = cpi->active_map.map;
140     const int mi_rows = mi_params->mi_rows;
141     const int mi_cols = mi_params->mi_cols;
142     const int row_scale = mi_size_high[BLOCK_16X16] == 2 ? 1 : 2;
143     const int col_scale = mi_size_wide[BLOCK_16X16] == 2 ? 1 : 2;
144     cpi->active_map.update = 1;
145     if (new_map_16x16) {
146       int r, c;
147       for (r = 0; r < mi_rows; ++r) {
148         for (c = 0; c < mi_cols; ++c) {
149           active_map_8x8[r * mi_cols + c] =
150               new_map_16x16[(r >> row_scale) * cols + (c >> col_scale)]
151                   ? AM_SEGMENT_ID_ACTIVE
152                   : AM_SEGMENT_ID_INACTIVE;
153         }
154       }
155       cpi->active_map.enabled = 1;
156     } else {
157       cpi->active_map.enabled = 0;
158     }
159     return 0;
160   } else {
161     return -1;
162   }
163 }
164 
av1_get_active_map(AV1_COMP * cpi,unsigned char * new_map_16x16,int rows,int cols)165 int av1_get_active_map(AV1_COMP *cpi, unsigned char *new_map_16x16, int rows,
166                        int cols) {
167   const CommonModeInfoParams *const mi_params = &cpi->common.mi_params;
168   if (rows == mi_params->mb_rows && cols == mi_params->mb_cols &&
169       new_map_16x16) {
170     unsigned char *const seg_map_8x8 = cpi->enc_seg.map;
171     const int mi_rows = mi_params->mi_rows;
172     const int mi_cols = mi_params->mi_cols;
173     const int row_scale = mi_size_high[BLOCK_16X16] == 2 ? 1 : 2;
174     const int col_scale = mi_size_wide[BLOCK_16X16] == 2 ? 1 : 2;
175 
176     memset(new_map_16x16, !cpi->active_map.enabled, rows * cols);
177     if (cpi->active_map.enabled) {
178       int r, c;
179       for (r = 0; r < mi_rows; ++r) {
180         for (c = 0; c < mi_cols; ++c) {
181           // Cyclic refresh segments are considered active despite not having
182           // AM_SEGMENT_ID_ACTIVE
183           new_map_16x16[(r >> row_scale) * cols + (c >> col_scale)] |=
184               seg_map_8x8[r * mi_cols + c] != AM_SEGMENT_ID_INACTIVE;
185         }
186       }
187     }
188     return 0;
189   } else {
190     return -1;
191   }
192 }
193 
av1_initialize_enc(void)194 void av1_initialize_enc(void) {
195   av1_rtcd();
196   aom_dsp_rtcd();
197   aom_scale_rtcd();
198   av1_init_intra_predictors();
199   av1_init_me_luts();
200   av1_rc_init_minq_luts();
201   av1_init_wedge_masks();
202 }
203 
update_reference_segmentation_map(AV1_COMP * cpi)204 static void update_reference_segmentation_map(AV1_COMP *cpi) {
205   AV1_COMMON *const cm = &cpi->common;
206   const CommonModeInfoParams *const mi_params = &cm->mi_params;
207   MB_MODE_INFO **mi_4x4_ptr = mi_params->mi_grid_base;
208   uint8_t *cache_ptr = cm->cur_frame->seg_map;
209 
210   for (int row = 0; row < mi_params->mi_rows; row++) {
211     MB_MODE_INFO **mi_4x4 = mi_4x4_ptr;
212     uint8_t *cache = cache_ptr;
213     for (int col = 0; col < mi_params->mi_cols; col++, mi_4x4++, cache++)
214       cache[0] = mi_4x4[0]->segment_id;
215     mi_4x4_ptr += mi_params->mi_stride;
216     cache_ptr += mi_params->mi_cols;
217   }
218 }
219 
av1_new_framerate(AV1_COMP * cpi,double framerate)220 void av1_new_framerate(AV1_COMP *cpi, double framerate) {
221   cpi->framerate = framerate < 0.1 ? 30 : framerate;
222   av1_rc_update_framerate(cpi, cpi->common.width, cpi->common.height);
223 }
224 
av1_get_compression_ratio(const AV1_COMMON * const cm,size_t encoded_frame_size)225 double av1_get_compression_ratio(const AV1_COMMON *const cm,
226                                  size_t encoded_frame_size) {
227   const int upscaled_width = cm->superres_upscaled_width;
228   const int height = cm->height;
229   const int luma_pic_size = upscaled_width * height;
230   const SequenceHeader *const seq_params = cm->seq_params;
231   const BITSTREAM_PROFILE profile = seq_params->profile;
232   const int pic_size_profile_factor =
233       profile == PROFILE_0 ? 15 : (profile == PROFILE_1 ? 30 : 36);
234   encoded_frame_size =
235       (encoded_frame_size > 129 ? encoded_frame_size - 128 : 1);
236   const size_t uncompressed_frame_size =
237       (luma_pic_size * pic_size_profile_factor) >> 3;
238   return uncompressed_frame_size / (double)encoded_frame_size;
239 }
240 
set_tile_info(AV1_COMMON * const cm,const TileConfig * const tile_cfg)241 static void set_tile_info(AV1_COMMON *const cm,
242                           const TileConfig *const tile_cfg) {
243   const CommonModeInfoParams *const mi_params = &cm->mi_params;
244   const SequenceHeader *const seq_params = cm->seq_params;
245   CommonTileParams *const tiles = &cm->tiles;
246   int i, start_sb;
247 
248   av1_get_tile_limits(cm);
249 
250   // configure tile columns
251   if (tile_cfg->tile_width_count == 0 || tile_cfg->tile_height_count == 0) {
252     tiles->uniform_spacing = 1;
253     tiles->log2_cols = AOMMAX(tile_cfg->tile_columns, tiles->min_log2_cols);
254     tiles->log2_cols = AOMMIN(tiles->log2_cols, tiles->max_log2_cols);
255   } else {
256     int mi_cols =
257         ALIGN_POWER_OF_TWO(mi_params->mi_cols, seq_params->mib_size_log2);
258     int sb_cols = mi_cols >> seq_params->mib_size_log2;
259     int size_sb, j = 0;
260     tiles->uniform_spacing = 0;
261     for (i = 0, start_sb = 0; start_sb < sb_cols && i < MAX_TILE_COLS; i++) {
262       tiles->col_start_sb[i] = start_sb;
263       size_sb = tile_cfg->tile_widths[j++];
264       if (j >= tile_cfg->tile_width_count) j = 0;
265       start_sb += AOMMIN(size_sb, tiles->max_width_sb);
266     }
267     tiles->cols = i;
268     tiles->col_start_sb[i] = sb_cols;
269   }
270   av1_calculate_tile_cols(seq_params, mi_params->mi_rows, mi_params->mi_cols,
271                           tiles);
272 
273   // configure tile rows
274   if (tiles->uniform_spacing) {
275     tiles->log2_rows = AOMMAX(tile_cfg->tile_rows, tiles->min_log2_rows);
276     tiles->log2_rows = AOMMIN(tiles->log2_rows, tiles->max_log2_rows);
277   } else {
278     int mi_rows =
279         ALIGN_POWER_OF_TWO(mi_params->mi_rows, seq_params->mib_size_log2);
280     int sb_rows = mi_rows >> seq_params->mib_size_log2;
281     int size_sb, j = 0;
282     for (i = 0, start_sb = 0; start_sb < sb_rows && i < MAX_TILE_ROWS; i++) {
283       tiles->row_start_sb[i] = start_sb;
284       size_sb = tile_cfg->tile_heights[j++];
285       if (j >= tile_cfg->tile_height_count) j = 0;
286       start_sb += AOMMIN(size_sb, tiles->max_height_sb);
287     }
288     tiles->rows = i;
289     tiles->row_start_sb[i] = sb_rows;
290   }
291   av1_calculate_tile_rows(seq_params, mi_params->mi_rows, tiles);
292 }
293 
av1_update_frame_size(AV1_COMP * cpi)294 void av1_update_frame_size(AV1_COMP *cpi) {
295   AV1_COMMON *const cm = &cpi->common;
296   MACROBLOCKD *const xd = &cpi->td.mb.e_mbd;
297 
298   // We need to reallocate the context buffers here in case we need more mis.
299   if (av1_alloc_context_buffers(cm, cm->width, cm->height)) {
300     aom_internal_error(cm->error, AOM_CODEC_MEM_ERROR,
301                        "Failed to allocate context buffers");
302   }
303   av1_init_mi_buffers(&cm->mi_params);
304 
305   av1_init_macroblockd(cm, xd);
306 
307   if (!is_stat_generation_stage(cpi))
308     alloc_context_buffers_ext(cm, &cpi->mbmi_ext_info);
309 
310   if (!cpi->ppi->seq_params_locked)
311     set_sb_size(cm->seq_params,
312                 av1_select_sb_size(&cpi->oxcf, cm->width, cm->height,
313                                    cpi->svc.number_spatial_layers));
314 
315   set_tile_info(cm, &cpi->oxcf.tile_cfg);
316 }
317 
does_level_match(int width,int height,double fps,int lvl_width,int lvl_height,double lvl_fps,int lvl_dim_mult)318 static INLINE int does_level_match(int width, int height, double fps,
319                                    int lvl_width, int lvl_height,
320                                    double lvl_fps, int lvl_dim_mult) {
321   const int64_t lvl_luma_pels = lvl_width * lvl_height;
322   const double lvl_display_sample_rate = lvl_luma_pels * lvl_fps;
323   const int64_t luma_pels = width * height;
324   const double display_sample_rate = luma_pels * fps;
325   return luma_pels <= lvl_luma_pels &&
326          display_sample_rate <= lvl_display_sample_rate &&
327          width <= lvl_width * lvl_dim_mult &&
328          height <= lvl_height * lvl_dim_mult;
329 }
330 
set_bitstream_level_tier(AV1_PRIMARY * const ppi,int width,int height,double init_framerate)331 static void set_bitstream_level_tier(AV1_PRIMARY *const ppi, int width,
332                                      int height, double init_framerate) {
333   SequenceHeader *const seq_params = &ppi->seq_params;
334   // TODO(any): This is a placeholder function that only addresses dimensions
335   // and max display sample rates.
336   // Need to add checks for max bit rate, max decoded luma sample rate, header
337   // rate, etc. that are not covered by this function.
338   AV1_LEVEL level = SEQ_LEVEL_MAX;
339   if (does_level_match(width, height, init_framerate, 512, 288, 30.0, 4)) {
340     level = SEQ_LEVEL_2_0;
341   } else if (does_level_match(width, height, init_framerate, 704, 396, 30.0,
342                               4)) {
343     level = SEQ_LEVEL_2_1;
344   } else if (does_level_match(width, height, init_framerate, 1088, 612, 30.0,
345                               4)) {
346     level = SEQ_LEVEL_3_0;
347   } else if (does_level_match(width, height, init_framerate, 1376, 774, 30.0,
348                               4)) {
349     level = SEQ_LEVEL_3_1;
350   } else if (does_level_match(width, height, init_framerate, 2048, 1152, 30.0,
351                               3)) {
352     level = SEQ_LEVEL_4_0;
353   } else if (does_level_match(width, height, init_framerate, 2048, 1152, 60.0,
354                               3)) {
355     level = SEQ_LEVEL_4_1;
356   } else if (does_level_match(width, height, init_framerate, 4096, 2176, 30.0,
357                               2)) {
358     level = SEQ_LEVEL_5_0;
359   } else if (does_level_match(width, height, init_framerate, 4096, 2176, 60.0,
360                               2)) {
361     level = SEQ_LEVEL_5_1;
362   } else if (does_level_match(width, height, init_framerate, 4096, 2176, 120.0,
363                               2)) {
364     level = SEQ_LEVEL_5_2;
365   } else if (does_level_match(width, height, init_framerate, 8192, 4352, 30.0,
366                               2)) {
367     level = SEQ_LEVEL_6_0;
368   } else if (does_level_match(width, height, init_framerate, 8192, 4352, 60.0,
369                               2)) {
370     level = SEQ_LEVEL_6_1;
371   } else if (does_level_match(width, height, init_framerate, 8192, 4352, 120.0,
372                               2)) {
373     level = SEQ_LEVEL_6_2;
374   }
375 
376   for (int i = 0; i < MAX_NUM_OPERATING_POINTS; ++i) {
377     seq_params->seq_level_idx[i] = level;
378     // Set the maximum parameters for bitrate and buffer size for this profile,
379     // level, and tier
380     seq_params->op_params[i].bitrate = av1_max_level_bitrate(
381         seq_params->profile, seq_params->seq_level_idx[i], seq_params->tier[i]);
382     // Level with seq_level_idx = 31 returns a high "dummy" bitrate to pass the
383     // check
384     if (seq_params->op_params[i].bitrate == 0)
385       aom_internal_error(
386           &ppi->error, AOM_CODEC_UNSUP_BITSTREAM,
387           "AV1 does not support this combination of profile, level, and tier.");
388     // Buffer size in bits/s is bitrate in bits/s * 1 s
389     seq_params->op_params[i].buffer_size = seq_params->op_params[i].bitrate;
390   }
391 }
392 
av1_init_seq_coding_tools(AV1_PRIMARY * const ppi,const AV1EncoderConfig * oxcf,int use_svc)393 void av1_init_seq_coding_tools(AV1_PRIMARY *const ppi,
394                                const AV1EncoderConfig *oxcf, int use_svc) {
395   SequenceHeader *const seq = &ppi->seq_params;
396   const FrameDimensionCfg *const frm_dim_cfg = &oxcf->frm_dim_cfg;
397   const ToolCfg *const tool_cfg = &oxcf->tool_cfg;
398 
399   seq->still_picture =
400       !tool_cfg->force_video_mode && (oxcf->input_cfg.limit == 1);
401   seq->reduced_still_picture_hdr =
402       seq->still_picture && !tool_cfg->full_still_picture_hdr;
403   seq->force_screen_content_tools = (oxcf->mode == REALTIME) ? 0 : 2;
404   seq->force_integer_mv = 2;
405   seq->order_hint_info.enable_order_hint = tool_cfg->enable_order_hint;
406   seq->frame_id_numbers_present_flag =
407       !seq->reduced_still_picture_hdr &&
408       !oxcf->tile_cfg.enable_large_scale_tile &&
409       tool_cfg->error_resilient_mode && !use_svc;
410   if (seq->reduced_still_picture_hdr) {
411     seq->order_hint_info.enable_order_hint = 0;
412     seq->force_screen_content_tools = 2;
413     seq->force_integer_mv = 2;
414   }
415   seq->order_hint_info.order_hint_bits_minus_1 =
416       seq->order_hint_info.enable_order_hint
417           ? DEFAULT_EXPLICIT_ORDER_HINT_BITS - 1
418           : -1;
419 
420   seq->max_frame_width = frm_dim_cfg->forced_max_frame_width
421                              ? frm_dim_cfg->forced_max_frame_width
422                              : frm_dim_cfg->width;
423   seq->max_frame_height = frm_dim_cfg->forced_max_frame_height
424                               ? frm_dim_cfg->forced_max_frame_height
425                               : frm_dim_cfg->height;
426   seq->num_bits_width =
427       (seq->max_frame_width > 1) ? get_msb(seq->max_frame_width - 1) + 1 : 1;
428   seq->num_bits_height =
429       (seq->max_frame_height > 1) ? get_msb(seq->max_frame_height - 1) + 1 : 1;
430   assert(seq->num_bits_width <= 16);
431   assert(seq->num_bits_height <= 16);
432 
433   seq->frame_id_length = FRAME_ID_LENGTH;
434   seq->delta_frame_id_length = DELTA_FRAME_ID_LENGTH;
435 
436   seq->enable_dual_filter = tool_cfg->enable_dual_filter;
437   seq->order_hint_info.enable_dist_wtd_comp =
438       oxcf->comp_type_cfg.enable_dist_wtd_comp;
439   seq->order_hint_info.enable_dist_wtd_comp &=
440       seq->order_hint_info.enable_order_hint;
441   seq->order_hint_info.enable_ref_frame_mvs = tool_cfg->ref_frame_mvs_present;
442   seq->order_hint_info.enable_ref_frame_mvs &=
443       seq->order_hint_info.enable_order_hint;
444   seq->enable_superres = oxcf->superres_cfg.enable_superres;
445   seq->enable_cdef = tool_cfg->enable_cdef;
446   seq->enable_restoration = tool_cfg->enable_restoration;
447   seq->enable_warped_motion = oxcf->motion_mode_cfg.enable_warped_motion;
448   seq->enable_interintra_compound = tool_cfg->enable_interintra_comp;
449   seq->enable_masked_compound = oxcf->comp_type_cfg.enable_masked_comp;
450   seq->enable_intra_edge_filter = oxcf->intra_mode_cfg.enable_intra_edge_filter;
451   seq->enable_filter_intra = oxcf->intra_mode_cfg.enable_filter_intra;
452 
453   set_bitstream_level_tier(ppi, frm_dim_cfg->width, frm_dim_cfg->height,
454                            oxcf->input_cfg.init_framerate);
455 
456   if (seq->operating_points_cnt_minus_1 == 0) {
457     seq->operating_point_idc[0] = 0;
458   } else {
459     // Set operating_point_idc[] such that the i=0 point corresponds to the
460     // highest quality operating point (all layers), and subsequent
461     // operarting points (i > 0) are lower quality corresponding to
462     // skip decoding enhancement  layers (temporal first).
463     int i = 0;
464     assert(seq->operating_points_cnt_minus_1 ==
465            (int)(ppi->number_spatial_layers * ppi->number_temporal_layers - 1));
466     for (unsigned int sl = 0; sl < ppi->number_spatial_layers; sl++) {
467       for (unsigned int tl = 0; tl < ppi->number_temporal_layers; tl++) {
468         seq->operating_point_idc[i] =
469             (~(~0u << (ppi->number_spatial_layers - sl)) << 8) |
470             ~(~0u << (ppi->number_temporal_layers - tl));
471         i++;
472       }
473     }
474   }
475 }
476 
init_config_sequence(struct AV1_PRIMARY * ppi,AV1EncoderConfig * oxcf)477 static void init_config_sequence(struct AV1_PRIMARY *ppi,
478                                  AV1EncoderConfig *oxcf) {
479   SequenceHeader *const seq_params = &ppi->seq_params;
480   const DecoderModelCfg *const dec_model_cfg = &oxcf->dec_model_cfg;
481   const ColorCfg *const color_cfg = &oxcf->color_cfg;
482 
483   ppi->use_svc = 0;
484   ppi->number_spatial_layers = 1;
485   ppi->number_temporal_layers = 1;
486 
487   seq_params->profile = oxcf->profile;
488   seq_params->bit_depth = oxcf->tool_cfg.bit_depth;
489   seq_params->use_highbitdepth = oxcf->use_highbitdepth;
490   seq_params->color_primaries = color_cfg->color_primaries;
491   seq_params->transfer_characteristics = color_cfg->transfer_characteristics;
492   seq_params->matrix_coefficients = color_cfg->matrix_coefficients;
493   seq_params->monochrome = oxcf->tool_cfg.enable_monochrome;
494   seq_params->chroma_sample_position = color_cfg->chroma_sample_position;
495   seq_params->color_range = color_cfg->color_range;
496   seq_params->timing_info_present = dec_model_cfg->timing_info_present;
497   seq_params->timing_info.num_units_in_display_tick =
498       dec_model_cfg->timing_info.num_units_in_display_tick;
499   seq_params->timing_info.time_scale = dec_model_cfg->timing_info.time_scale;
500   seq_params->timing_info.equal_picture_interval =
501       dec_model_cfg->timing_info.equal_picture_interval;
502   seq_params->timing_info.num_ticks_per_picture =
503       dec_model_cfg->timing_info.num_ticks_per_picture;
504 
505   seq_params->display_model_info_present_flag =
506       dec_model_cfg->display_model_info_present_flag;
507   seq_params->decoder_model_info_present_flag =
508       dec_model_cfg->decoder_model_info_present_flag;
509   if (dec_model_cfg->decoder_model_info_present_flag) {
510     // set the decoder model parameters in schedule mode
511     seq_params->decoder_model_info.num_units_in_decoding_tick =
512         dec_model_cfg->num_units_in_decoding_tick;
513     ppi->buffer_removal_time_present = 1;
514     av1_set_aom_dec_model_info(&seq_params->decoder_model_info);
515     av1_set_dec_model_op_parameters(&seq_params->op_params[0]);
516   } else if (seq_params->timing_info_present &&
517              seq_params->timing_info.equal_picture_interval &&
518              !seq_params->decoder_model_info_present_flag) {
519     // set the decoder model parameters in resource availability mode
520     av1_set_resource_availability_parameters(&seq_params->op_params[0]);
521   } else {
522     seq_params->op_params[0].initial_display_delay =
523         10;  // Default value (not signaled)
524   }
525 
526   if (seq_params->monochrome) {
527     seq_params->subsampling_x = 1;
528     seq_params->subsampling_y = 1;
529   } else if (seq_params->color_primaries == AOM_CICP_CP_BT_709 &&
530              seq_params->transfer_characteristics == AOM_CICP_TC_SRGB &&
531              seq_params->matrix_coefficients == AOM_CICP_MC_IDENTITY) {
532     seq_params->subsampling_x = 0;
533     seq_params->subsampling_y = 0;
534   } else {
535     if (seq_params->profile == 0) {
536       seq_params->subsampling_x = 1;
537       seq_params->subsampling_y = 1;
538     } else if (seq_params->profile == 1) {
539       seq_params->subsampling_x = 0;
540       seq_params->subsampling_y = 0;
541     } else {
542       if (seq_params->bit_depth == AOM_BITS_12) {
543         seq_params->subsampling_x = oxcf->input_cfg.chroma_subsampling_x;
544         seq_params->subsampling_y = oxcf->input_cfg.chroma_subsampling_y;
545       } else {
546         seq_params->subsampling_x = 1;
547         seq_params->subsampling_y = 0;
548       }
549     }
550   }
551   av1_change_config_seq(ppi, oxcf, NULL);
552 }
553 
init_config(struct AV1_COMP * cpi,AV1EncoderConfig * oxcf)554 static void init_config(struct AV1_COMP *cpi, AV1EncoderConfig *oxcf) {
555   AV1_COMMON *const cm = &cpi->common;
556   ResizePendingParams *resize_pending_params = &cpi->resize_pending_params;
557 
558   cpi->oxcf = *oxcf;
559   cpi->framerate = oxcf->input_cfg.init_framerate;
560 
561   cm->width = oxcf->frm_dim_cfg.width;
562   cm->height = oxcf->frm_dim_cfg.height;
563   cpi->is_dropped_frame = false;
564 
565   alloc_compressor_data(cpi);
566 
567   av1_update_film_grain_parameters(cpi, oxcf);
568 
569   // Single thread case: use counts in common.
570   cpi->td.counts = &cpi->counts;
571 
572   // Set init SVC parameters.
573   cpi->svc.set_ref_frame_config = 0;
574   cpi->svc.non_reference_frame = 0;
575   cpi->svc.number_spatial_layers = 1;
576   cpi->svc.number_temporal_layers = 1;
577   cm->spatial_layer_id = 0;
578   cm->temporal_layer_id = 0;
579 
580   // change includes all joint functionality
581   av1_change_config(cpi, oxcf, true);
582 
583   cpi->ref_frame_flags = 0;
584 
585   // Reset resize pending flags
586   resize_pending_params->width = 0;
587   resize_pending_params->height = 0;
588 
589   init_buffer_indices(&cpi->force_intpel_info, cm->remapped_ref_idx);
590 
591   av1_noise_estimate_init(&cpi->noise_estimate, cm->width, cm->height);
592 }
593 
av1_change_config_seq(struct AV1_PRIMARY * ppi,const AV1EncoderConfig * oxcf,bool * is_sb_size_changed)594 void av1_change_config_seq(struct AV1_PRIMARY *ppi,
595                            const AV1EncoderConfig *oxcf,
596                            bool *is_sb_size_changed) {
597   SequenceHeader *const seq_params = &ppi->seq_params;
598   const FrameDimensionCfg *const frm_dim_cfg = &oxcf->frm_dim_cfg;
599   const DecoderModelCfg *const dec_model_cfg = &oxcf->dec_model_cfg;
600   const ColorCfg *const color_cfg = &oxcf->color_cfg;
601 
602   if (seq_params->profile != oxcf->profile) seq_params->profile = oxcf->profile;
603   seq_params->bit_depth = oxcf->tool_cfg.bit_depth;
604   seq_params->color_primaries = color_cfg->color_primaries;
605   seq_params->transfer_characteristics = color_cfg->transfer_characteristics;
606   seq_params->matrix_coefficients = color_cfg->matrix_coefficients;
607   seq_params->monochrome = oxcf->tool_cfg.enable_monochrome;
608   seq_params->chroma_sample_position = color_cfg->chroma_sample_position;
609   seq_params->color_range = color_cfg->color_range;
610 
611   assert(IMPLIES(seq_params->profile <= PROFILE_1,
612                  seq_params->bit_depth <= AOM_BITS_10));
613 
614   seq_params->timing_info_present = dec_model_cfg->timing_info_present;
615   seq_params->timing_info.num_units_in_display_tick =
616       dec_model_cfg->timing_info.num_units_in_display_tick;
617   seq_params->timing_info.time_scale = dec_model_cfg->timing_info.time_scale;
618   seq_params->timing_info.equal_picture_interval =
619       dec_model_cfg->timing_info.equal_picture_interval;
620   seq_params->timing_info.num_ticks_per_picture =
621       dec_model_cfg->timing_info.num_ticks_per_picture;
622 
623   seq_params->display_model_info_present_flag =
624       dec_model_cfg->display_model_info_present_flag;
625   seq_params->decoder_model_info_present_flag =
626       dec_model_cfg->decoder_model_info_present_flag;
627   if (dec_model_cfg->decoder_model_info_present_flag) {
628     // set the decoder model parameters in schedule mode
629     seq_params->decoder_model_info.num_units_in_decoding_tick =
630         dec_model_cfg->num_units_in_decoding_tick;
631     ppi->buffer_removal_time_present = 1;
632     av1_set_aom_dec_model_info(&seq_params->decoder_model_info);
633     av1_set_dec_model_op_parameters(&seq_params->op_params[0]);
634   } else if (seq_params->timing_info_present &&
635              seq_params->timing_info.equal_picture_interval &&
636              !seq_params->decoder_model_info_present_flag) {
637     // set the decoder model parameters in resource availability mode
638     av1_set_resource_availability_parameters(&seq_params->op_params[0]);
639   } else {
640     seq_params->op_params[0].initial_display_delay =
641         10;  // Default value (not signaled)
642   }
643 
644   av1_update_film_grain_parameters_seq(ppi, oxcf);
645 
646   int sb_size = seq_params->sb_size;
647   // Superblock size should not be updated after the first key frame.
648   if (!ppi->seq_params_locked) {
649     set_sb_size(seq_params, av1_select_sb_size(oxcf, frm_dim_cfg->width,
650                                                frm_dim_cfg->height,
651                                                ppi->number_spatial_layers));
652     for (int i = 0; i < MAX_NUM_OPERATING_POINTS; ++i)
653       seq_params->tier[i] = (oxcf->tier_mask >> i) & 1;
654   }
655   if (is_sb_size_changed != NULL && sb_size != seq_params->sb_size)
656     *is_sb_size_changed = true;
657 
658   // Init sequence level coding tools
659   // This should not be called after the first key frame.
660   if (!ppi->seq_params_locked) {
661     seq_params->operating_points_cnt_minus_1 =
662         (ppi->number_spatial_layers > 1 || ppi->number_temporal_layers > 1)
663             ? ppi->number_spatial_layers * ppi->number_temporal_layers - 1
664             : 0;
665     av1_init_seq_coding_tools(ppi, oxcf, ppi->use_svc);
666   }
667   seq_params->timing_info_present &= !seq_params->reduced_still_picture_hdr;
668 
669 #if CONFIG_AV1_HIGHBITDEPTH
670   highbd_set_var_fns(ppi);
671 #endif
672 
673   set_primary_rc_buffer_sizes(oxcf, ppi);
674 }
675 
av1_change_config(struct AV1_COMP * cpi,const AV1EncoderConfig * oxcf,bool is_sb_size_changed)676 void av1_change_config(struct AV1_COMP *cpi, const AV1EncoderConfig *oxcf,
677                        bool is_sb_size_changed) {
678   AV1_COMMON *const cm = &cpi->common;
679   SequenceHeader *const seq_params = cm->seq_params;
680   RATE_CONTROL *const rc = &cpi->rc;
681   PRIMARY_RATE_CONTROL *const p_rc = &cpi->ppi->p_rc;
682   MACROBLOCK *const x = &cpi->td.mb;
683   AV1LevelParams *const level_params = &cpi->ppi->level_params;
684   InitialDimensions *const initial_dimensions = &cpi->initial_dimensions;
685   RefreshFrameFlagsInfo *const refresh_frame_flags = &cpi->refresh_frame;
686   const FrameDimensionCfg *const frm_dim_cfg = &cpi->oxcf.frm_dim_cfg;
687   const RateControlCfg *const rc_cfg = &oxcf->rc_cfg;
688 
689   // in case of LAP, lag in frames is set according to number of lap buffers
690   // calculated at init time. This stores and restores LAP's lag in frames to
691   // prevent override by new cfg.
692   int lap_lag_in_frames = -1;
693   if (cpi->ppi->lap_enabled && cpi->compressor_stage == LAP_STAGE) {
694     lap_lag_in_frames = cpi->oxcf.gf_cfg.lag_in_frames;
695   }
696 
697   av1_update_film_grain_parameters(cpi, oxcf);
698 
699   cpi->oxcf = *oxcf;
700   // When user provides superres_mode = AOM_SUPERRES_AUTO, we still initialize
701   // superres mode for current encoding = AOM_SUPERRES_NONE. This is to ensure
702   // that any analysis (e.g. TPL) happening outside the main encoding loop still
703   // happens at full resolution.
704   // This value will later be set appropriately just before main encoding loop.
705   cpi->superres_mode = oxcf->superres_cfg.superres_mode == AOM_SUPERRES_AUTO
706                            ? AOM_SUPERRES_NONE
707                            : oxcf->superres_cfg.superres_mode;  // default
708   x->e_mbd.bd = (int)seq_params->bit_depth;
709   x->e_mbd.global_motion = cm->global_motion;
710 
711   memcpy(level_params->target_seq_level_idx, cpi->oxcf.target_seq_level_idx,
712          sizeof(level_params->target_seq_level_idx));
713   level_params->keep_level_stats = 0;
714   for (int i = 0; i < MAX_NUM_OPERATING_POINTS; ++i) {
715     if (level_params->target_seq_level_idx[i] <= SEQ_LEVELS) {
716       level_params->keep_level_stats |= 1u << i;
717       if (!level_params->level_info[i]) {
718         CHECK_MEM_ERROR(cm, level_params->level_info[i],
719                         aom_calloc(1, sizeof(*level_params->level_info[i])));
720       }
721     }
722   }
723 
724   // TODO(huisu@): level targeting currently only works for the 0th operating
725   // point, so scalable coding is not supported yet.
726   if (level_params->target_seq_level_idx[0] < SEQ_LEVELS) {
727     // Adjust encoder config in order to meet target level.
728     config_target_level(cpi, level_params->target_seq_level_idx[0],
729                         seq_params->tier[0]);
730   }
731 
732   if (has_no_stats_stage(cpi) && (rc_cfg->mode == AOM_Q)) {
733     p_rc->baseline_gf_interval = FIXED_GF_INTERVAL;
734   } else {
735     p_rc->baseline_gf_interval = (MIN_GF_INTERVAL + MAX_GF_INTERVAL) / 2;
736   }
737 
738   refresh_frame_flags->golden_frame = false;
739   refresh_frame_flags->bwd_ref_frame = false;
740 
741   cm->features.refresh_frame_context =
742       (oxcf->tool_cfg.frame_parallel_decoding_mode)
743           ? REFRESH_FRAME_CONTEXT_DISABLED
744           : REFRESH_FRAME_CONTEXT_BACKWARD;
745   if (oxcf->tile_cfg.enable_large_scale_tile)
746     cm->features.refresh_frame_context = REFRESH_FRAME_CONTEXT_DISABLED;
747 
748   if (x->palette_buffer == NULL) {
749     CHECK_MEM_ERROR(cm, x->palette_buffer,
750                     aom_memalign(16, sizeof(*x->palette_buffer)));
751   }
752 
753   if (x->comp_rd_buffer.pred0 == NULL) {
754     alloc_compound_type_rd_buffers(cm->error, &x->comp_rd_buffer);
755   }
756 
757   if (x->tmp_conv_dst == NULL) {
758     CHECK_MEM_ERROR(
759         cm, x->tmp_conv_dst,
760         aom_memalign(32, MAX_SB_SIZE * MAX_SB_SIZE * sizeof(*x->tmp_conv_dst)));
761     x->e_mbd.tmp_conv_dst = x->tmp_conv_dst;
762   }
763   for (int i = 0; i < 2; ++i) {
764     if (x->tmp_pred_bufs[i] == NULL) {
765       CHECK_MEM_ERROR(cm, x->tmp_pred_bufs[i],
766                       aom_memalign(32, 2 * MAX_MB_PLANE * MAX_SB_SQUARE *
767                                            sizeof(*x->tmp_pred_bufs[i])));
768       x->e_mbd.tmp_obmc_bufs[i] = x->tmp_pred_bufs[i];
769     }
770   }
771 
772   av1_reset_segment_features(cm);
773 
774   av1_set_high_precision_mv(cpi, 1, 0);
775 
776   // Under a configuration change, where maximum_buffer_size may change,
777   // keep buffer level clipped to the maximum allowed buffer size.
778   p_rc->bits_off_target =
779       AOMMIN(p_rc->bits_off_target, p_rc->maximum_buffer_size);
780   p_rc->buffer_level = AOMMIN(p_rc->buffer_level, p_rc->maximum_buffer_size);
781 
782   // Set up frame rate and related parameters rate control values.
783   av1_new_framerate(cpi, cpi->framerate);
784 
785   // Set absolute upper and lower quality limits
786   rc->worst_quality = rc_cfg->worst_allowed_q;
787   rc->best_quality = rc_cfg->best_allowed_q;
788 
789   cm->features.interp_filter =
790       oxcf->tile_cfg.enable_large_scale_tile ? EIGHTTAP_REGULAR : SWITCHABLE;
791   cm->features.switchable_motion_mode = 1;
792 
793   if (frm_dim_cfg->render_width > 0 && frm_dim_cfg->render_height > 0) {
794     cm->render_width = frm_dim_cfg->render_width;
795     cm->render_height = frm_dim_cfg->render_height;
796   } else {
797     cm->render_width = frm_dim_cfg->width;
798     cm->render_height = frm_dim_cfg->height;
799   }
800   cm->width = frm_dim_cfg->width;
801   cm->height = frm_dim_cfg->height;
802 
803   if (initial_dimensions->width || is_sb_size_changed) {
804     if (cm->width > initial_dimensions->width ||
805         cm->height > initial_dimensions->height || is_sb_size_changed) {
806       av1_free_context_buffers(cm);
807       av1_free_shared_coeff_buffer(&cpi->td.shared_coeff_buf);
808       av1_free_sms_tree(&cpi->td);
809       av1_free_pmc(cpi->td.firstpass_ctx, av1_num_planes(cm));
810       cpi->td.firstpass_ctx = NULL;
811       alloc_compressor_data(cpi);
812       realloc_segmentation_maps(cpi);
813       initial_dimensions->width = initial_dimensions->height = 0;
814     }
815   }
816   av1_update_frame_size(cpi);
817 
818   rc->is_src_frame_alt_ref = 0;
819 
820   set_tile_info(cm, &cpi->oxcf.tile_cfg);
821 
822   if (!cpi->svc.set_ref_frame_config)
823     cpi->ext_flags.refresh_frame.update_pending = 0;
824   cpi->ext_flags.refresh_frame_context_pending = 0;
825 
826   if (cpi->ppi->use_svc)
827     av1_update_layer_context_change_config(cpi, rc_cfg->target_bandwidth);
828 
829   check_reset_rc_flag(cpi);
830 
831   // restore the value of lag_in_frame for LAP stage.
832   if (lap_lag_in_frames != -1) {
833     cpi->oxcf.gf_cfg.lag_in_frames = lap_lag_in_frames;
834   }
835 }
836 
init_frame_info(FRAME_INFO * frame_info,const AV1_COMMON * const cm)837 static INLINE void init_frame_info(FRAME_INFO *frame_info,
838                                    const AV1_COMMON *const cm) {
839   const CommonModeInfoParams *const mi_params = &cm->mi_params;
840   const SequenceHeader *const seq_params = cm->seq_params;
841   frame_info->frame_width = cm->width;
842   frame_info->frame_height = cm->height;
843   frame_info->mi_cols = mi_params->mi_cols;
844   frame_info->mi_rows = mi_params->mi_rows;
845   frame_info->mb_cols = mi_params->mb_cols;
846   frame_info->mb_rows = mi_params->mb_rows;
847   frame_info->num_mbs = mi_params->MBs;
848   frame_info->bit_depth = seq_params->bit_depth;
849   frame_info->subsampling_x = seq_params->subsampling_x;
850   frame_info->subsampling_y = seq_params->subsampling_y;
851 }
852 
init_frame_index_set(FRAME_INDEX_SET * frame_index_set)853 static INLINE void init_frame_index_set(FRAME_INDEX_SET *frame_index_set) {
854   frame_index_set->show_frame_count = 0;
855 }
856 
update_frame_index_set(FRAME_INDEX_SET * frame_index_set,int is_show_frame)857 static INLINE void update_frame_index_set(FRAME_INDEX_SET *frame_index_set,
858                                           int is_show_frame) {
859   if (is_show_frame) {
860     frame_index_set->show_frame_count++;
861   }
862 }
863 
av1_create_primary_compressor(struct aom_codec_pkt_list * pkt_list_head,int num_lap_buffers,AV1EncoderConfig * oxcf)864 AV1_PRIMARY *av1_create_primary_compressor(
865     struct aom_codec_pkt_list *pkt_list_head, int num_lap_buffers,
866     AV1EncoderConfig *oxcf) {
867   AV1_PRIMARY *volatile const ppi = aom_memalign(32, sizeof(AV1_PRIMARY));
868   if (!ppi) return NULL;
869   av1_zero(*ppi);
870 
871   // The jmp_buf is valid only for the duration of the function that calls
872   // setjmp(). Therefore, this function must reset the 'setjmp' field to 0
873   // before it returns.
874   if (setjmp(ppi->error.jmp)) {
875     ppi->error.setjmp = 0;
876     av1_remove_primary_compressor(ppi);
877     return 0;
878   }
879   ppi->error.setjmp = 1;
880 
881   ppi->seq_params_locked = 0;
882   ppi->lap_enabled = num_lap_buffers > 0;
883   ppi->output_pkt_list = pkt_list_head;
884   ppi->b_calculate_psnr = CONFIG_INTERNAL_STATS;
885   ppi->frames_left = oxcf->input_cfg.limit;
886 #if CONFIG_FRAME_PARALLEL_ENCODE
887   ppi->num_fp_contexts = 1;
888 #endif
889 
890   init_config_sequence(ppi, oxcf);
891 
892 #if CONFIG_ENTROPY_STATS
893   av1_zero(ppi->aggregate_fc);
894 #endif  // CONFIG_ENTROPY_STATS
895 
896   av1_primary_rc_init(oxcf, &ppi->p_rc);
897 
898   // For two pass and lag_in_frames > 33 in LAP.
899   ppi->p_rc.enable_scenecut_detection = ENABLE_SCENECUT_MODE_2;
900   if (ppi->lap_enabled) {
901     if ((num_lap_buffers <
902          (MAX_GF_LENGTH_LAP + SCENE_CUT_KEY_TEST_INTERVAL + 1)) &&
903         num_lap_buffers >= (MAX_GF_LENGTH_LAP + 3)) {
904       /*
905        * For lag in frames >= 19 and <33, enable scenecut
906        * with limited future frame prediction.
907        */
908       ppi->p_rc.enable_scenecut_detection = ENABLE_SCENECUT_MODE_1;
909     } else if (num_lap_buffers < (MAX_GF_LENGTH_LAP + 3)) {
910       // Disable scenecut when lag_in_frames < 19.
911       ppi->p_rc.enable_scenecut_detection = DISABLE_SCENECUT;
912     }
913   }
914 
915 #define BFP(BT, SDF, SDAF, VF, SVF, SVAF, SDX4DF, JSDAF, JSVAF) \
916   ppi->fn_ptr[BT].sdf = SDF;                                    \
917   ppi->fn_ptr[BT].sdaf = SDAF;                                  \
918   ppi->fn_ptr[BT].vf = VF;                                      \
919   ppi->fn_ptr[BT].svf = SVF;                                    \
920   ppi->fn_ptr[BT].svaf = SVAF;                                  \
921   ppi->fn_ptr[BT].sdx4df = SDX4DF;                              \
922   ppi->fn_ptr[BT].jsdaf = JSDAF;                                \
923   ppi->fn_ptr[BT].jsvaf = JSVAF;
924 
925 // Realtime mode doesn't use 4x rectangular blocks.
926 #if !CONFIG_REALTIME_ONLY
927   BFP(BLOCK_4X16, aom_sad4x16, aom_sad4x16_avg, aom_variance4x16,
928       aom_sub_pixel_variance4x16, aom_sub_pixel_avg_variance4x16,
929       aom_sad4x16x4d, aom_dist_wtd_sad4x16_avg,
930       aom_dist_wtd_sub_pixel_avg_variance4x16)
931 
932   BFP(BLOCK_16X4, aom_sad16x4, aom_sad16x4_avg, aom_variance16x4,
933       aom_sub_pixel_variance16x4, aom_sub_pixel_avg_variance16x4,
934       aom_sad16x4x4d, aom_dist_wtd_sad16x4_avg,
935       aom_dist_wtd_sub_pixel_avg_variance16x4)
936 
937   BFP(BLOCK_8X32, aom_sad8x32, aom_sad8x32_avg, aom_variance8x32,
938       aom_sub_pixel_variance8x32, aom_sub_pixel_avg_variance8x32,
939       aom_sad8x32x4d, aom_dist_wtd_sad8x32_avg,
940       aom_dist_wtd_sub_pixel_avg_variance8x32)
941 
942   BFP(BLOCK_32X8, aom_sad32x8, aom_sad32x8_avg, aom_variance32x8,
943       aom_sub_pixel_variance32x8, aom_sub_pixel_avg_variance32x8,
944       aom_sad32x8x4d, aom_dist_wtd_sad32x8_avg,
945       aom_dist_wtd_sub_pixel_avg_variance32x8)
946 
947   BFP(BLOCK_16X64, aom_sad16x64, aom_sad16x64_avg, aom_variance16x64,
948       aom_sub_pixel_variance16x64, aom_sub_pixel_avg_variance16x64,
949       aom_sad16x64x4d, aom_dist_wtd_sad16x64_avg,
950       aom_dist_wtd_sub_pixel_avg_variance16x64)
951 
952   BFP(BLOCK_64X16, aom_sad64x16, aom_sad64x16_avg, aom_variance64x16,
953       aom_sub_pixel_variance64x16, aom_sub_pixel_avg_variance64x16,
954       aom_sad64x16x4d, aom_dist_wtd_sad64x16_avg,
955       aom_dist_wtd_sub_pixel_avg_variance64x16)
956 #endif  // !CONFIG_REALTIME_ONLY
957 
958   BFP(BLOCK_128X128, aom_sad128x128, aom_sad128x128_avg, aom_variance128x128,
959       aom_sub_pixel_variance128x128, aom_sub_pixel_avg_variance128x128,
960       aom_sad128x128x4d, aom_dist_wtd_sad128x128_avg,
961       aom_dist_wtd_sub_pixel_avg_variance128x128)
962 
963   BFP(BLOCK_128X64, aom_sad128x64, aom_sad128x64_avg, aom_variance128x64,
964       aom_sub_pixel_variance128x64, aom_sub_pixel_avg_variance128x64,
965       aom_sad128x64x4d, aom_dist_wtd_sad128x64_avg,
966       aom_dist_wtd_sub_pixel_avg_variance128x64)
967 
968   BFP(BLOCK_64X128, aom_sad64x128, aom_sad64x128_avg, aom_variance64x128,
969       aom_sub_pixel_variance64x128, aom_sub_pixel_avg_variance64x128,
970       aom_sad64x128x4d, aom_dist_wtd_sad64x128_avg,
971       aom_dist_wtd_sub_pixel_avg_variance64x128)
972 
973   BFP(BLOCK_32X16, aom_sad32x16, aom_sad32x16_avg, aom_variance32x16,
974       aom_sub_pixel_variance32x16, aom_sub_pixel_avg_variance32x16,
975       aom_sad32x16x4d, aom_dist_wtd_sad32x16_avg,
976       aom_dist_wtd_sub_pixel_avg_variance32x16)
977 
978   BFP(BLOCK_16X32, aom_sad16x32, aom_sad16x32_avg, aom_variance16x32,
979       aom_sub_pixel_variance16x32, aom_sub_pixel_avg_variance16x32,
980       aom_sad16x32x4d, aom_dist_wtd_sad16x32_avg,
981       aom_dist_wtd_sub_pixel_avg_variance16x32)
982 
983   BFP(BLOCK_64X32, aom_sad64x32, aom_sad64x32_avg, aom_variance64x32,
984       aom_sub_pixel_variance64x32, aom_sub_pixel_avg_variance64x32,
985       aom_sad64x32x4d, aom_dist_wtd_sad64x32_avg,
986       aom_dist_wtd_sub_pixel_avg_variance64x32)
987 
988   BFP(BLOCK_32X64, aom_sad32x64, aom_sad32x64_avg, aom_variance32x64,
989       aom_sub_pixel_variance32x64, aom_sub_pixel_avg_variance32x64,
990       aom_sad32x64x4d, aom_dist_wtd_sad32x64_avg,
991       aom_dist_wtd_sub_pixel_avg_variance32x64)
992 
993   BFP(BLOCK_32X32, aom_sad32x32, aom_sad32x32_avg, aom_variance32x32,
994       aom_sub_pixel_variance32x32, aom_sub_pixel_avg_variance32x32,
995       aom_sad32x32x4d, aom_dist_wtd_sad32x32_avg,
996       aom_dist_wtd_sub_pixel_avg_variance32x32)
997 
998   BFP(BLOCK_64X64, aom_sad64x64, aom_sad64x64_avg, aom_variance64x64,
999       aom_sub_pixel_variance64x64, aom_sub_pixel_avg_variance64x64,
1000       aom_sad64x64x4d, aom_dist_wtd_sad64x64_avg,
1001       aom_dist_wtd_sub_pixel_avg_variance64x64)
1002 
1003   BFP(BLOCK_16X16, aom_sad16x16, aom_sad16x16_avg, aom_variance16x16,
1004       aom_sub_pixel_variance16x16, aom_sub_pixel_avg_variance16x16,
1005       aom_sad16x16x4d, aom_dist_wtd_sad16x16_avg,
1006       aom_dist_wtd_sub_pixel_avg_variance16x16)
1007 
1008   BFP(BLOCK_16X8, aom_sad16x8, aom_sad16x8_avg, aom_variance16x8,
1009       aom_sub_pixel_variance16x8, aom_sub_pixel_avg_variance16x8,
1010       aom_sad16x8x4d, aom_dist_wtd_sad16x8_avg,
1011       aom_dist_wtd_sub_pixel_avg_variance16x8)
1012 
1013   BFP(BLOCK_8X16, aom_sad8x16, aom_sad8x16_avg, aom_variance8x16,
1014       aom_sub_pixel_variance8x16, aom_sub_pixel_avg_variance8x16,
1015       aom_sad8x16x4d, aom_dist_wtd_sad8x16_avg,
1016       aom_dist_wtd_sub_pixel_avg_variance8x16)
1017 
1018   BFP(BLOCK_8X8, aom_sad8x8, aom_sad8x8_avg, aom_variance8x8,
1019       aom_sub_pixel_variance8x8, aom_sub_pixel_avg_variance8x8, aom_sad8x8x4d,
1020       aom_dist_wtd_sad8x8_avg, aom_dist_wtd_sub_pixel_avg_variance8x8)
1021 
1022   BFP(BLOCK_8X4, aom_sad8x4, aom_sad8x4_avg, aom_variance8x4,
1023       aom_sub_pixel_variance8x4, aom_sub_pixel_avg_variance8x4, aom_sad8x4x4d,
1024       aom_dist_wtd_sad8x4_avg, aom_dist_wtd_sub_pixel_avg_variance8x4)
1025 
1026   BFP(BLOCK_4X8, aom_sad4x8, aom_sad4x8_avg, aom_variance4x8,
1027       aom_sub_pixel_variance4x8, aom_sub_pixel_avg_variance4x8, aom_sad4x8x4d,
1028       aom_dist_wtd_sad4x8_avg, aom_dist_wtd_sub_pixel_avg_variance4x8)
1029 
1030   BFP(BLOCK_4X4, aom_sad4x4, aom_sad4x4_avg, aom_variance4x4,
1031       aom_sub_pixel_variance4x4, aom_sub_pixel_avg_variance4x4, aom_sad4x4x4d,
1032       aom_dist_wtd_sad4x4_avg, aom_dist_wtd_sub_pixel_avg_variance4x4)
1033 
1034 #if !CONFIG_REALTIME_ONLY
1035 #define OBFP(BT, OSDF, OVF, OSVF) \
1036   ppi->fn_ptr[BT].osdf = OSDF;    \
1037   ppi->fn_ptr[BT].ovf = OVF;      \
1038   ppi->fn_ptr[BT].osvf = OSVF;
1039 
1040   OBFP(BLOCK_128X128, aom_obmc_sad128x128, aom_obmc_variance128x128,
1041        aom_obmc_sub_pixel_variance128x128)
1042   OBFP(BLOCK_128X64, aom_obmc_sad128x64, aom_obmc_variance128x64,
1043        aom_obmc_sub_pixel_variance128x64)
1044   OBFP(BLOCK_64X128, aom_obmc_sad64x128, aom_obmc_variance64x128,
1045        aom_obmc_sub_pixel_variance64x128)
1046   OBFP(BLOCK_64X64, aom_obmc_sad64x64, aom_obmc_variance64x64,
1047        aom_obmc_sub_pixel_variance64x64)
1048   OBFP(BLOCK_64X32, aom_obmc_sad64x32, aom_obmc_variance64x32,
1049        aom_obmc_sub_pixel_variance64x32)
1050   OBFP(BLOCK_32X64, aom_obmc_sad32x64, aom_obmc_variance32x64,
1051        aom_obmc_sub_pixel_variance32x64)
1052   OBFP(BLOCK_32X32, aom_obmc_sad32x32, aom_obmc_variance32x32,
1053        aom_obmc_sub_pixel_variance32x32)
1054   OBFP(BLOCK_32X16, aom_obmc_sad32x16, aom_obmc_variance32x16,
1055        aom_obmc_sub_pixel_variance32x16)
1056   OBFP(BLOCK_16X32, aom_obmc_sad16x32, aom_obmc_variance16x32,
1057        aom_obmc_sub_pixel_variance16x32)
1058   OBFP(BLOCK_16X16, aom_obmc_sad16x16, aom_obmc_variance16x16,
1059        aom_obmc_sub_pixel_variance16x16)
1060   OBFP(BLOCK_16X8, aom_obmc_sad16x8, aom_obmc_variance16x8,
1061        aom_obmc_sub_pixel_variance16x8)
1062   OBFP(BLOCK_8X16, aom_obmc_sad8x16, aom_obmc_variance8x16,
1063        aom_obmc_sub_pixel_variance8x16)
1064   OBFP(BLOCK_8X8, aom_obmc_sad8x8, aom_obmc_variance8x8,
1065        aom_obmc_sub_pixel_variance8x8)
1066   OBFP(BLOCK_4X8, aom_obmc_sad4x8, aom_obmc_variance4x8,
1067        aom_obmc_sub_pixel_variance4x8)
1068   OBFP(BLOCK_8X4, aom_obmc_sad8x4, aom_obmc_variance8x4,
1069        aom_obmc_sub_pixel_variance8x4)
1070   OBFP(BLOCK_4X4, aom_obmc_sad4x4, aom_obmc_variance4x4,
1071        aom_obmc_sub_pixel_variance4x4)
1072   OBFP(BLOCK_4X16, aom_obmc_sad4x16, aom_obmc_variance4x16,
1073        aom_obmc_sub_pixel_variance4x16)
1074   OBFP(BLOCK_16X4, aom_obmc_sad16x4, aom_obmc_variance16x4,
1075        aom_obmc_sub_pixel_variance16x4)
1076   OBFP(BLOCK_8X32, aom_obmc_sad8x32, aom_obmc_variance8x32,
1077        aom_obmc_sub_pixel_variance8x32)
1078   OBFP(BLOCK_32X8, aom_obmc_sad32x8, aom_obmc_variance32x8,
1079        aom_obmc_sub_pixel_variance32x8)
1080   OBFP(BLOCK_16X64, aom_obmc_sad16x64, aom_obmc_variance16x64,
1081        aom_obmc_sub_pixel_variance16x64)
1082   OBFP(BLOCK_64X16, aom_obmc_sad64x16, aom_obmc_variance64x16,
1083        aom_obmc_sub_pixel_variance64x16)
1084 #endif  // !CONFIG_REALTIME_ONLY
1085 
1086 #define MBFP(BT, MCSDF, MCSVF)  \
1087   ppi->fn_ptr[BT].msdf = MCSDF; \
1088   ppi->fn_ptr[BT].msvf = MCSVF;
1089 
1090   MBFP(BLOCK_128X128, aom_masked_sad128x128,
1091        aom_masked_sub_pixel_variance128x128)
1092   MBFP(BLOCK_128X64, aom_masked_sad128x64, aom_masked_sub_pixel_variance128x64)
1093   MBFP(BLOCK_64X128, aom_masked_sad64x128, aom_masked_sub_pixel_variance64x128)
1094   MBFP(BLOCK_64X64, aom_masked_sad64x64, aom_masked_sub_pixel_variance64x64)
1095   MBFP(BLOCK_64X32, aom_masked_sad64x32, aom_masked_sub_pixel_variance64x32)
1096   MBFP(BLOCK_32X64, aom_masked_sad32x64, aom_masked_sub_pixel_variance32x64)
1097   MBFP(BLOCK_32X32, aom_masked_sad32x32, aom_masked_sub_pixel_variance32x32)
1098   MBFP(BLOCK_32X16, aom_masked_sad32x16, aom_masked_sub_pixel_variance32x16)
1099   MBFP(BLOCK_16X32, aom_masked_sad16x32, aom_masked_sub_pixel_variance16x32)
1100   MBFP(BLOCK_16X16, aom_masked_sad16x16, aom_masked_sub_pixel_variance16x16)
1101   MBFP(BLOCK_16X8, aom_masked_sad16x8, aom_masked_sub_pixel_variance16x8)
1102   MBFP(BLOCK_8X16, aom_masked_sad8x16, aom_masked_sub_pixel_variance8x16)
1103   MBFP(BLOCK_8X8, aom_masked_sad8x8, aom_masked_sub_pixel_variance8x8)
1104   MBFP(BLOCK_4X8, aom_masked_sad4x8, aom_masked_sub_pixel_variance4x8)
1105   MBFP(BLOCK_8X4, aom_masked_sad8x4, aom_masked_sub_pixel_variance8x4)
1106   MBFP(BLOCK_4X4, aom_masked_sad4x4, aom_masked_sub_pixel_variance4x4)
1107 
1108 #if !CONFIG_REALTIME_ONLY
1109   MBFP(BLOCK_4X16, aom_masked_sad4x16, aom_masked_sub_pixel_variance4x16)
1110   MBFP(BLOCK_16X4, aom_masked_sad16x4, aom_masked_sub_pixel_variance16x4)
1111   MBFP(BLOCK_8X32, aom_masked_sad8x32, aom_masked_sub_pixel_variance8x32)
1112   MBFP(BLOCK_32X8, aom_masked_sad32x8, aom_masked_sub_pixel_variance32x8)
1113   MBFP(BLOCK_16X64, aom_masked_sad16x64, aom_masked_sub_pixel_variance16x64)
1114   MBFP(BLOCK_64X16, aom_masked_sad64x16, aom_masked_sub_pixel_variance64x16)
1115 #endif
1116 
1117 #define SDSFP(BT, SDSF, SDSX4DF) \
1118   ppi->fn_ptr[BT].sdsf = SDSF;   \
1119   ppi->fn_ptr[BT].sdsx4df = SDSX4DF;
1120 
1121   SDSFP(BLOCK_128X128, aom_sad_skip_128x128, aom_sad_skip_128x128x4d);
1122   SDSFP(BLOCK_128X64, aom_sad_skip_128x64, aom_sad_skip_128x64x4d);
1123   SDSFP(BLOCK_64X128, aom_sad_skip_64x128, aom_sad_skip_64x128x4d);
1124   SDSFP(BLOCK_64X64, aom_sad_skip_64x64, aom_sad_skip_64x64x4d);
1125   SDSFP(BLOCK_64X32, aom_sad_skip_64x32, aom_sad_skip_64x32x4d);
1126 
1127   SDSFP(BLOCK_32X64, aom_sad_skip_32x64, aom_sad_skip_32x64x4d);
1128   SDSFP(BLOCK_32X32, aom_sad_skip_32x32, aom_sad_skip_32x32x4d);
1129   SDSFP(BLOCK_32X16, aom_sad_skip_32x16, aom_sad_skip_32x16x4d);
1130 
1131   SDSFP(BLOCK_16X32, aom_sad_skip_16x32, aom_sad_skip_16x32x4d);
1132   SDSFP(BLOCK_16X16, aom_sad_skip_16x16, aom_sad_skip_16x16x4d);
1133   SDSFP(BLOCK_16X8, aom_sad_skip_16x8, aom_sad_skip_16x8x4d);
1134   SDSFP(BLOCK_8X16, aom_sad_skip_8x16, aom_sad_skip_8x16x4d);
1135   SDSFP(BLOCK_8X8, aom_sad_skip_8x8, aom_sad_skip_8x8x4d);
1136 
1137   SDSFP(BLOCK_4X8, aom_sad_skip_4x8, aom_sad_skip_4x8x4d);
1138 
1139 #if !CONFIG_REALTIME_ONLY
1140   SDSFP(BLOCK_64X16, aom_sad_skip_64x16, aom_sad_skip_64x16x4d);
1141   SDSFP(BLOCK_16X64, aom_sad_skip_16x64, aom_sad_skip_16x64x4d);
1142   SDSFP(BLOCK_32X8, aom_sad_skip_32x8, aom_sad_skip_32x8x4d);
1143   SDSFP(BLOCK_8X32, aom_sad_skip_8x32, aom_sad_skip_8x32x4d);
1144   SDSFP(BLOCK_4X16, aom_sad_skip_4x16, aom_sad_skip_4x16x4d);
1145 #endif
1146 #undef SDSFP
1147 
1148 #if CONFIG_AV1_HIGHBITDEPTH
1149   highbd_set_var_fns(ppi);
1150 #endif
1151 
1152   {
1153     // As cm->mi_params is a part of the frame level context (cpi), it is
1154     // unavailable at this point. mi_params is created as a local temporary
1155     // variable, to be passed into the functions used for allocating tpl
1156     // buffers. The values in this variable are populated according to initial
1157     // width and height of the frame.
1158     CommonModeInfoParams mi_params;
1159     enc_set_mb_mi(&mi_params, oxcf->frm_dim_cfg.width,
1160                   oxcf->frm_dim_cfg.height);
1161 
1162     const int bsize = BLOCK_16X16;
1163     const int w = mi_size_wide[bsize];
1164     const int h = mi_size_high[bsize];
1165     const int num_cols = (mi_params.mi_cols + w - 1) / w;
1166     const int num_rows = (mi_params.mi_rows + h - 1) / h;
1167     AOM_CHECK_MEM_ERROR(&ppi->error, ppi->tpl_rdmult_scaling_factors,
1168                         aom_calloc(num_rows * num_cols,
1169                                    sizeof(*ppi->tpl_rdmult_scaling_factors)));
1170     AOM_CHECK_MEM_ERROR(
1171         &ppi->error, ppi->tpl_sb_rdmult_scaling_factors,
1172         aom_calloc(num_rows * num_cols,
1173                    sizeof(*ppi->tpl_sb_rdmult_scaling_factors)));
1174 
1175 #if !CONFIG_REALTIME_ONLY
1176     if (oxcf->pass != AOM_RC_FIRST_PASS) {
1177       av1_setup_tpl_buffers(ppi, &mi_params, oxcf->frm_dim_cfg.width,
1178                             oxcf->frm_dim_cfg.height, 0,
1179                             oxcf->gf_cfg.lag_in_frames);
1180     }
1181 #endif
1182 
1183 #if CONFIG_INTERNAL_STATS
1184     ppi->b_calculate_blockiness = 1;
1185     ppi->b_calculate_consistency = 1;
1186 
1187     for (int i = 0; i <= STAT_ALL; i++) {
1188       ppi->psnr[0].stat[i] = 0;
1189       ppi->psnr[1].stat[i] = 0;
1190 
1191       ppi->fastssim.stat[i] = 0;
1192       ppi->psnrhvs.stat[i] = 0;
1193     }
1194 
1195     ppi->psnr[0].worst = 100.0;
1196     ppi->psnr[1].worst = 100.0;
1197     ppi->worst_ssim = 100.0;
1198     ppi->worst_ssim_hbd = 100.0;
1199 
1200     ppi->count[0] = 0;
1201     ppi->count[1] = 0;
1202     ppi->total_bytes = 0;
1203 
1204     if (ppi->b_calculate_psnr) {
1205       ppi->total_sq_error[0] = 0;
1206       ppi->total_samples[0] = 0;
1207       ppi->total_sq_error[1] = 0;
1208       ppi->total_samples[1] = 0;
1209       ppi->total_recode_hits = 0;
1210       ppi->summed_quality = 0;
1211       ppi->summed_weights = 0;
1212       ppi->summed_quality_hbd = 0;
1213       ppi->summed_weights_hbd = 0;
1214     }
1215 
1216     ppi->fastssim.worst = 100.0;
1217     ppi->psnrhvs.worst = 100.0;
1218 
1219     if (ppi->b_calculate_blockiness) {
1220       ppi->total_blockiness = 0;
1221       ppi->worst_blockiness = 0.0;
1222     }
1223 
1224     ppi->total_inconsistency = 0;
1225     ppi->worst_consistency = 100.0;
1226     if (ppi->b_calculate_consistency) {
1227       AOM_CHECK_MEM_ERROR(&ppi->error, ppi->ssim_vars,
1228                           aom_malloc(sizeof(*ppi->ssim_vars) * 4 *
1229                                      mi_params.mi_rows * mi_params.mi_cols));
1230     }
1231 #endif
1232   }
1233 
1234   ppi->error.setjmp = 0;
1235   return ppi;
1236 }
1237 
av1_create_compressor(AV1_PRIMARY * ppi,AV1EncoderConfig * oxcf,BufferPool * const pool,COMPRESSOR_STAGE stage,int lap_lag_in_frames)1238 AV1_COMP *av1_create_compressor(AV1_PRIMARY *ppi, AV1EncoderConfig *oxcf,
1239                                 BufferPool *const pool, COMPRESSOR_STAGE stage,
1240                                 int lap_lag_in_frames) {
1241   AV1_COMP *volatile const cpi = aom_memalign(32, sizeof(AV1_COMP));
1242   AV1_COMMON *volatile const cm = cpi != NULL ? &cpi->common : NULL;
1243 
1244   if (!cm) return NULL;
1245 
1246   av1_zero(*cpi);
1247 
1248   cpi->ppi = ppi;
1249   cm->seq_params = &ppi->seq_params;
1250 #if CONFIG_FRAME_PARALLEL_ENCODE
1251   cm->error =
1252       (struct aom_internal_error_info *)aom_calloc(1, sizeof(*cm->error));
1253 #else
1254   cm->error = &ppi->error;
1255 #endif  // CONFIG_FRAME_PARALLEL_ENCODE
1256 
1257   // The jmp_buf is valid only for the duration of the function that calls
1258   // setjmp(). Therefore, this function must reset the 'setjmp' field to 0
1259   // before it returns.
1260   if (setjmp(cm->error->jmp)) {
1261     cm->error->setjmp = 0;
1262     av1_remove_compressor(cpi);
1263     return 0;
1264   }
1265 
1266   cm->error->setjmp = 1;
1267   cpi->compressor_stage = stage;
1268 
1269 #if CONFIG_FRAME_PARALLEL_ENCODE
1270   cpi->do_frame_data_update = true;
1271 #endif
1272 
1273   CommonModeInfoParams *const mi_params = &cm->mi_params;
1274   mi_params->free_mi = enc_free_mi;
1275   mi_params->setup_mi = enc_setup_mi;
1276   mi_params->set_mb_mi =
1277       (oxcf->pass == AOM_RC_FIRST_PASS || cpi->compressor_stage == LAP_STAGE)
1278           ? stat_stage_set_mb_mi
1279           : enc_set_mb_mi;
1280 
1281   mi_params->mi_alloc_bsize = BLOCK_4X4;
1282 
1283   CHECK_MEM_ERROR(cm, cm->fc,
1284                   (FRAME_CONTEXT *)aom_memalign(32, sizeof(*cm->fc)));
1285   CHECK_MEM_ERROR(
1286       cm, cm->default_frame_context,
1287       (FRAME_CONTEXT *)aom_memalign(32, sizeof(*cm->default_frame_context)));
1288   memset(cm->fc, 0, sizeof(*cm->fc));
1289   memset(cm->default_frame_context, 0, sizeof(*cm->default_frame_context));
1290 
1291   cpi->common.buffer_pool = pool;
1292 
1293   init_config(cpi, oxcf);
1294   if (cpi->compressor_stage == LAP_STAGE) {
1295     cpi->oxcf.gf_cfg.lag_in_frames = lap_lag_in_frames;
1296   }
1297 
1298   av1_rc_init(&cpi->oxcf, &cpi->rc);
1299 
1300   init_frame_info(&cpi->frame_info, cm);
1301   init_frame_index_set(&cpi->frame_index_set);
1302 
1303   cm->current_frame.frame_number = 0;
1304   cm->current_frame_id = -1;
1305   cpi->tile_data = NULL;
1306   cpi->last_show_frame_buf = NULL;
1307   realloc_segmentation_maps(cpi);
1308 
1309   cpi->refresh_frame.alt_ref_frame = false;
1310 
1311 #if CONFIG_SPEED_STATS
1312   cpi->tx_search_count = 0;
1313 #endif  // CONFIG_SPEED_STATS
1314 
1315   cpi->time_stamps.first_ts_start = INT64_MAX;
1316 
1317 #ifdef OUTPUT_YUV_REC
1318   yuv_rec_file = fopen("rec.yuv", "wb");
1319 #endif
1320 #ifdef OUTPUT_YUV_DENOISED
1321   yuv_denoised_file = fopen("denoised.yuv", "wb");
1322 #endif
1323 
1324 #if !CONFIG_REALTIME_ONLY
1325   if (is_stat_consumption_stage(cpi)) {
1326     const size_t packet_sz = sizeof(FIRSTPASS_STATS);
1327     const int packets = (int)(oxcf->twopass_stats_in.sz / packet_sz);
1328 
1329     if (!cpi->ppi->lap_enabled) {
1330       /*Re-initialize to stats buffer, populated by application in the case of
1331        * two pass*/
1332       cpi->ppi->twopass.stats_buf_ctx->stats_in_start =
1333           oxcf->twopass_stats_in.buf;
1334       cpi->twopass_frame.stats_in =
1335           cpi->ppi->twopass.stats_buf_ctx->stats_in_start;
1336       cpi->ppi->twopass.stats_buf_ctx->stats_in_end =
1337           &cpi->ppi->twopass.stats_buf_ctx->stats_in_start[packets - 1];
1338 
1339       // The buffer size is packets - 1 because the last packet is total_stats.
1340       av1_firstpass_info_init(&cpi->ppi->twopass.firstpass_info,
1341                               oxcf->twopass_stats_in.buf, packets - 1);
1342       av1_init_second_pass(cpi);
1343     } else {
1344       av1_firstpass_info_init(&cpi->ppi->twopass.firstpass_info, NULL, 0);
1345       av1_init_single_pass_lap(cpi);
1346     }
1347   }
1348 #endif
1349 
1350   alloc_obmc_buffers(&cpi->td.mb.obmc_buffer, cm->error);
1351 
1352   for (int x = 0; x < 2; x++)
1353     for (int y = 0; y < 2; y++)
1354       CHECK_MEM_ERROR(
1355           cm, cpi->td.mb.intrabc_hash_info.hash_value_buffer[x][y],
1356           (uint32_t *)aom_malloc(
1357               AOM_BUFFER_SIZE_FOR_BLOCK_HASH *
1358               sizeof(*cpi->td.mb.intrabc_hash_info.hash_value_buffer[0][0])));
1359 
1360   cpi->td.mb.intrabc_hash_info.g_crc_initialized = 0;
1361 
1362   av1_set_speed_features_framesize_independent(cpi, oxcf->speed);
1363   av1_set_speed_features_framesize_dependent(cpi, oxcf->speed);
1364 
1365   CHECK_MEM_ERROR(cm, cpi->consec_zero_mv,
1366                   aom_calloc((mi_params->mi_rows * mi_params->mi_cols) >> 2,
1367                              sizeof(*cpi->consec_zero_mv)));
1368 
1369   cpi->mb_weber_stats = NULL;
1370   cpi->mb_delta_q = NULL;
1371 
1372   {
1373     const int bsize = BLOCK_16X16;
1374     const int w = mi_size_wide[bsize];
1375     const int h = mi_size_high[bsize];
1376     const int num_cols = (mi_params->mi_cols + w - 1) / w;
1377     const int num_rows = (mi_params->mi_rows + h - 1) / h;
1378     CHECK_MEM_ERROR(cm, cpi->ssim_rdmult_scaling_factors,
1379                     aom_calloc(num_rows * num_cols,
1380                                sizeof(*cpi->ssim_rdmult_scaling_factors)));
1381   }
1382 
1383 #if CONFIG_TUNE_VMAF
1384   {
1385     const int bsize = BLOCK_64X64;
1386     const int w = mi_size_wide[bsize];
1387     const int h = mi_size_high[bsize];
1388     const int num_cols = (mi_params->mi_cols + w - 1) / w;
1389     const int num_rows = (mi_params->mi_rows + h - 1) / h;
1390     CHECK_MEM_ERROR(cm, cpi->vmaf_info.rdmult_scaling_factors,
1391                     aom_calloc(num_rows * num_cols,
1392                                sizeof(*cpi->vmaf_info.rdmult_scaling_factors)));
1393     for (int i = 0; i < MAX_ARF_LAYERS; i++) {
1394       cpi->vmaf_info.last_frame_unsharp_amount[i] = -1.0;
1395       cpi->vmaf_info.last_frame_ysse[i] = -1.0;
1396       cpi->vmaf_info.last_frame_vmaf[i] = -1.0;
1397     }
1398     cpi->vmaf_info.original_qindex = -1;
1399     cpi->vmaf_info.vmaf_model = NULL;
1400   }
1401 #endif
1402 
1403 #if CONFIG_TUNE_BUTTERAUGLI
1404   {
1405     const int w = mi_size_wide[butteraugli_rdo_bsize];
1406     const int h = mi_size_high[butteraugli_rdo_bsize];
1407     const int num_cols = (mi_params->mi_cols + w - 1) / w;
1408     const int num_rows = (mi_params->mi_rows + h - 1) / h;
1409     CHECK_MEM_ERROR(
1410         cm, cpi->butteraugli_info.rdmult_scaling_factors,
1411         aom_malloc(num_rows * num_cols *
1412                    sizeof(*cpi->butteraugli_info.rdmult_scaling_factors)));
1413     memset(&cpi->butteraugli_info.source, 0,
1414            sizeof(cpi->butteraugli_info.source));
1415     memset(&cpi->butteraugli_info.resized_source, 0,
1416            sizeof(cpi->butteraugli_info.resized_source));
1417     cpi->butteraugli_info.recon_set = false;
1418   }
1419 #endif
1420 
1421 #if CONFIG_COLLECT_PARTITION_STATS
1422   av1_zero(cpi->partition_stats);
1423 #endif  // CONFIG_COLLECT_PARTITION_STATS
1424 
1425   /* av1_init_quantizer() is first called here. Add check in
1426    * av1_frame_init_quantizer() so that av1_init_quantizer is only
1427    * called later when needed. This will avoid unnecessary calls of
1428    * av1_init_quantizer() for every frame.
1429    */
1430   av1_init_quantizer(&cpi->enc_quant_dequant_params, &cm->quant_params,
1431                      cm->seq_params->bit_depth);
1432   av1_qm_init(&cm->quant_params, av1_num_planes(cm));
1433 
1434   av1_loop_filter_init(cm);
1435   cm->superres_scale_denominator = SCALE_NUMERATOR;
1436   cm->superres_upscaled_width = oxcf->frm_dim_cfg.width;
1437   cm->superres_upscaled_height = oxcf->frm_dim_cfg.height;
1438 #if !CONFIG_REALTIME_ONLY
1439   av1_loop_restoration_precal();
1440 #endif
1441 
1442   cpi->third_pass_ctx = NULL;
1443   if (cpi->oxcf.pass == AOM_RC_THIRD_PASS) {
1444     av1_init_thirdpass_ctx(cm, &cpi->third_pass_ctx, NULL);
1445   }
1446 
1447   cm->error->setjmp = 0;
1448   return cpi;
1449 }
1450 
1451 #if CONFIG_INTERNAL_STATS
1452 #define SNPRINT(H, T) snprintf((H) + strlen(H), sizeof(H) - strlen(H), (T))
1453 
1454 #define SNPRINT2(H, T, V) \
1455   snprintf((H) + strlen(H), sizeof(H) - strlen(H), (T), (V))
1456 #endif  // CONFIG_INTERNAL_STATS
1457 
1458 // This function will change the state and free the mutex of corresponding
1459 // workers and terminate the object. The object can not be re-used unless a call
1460 // to reset() is made.
terminate_worker_data(AV1_PRIMARY * ppi)1461 static AOM_INLINE void terminate_worker_data(AV1_PRIMARY *ppi) {
1462   PrimaryMultiThreadInfo *const p_mt_info = &ppi->p_mt_info;
1463   for (int t = p_mt_info->num_workers - 1; t >= 0; --t) {
1464     AVxWorker *const worker = &p_mt_info->workers[t];
1465     aom_get_worker_interface()->end(worker);
1466   }
1467 }
1468 
1469 // Deallocate allocated thread_data.
free_thread_data(AV1_PRIMARY * ppi)1470 static AOM_INLINE void free_thread_data(AV1_PRIMARY *ppi) {
1471   PrimaryMultiThreadInfo *const p_mt_info = &ppi->p_mt_info;
1472   for (int t = 1; t < p_mt_info->num_workers; ++t) {
1473     EncWorkerData *const thread_data = &p_mt_info->tile_thr_data[t];
1474 #if CONFIG_FRAME_PARALLEL_ENCODE
1475     thread_data->td = thread_data->original_td;
1476 #endif
1477     aom_free(thread_data->td->tctx);
1478     aom_free(thread_data->td->palette_buffer);
1479     aom_free(thread_data->td->tmp_conv_dst);
1480     release_compound_type_rd_buffers(&thread_data->td->comp_rd_buffer);
1481     for (int j = 0; j < 2; ++j) {
1482       aom_free(thread_data->td->tmp_pred_bufs[j]);
1483     }
1484     aom_free(thread_data->td->pixel_gradient_info);
1485     release_obmc_buffers(&thread_data->td->obmc_buffer);
1486     aom_free(thread_data->td->vt64x64);
1487 
1488     for (int x = 0; x < 2; x++) {
1489       for (int y = 0; y < 2; y++) {
1490         aom_free(thread_data->td->hash_value_buffer[x][y]);
1491         thread_data->td->hash_value_buffer[x][y] = NULL;
1492       }
1493     }
1494     aom_free(thread_data->td->counts);
1495     av1_free_pmc(thread_data->td->firstpass_ctx,
1496                  ppi->seq_params.monochrome ? 1 : MAX_MB_PLANE);
1497     thread_data->td->firstpass_ctx = NULL;
1498     av1_free_shared_coeff_buffer(&thread_data->td->shared_coeff_buf);
1499     av1_free_sms_tree(thread_data->td);
1500     aom_free(thread_data->td);
1501   }
1502 }
1503 
av1_remove_primary_compressor(AV1_PRIMARY * ppi)1504 void av1_remove_primary_compressor(AV1_PRIMARY *ppi) {
1505   if (!ppi) return;
1506   aom_free_frame_buffer(&ppi->alt_ref_buffer);
1507   for (int i = 0; i < MAX_NUM_OPERATING_POINTS; ++i) {
1508     aom_free(ppi->level_params.level_info[i]);
1509   }
1510   av1_lookahead_destroy(ppi->lookahead);
1511 
1512   aom_free(ppi->tpl_rdmult_scaling_factors);
1513   ppi->tpl_rdmult_scaling_factors = NULL;
1514   aom_free(ppi->tpl_sb_rdmult_scaling_factors);
1515   ppi->tpl_sb_rdmult_scaling_factors = NULL;
1516 
1517   TplParams *const tpl_data = &ppi->tpl_data;
1518   for (int frame = 0; frame < MAX_LAG_BUFFERS; ++frame) {
1519     aom_free(tpl_data->tpl_stats_pool[frame]);
1520     aom_free_frame_buffer(&tpl_data->tpl_rec_pool[frame]);
1521   }
1522 
1523 #if !CONFIG_REALTIME_ONLY
1524   av1_tpl_dealloc(&tpl_data->tpl_mt_sync);
1525 #endif
1526 
1527   terminate_worker_data(ppi);
1528   free_thread_data(ppi);
1529 
1530   aom_free(ppi->p_mt_info.tile_thr_data);
1531   aom_free(ppi->p_mt_info.workers);
1532 
1533   aom_free(ppi);
1534 }
1535 
av1_remove_compressor(AV1_COMP * cpi)1536 void av1_remove_compressor(AV1_COMP *cpi) {
1537   if (!cpi) return;
1538 
1539   AV1_COMMON *cm = &cpi->common;
1540   if (cm->current_frame.frame_number > 0) {
1541 #if CONFIG_SPEED_STATS
1542     if (!is_stat_generation_stage(cpi)) {
1543       fprintf(stdout, "tx_search_count = %d\n", cpi->tx_search_count);
1544     }
1545 #endif  // CONFIG_SPEED_STATS
1546 
1547 #if CONFIG_COLLECT_PARTITION_STATS == 2
1548     if (!is_stat_generation_stage(cpi)) {
1549       av1_print_fr_partition_timing_stats(&cpi->partition_stats,
1550                                           "fr_part_timing_data.csv");
1551     }
1552 #endif
1553   }
1554 
1555 #if CONFIG_AV1_TEMPORAL_DENOISING
1556   av1_denoiser_free(&(cpi->denoiser));
1557 #endif
1558 
1559 #if CONFIG_FRAME_PARALLEL_ENCODE
1560   aom_free(cm->error);
1561 #endif
1562   aom_free(cpi->td.tctx);
1563   MultiThreadInfo *const mt_info = &cpi->mt_info;
1564 #if CONFIG_MULTITHREAD
1565   pthread_mutex_t *const enc_row_mt_mutex_ = mt_info->enc_row_mt.mutex_;
1566   pthread_mutex_t *const gm_mt_mutex_ = mt_info->gm_sync.mutex_;
1567   pthread_mutex_t *const pack_bs_mt_mutex_ = mt_info->pack_bs_sync.mutex_;
1568   if (enc_row_mt_mutex_ != NULL) {
1569     pthread_mutex_destroy(enc_row_mt_mutex_);
1570     aom_free(enc_row_mt_mutex_);
1571   }
1572   if (gm_mt_mutex_ != NULL) {
1573     pthread_mutex_destroy(gm_mt_mutex_);
1574     aom_free(gm_mt_mutex_);
1575   }
1576   if (pack_bs_mt_mutex_ != NULL) {
1577     pthread_mutex_destroy(pack_bs_mt_mutex_);
1578     aom_free(pack_bs_mt_mutex_);
1579   }
1580 #endif
1581   av1_row_mt_mem_dealloc(cpi);
1582 
1583   if (mt_info->num_workers > 1) {
1584     av1_loop_filter_dealloc(&mt_info->lf_row_sync);
1585     av1_cdef_mt_dealloc(&mt_info->cdef_sync);
1586 #if !CONFIG_REALTIME_ONLY
1587     int num_lr_workers =
1588         av1_get_num_mod_workers_for_alloc(&cpi->ppi->p_mt_info, MOD_LR);
1589     av1_loop_restoration_dealloc(&mt_info->lr_row_sync, num_lr_workers);
1590     av1_gm_dealloc(&mt_info->gm_sync);
1591     av1_tf_mt_dealloc(&mt_info->tf_sync);
1592 #endif
1593   }
1594 
1595   av1_free_thirdpass_ctx(cpi->third_pass_ctx);
1596 
1597   dealloc_compressor_data(cpi);
1598 
1599   av1_ext_part_delete(&cpi->ext_part_controller);
1600 
1601   av1_remove_common(cm);
1602 
1603   aom_free(cpi);
1604 
1605 #ifdef OUTPUT_YUV_REC
1606   fclose(yuv_rec_file);
1607 #endif
1608 
1609 #ifdef OUTPUT_YUV_DENOISED
1610   fclose(yuv_denoised_file);
1611 #endif
1612 }
1613 
generate_psnr_packet(AV1_COMP * cpi)1614 static void generate_psnr_packet(AV1_COMP *cpi) {
1615   struct aom_codec_cx_pkt pkt;
1616   int i;
1617   PSNR_STATS psnr;
1618 #if CONFIG_AV1_HIGHBITDEPTH
1619   const uint32_t in_bit_depth = cpi->oxcf.input_cfg.input_bit_depth;
1620   const uint32_t bit_depth = cpi->td.mb.e_mbd.bd;
1621   aom_calc_highbd_psnr(cpi->source, &cpi->common.cur_frame->buf, &psnr,
1622                        bit_depth, in_bit_depth);
1623 #else
1624   aom_calc_psnr(cpi->source, &cpi->common.cur_frame->buf, &psnr);
1625 #endif
1626 
1627   for (i = 0; i < 4; ++i) {
1628     pkt.data.psnr.samples[i] = psnr.samples[i];
1629     pkt.data.psnr.sse[i] = psnr.sse[i];
1630     pkt.data.psnr.psnr[i] = psnr.psnr[i];
1631   }
1632 
1633 #if CONFIG_AV1_HIGHBITDEPTH
1634   if ((cpi->source->flags & YV12_FLAG_HIGHBITDEPTH) &&
1635       (in_bit_depth < bit_depth)) {
1636     for (i = 0; i < 4; ++i) {
1637       pkt.data.psnr.samples_hbd[i] = psnr.samples_hbd[i];
1638       pkt.data.psnr.sse_hbd[i] = psnr.sse_hbd[i];
1639       pkt.data.psnr.psnr_hbd[i] = psnr.psnr_hbd[i];
1640     }
1641   }
1642 #endif
1643 
1644   pkt.kind = AOM_CODEC_PSNR_PKT;
1645   aom_codec_pkt_list_add(cpi->ppi->output_pkt_list, &pkt);
1646 }
1647 
av1_use_as_reference(int * ext_ref_frame_flags,int ref_frame_flags)1648 int av1_use_as_reference(int *ext_ref_frame_flags, int ref_frame_flags) {
1649   if (ref_frame_flags > ((1 << INTER_REFS_PER_FRAME) - 1)) return -1;
1650 
1651   *ext_ref_frame_flags = ref_frame_flags;
1652   return 0;
1653 }
1654 
av1_copy_reference_enc(AV1_COMP * cpi,int idx,YV12_BUFFER_CONFIG * sd)1655 int av1_copy_reference_enc(AV1_COMP *cpi, int idx, YV12_BUFFER_CONFIG *sd) {
1656   AV1_COMMON *const cm = &cpi->common;
1657   const int num_planes = av1_num_planes(cm);
1658   YV12_BUFFER_CONFIG *cfg = get_ref_frame(cm, idx);
1659   if (cfg) {
1660     aom_yv12_copy_frame(cfg, sd, num_planes);
1661     return 0;
1662   } else {
1663     return -1;
1664   }
1665 }
1666 
av1_set_reference_enc(AV1_COMP * cpi,int idx,YV12_BUFFER_CONFIG * sd)1667 int av1_set_reference_enc(AV1_COMP *cpi, int idx, YV12_BUFFER_CONFIG *sd) {
1668   AV1_COMMON *const cm = &cpi->common;
1669   const int num_planes = av1_num_planes(cm);
1670   YV12_BUFFER_CONFIG *cfg = get_ref_frame(cm, idx);
1671   if (cfg) {
1672     aom_yv12_copy_frame(sd, cfg, num_planes);
1673     return 0;
1674   } else {
1675     return -1;
1676   }
1677 }
1678 
1679 #ifdef OUTPUT_YUV_REC
aom_write_one_yuv_frame(AV1_COMMON * cm,YV12_BUFFER_CONFIG * s)1680 void aom_write_one_yuv_frame(AV1_COMMON *cm, YV12_BUFFER_CONFIG *s) {
1681   uint8_t *src = s->y_buffer;
1682   int h = cm->height;
1683   if (yuv_rec_file == NULL) return;
1684   if (s->flags & YV12_FLAG_HIGHBITDEPTH) {
1685     uint16_t *src16 = CONVERT_TO_SHORTPTR(s->y_buffer);
1686 
1687     do {
1688       fwrite(src16, s->y_width, 2, yuv_rec_file);
1689       src16 += s->y_stride;
1690     } while (--h);
1691 
1692     src16 = CONVERT_TO_SHORTPTR(s->u_buffer);
1693     h = s->uv_height;
1694 
1695     do {
1696       fwrite(src16, s->uv_width, 2, yuv_rec_file);
1697       src16 += s->uv_stride;
1698     } while (--h);
1699 
1700     src16 = CONVERT_TO_SHORTPTR(s->v_buffer);
1701     h = s->uv_height;
1702 
1703     do {
1704       fwrite(src16, s->uv_width, 2, yuv_rec_file);
1705       src16 += s->uv_stride;
1706     } while (--h);
1707 
1708     fflush(yuv_rec_file);
1709     return;
1710   }
1711 
1712   do {
1713     fwrite(src, s->y_width, 1, yuv_rec_file);
1714     src += s->y_stride;
1715   } while (--h);
1716 
1717   src = s->u_buffer;
1718   h = s->uv_height;
1719 
1720   do {
1721     fwrite(src, s->uv_width, 1, yuv_rec_file);
1722     src += s->uv_stride;
1723   } while (--h);
1724 
1725   src = s->v_buffer;
1726   h = s->uv_height;
1727 
1728   do {
1729     fwrite(src, s->uv_width, 1, yuv_rec_file);
1730     src += s->uv_stride;
1731   } while (--h);
1732 
1733   fflush(yuv_rec_file);
1734 }
1735 #endif  // OUTPUT_YUV_REC
1736 
set_mv_search_params(AV1_COMP * cpi)1737 static void set_mv_search_params(AV1_COMP *cpi) {
1738   const AV1_COMMON *const cm = &cpi->common;
1739   MotionVectorSearchParams *const mv_search_params = &cpi->mv_search_params;
1740   const int max_mv_def = AOMMAX(cm->width, cm->height);
1741 
1742   // Default based on max resolution.
1743   mv_search_params->mv_step_param = av1_init_search_range(max_mv_def);
1744 
1745   if (cpi->sf.mv_sf.auto_mv_step_size) {
1746     if (frame_is_intra_only(cm)) {
1747       // Initialize max_mv_magnitude for use in the first INTER frame
1748       // after a key/intra-only frame.
1749       mv_search_params->max_mv_magnitude = max_mv_def;
1750     } else {
1751       // Use cpi->max_mv_magnitude == -1 to exclude first pass case.
1752       if (cm->show_frame && mv_search_params->max_mv_magnitude != -1) {
1753         // Allow mv_steps to correspond to twice the max mv magnitude found
1754         // in the previous frame, capped by the default max_mv_magnitude based
1755         // on resolution.
1756         mv_search_params->mv_step_param = av1_init_search_range(
1757             AOMMIN(max_mv_def, 2 * mv_search_params->max_mv_magnitude));
1758       }
1759 #if CONFIG_FRAME_PARALLEL_ENCODE
1760       // Reset max_mv_magnitude for parallel frames based on update flag.
1761       if (cpi->do_frame_data_update) mv_search_params->max_mv_magnitude = -1;
1762 #else
1763       mv_search_params->max_mv_magnitude = -1;
1764 #endif
1765     }
1766   }
1767 }
1768 
av1_set_screen_content_options(AV1_COMP * cpi,FeatureFlags * features)1769 void av1_set_screen_content_options(AV1_COMP *cpi, FeatureFlags *features) {
1770   const AV1_COMMON *const cm = &cpi->common;
1771 
1772   if (cm->seq_params->force_screen_content_tools != 2) {
1773     features->allow_screen_content_tools = features->allow_intrabc =
1774         cm->seq_params->force_screen_content_tools;
1775     return;
1776   }
1777 
1778   if (cpi->oxcf.mode == REALTIME) {
1779     assert(cm->seq_params->reduced_still_picture_hdr);
1780     features->allow_screen_content_tools = features->allow_intrabc = 0;
1781     return;
1782   }
1783 
1784   if (cpi->oxcf.tune_cfg.content == AOM_CONTENT_SCREEN) {
1785     features->allow_screen_content_tools = features->allow_intrabc = 1;
1786     return;
1787   }
1788 
1789   // Estimate if the source frame is screen content, based on the portion of
1790   // blocks that have few luma colors.
1791   const uint8_t *src = cpi->unfiltered_source->y_buffer;
1792   assert(src != NULL);
1793   const int use_hbd = cpi->unfiltered_source->flags & YV12_FLAG_HIGHBITDEPTH;
1794   const int stride = cpi->unfiltered_source->y_stride;
1795   const int width = cpi->unfiltered_source->y_width;
1796   const int height = cpi->unfiltered_source->y_height;
1797   const int bd = cm->seq_params->bit_depth;
1798   const int blk_w = 16;
1799   const int blk_h = 16;
1800   // These threshold values are selected experimentally.
1801   const int color_thresh = 4;
1802   const unsigned int var_thresh = 0;
1803   // Counts of blocks with no more than color_thresh colors.
1804   int counts_1 = 0;
1805   // Counts of blocks with no more than color_thresh colors and variance larger
1806   // than var_thresh.
1807   int counts_2 = 0;
1808 
1809   for (int r = 0; r + blk_h <= height; r += blk_h) {
1810     for (int c = 0; c + blk_w <= width; c += blk_w) {
1811       int count_buf[1 << 8];  // Maximum (1 << 8) bins for hbd path.
1812       const uint8_t *const this_src = src + r * stride + c;
1813       int n_colors;
1814       if (use_hbd)
1815         av1_count_colors_highbd(this_src, stride, blk_w, blk_h, bd, NULL,
1816                                 count_buf, &n_colors, NULL);
1817       else
1818         av1_count_colors(this_src, stride, blk_w, blk_h, count_buf, &n_colors);
1819       if (n_colors > 1 && n_colors <= color_thresh) {
1820         ++counts_1;
1821         struct buf_2d buf;
1822         buf.stride = stride;
1823         buf.buf = (uint8_t *)this_src;
1824         const unsigned int var =
1825             use_hbd
1826                 ? av1_high_get_sby_perpixel_variance(cpi, &buf, BLOCK_16X16, bd)
1827                 : av1_get_sby_perpixel_variance(cpi, &buf, BLOCK_16X16);
1828         if (var > var_thresh) ++counts_2;
1829       }
1830     }
1831   }
1832 
1833   // The threshold values are selected experimentally.
1834   features->allow_screen_content_tools =
1835       counts_1 * blk_h * blk_w * 10 > width * height;
1836   // IntraBC would force loop filters off, so we use more strict rules that also
1837   // requires that the block has high variance.
1838   features->allow_intrabc = features->allow_screen_content_tools &&
1839                             counts_2 * blk_h * blk_w * 12 > width * height;
1840   cpi->use_screen_content_tools = features->allow_screen_content_tools;
1841   cpi->is_screen_content_type =
1842       features->allow_intrabc ||
1843       (counts_1 * blk_h * blk_w * 10 > width * height * 4 &&
1844        counts_2 * blk_h * blk_w * 30 > width * height);
1845 }
1846 
1847 // Function pointer to search site config initialization
1848 // of different search method functions.
1849 typedef void (*av1_init_search_site_config)(search_site_config *cfg, int stride,
1850                                             int level);
1851 
1852 av1_init_search_site_config
1853     av1_init_motion_compensation[NUM_DISTINCT_SEARCH_METHODS] = {
1854       av1_init_dsmotion_compensation,     av1_init_motion_compensation_nstep,
1855       av1_init_motion_compensation_nstep, av1_init_dsmotion_compensation,
1856       av1_init_motion_compensation_hex,   av1_init_motion_compensation_bigdia,
1857       av1_init_motion_compensation_square
1858     };
1859 
init_motion_estimation(AV1_COMP * cpi)1860 static void init_motion_estimation(AV1_COMP *cpi) {
1861   AV1_COMMON *const cm = &cpi->common;
1862   MotionVectorSearchParams *const mv_search_params = &cpi->mv_search_params;
1863   const int y_stride = cpi->scaled_source.y_stride;
1864   const int y_stride_src = ((cpi->oxcf.frm_dim_cfg.width != cm->width ||
1865                              cpi->oxcf.frm_dim_cfg.height != cm->height) ||
1866                             av1_superres_scaled(cm))
1867                                ? y_stride
1868                                : cpi->ppi->lookahead->buf->img.y_stride;
1869   int fpf_y_stride = cm->cur_frame != NULL ? cm->cur_frame->buf.y_stride
1870                                            : cpi->scaled_source.y_stride;
1871 
1872   // Update if search_site_cfg is uninitialized or the current frame has a new
1873   // stride
1874   const int should_update =
1875       !mv_search_params->search_site_cfg[SS_CFG_SRC][DIAMOND].stride ||
1876       !mv_search_params->search_site_cfg[SS_CFG_LOOKAHEAD][DIAMOND].stride ||
1877       (y_stride !=
1878        mv_search_params->search_site_cfg[SS_CFG_SRC][DIAMOND].stride);
1879 
1880   if (!should_update) {
1881     return;
1882   }
1883 
1884   // Initialization of search_site_cfg for NUM_DISTINCT_SEARCH_METHODS.
1885   for (SEARCH_METHODS i = DIAMOND; i < NUM_DISTINCT_SEARCH_METHODS; i++) {
1886     const int level = ((i == NSTEP_8PT) || (i == CLAMPED_DIAMOND)) ? 1 : 0;
1887     av1_init_motion_compensation[i](
1888         &mv_search_params->search_site_cfg[SS_CFG_SRC][i], y_stride, level);
1889     av1_init_motion_compensation[i](
1890         &mv_search_params->search_site_cfg[SS_CFG_LOOKAHEAD][i], y_stride_src,
1891         level);
1892   }
1893 
1894   // First pass search site config initialization.
1895   av1_init_motion_fpf(&mv_search_params->search_site_cfg[SS_CFG_FPF][DIAMOND],
1896                       fpf_y_stride);
1897   for (SEARCH_METHODS i = NSTEP; i < NUM_DISTINCT_SEARCH_METHODS; i++) {
1898     memcpy(&mv_search_params->search_site_cfg[SS_CFG_FPF][i],
1899            &mv_search_params->search_site_cfg[SS_CFG_FPF][DIAMOND],
1900            sizeof(search_site_config));
1901   }
1902 }
1903 
1904 #if !CONFIG_REALTIME_ONLY
1905 #define COUPLED_CHROMA_FROM_LUMA_RESTORATION 0
set_restoration_unit_size(int width,int height,int sx,int sy,RestorationInfo * rst)1906 static void set_restoration_unit_size(int width, int height, int sx, int sy,
1907                                       RestorationInfo *rst) {
1908   (void)width;
1909   (void)height;
1910   (void)sx;
1911   (void)sy;
1912 #if COUPLED_CHROMA_FROM_LUMA_RESTORATION
1913   int s = AOMMIN(sx, sy);
1914 #else
1915   int s = 0;
1916 #endif  // !COUPLED_CHROMA_FROM_LUMA_RESTORATION
1917 
1918   if (width * height > 352 * 288)
1919     rst[0].restoration_unit_size = RESTORATION_UNITSIZE_MAX;
1920   else
1921     rst[0].restoration_unit_size = (RESTORATION_UNITSIZE_MAX >> 1);
1922   rst[1].restoration_unit_size = rst[0].restoration_unit_size >> s;
1923   rst[2].restoration_unit_size = rst[1].restoration_unit_size;
1924 }
1925 #endif
1926 
init_ref_frame_bufs(AV1_COMP * cpi)1927 static void init_ref_frame_bufs(AV1_COMP *cpi) {
1928   AV1_COMMON *const cm = &cpi->common;
1929   int i;
1930   BufferPool *const pool = cm->buffer_pool;
1931   cm->cur_frame = NULL;
1932   for (i = 0; i < REF_FRAMES; ++i) {
1933     cm->ref_frame_map[i] = NULL;
1934   }
1935   for (i = 0; i < FRAME_BUFFERS; ++i) {
1936     pool->frame_bufs[i].ref_count = 0;
1937   }
1938 }
1939 
av1_check_initial_width(AV1_COMP * cpi,int use_highbitdepth,int subsampling_x,int subsampling_y)1940 void av1_check_initial_width(AV1_COMP *cpi, int use_highbitdepth,
1941                              int subsampling_x, int subsampling_y) {
1942   AV1_COMMON *const cm = &cpi->common;
1943   SequenceHeader *const seq_params = cm->seq_params;
1944   InitialDimensions *const initial_dimensions = &cpi->initial_dimensions;
1945 
1946   if (!initial_dimensions->width ||
1947       seq_params->use_highbitdepth != use_highbitdepth ||
1948       seq_params->subsampling_x != subsampling_x ||
1949       seq_params->subsampling_y != subsampling_y) {
1950     seq_params->subsampling_x = subsampling_x;
1951     seq_params->subsampling_y = subsampling_y;
1952     seq_params->use_highbitdepth = use_highbitdepth;
1953 
1954     av1_set_speed_features_framesize_independent(cpi, cpi->oxcf.speed);
1955     av1_set_speed_features_framesize_dependent(cpi, cpi->oxcf.speed);
1956 
1957     if (!is_stat_generation_stage(cpi)) {
1958       alloc_altref_frame_buffer(cpi);
1959       alloc_util_frame_buffers(cpi);
1960     }
1961     init_ref_frame_bufs(cpi);
1962 
1963     init_motion_estimation(cpi);  // TODO(agrange) This can be removed.
1964 
1965     initial_dimensions->width = cm->width;
1966     initial_dimensions->height = cm->height;
1967     cpi->initial_mbs = cm->mi_params.MBs;
1968   }
1969 }
1970 
1971 #if CONFIG_AV1_TEMPORAL_DENOISING
setup_denoiser_buffer(AV1_COMP * cpi)1972 static void setup_denoiser_buffer(AV1_COMP *cpi) {
1973   AV1_COMMON *const cm = &cpi->common;
1974   if (cpi->oxcf.noise_sensitivity > 0 &&
1975       !cpi->denoiser.frame_buffer_initialized) {
1976     if (av1_denoiser_alloc(
1977             cm, &cpi->svc, &cpi->denoiser, cpi->ppi->use_svc,
1978             cpi->oxcf.noise_sensitivity, cm->width, cm->height,
1979             cm->seq_params->subsampling_x, cm->seq_params->subsampling_y,
1980             cm->seq_params->use_highbitdepth, AOM_BORDER_IN_PIXELS))
1981       aom_internal_error(cm->error, AOM_CODEC_MEM_ERROR,
1982                          "Failed to allocate denoiser");
1983   }
1984 }
1985 #endif
1986 
1987 // Returns 1 if the assigned width or height was <= 0.
av1_set_size_literal(AV1_COMP * cpi,int width,int height)1988 int av1_set_size_literal(AV1_COMP *cpi, int width, int height) {
1989   AV1_COMMON *cm = &cpi->common;
1990   InitialDimensions *const initial_dimensions = &cpi->initial_dimensions;
1991   av1_check_initial_width(cpi, cm->seq_params->use_highbitdepth,
1992                           cm->seq_params->subsampling_x,
1993                           cm->seq_params->subsampling_y);
1994 
1995   if (width <= 0 || height <= 0) return 1;
1996 
1997   cm->width = width;
1998   cm->height = height;
1999 
2000 #if CONFIG_AV1_TEMPORAL_DENOISING
2001   setup_denoiser_buffer(cpi);
2002 #endif
2003 
2004   if (initial_dimensions->width && initial_dimensions->height &&
2005       (cm->width > initial_dimensions->width ||
2006        cm->height > initial_dimensions->height)) {
2007     av1_free_context_buffers(cm);
2008     av1_free_shared_coeff_buffer(&cpi->td.shared_coeff_buf);
2009     av1_free_sms_tree(&cpi->td);
2010     av1_free_pmc(cpi->td.firstpass_ctx, av1_num_planes(cm));
2011     cpi->td.firstpass_ctx = NULL;
2012     alloc_compressor_data(cpi);
2013     realloc_segmentation_maps(cpi);
2014     initial_dimensions->width = initial_dimensions->height = 0;
2015   }
2016   av1_update_frame_size(cpi);
2017 
2018   return 0;
2019 }
2020 
av1_set_frame_size(AV1_COMP * cpi,int width,int height)2021 void av1_set_frame_size(AV1_COMP *cpi, int width, int height) {
2022   AV1_COMMON *const cm = &cpi->common;
2023   const SequenceHeader *const seq_params = cm->seq_params;
2024   const int num_planes = av1_num_planes(cm);
2025   MACROBLOCKD *const xd = &cpi->td.mb.e_mbd;
2026   int ref_frame;
2027 
2028   if (width != cm->width || height != cm->height) {
2029     // There has been a change in the encoded frame size
2030     av1_set_size_literal(cpi, width, height);
2031     // Recalculate 'all_lossless' in case super-resolution was (un)selected.
2032     cm->features.all_lossless =
2033         cm->features.coded_lossless && !av1_superres_scaled(cm);
2034 
2035     av1_noise_estimate_init(&cpi->noise_estimate, cm->width, cm->height);
2036 #if CONFIG_AV1_TEMPORAL_DENOISING
2037     // Reset the denoiser on the resized frame.
2038     if (cpi->oxcf.noise_sensitivity > 0) {
2039       av1_denoiser_free(&(cpi->denoiser));
2040       setup_denoiser_buffer(cpi);
2041     }
2042 #endif
2043   }
2044   set_mv_search_params(cpi);
2045 
2046   if (is_stat_consumption_stage(cpi)) {
2047     av1_set_target_rate(cpi, cm->width, cm->height);
2048   }
2049 
2050   alloc_frame_mvs(cm, cm->cur_frame);
2051 
2052   // Allocate above context buffers
2053   CommonContexts *const above_contexts = &cm->above_contexts;
2054   if (above_contexts->num_planes < av1_num_planes(cm) ||
2055       above_contexts->num_mi_cols < cm->mi_params.mi_cols ||
2056       above_contexts->num_tile_rows < cm->tiles.rows) {
2057     av1_free_above_context_buffers(above_contexts);
2058     if (av1_alloc_above_context_buffers(above_contexts, cm->tiles.rows,
2059                                         cm->mi_params.mi_cols,
2060                                         av1_num_planes(cm)))
2061       aom_internal_error(cm->error, AOM_CODEC_MEM_ERROR,
2062                          "Failed to allocate context buffers");
2063   }
2064 
2065   // Reset the frame pointers to the current frame size.
2066   if (aom_realloc_frame_buffer(
2067           &cm->cur_frame->buf, cm->width, cm->height, seq_params->subsampling_x,
2068           seq_params->subsampling_y, seq_params->use_highbitdepth,
2069           cpi->oxcf.border_in_pixels, cm->features.byte_alignment, NULL, NULL,
2070           NULL, cpi->oxcf.tool_cfg.enable_global_motion))
2071     aom_internal_error(cm->error, AOM_CODEC_MEM_ERROR,
2072                        "Failed to allocate frame buffer");
2073 
2074   if (!is_stat_generation_stage(cpi)) av1_init_cdef_worker(cpi);
2075 
2076 #if !CONFIG_REALTIME_ONLY
2077   const int use_restoration = cm->seq_params->enable_restoration &&
2078                               !cm->features.all_lossless &&
2079                               !cm->tiles.large_scale;
2080   if (use_restoration) {
2081     const int frame_width = cm->superres_upscaled_width;
2082     const int frame_height = cm->superres_upscaled_height;
2083     set_restoration_unit_size(frame_width, frame_height,
2084                               seq_params->subsampling_x,
2085                               seq_params->subsampling_y, cm->rst_info);
2086     for (int i = 0; i < num_planes; ++i)
2087       cm->rst_info[i].frame_restoration_type = RESTORE_NONE;
2088 
2089     av1_alloc_restoration_buffers(cm);
2090     // Store the allocated restoration buffers in MT object.
2091     if (cpi->ppi->p_mt_info.num_workers > 1) {
2092       av1_init_lr_mt_buffers(cpi);
2093     }
2094   }
2095 #endif
2096 
2097   if (!is_stat_generation_stage(cpi)) alloc_util_frame_buffers(cpi);
2098   init_motion_estimation(cpi);
2099 
2100   for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
2101     RefCntBuffer *const buf = get_ref_frame_buf(cm, ref_frame);
2102     if (buf != NULL) {
2103       struct scale_factors *sf = get_ref_scale_factors(cm, ref_frame);
2104       av1_setup_scale_factors_for_frame(sf, buf->buf.y_crop_width,
2105                                         buf->buf.y_crop_height, cm->width,
2106                                         cm->height);
2107       if (av1_is_scaled(sf)) aom_extend_frame_borders(&buf->buf, num_planes);
2108     }
2109   }
2110 
2111   av1_setup_scale_factors_for_frame(&cm->sf_identity, cm->width, cm->height,
2112                                     cm->width, cm->height);
2113 
2114   set_ref_ptrs(cm, xd, LAST_FRAME, LAST_FRAME);
2115 }
2116 
2117 /*!\brief Select and apply cdef filters and switchable restoration filters
2118  *
2119  * \ingroup high_level_algo
2120  */
cdef_restoration_frame(AV1_COMP * cpi,AV1_COMMON * cm,MACROBLOCKD * xd,int use_restoration,int use_cdef)2121 static void cdef_restoration_frame(AV1_COMP *cpi, AV1_COMMON *cm,
2122                                    MACROBLOCKD *xd, int use_restoration,
2123                                    int use_cdef) {
2124 #if !CONFIG_REALTIME_ONLY
2125   if (use_restoration)
2126     av1_loop_restoration_save_boundary_lines(&cm->cur_frame->buf, cm, 0);
2127 #else
2128   (void)use_restoration;
2129 #endif
2130 
2131   if (use_cdef) {
2132 #if CONFIG_COLLECT_COMPONENT_TIMING
2133     start_timing(cpi, cdef_time);
2134 #endif
2135     const int num_workers = cpi->mt_info.num_mod_workers[MOD_CDEF];
2136     // Find CDEF parameters
2137     av1_cdef_search(&cpi->mt_info, &cm->cur_frame->buf, cpi->source, cm, xd,
2138                     cpi->sf.lpf_sf.cdef_pick_method, cpi->td.mb.rdmult,
2139                     cpi->sf.rt_sf.skip_cdef_sb, cpi->rc.frames_since_key);
2140 
2141     // Apply the filter
2142     if (!cpi->sf.rt_sf.skip_loopfilter_non_reference) {
2143       if (num_workers > 1) {
2144         av1_cdef_frame_mt(cm, xd, cpi->mt_info.cdef_worker,
2145                           cpi->mt_info.workers, &cpi->mt_info.cdef_sync,
2146                           num_workers, av1_cdef_init_fb_row_mt);
2147       } else {
2148         av1_cdef_frame(&cm->cur_frame->buf, cm, xd, av1_cdef_init_fb_row);
2149       }
2150     }
2151 #if CONFIG_COLLECT_COMPONENT_TIMING
2152     end_timing(cpi, cdef_time);
2153 #endif
2154   } else {
2155     cm->cdef_info.cdef_bits = 0;
2156     cm->cdef_info.cdef_strengths[0] = 0;
2157     cm->cdef_info.nb_cdef_strengths = 1;
2158     cm->cdef_info.cdef_uv_strengths[0] = 0;
2159   }
2160 
2161   av1_superres_post_encode(cpi);
2162 
2163 #if !CONFIG_REALTIME_ONLY
2164 #if CONFIG_COLLECT_COMPONENT_TIMING
2165   start_timing(cpi, loop_restoration_time);
2166 #endif
2167   if (use_restoration) {
2168     MultiThreadInfo *const mt_info = &cpi->mt_info;
2169     const int num_workers = mt_info->num_mod_workers[MOD_LR];
2170     av1_loop_restoration_save_boundary_lines(&cm->cur_frame->buf, cm, 1);
2171     av1_pick_filter_restoration(cpi->source, cpi);
2172     if (cm->rst_info[0].frame_restoration_type != RESTORE_NONE ||
2173         cm->rst_info[1].frame_restoration_type != RESTORE_NONE ||
2174         cm->rst_info[2].frame_restoration_type != RESTORE_NONE) {
2175       if (num_workers > 1)
2176         av1_loop_restoration_filter_frame_mt(
2177             &cm->cur_frame->buf, cm, 0, mt_info->workers, num_workers,
2178             &mt_info->lr_row_sync, &cpi->lr_ctxt);
2179       else
2180         av1_loop_restoration_filter_frame(&cm->cur_frame->buf, cm, 0,
2181                                           &cpi->lr_ctxt);
2182     }
2183   } else {
2184     cm->rst_info[0].frame_restoration_type = RESTORE_NONE;
2185     cm->rst_info[1].frame_restoration_type = RESTORE_NONE;
2186     cm->rst_info[2].frame_restoration_type = RESTORE_NONE;
2187   }
2188 #if CONFIG_COLLECT_COMPONENT_TIMING
2189   end_timing(cpi, loop_restoration_time);
2190 #endif
2191 #endif  // !CONFIG_REALTIME_ONLY
2192 }
2193 
2194 /*!\brief Select and apply in-loop deblocking filters, cdef filters, and
2195  * restoration filters
2196  *
2197  * \ingroup high_level_algo
2198  */
loopfilter_frame(AV1_COMP * cpi,AV1_COMMON * cm)2199 static void loopfilter_frame(AV1_COMP *cpi, AV1_COMMON *cm) {
2200   MultiThreadInfo *const mt_info = &cpi->mt_info;
2201   const int num_workers = mt_info->num_mod_workers[MOD_LPF];
2202   const int num_planes = av1_num_planes(cm);
2203   MACROBLOCKD *xd = &cpi->td.mb.e_mbd;
2204 
2205   assert(IMPLIES(is_lossless_requested(&cpi->oxcf.rc_cfg),
2206                  cm->features.coded_lossless && cm->features.all_lossless));
2207 
2208   const int use_loopfilter =
2209       !cm->features.coded_lossless && !cm->tiles.large_scale;
2210   const int use_cdef = cm->seq_params->enable_cdef &&
2211                        !cm->features.coded_lossless && !cm->tiles.large_scale;
2212   const int use_restoration = cm->seq_params->enable_restoration &&
2213                               !cm->features.all_lossless &&
2214                               !cm->tiles.large_scale;
2215   const int cur_width = cm->cur_frame->width;
2216   const int cur_height = cm->cur_frame->height;
2217   const int cur_width_mib = cm->mi_params.mi_cols * MI_SIZE;
2218   const int cur_height_mib = cm->mi_params.mi_rows * MI_SIZE;
2219   const int is_realtime =
2220       cpi->sf.rt_sf.use_nonrd_pick_mode && !(cm->mi_params.mi_cols % 2) &&
2221       !(cm->mi_params.mi_rows % 2) && (cur_width_mib - cur_width < MI_SIZE) &&
2222       (cur_height_mib - cur_height < MI_SIZE);
2223 
2224   struct loopfilter *lf = &cm->lf;
2225 
2226 #if CONFIG_COLLECT_COMPONENT_TIMING
2227   start_timing(cpi, loop_filter_time);
2228 #endif
2229   if (use_loopfilter) {
2230     av1_pick_filter_level(cpi->source, cpi, cpi->sf.lpf_sf.lpf_pick);
2231   } else {
2232     lf->filter_level[0] = 0;
2233     lf->filter_level[1] = 0;
2234   }
2235 
2236   if ((lf->filter_level[0] || lf->filter_level[1]) &&
2237       !cpi->sf.rt_sf.skip_loopfilter_non_reference) {
2238     av1_loop_filter_frame_mt(&cm->cur_frame->buf, cm, xd, 0, num_planes, 0,
2239                              mt_info->workers, num_workers,
2240                              &mt_info->lf_row_sync, is_realtime);
2241   }
2242 #if CONFIG_COLLECT_COMPONENT_TIMING
2243   end_timing(cpi, loop_filter_time);
2244 #endif
2245 
2246   cdef_restoration_frame(cpi, cm, xd, use_restoration, use_cdef);
2247 }
2248 
2249 /*!\brief Encode a frame without the recode loop, usually used in one-pass
2250  * encoding and realtime coding.
2251  *
2252  * \ingroup high_level_algo
2253  *
2254  * \param[in]    cpi             Top-level encoder structure
2255  *
2256  * \return Returns a value to indicate if the encoding is done successfully.
2257  * \retval #AOM_CODEC_OK
2258  * \retval #AOM_CODEC_ERROR
2259  */
encode_without_recode(AV1_COMP * cpi)2260 static int encode_without_recode(AV1_COMP *cpi) {
2261   AV1_COMMON *const cm = &cpi->common;
2262   const QuantizationCfg *const q_cfg = &cpi->oxcf.q_cfg;
2263   SVC *const svc = &cpi->svc;
2264   ResizePendingParams *const resize_pending_params =
2265       &cpi->resize_pending_params;
2266   const int resize_pending =
2267       (resize_pending_params->width && resize_pending_params->height &&
2268        (cpi->common.width != resize_pending_params->width ||
2269         cpi->common.height != resize_pending_params->height));
2270 
2271   int top_index = 0, bottom_index = 0, q = 0;
2272   YV12_BUFFER_CONFIG *unscaled = cpi->unscaled_source;
2273   InterpFilter filter_scaler =
2274       cpi->ppi->use_svc ? svc->downsample_filter_type[svc->spatial_layer_id]
2275                         : EIGHTTAP_SMOOTH;
2276   int phase_scaler = cpi->ppi->use_svc
2277                          ? svc->downsample_filter_phase[svc->spatial_layer_id]
2278                          : 0;
2279 
2280   set_size_independent_vars(cpi);
2281   av1_setup_frame_size(cpi);
2282   av1_set_size_dependent_vars(cpi, &q, &bottom_index, &top_index);
2283 
2284   if (!cpi->ppi->use_svc) {
2285     phase_scaler = 8;
2286     // 2:1 scaling.
2287     if ((cm->width << 1) == unscaled->y_crop_width &&
2288         (cm->height << 1) == unscaled->y_crop_height) {
2289       filter_scaler = BILINEAR;
2290       // For lower resolutions use eighttap_smooth.
2291       if (cm->width * cm->height <= 320 * 180) filter_scaler = EIGHTTAP_SMOOTH;
2292     } else if ((cm->width << 2) == unscaled->y_crop_width &&
2293                (cm->height << 2) == unscaled->y_crop_height) {
2294       // 4:1 scaling.
2295       filter_scaler = EIGHTTAP_SMOOTH;
2296     } else if ((cm->width << 2) == 3 * unscaled->y_crop_width &&
2297                (cm->height << 2) == 3 * unscaled->y_crop_height) {
2298       // 4:3 scaling.
2299       filter_scaler = EIGHTTAP_REGULAR;
2300     }
2301   }
2302 
2303   const SPEED_FEATURES *sf = &cpi->sf;
2304   if (sf->intra_sf.intra_pruning_with_hog ||
2305       sf->intra_sf.chroma_intra_pruning_with_hog) {
2306     allocate_gradient_info_for_hog(&cpi->td.pixel_gradient_info, cpi);
2307   }
2308 
2309   if (sf->part_sf.partition_search_type == VAR_BASED_PARTITION)
2310     variance_partition_alloc(cpi);
2311 
2312   if (cm->current_frame.frame_type == KEY_FRAME) copy_frame_prob_info(cpi);
2313 
2314 #if CONFIG_COLLECT_COMPONENT_TIMING
2315   printf("\n Encoding a frame:");
2316 #endif
2317 
2318 #if CONFIG_TUNE_BUTTERAUGLI
2319   if (cpi->oxcf.tune_cfg.tuning == AOM_TUNE_BUTTERAUGLI) {
2320     av1_setup_butteraugli_rdmult(cpi);
2321   }
2322 #endif
2323 
2324   cpi->source = av1_scale_if_required(cm, unscaled, &cpi->scaled_source,
2325                                       filter_scaler, phase_scaler, true, false);
2326   if (frame_is_intra_only(cm) || resize_pending != 0) {
2327     memset(cpi->consec_zero_mv, 0,
2328            ((cm->mi_params.mi_rows * cm->mi_params.mi_cols) >> 2) *
2329                sizeof(*cpi->consec_zero_mv));
2330   }
2331 
2332   if (cpi->unscaled_last_source != NULL) {
2333     cpi->last_source = av1_scale_if_required(
2334         cm, cpi->unscaled_last_source, &cpi->scaled_last_source, filter_scaler,
2335         phase_scaler, true, false);
2336   }
2337 
2338   if (cpi->sf.rt_sf.use_temporal_noise_estimate) {
2339     av1_update_noise_estimate(cpi);
2340   }
2341 
2342 #if CONFIG_AV1_TEMPORAL_DENOISING
2343   if (cpi->oxcf.noise_sensitivity > 0 && cpi->ppi->use_svc)
2344     av1_denoiser_reset_on_first_frame(cpi);
2345 #endif
2346 
2347   // For 1 spatial layer encoding: if the (non-LAST) reference has different
2348   // resolution from the source then disable that reference. This is to avoid
2349   // significant increase in encode time from scaling the references in
2350   // av1_scale_references. Note GOLDEN is forced to update on the (first/tigger)
2351   // resized frame and ALTREF will be refreshed ~4 frames later, so both
2352   // references become available again after few frames.
2353   if (svc->number_spatial_layers == 1) {
2354     if (cpi->ref_frame_flags & av1_ref_frame_flag_list[GOLDEN_FRAME]) {
2355       const YV12_BUFFER_CONFIG *const ref =
2356           get_ref_frame_yv12_buf(cm, GOLDEN_FRAME);
2357       if (ref->y_crop_width != cm->width || ref->y_crop_height != cm->height)
2358         cpi->ref_frame_flags ^= AOM_GOLD_FLAG;
2359     }
2360     if (cpi->ref_frame_flags & av1_ref_frame_flag_list[ALTREF_FRAME]) {
2361       const YV12_BUFFER_CONFIG *const ref =
2362           get_ref_frame_yv12_buf(cm, ALTREF_FRAME);
2363       if (ref->y_crop_width != cm->width || ref->y_crop_height != cm->height)
2364         cpi->ref_frame_flags ^= AOM_ALT_FLAG;
2365     }
2366   }
2367 
2368 #if CONFIG_FRAME_PARALLEL_ENCODE
2369   if (cpi->ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] == 0) {
2370 #else
2371   {
2372 #endif
2373     // For SVC the inter-layer/spatial prediction is not done for newmv
2374     // (zero_mode is forced), and since the scaled references are only
2375     // use for newmv search, we can avoid scaling here.
2376     if (!frame_is_intra_only(cm) &&
2377         !(cpi->ppi->use_svc && cpi->svc.force_zero_mode_spatial_ref))
2378       av1_scale_references(cpi, filter_scaler, phase_scaler, 1);
2379   }
2380 
2381   av1_set_quantizer(cm, q_cfg->qm_minlevel, q_cfg->qm_maxlevel, q,
2382                     q_cfg->enable_chroma_deltaq);
2383   av1_set_speed_features_qindex_dependent(cpi, cpi->oxcf.speed);
2384   if ((q_cfg->deltaq_mode != NO_DELTA_Q) || q_cfg->enable_chroma_deltaq)
2385     av1_init_quantizer(&cpi->enc_quant_dequant_params, &cm->quant_params,
2386                        cm->seq_params->bit_depth);
2387   av1_set_variance_partition_thresholds(cpi, q, 0);
2388   av1_setup_frame(cpi);
2389 
2390   // Check if this high_source_sad (scene/slide change) frame should be
2391   // encoded at high/max QP, and if so, set the q and adjust some rate
2392   // control parameters.
2393   if (cpi->sf.rt_sf.overshoot_detection_cbr == FAST_DETECTION_MAXQ &&
2394       cpi->rc.high_source_sad) {
2395     if (av1_encodedframe_overshoot_cbr(cpi, &q)) {
2396       av1_set_quantizer(cm, q_cfg->qm_minlevel, q_cfg->qm_maxlevel, q,
2397                         q_cfg->enable_chroma_deltaq);
2398       av1_set_speed_features_qindex_dependent(cpi, cpi->oxcf.speed);
2399       if (q_cfg->deltaq_mode != NO_DELTA_Q || q_cfg->enable_chroma_deltaq)
2400         av1_init_quantizer(&cpi->enc_quant_dequant_params, &cm->quant_params,
2401                            cm->seq_params->bit_depth);
2402       av1_set_variance_partition_thresholds(cpi, q, 0);
2403       if (frame_is_intra_only(cm) || cm->features.error_resilient_mode)
2404         av1_setup_frame(cpi);
2405     }
2406   }
2407 
2408   if (q_cfg->aq_mode == CYCLIC_REFRESH_AQ) {
2409     suppress_active_map(cpi);
2410     av1_cyclic_refresh_setup(cpi);
2411     av1_apply_active_map(cpi);
2412   }
2413   if (cm->seg.enabled) {
2414     if (!cm->seg.update_data && cm->prev_frame) {
2415       segfeatures_copy(&cm->seg, &cm->prev_frame->seg);
2416       cm->seg.enabled = cm->prev_frame->seg.enabled;
2417     } else {
2418       av1_calculate_segdata(&cm->seg);
2419     }
2420   } else {
2421     memset(&cm->seg, 0, sizeof(cm->seg));
2422   }
2423   segfeatures_copy(&cm->cur_frame->seg, &cm->seg);
2424   cm->cur_frame->seg.enabled = cm->seg.enabled;
2425 
2426 #if CONFIG_COLLECT_COMPONENT_TIMING
2427   start_timing(cpi, av1_encode_frame_time);
2428 #endif
2429 
2430   // Set the motion vector precision based on mv stats from the last coded
2431   // frame.
2432   if (!frame_is_intra_only(cm)) av1_pick_and_set_high_precision_mv(cpi, q);
2433 
2434   // transform / motion compensation build reconstruction frame
2435   av1_encode_frame(cpi);
2436 
2437   // Update some stats from cyclic refresh.
2438   if (q_cfg->aq_mode == CYCLIC_REFRESH_AQ && !frame_is_intra_only(cm))
2439     av1_cyclic_refresh_postencode(cpi);
2440 
2441 #if CONFIG_COLLECT_COMPONENT_TIMING
2442   end_timing(cpi, av1_encode_frame_time);
2443 #endif
2444 #if CONFIG_INTERNAL_STATS
2445   ++cpi->frame_recode_hits;
2446 #endif
2447 
2448   return AOM_CODEC_OK;
2449 }
2450 
2451 #if !CONFIG_REALTIME_ONLY
2452 
2453 /*!\brief Recode loop for encoding one frame. the purpose of encoding one frame
2454  * for multiple times can be approaching a target bitrate or adjusting the usage
2455  * of global motions.
2456  *
2457  * \ingroup high_level_algo
2458  *
2459  * \param[in]    cpi             Top-level encoder structure
2460  * \param[in]    size            Bitstream size
2461  * \param[in]    dest            Bitstream output
2462  *
2463  * \return Returns a value to indicate if the encoding is done successfully.
2464  * \retval #AOM_CODEC_OK
2465  * \retval -1
2466  * \retval #AOM_CODEC_ERROR
2467  */
2468 static int encode_with_recode_loop(AV1_COMP *cpi, size_t *size, uint8_t *dest) {
2469   AV1_COMMON *const cm = &cpi->common;
2470   RATE_CONTROL *const rc = &cpi->rc;
2471   GlobalMotionInfo *const gm_info = &cpi->gm_info;
2472   const AV1EncoderConfig *const oxcf = &cpi->oxcf;
2473   const QuantizationCfg *const q_cfg = &oxcf->q_cfg;
2474   const int allow_recode = (cpi->sf.hl_sf.recode_loop != DISALLOW_RECODE);
2475   // Must allow recode if minimum compression ratio is set.
2476   assert(IMPLIES(oxcf->rc_cfg.min_cr > 0, allow_recode));
2477 
2478   set_size_independent_vars(cpi);
2479   if (is_stat_consumption_stage_twopass(cpi) &&
2480       cpi->sf.interp_sf.adaptive_interp_filter_search)
2481     cpi->interp_search_flags.interp_filter_search_mask =
2482         av1_setup_interp_filter_search_mask(cpi);
2483   cpi->source->buf_8bit_valid = 0;
2484 
2485   av1_setup_frame_size(cpi);
2486 
2487   if (av1_superres_in_recode_allowed(cpi) &&
2488       cpi->superres_mode != AOM_SUPERRES_NONE &&
2489       cm->superres_scale_denominator == SCALE_NUMERATOR) {
2490     // Superres mode is currently enabled, but the denominator selected will
2491     // disable superres. So no need to continue, as we will go through another
2492     // recode loop for full-resolution after this anyway.
2493     return -1;
2494   }
2495 
2496   int top_index = 0, bottom_index = 0;
2497   int q = 0, q_low = 0, q_high = 0;
2498   av1_set_size_dependent_vars(cpi, &q, &bottom_index, &top_index);
2499   q_low = bottom_index;
2500   q_high = top_index;
2501 
2502   const SPEED_FEATURES *sf = &cpi->sf;
2503   if (sf->intra_sf.intra_pruning_with_hog ||
2504       sf->intra_sf.chroma_intra_pruning_with_hog) {
2505     allocate_gradient_info_for_hog(&cpi->td.pixel_gradient_info, cpi);
2506   }
2507 
2508   if (sf->part_sf.partition_search_type == VAR_BASED_PARTITION)
2509     variance_partition_alloc(cpi);
2510 
2511   if (cm->current_frame.frame_type == KEY_FRAME) copy_frame_prob_info(cpi);
2512 
2513 #if CONFIG_COLLECT_COMPONENT_TIMING
2514   printf("\n Encoding a frame:");
2515 #endif
2516 
2517 #if !CONFIG_RD_COMMAND
2518   // Determine whether to use screen content tools using two fast encoding.
2519   if (!cpi->sf.hl_sf.disable_extra_sc_testing)
2520     av1_determine_sc_tools_with_encoding(cpi, q);
2521 #endif  // !CONFIG_RD_COMMAND
2522 
2523 #if CONFIG_TUNE_VMAF
2524   if (oxcf->tune_cfg.tuning == AOM_TUNE_VMAF_NEG_MAX_GAIN) {
2525     av1_vmaf_neg_preprocessing(cpi, cpi->unscaled_source);
2526   }
2527 #endif
2528 
2529 #if CONFIG_TUNE_BUTTERAUGLI
2530   cpi->butteraugli_info.recon_set = false;
2531   int original_q = 0;
2532 #endif
2533 
2534 #if CONFIG_FRAME_PARALLEL_ENCODE
2535   cpi->num_frame_recode = 0;
2536 #endif
2537   // Loop variables
2538   int loop = 0;
2539   int loop_count = 0;
2540   int overshoot_seen = 0;
2541   int undershoot_seen = 0;
2542   int low_cr_seen = 0;
2543   int last_loop_allow_hp = 0;
2544 
2545   do {
2546     loop = 0;
2547     int do_mv_stats_collection = 1;
2548 
2549     // if frame was scaled calculate global_motion_search again if already
2550     // done
2551     if (loop_count > 0 && cpi->source && gm_info->search_done) {
2552       if (cpi->source->y_crop_width != cm->width ||
2553           cpi->source->y_crop_height != cm->height) {
2554         gm_info->search_done = 0;
2555       }
2556     }
2557     cpi->source =
2558         av1_scale_if_required(cm, cpi->unscaled_source, &cpi->scaled_source,
2559                               EIGHTTAP_REGULAR, 0, false, false);
2560 
2561 #if CONFIG_TUNE_BUTTERAUGLI
2562     if (oxcf->tune_cfg.tuning == AOM_TUNE_BUTTERAUGLI) {
2563       if (loop_count == 0) {
2564         original_q = q;
2565         // TODO(sdeng): different q here does not make big difference. Use a
2566         // faster pass instead.
2567         q = 96;
2568         av1_setup_butteraugli_source(cpi);
2569       } else {
2570         q = original_q;
2571       }
2572     }
2573 #endif
2574 
2575     if (cpi->unscaled_last_source != NULL) {
2576       cpi->last_source = av1_scale_if_required(
2577           cm, cpi->unscaled_last_source, &cpi->scaled_last_source,
2578           EIGHTTAP_REGULAR, 0, false, false);
2579     }
2580 
2581 #if CONFIG_FRAME_PARALLEL_ENCODE
2582     if (cpi->ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] == 0) {
2583 #else
2584     {
2585 #endif
2586       if (!frame_is_intra_only(cm)) {
2587         if (loop_count > 0) {
2588           release_scaled_references(cpi);
2589         }
2590         av1_scale_references(cpi, EIGHTTAP_REGULAR, 0, 0);
2591       }
2592     }
2593 
2594 #if CONFIG_TUNE_VMAF
2595     if (oxcf->tune_cfg.tuning >= AOM_TUNE_VMAF_WITH_PREPROCESSING &&
2596         oxcf->tune_cfg.tuning <= AOM_TUNE_VMAF_NEG_MAX_GAIN) {
2597       cpi->vmaf_info.original_qindex = q;
2598       q = av1_get_vmaf_base_qindex(cpi, q);
2599     }
2600 #endif
2601 
2602 #if CONFIG_RD_COMMAND
2603     RD_COMMAND *rd_command = &cpi->rd_command;
2604     RD_OPTION option = rd_command->option_ls[rd_command->frame_index];
2605     if (option == RD_OPTION_SET_Q || option == RD_OPTION_SET_Q_RDMULT) {
2606       q = rd_command->q_index_ls[rd_command->frame_index];
2607     }
2608 #endif  // CONFIG_RD_COMMAND
2609 
2610 #if CONFIG_BITRATE_ACCURACY
2611     if (cpi->vbr_rc_info.q_index_list_ready) {
2612       q = cpi->vbr_rc_info.q_index_list[cpi->gf_frame_index];
2613     }
2614 #endif
2615     av1_set_quantizer(cm, q_cfg->qm_minlevel, q_cfg->qm_maxlevel, q,
2616                       q_cfg->enable_chroma_deltaq);
2617     av1_set_speed_features_qindex_dependent(cpi, oxcf->speed);
2618 
2619     if (q_cfg->deltaq_mode != NO_DELTA_Q || q_cfg->enable_chroma_deltaq)
2620       av1_init_quantizer(&cpi->enc_quant_dequant_params, &cm->quant_params,
2621                          cm->seq_params->bit_depth);
2622 
2623     av1_set_variance_partition_thresholds(cpi, q, 0);
2624 
2625     // printf("Frame %d/%d: q = %d, frame_type = %d superres_denom = %d\n",
2626     //        cm->current_frame.frame_number, cm->show_frame, q,
2627     //        cm->current_frame.frame_type, cm->superres_scale_denominator);
2628 
2629     if (loop_count == 0) {
2630       av1_setup_frame(cpi);
2631     } else if (get_primary_ref_frame_buf(cm) == NULL) {
2632       // Base q-index may have changed, so we need to assign proper default coef
2633       // probs before every iteration.
2634       av1_default_coef_probs(cm);
2635       av1_setup_frame_contexts(cm);
2636     }
2637 
2638     if (q_cfg->aq_mode == VARIANCE_AQ) {
2639       av1_vaq_frame_setup(cpi);
2640     } else if (q_cfg->aq_mode == COMPLEXITY_AQ) {
2641       av1_setup_in_frame_q_adj(cpi);
2642     }
2643 
2644     if (cm->seg.enabled) {
2645       if (!cm->seg.update_data && cm->prev_frame) {
2646         segfeatures_copy(&cm->seg, &cm->prev_frame->seg);
2647         cm->seg.enabled = cm->prev_frame->seg.enabled;
2648       } else {
2649         av1_calculate_segdata(&cm->seg);
2650       }
2651     } else {
2652       memset(&cm->seg, 0, sizeof(cm->seg));
2653     }
2654     segfeatures_copy(&cm->cur_frame->seg, &cm->seg);
2655     cm->cur_frame->seg.enabled = cm->seg.enabled;
2656 
2657 #if CONFIG_COLLECT_COMPONENT_TIMING
2658     start_timing(cpi, av1_encode_frame_time);
2659 #endif
2660     // Set the motion vector precision based on mv stats from the last coded
2661     // frame.
2662     if (!frame_is_intra_only(cm)) {
2663       av1_pick_and_set_high_precision_mv(cpi, q);
2664 
2665       // If the precision has changed during different iteration of the loop,
2666       // then we need to reset the global motion vectors
2667       if (loop_count > 0 &&
2668           cm->features.allow_high_precision_mv != last_loop_allow_hp) {
2669         gm_info->search_done = 0;
2670       }
2671       last_loop_allow_hp = cm->features.allow_high_precision_mv;
2672     }
2673 
2674     // transform / motion compensation build reconstruction frame
2675     av1_encode_frame(cpi);
2676 
2677 #if CONFIG_FRAME_PARALLEL_ENCODE
2678     // Disable mv_stats collection for parallel frames based on update flag.
2679     if (!cpi->do_frame_data_update) do_mv_stats_collection = 0;
2680 #endif  // CONFIG_FRAME_PARALLEL_ENCODE
2681 
2682     // Reset the mv_stats in case we are interrupted by an intraframe or an
2683     // overlay frame.
2684     if (cpi->ppi->mv_stats.valid && do_mv_stats_collection) {
2685 #if CONFIG_FRAME_PARALLEL_ENCODE
2686       av1_zero(cpi->mv_stats);
2687 #else
2688       av1_zero(cpi->ppi->mv_stats);
2689 #endif
2690     }
2691     // Gather the mv_stats for the next frame
2692     if (cpi->sf.hl_sf.high_precision_mv_usage == LAST_MV_DATA &&
2693         av1_frame_allows_smart_mv(cpi) && do_mv_stats_collection) {
2694       av1_collect_mv_stats(cpi, q);
2695     }
2696 
2697 #if CONFIG_COLLECT_COMPONENT_TIMING
2698     end_timing(cpi, av1_encode_frame_time);
2699 #endif
2700 
2701 #if CONFIG_BITRATE_ACCURACY || CONFIG_RD_COMMAND
2702     const int do_dummy_pack = 1;
2703 #else   // CONFIG_BITRATE_ACCURACY
2704     // Dummy pack of the bitstream using up to date stats to get an
2705     // accurate estimate of output frame size to determine if we need
2706     // to recode.
2707     const int do_dummy_pack =
2708         (cpi->sf.hl_sf.recode_loop >= ALLOW_RECODE_KFARFGF &&
2709          oxcf->rc_cfg.mode != AOM_Q) ||
2710         oxcf->rc_cfg.min_cr > 0;
2711 #endif  // CONFIG_BITRATE_ACCURACY
2712     if (do_dummy_pack) {
2713       av1_finalize_encoded_frame(cpi);
2714       int largest_tile_id = 0;  // Output from bitstream: unused here
2715       rc->coefficient_size = 0;
2716       if (av1_pack_bitstream(cpi, dest, size, &largest_tile_id) !=
2717           AOM_CODEC_OK) {
2718         return AOM_CODEC_ERROR;
2719       }
2720 
2721 #if CONFIG_BITRATE_ACCURACY
2722       cpi->vbr_rc_info.actual_coeff_bitrate_byframe[cpi->gf_frame_index] =
2723           rc->coefficient_size;
2724 #endif
2725 
2726       // bits used for this frame
2727       rc->projected_frame_size = (int)(*size) << 3;
2728 #if CONFIG_RD_COMMAND
2729       PSNR_STATS psnr;
2730       aom_calc_psnr(cpi->source, &cpi->common.cur_frame->buf, &psnr);
2731       printf("q %d rdmult %d rate %d dist %" PRIu64 "\n", q, cpi->rd.RDMULT,
2732              rc->projected_frame_size, psnr.sse[0]);
2733       ++rd_command->frame_index;
2734       if (rd_command->frame_index == rd_command->frame_count) {
2735         exit(0);
2736       }
2737 #endif  // CONFIG_RD_COMMAND
2738 
2739 #if CONFIG_BITRATE_ACCURACY
2740       cpi->vbr_rc_info.actual_bitrate_byframe[cpi->gf_frame_index] =
2741           rc->projected_frame_size;
2742       cpi->vbr_rc_info.actual_mv_bitrate_byframe[cpi->gf_frame_index] =
2743           rc->projected_frame_size -
2744           cpi->vbr_rc_info.actual_coeff_bitrate_byframe[cpi->gf_frame_index];
2745       cpi->ppi->tpl_data.actual_gop_bitrate += rc->projected_frame_size;
2746       if (cpi->ppi->gf_group.update_type[cpi->gf_frame_index] == KF_UPDATE) {
2747         vbr_rc_set_keyframe_bitrate(&cpi->vbr_rc_info,
2748                                     rc->projected_frame_size);
2749       }
2750 
2751 #if 0
2752       vbr_rc_info_log(&cpi->vbr_rc_info, cpi->gf_frame_index,
2753                       cpi->ppi->gf_group.size, &cpi->ppi->gf_group.update_type);
2754 #endif
2755 
2756 #endif
2757     }
2758 
2759 #if CONFIG_TUNE_VMAF
2760     if (oxcf->tune_cfg.tuning >= AOM_TUNE_VMAF_WITH_PREPROCESSING &&
2761         oxcf->tune_cfg.tuning <= AOM_TUNE_VMAF_NEG_MAX_GAIN) {
2762       q = cpi->vmaf_info.original_qindex;
2763     }
2764 #endif
2765     if (allow_recode) {
2766       // Update q and decide whether to do a recode loop
2767       recode_loop_update_q(cpi, &loop, &q, &q_low, &q_high, top_index,
2768                            bottom_index, &undershoot_seen, &overshoot_seen,
2769                            &low_cr_seen, loop_count);
2770     }
2771 
2772 #if CONFIG_TUNE_BUTTERAUGLI
2773     if (loop_count == 0 && oxcf->tune_cfg.tuning == AOM_TUNE_BUTTERAUGLI) {
2774       loop = 1;
2775       av1_setup_butteraugli_rdmult_and_restore_source(cpi, 0.4);
2776     }
2777 #endif
2778 
2779 #if CONFIG_BITRATE_ACCURACY || CONFIG_RD_COMMAND
2780     loop = 0;  // turn off recode loop when CONFIG_BITRATE_ACCURACY is on
2781 #endif         // CONFIG_BITRATE_ACCURACY || CONFIG_RD_COMMAND
2782 
2783     if (loop) {
2784       ++loop_count;
2785 #if CONFIG_FRAME_PARALLEL_ENCODE
2786       cpi->num_frame_recode =
2787           (cpi->num_frame_recode < (NUM_RECODES_PER_FRAME - 1))
2788               ? (cpi->num_frame_recode + 1)
2789               : (NUM_RECODES_PER_FRAME - 1);
2790 #endif
2791 #if CONFIG_INTERNAL_STATS
2792       ++cpi->frame_recode_hits;
2793 #endif
2794     }
2795 #if CONFIG_COLLECT_COMPONENT_TIMING
2796     if (loop) printf("\n Recoding:");
2797 #endif
2798   } while (loop);
2799 
2800   return AOM_CODEC_OK;
2801 }
2802 #endif  // !CONFIG_REALTIME_ONLY
2803 
2804 // TODO(jingning, paulwilkins): Set up high grain level to test
2805 // hardware decoders. Need to adapt the actual noise variance
2806 // according to the difference between reconstructed frame and the
2807 // source signal.
2808 static void set_grain_syn_params(AV1_COMMON *cm) {
2809   aom_film_grain_t *film_grain_params = &cm->film_grain_params;
2810   film_grain_params->apply_grain = 1;
2811   film_grain_params->update_parameters = 1;
2812   film_grain_params->random_seed = rand() & 0xffff;
2813 
2814   film_grain_params->num_y_points = 1;
2815   film_grain_params->scaling_points_y[0][0] = 128;
2816   film_grain_params->scaling_points_y[0][1] = 100;
2817 
2818   film_grain_params->num_cb_points = 1;
2819   film_grain_params->scaling_points_cb[0][0] = 128;
2820   film_grain_params->scaling_points_cb[0][1] = 100;
2821 
2822   film_grain_params->num_cr_points = 1;
2823   film_grain_params->scaling_points_cr[0][0] = 128;
2824   film_grain_params->scaling_points_cr[0][1] = 100;
2825 
2826   film_grain_params->chroma_scaling_from_luma = 0;
2827   film_grain_params->scaling_shift = 1;
2828   film_grain_params->ar_coeff_lag = 0;
2829   film_grain_params->ar_coeff_shift = 1;
2830   film_grain_params->overlap_flag = 1;
2831   film_grain_params->grain_scale_shift = 0;
2832 }
2833 
2834 /*!\brief Recode loop or a single loop for encoding one frame, followed by
2835  * in-loop deblocking filters, CDEF filters, and restoration filters.
2836  *
2837  * \ingroup high_level_algo
2838  * \callgraph
2839  * \callergraph
2840  *
2841  * \param[in]    cpi             Top-level encoder structure
2842  * \param[in]    size            Bitstream size
2843  * \param[in]    dest            Bitstream output
2844  * \param[in]    sse             Total distortion of the frame
2845  * \param[in]    rate            Total rate of the frame
2846  * \param[in]    largest_tile_id Tile id of the last tile
2847  *
2848  * \return Returns a value to indicate if the encoding is done successfully.
2849  * \retval #AOM_CODEC_OK
2850  * \retval #AOM_CODEC_ERROR
2851  */
2852 static int encode_with_recode_loop_and_filter(AV1_COMP *cpi, size_t *size,
2853                                               uint8_t *dest, int64_t *sse,
2854                                               int64_t *rate,
2855                                               int *largest_tile_id) {
2856 #if CONFIG_COLLECT_COMPONENT_TIMING
2857   start_timing(cpi, encode_with_or_without_recode_time);
2858 #endif
2859 #if CONFIG_FRAME_PARALLEL_ENCODE
2860   for (int i = 0; i < NUM_RECODES_PER_FRAME; i++) {
2861     cpi->do_update_frame_probs_txtype[i] = 0;
2862     cpi->do_update_frame_probs_obmc[i] = 0;
2863     cpi->do_update_frame_probs_warp[i] = 0;
2864     cpi->do_update_frame_probs_interpfilter[i] = 0;
2865   }
2866   cpi->do_update_vbr_bits_off_target_fast = 0;
2867 #endif
2868 
2869   int err;
2870 #if CONFIG_REALTIME_ONLY
2871   err = encode_without_recode(cpi);
2872 #else
2873   if (cpi->sf.hl_sf.recode_loop == DISALLOW_RECODE)
2874     err = encode_without_recode(cpi);
2875   else
2876     err = encode_with_recode_loop(cpi, size, dest);
2877 #endif
2878 #if CONFIG_COLLECT_COMPONENT_TIMING
2879   end_timing(cpi, encode_with_or_without_recode_time);
2880 #endif
2881   if (err != AOM_CODEC_OK) {
2882     if (err == -1) {
2883       // special case as described in encode_with_recode_loop().
2884       // Encoding was skipped.
2885       err = AOM_CODEC_OK;
2886       if (sse != NULL) *sse = INT64_MAX;
2887       if (rate != NULL) *rate = INT64_MAX;
2888       *largest_tile_id = 0;
2889     }
2890     return err;
2891   }
2892 
2893 #ifdef OUTPUT_YUV_DENOISED
2894   const AV1EncoderConfig *const oxcf = &cpi->oxcf;
2895   if (oxcf->noise_sensitivity > 0 && denoise_svc(cpi)) {
2896     aom_write_yuv_frame(yuv_denoised_file,
2897                         &cpi->denoiser.running_avg_y[INTRA_FRAME]);
2898   }
2899 #endif
2900 
2901   AV1_COMMON *const cm = &cpi->common;
2902   SequenceHeader *const seq_params = cm->seq_params;
2903 
2904   // Special case code to reduce pulsing when key frames are forced at a
2905   // fixed interval. Note the reconstruction error if it is the frame before
2906   // the force key frame
2907   if (cpi->ppi->p_rc.next_key_frame_forced && cpi->rc.frames_to_key == 1) {
2908 #if CONFIG_AV1_HIGHBITDEPTH
2909     if (seq_params->use_highbitdepth) {
2910       cpi->ambient_err = aom_highbd_get_y_sse(cpi->source, &cm->cur_frame->buf);
2911     } else {
2912       cpi->ambient_err = aom_get_y_sse(cpi->source, &cm->cur_frame->buf);
2913     }
2914 #else
2915     cpi->ambient_err = aom_get_y_sse(cpi->source, &cm->cur_frame->buf);
2916 #endif
2917   }
2918 
2919   cm->cur_frame->buf.color_primaries = seq_params->color_primaries;
2920   cm->cur_frame->buf.transfer_characteristics =
2921       seq_params->transfer_characteristics;
2922   cm->cur_frame->buf.matrix_coefficients = seq_params->matrix_coefficients;
2923   cm->cur_frame->buf.monochrome = seq_params->monochrome;
2924   cm->cur_frame->buf.chroma_sample_position =
2925       seq_params->chroma_sample_position;
2926   cm->cur_frame->buf.color_range = seq_params->color_range;
2927   cm->cur_frame->buf.render_width = cm->render_width;
2928   cm->cur_frame->buf.render_height = cm->render_height;
2929 
2930   // Pick the loop filter level for the frame.
2931   if (!cm->features.allow_intrabc) {
2932     loopfilter_frame(cpi, cm);
2933   } else {
2934     cm->lf.filter_level[0] = 0;
2935     cm->lf.filter_level[1] = 0;
2936     cm->cdef_info.cdef_bits = 0;
2937     cm->cdef_info.cdef_strengths[0] = 0;
2938     cm->cdef_info.nb_cdef_strengths = 1;
2939     cm->cdef_info.cdef_uv_strengths[0] = 0;
2940     cm->rst_info[0].frame_restoration_type = RESTORE_NONE;
2941     cm->rst_info[1].frame_restoration_type = RESTORE_NONE;
2942     cm->rst_info[2].frame_restoration_type = RESTORE_NONE;
2943   }
2944 
2945   // TODO(debargha): Fix mv search range on encoder side
2946   // aom_extend_frame_inner_borders(&cm->cur_frame->buf, av1_num_planes(cm));
2947   aom_extend_frame_borders(&cm->cur_frame->buf, av1_num_planes(cm));
2948 
2949 #ifdef OUTPUT_YUV_REC
2950   aom_write_one_yuv_frame(cm, &cm->cur_frame->buf);
2951 #endif
2952 
2953   if (cpi->oxcf.tune_cfg.content == AOM_CONTENT_FILM) {
2954     set_grain_syn_params(cm);
2955   }
2956 
2957   av1_finalize_encoded_frame(cpi);
2958   // Build the bitstream
2959 #if CONFIG_COLLECT_COMPONENT_TIMING
2960   start_timing(cpi, av1_pack_bitstream_final_time);
2961 #endif
2962   cpi->rc.coefficient_size = 0;
2963   if (av1_pack_bitstream(cpi, dest, size, largest_tile_id) != AOM_CODEC_OK)
2964     return AOM_CODEC_ERROR;
2965 #if CONFIG_COLLECT_COMPONENT_TIMING
2966   end_timing(cpi, av1_pack_bitstream_final_time);
2967 #endif
2968 
2969   // Compute sse and rate.
2970   if (sse != NULL) {
2971 #if CONFIG_AV1_HIGHBITDEPTH
2972     *sse = (seq_params->use_highbitdepth)
2973                ? aom_highbd_get_y_sse(cpi->source, &cm->cur_frame->buf)
2974                : aom_get_y_sse(cpi->source, &cm->cur_frame->buf);
2975 #else
2976     *sse = aom_get_y_sse(cpi->source, &cm->cur_frame->buf);
2977 #endif
2978   }
2979   if (rate != NULL) {
2980     const int64_t bits = (*size << 3);
2981     *rate = (bits << 5);  // To match scale.
2982   }
2983   return AOM_CODEC_OK;
2984 }
2985 
2986 static int encode_with_and_without_superres(AV1_COMP *cpi, size_t *size,
2987                                             uint8_t *dest,
2988                                             int *largest_tile_id) {
2989   const AV1_COMMON *const cm = &cpi->common;
2990   assert(cm->seq_params->enable_superres);
2991   assert(av1_superres_in_recode_allowed(cpi));
2992   aom_codec_err_t err = AOM_CODEC_OK;
2993   av1_save_all_coding_context(cpi);
2994 
2995   int64_t sse1 = INT64_MAX;
2996   int64_t rate1 = INT64_MAX;
2997   int largest_tile_id1 = 0;
2998   int64_t sse2 = INT64_MAX;
2999   int64_t rate2 = INT64_MAX;
3000   int largest_tile_id2;
3001   double proj_rdcost1 = DBL_MAX;
3002   const GF_GROUP *const gf_group = &cpi->ppi->gf_group;
3003   const FRAME_UPDATE_TYPE update_type =
3004       gf_group->update_type[cpi->gf_frame_index];
3005   const aom_bit_depth_t bit_depth = cm->seq_params->bit_depth;
3006 
3007   // Encode with superres.
3008   if (cpi->sf.hl_sf.superres_auto_search_type == SUPERRES_AUTO_ALL) {
3009     SuperResCfg *const superres_cfg = &cpi->oxcf.superres_cfg;
3010     int64_t superres_sses[SCALE_NUMERATOR];
3011     int64_t superres_rates[SCALE_NUMERATOR];
3012     int superres_largest_tile_ids[SCALE_NUMERATOR];
3013     // Use superres for Key-frames and Alt-ref frames only.
3014     if (update_type != OVERLAY_UPDATE && update_type != INTNL_OVERLAY_UPDATE) {
3015       for (int denom = SCALE_NUMERATOR + 1; denom <= 2 * SCALE_NUMERATOR;
3016            ++denom) {
3017         superres_cfg->superres_scale_denominator = denom;
3018         superres_cfg->superres_kf_scale_denominator = denom;
3019         const int this_index = denom - (SCALE_NUMERATOR + 1);
3020 
3021         cpi->superres_mode = AOM_SUPERRES_AUTO;  // Super-res on for this loop.
3022         err = encode_with_recode_loop_and_filter(
3023             cpi, size, dest, &superres_sses[this_index],
3024             &superres_rates[this_index],
3025             &superres_largest_tile_ids[this_index]);
3026         cpi->superres_mode = AOM_SUPERRES_NONE;  // Reset to default (full-res).
3027         if (err != AOM_CODEC_OK) return err;
3028         restore_all_coding_context(cpi);
3029       }
3030       // Reset.
3031       superres_cfg->superres_scale_denominator = SCALE_NUMERATOR;
3032       superres_cfg->superres_kf_scale_denominator = SCALE_NUMERATOR;
3033     } else {
3034       for (int denom = SCALE_NUMERATOR + 1; denom <= 2 * SCALE_NUMERATOR;
3035            ++denom) {
3036         const int this_index = denom - (SCALE_NUMERATOR + 1);
3037         superres_sses[this_index] = INT64_MAX;
3038         superres_rates[this_index] = INT64_MAX;
3039       }
3040     }
3041     // Encode without superres.
3042     assert(cpi->superres_mode == AOM_SUPERRES_NONE);
3043     err = encode_with_recode_loop_and_filter(cpi, size, dest, &sse2, &rate2,
3044                                              &largest_tile_id2);
3045     if (err != AOM_CODEC_OK) return err;
3046 
3047     // Note: Both use common rdmult based on base qindex of fullres.
3048     const int64_t rdmult = av1_compute_rd_mult_based_on_qindex(
3049         bit_depth, update_type, cm->quant_params.base_qindex);
3050 
3051     // Find the best rdcost among all superres denoms.
3052     int best_denom = -1;
3053     for (int denom = SCALE_NUMERATOR + 1; denom <= 2 * SCALE_NUMERATOR;
3054          ++denom) {
3055       const int this_index = denom - (SCALE_NUMERATOR + 1);
3056       const int64_t this_sse = superres_sses[this_index];
3057       const int64_t this_rate = superres_rates[this_index];
3058       const int this_largest_tile_id = superres_largest_tile_ids[this_index];
3059       const double this_rdcost = RDCOST_DBL_WITH_NATIVE_BD_DIST(
3060           rdmult, this_rate, this_sse, bit_depth);
3061       if (this_rdcost < proj_rdcost1) {
3062         sse1 = this_sse;
3063         rate1 = this_rate;
3064         largest_tile_id1 = this_largest_tile_id;
3065         proj_rdcost1 = this_rdcost;
3066         best_denom = denom;
3067       }
3068     }
3069     const double proj_rdcost2 =
3070         RDCOST_DBL_WITH_NATIVE_BD_DIST(rdmult, rate2, sse2, bit_depth);
3071     // Re-encode with superres if it's better.
3072     if (proj_rdcost1 < proj_rdcost2) {
3073       restore_all_coding_context(cpi);
3074       // TODO(urvang): We should avoid rerunning the recode loop by saving
3075       // previous output+state, or running encode only for the selected 'q' in
3076       // previous step.
3077       // Again, temporarily force the best denom.
3078       superres_cfg->superres_scale_denominator = best_denom;
3079       superres_cfg->superres_kf_scale_denominator = best_denom;
3080       int64_t sse3 = INT64_MAX;
3081       int64_t rate3 = INT64_MAX;
3082       cpi->superres_mode =
3083           AOM_SUPERRES_AUTO;  // Super-res on for this recode loop.
3084       err = encode_with_recode_loop_and_filter(cpi, size, dest, &sse3, &rate3,
3085                                                largest_tile_id);
3086       cpi->superres_mode = AOM_SUPERRES_NONE;  // Reset to default (full-res).
3087       assert(sse1 == sse3);
3088       assert(rate1 == rate3);
3089       assert(largest_tile_id1 == *largest_tile_id);
3090       // Reset.
3091       superres_cfg->superres_scale_denominator = SCALE_NUMERATOR;
3092       superres_cfg->superres_kf_scale_denominator = SCALE_NUMERATOR;
3093     } else {
3094       *largest_tile_id = largest_tile_id2;
3095     }
3096   } else {
3097     assert(cpi->sf.hl_sf.superres_auto_search_type == SUPERRES_AUTO_DUAL);
3098     cpi->superres_mode =
3099         AOM_SUPERRES_AUTO;  // Super-res on for this recode loop.
3100     err = encode_with_recode_loop_and_filter(cpi, size, dest, &sse1, &rate1,
3101                                              &largest_tile_id1);
3102     cpi->superres_mode = AOM_SUPERRES_NONE;  // Reset to default (full-res).
3103     if (err != AOM_CODEC_OK) return err;
3104     restore_all_coding_context(cpi);
3105     // Encode without superres.
3106     assert(cpi->superres_mode == AOM_SUPERRES_NONE);
3107     err = encode_with_recode_loop_and_filter(cpi, size, dest, &sse2, &rate2,
3108                                              &largest_tile_id2);
3109     if (err != AOM_CODEC_OK) return err;
3110 
3111     // Note: Both use common rdmult based on base qindex of fullres.
3112     const int64_t rdmult = av1_compute_rd_mult_based_on_qindex(
3113         bit_depth, update_type, cm->quant_params.base_qindex);
3114     proj_rdcost1 =
3115         RDCOST_DBL_WITH_NATIVE_BD_DIST(rdmult, rate1, sse1, bit_depth);
3116     const double proj_rdcost2 =
3117         RDCOST_DBL_WITH_NATIVE_BD_DIST(rdmult, rate2, sse2, bit_depth);
3118     // Re-encode with superres if it's better.
3119     if (proj_rdcost1 < proj_rdcost2) {
3120       restore_all_coding_context(cpi);
3121       // TODO(urvang): We should avoid rerunning the recode loop by saving
3122       // previous output+state, or running encode only for the selected 'q' in
3123       // previous step.
3124       int64_t sse3 = INT64_MAX;
3125       int64_t rate3 = INT64_MAX;
3126       cpi->superres_mode =
3127           AOM_SUPERRES_AUTO;  // Super-res on for this recode loop.
3128       err = encode_with_recode_loop_and_filter(cpi, size, dest, &sse3, &rate3,
3129                                                largest_tile_id);
3130       cpi->superres_mode = AOM_SUPERRES_NONE;  // Reset to default (full-res).
3131       assert(sse1 == sse3);
3132       assert(rate1 == rate3);
3133       assert(largest_tile_id1 == *largest_tile_id);
3134     } else {
3135       *largest_tile_id = largest_tile_id2;
3136     }
3137   }
3138 
3139   return err;
3140 }
3141 
3142 #if !CONFIG_REALTIME_ONLY
3143 static void subtract_stats(FIRSTPASS_STATS *section,
3144                            const FIRSTPASS_STATS *frame) {
3145   section->frame -= frame->frame;
3146   section->weight -= frame->weight;
3147   section->intra_error -= frame->intra_error;
3148   section->frame_avg_wavelet_energy -= frame->frame_avg_wavelet_energy;
3149   section->coded_error -= frame->coded_error;
3150   section->sr_coded_error -= frame->sr_coded_error;
3151   section->pcnt_inter -= frame->pcnt_inter;
3152   section->pcnt_motion -= frame->pcnt_motion;
3153   section->pcnt_second_ref -= frame->pcnt_second_ref;
3154   section->pcnt_neutral -= frame->pcnt_neutral;
3155   section->intra_skip_pct -= frame->intra_skip_pct;
3156   section->inactive_zone_rows -= frame->inactive_zone_rows;
3157   section->inactive_zone_cols -= frame->inactive_zone_cols;
3158   section->MVr -= frame->MVr;
3159   section->mvr_abs -= frame->mvr_abs;
3160   section->MVc -= frame->MVc;
3161   section->mvc_abs -= frame->mvc_abs;
3162   section->MVrv -= frame->MVrv;
3163   section->MVcv -= frame->MVcv;
3164   section->mv_in_out_count -= frame->mv_in_out_count;
3165   section->new_mv_count -= frame->new_mv_count;
3166   section->count -= frame->count;
3167   section->duration -= frame->duration;
3168 }
3169 
3170 static void calculate_frame_avg_haar_energy(AV1_COMP *cpi) {
3171   TWO_PASS *const twopass = &cpi->ppi->twopass;
3172   const FIRSTPASS_STATS *const total_stats =
3173       twopass->stats_buf_ctx->total_stats;
3174 
3175   if (is_one_pass_rt_params(cpi) ||
3176       (cpi->oxcf.q_cfg.deltaq_mode != DELTA_Q_PERCEPTUAL) ||
3177       (is_fp_wavelet_energy_invalid(total_stats) == 0))
3178     return;
3179 
3180   const int num_mbs = (cpi->oxcf.resize_cfg.resize_mode != RESIZE_NONE)
3181                           ? cpi->initial_mbs
3182                           : cpi->common.mi_params.MBs;
3183   const YV12_BUFFER_CONFIG *const unfiltered_source = cpi->unfiltered_source;
3184   const uint8_t *const src = unfiltered_source->y_buffer;
3185   const int hbd = unfiltered_source->flags & YV12_FLAG_HIGHBITDEPTH;
3186   const int stride = unfiltered_source->y_stride;
3187   const BLOCK_SIZE fp_block_size =
3188       get_fp_block_size(cpi->is_screen_content_type);
3189   const int fp_block_size_width = block_size_wide[fp_block_size];
3190   const int fp_block_size_height = block_size_high[fp_block_size];
3191   const int num_unit_cols =
3192       get_num_blocks(unfiltered_source->y_crop_width, fp_block_size_width);
3193   const int num_unit_rows =
3194       get_num_blocks(unfiltered_source->y_crop_height, fp_block_size_height);
3195   const int num_8x8_cols = num_unit_cols * (fp_block_size_width / 8);
3196   const int num_8x8_rows = num_unit_rows * (fp_block_size_height / 8);
3197   int64_t frame_avg_wavelet_energy = av1_haar_ac_sad_mxn_uint8_input(
3198       src, stride, hbd, num_8x8_rows, num_8x8_cols);
3199 
3200   cpi->twopass_frame.frame_avg_haar_energy =
3201       log(((double)frame_avg_wavelet_energy / num_mbs) + 1.0);
3202 }
3203 #endif
3204 
3205 extern void av1_print_frame_contexts(const FRAME_CONTEXT *fc,
3206                                      const char *filename);
3207 
3208 /*!\brief Run the final pass encoding for 1-pass/2-pass encoding mode, and pack
3209  * the bitstream
3210  *
3211  * \ingroup high_level_algo
3212  * \callgraph
3213  * \callergraph
3214  *
3215  * \param[in]    cpi             Top-level encoder structure
3216  * \param[in]    size            Bitstream size
3217  * \param[in]    dest            Bitstream output
3218  *
3219  * \return Returns a value to indicate if the encoding is done successfully.
3220  * \retval #AOM_CODEC_OK
3221  * \retval #AOM_CODEC_ERROR
3222  */
3223 static int encode_frame_to_data_rate(AV1_COMP *cpi, size_t *size,
3224                                      uint8_t *dest) {
3225   AV1_COMMON *const cm = &cpi->common;
3226   SequenceHeader *const seq_params = cm->seq_params;
3227   CurrentFrame *const current_frame = &cm->current_frame;
3228   const AV1EncoderConfig *const oxcf = &cpi->oxcf;
3229   struct segmentation *const seg = &cm->seg;
3230   FeatureFlags *const features = &cm->features;
3231   const TileConfig *const tile_cfg = &oxcf->tile_cfg;
3232 
3233 #if CONFIG_COLLECT_COMPONENT_TIMING
3234   start_timing(cpi, encode_frame_to_data_rate_time);
3235 #endif
3236 
3237   if (frame_is_intra_only(cm)) {
3238     av1_set_screen_content_options(cpi, features);
3239   }
3240 
3241 #if !CONFIG_REALTIME_ONLY
3242   calculate_frame_avg_haar_energy(cpi);
3243 #endif
3244 
3245   // frame type has been decided outside of this function call
3246   cm->cur_frame->frame_type = current_frame->frame_type;
3247 
3248   cm->tiles.large_scale = tile_cfg->enable_large_scale_tile;
3249   cm->tiles.single_tile_decoding = tile_cfg->enable_single_tile_decoding;
3250 
3251   features->allow_ref_frame_mvs &= frame_might_allow_ref_frame_mvs(cm);
3252   // features->allow_ref_frame_mvs needs to be written into the frame header
3253   // while cm->tiles.large_scale is 1, therefore, "cm->tiles.large_scale=1" case
3254   // is separated from frame_might_allow_ref_frame_mvs().
3255   features->allow_ref_frame_mvs &= !cm->tiles.large_scale;
3256 
3257   features->allow_warped_motion = oxcf->motion_mode_cfg.allow_warped_motion &&
3258                                   frame_might_allow_warped_motion(cm);
3259 
3260   cpi->last_frame_type = current_frame->frame_type;
3261 
3262   if (frame_is_sframe(cm)) {
3263     GF_GROUP *gf_group = &cpi->ppi->gf_group;
3264     // S frame will wipe out any previously encoded altref so we cannot place
3265     // an overlay frame
3266     gf_group->update_type[gf_group->size] = GF_UPDATE;
3267   }
3268 
3269   if (encode_show_existing_frame(cm)) {
3270     av1_finalize_encoded_frame(cpi);
3271     // Build the bitstream
3272     int largest_tile_id = 0;  // Output from bitstream: unused here
3273     cpi->rc.coefficient_size = 0;
3274     if (av1_pack_bitstream(cpi, dest, size, &largest_tile_id) != AOM_CODEC_OK)
3275       return AOM_CODEC_ERROR;
3276 
3277     if (seq_params->frame_id_numbers_present_flag &&
3278         current_frame->frame_type == KEY_FRAME) {
3279       // Displaying a forward key-frame, so reset the ref buffer IDs
3280       int display_frame_id = cm->ref_frame_id[cpi->existing_fb_idx_to_show];
3281       for (int i = 0; i < REF_FRAMES; i++)
3282         cm->ref_frame_id[i] = display_frame_id;
3283     }
3284 
3285 #if DUMP_RECON_FRAMES == 1
3286     // NOTE(zoeliu): For debug - Output the filtered reconstructed video.
3287     av1_dump_filtered_recon_frames(cpi);
3288 #endif  // DUMP_RECON_FRAMES
3289 
3290     // NOTE: Save the new show frame buffer index for --test-code=warn, i.e.,
3291     //       for the purpose to verify no mismatch between encoder and decoder.
3292     if (cm->show_frame) cpi->last_show_frame_buf = cm->cur_frame;
3293 
3294 #if CONFIG_AV1_TEMPORAL_DENOISING
3295     av1_denoiser_update_ref_frame(cpi);
3296 #endif
3297 
3298     // Since we allocate a spot for the OVERLAY frame in the gf group, we need
3299     // to do post-encoding update accordingly.
3300     av1_set_target_rate(cpi, cm->width, cm->height);
3301 
3302     if (is_psnr_calc_enabled(cpi)) {
3303       cpi->source =
3304           realloc_and_scale_source(cpi, cm->cur_frame->buf.y_crop_width,
3305                                    cm->cur_frame->buf.y_crop_height);
3306     }
3307 
3308     ++current_frame->frame_number;
3309     update_frame_index_set(&cpi->frame_index_set, cm->show_frame);
3310     return AOM_CODEC_OK;
3311   }
3312 
3313   // Work out whether to force_integer_mv this frame
3314   if (!is_stat_generation_stage(cpi) &&
3315       cpi->common.features.allow_screen_content_tools &&
3316       !frame_is_intra_only(cm)) {
3317     if (cpi->common.seq_params->force_integer_mv == 2) {
3318       // Adaptive mode: see what previous frame encoded did
3319       if (cpi->unscaled_last_source != NULL) {
3320         features->cur_frame_force_integer_mv = av1_is_integer_mv(
3321             cpi->source, cpi->unscaled_last_source, &cpi->force_intpel_info);
3322       } else {
3323         cpi->common.features.cur_frame_force_integer_mv = 0;
3324       }
3325     } else {
3326       cpi->common.features.cur_frame_force_integer_mv =
3327           cpi->common.seq_params->force_integer_mv;
3328     }
3329   } else {
3330     cpi->common.features.cur_frame_force_integer_mv = 0;
3331   }
3332 
3333   // Set default state for segment based loop filter update flags.
3334   cm->lf.mode_ref_delta_update = 0;
3335 
3336   // Set various flags etc to special state if it is a key frame.
3337   if (frame_is_intra_only(cm) || frame_is_sframe(cm)) {
3338     // Reset the loop filter deltas and segmentation map.
3339     av1_reset_segment_features(cm);
3340 
3341     // If segmentation is enabled force a map update for key frames.
3342     if (seg->enabled) {
3343       seg->update_map = 1;
3344       seg->update_data = 1;
3345     }
3346   }
3347   if (tile_cfg->mtu == 0) {
3348     cpi->num_tg = tile_cfg->num_tile_groups;
3349   } else {
3350     // Use a default value for the purposes of weighting costs in probability
3351     // updates
3352     cpi->num_tg = DEFAULT_MAX_NUM_TG;
3353   }
3354 
3355   // For 1 pass CBR, check if we are dropping this frame.
3356   // Never drop on key frame.
3357   if (has_no_stats_stage(cpi) && oxcf->rc_cfg.mode == AOM_CBR &&
3358       current_frame->frame_type != KEY_FRAME) {
3359     if (av1_rc_drop_frame(cpi)) {
3360       av1_setup_frame_size(cpi);
3361       av1_rc_postencode_update_drop_frame(cpi);
3362       release_scaled_references(cpi);
3363       cpi->is_dropped_frame = true;
3364       return AOM_CODEC_OK;
3365     }
3366   }
3367 
3368   if (oxcf->tune_cfg.tuning == AOM_TUNE_SSIM) {
3369     av1_set_mb_ssim_rdmult_scaling(cpi);
3370   }
3371 
3372 #if CONFIG_TUNE_VMAF
3373   if (oxcf->tune_cfg.tuning == AOM_TUNE_VMAF_WITHOUT_PREPROCESSING ||
3374       oxcf->tune_cfg.tuning == AOM_TUNE_VMAF_MAX_GAIN ||
3375       oxcf->tune_cfg.tuning == AOM_TUNE_VMAF_NEG_MAX_GAIN) {
3376     av1_set_mb_vmaf_rdmult_scaling(cpi);
3377   }
3378 #endif
3379 
3380   if (cpi->oxcf.q_cfg.deltaq_mode == DELTA_Q_PERCEPTUAL_AI) {
3381     av1_init_mb_wiener_var_buffer(cpi);
3382     av1_set_mb_wiener_variance(cpi);
3383   }
3384 
3385   if (cpi->oxcf.q_cfg.deltaq_mode == DELTA_Q_USER_RATING_BASED) {
3386     av1_init_mb_ur_var_buffer(cpi);
3387     av1_set_mb_ur_variance(cpi);
3388   }
3389 
3390 #if CONFIG_INTERNAL_STATS
3391   memset(cpi->mode_chosen_counts, 0,
3392          MAX_MODES * sizeof(*cpi->mode_chosen_counts));
3393 #endif
3394 
3395   if (seq_params->frame_id_numbers_present_flag) {
3396     /* Non-normative definition of current_frame_id ("frame counter" with
3397      * wraparound) */
3398     if (cm->current_frame_id == -1) {
3399       int lsb, msb;
3400       /* quasi-random initialization of current_frame_id for a key frame */
3401       if (cpi->source->flags & YV12_FLAG_HIGHBITDEPTH) {
3402         lsb = CONVERT_TO_SHORTPTR(cpi->source->y_buffer)[0] & 0xff;
3403         msb = CONVERT_TO_SHORTPTR(cpi->source->y_buffer)[1] & 0xff;
3404       } else {
3405         lsb = cpi->source->y_buffer[0] & 0xff;
3406         msb = cpi->source->y_buffer[1] & 0xff;
3407       }
3408       cm->current_frame_id =
3409           ((msb << 8) + lsb) % (1 << seq_params->frame_id_length);
3410 
3411       // S_frame is meant for stitching different streams of different
3412       // resolutions together, so current_frame_id must be the
3413       // same across different streams of the same content current_frame_id
3414       // should be the same and not random. 0x37 is a chosen number as start
3415       // point
3416       if (oxcf->kf_cfg.sframe_dist != 0) cm->current_frame_id = 0x37;
3417     } else {
3418       cm->current_frame_id =
3419           (cm->current_frame_id + 1 + (1 << seq_params->frame_id_length)) %
3420           (1 << seq_params->frame_id_length);
3421     }
3422   }
3423 
3424   switch (oxcf->algo_cfg.cdf_update_mode) {
3425     case 0:  // No CDF update for any frames(4~6% compression loss).
3426       features->disable_cdf_update = 1;
3427       break;
3428     case 1:  // Enable CDF update for all frames.
3429       features->disable_cdf_update = 0;
3430       break;
3431     case 2:
3432       // Strategically determine at which frames to do CDF update.
3433       // Currently only enable CDF update for all-intra and no-show frames(1.5%
3434       // compression loss).
3435       // TODO(huisu@google.com): design schemes for various trade-offs between
3436       // compression quality and decoding speed.
3437       if (oxcf->mode == GOOD || oxcf->mode == ALLINTRA) {
3438         features->disable_cdf_update =
3439             (frame_is_intra_only(cm) || !cm->show_frame) ? 0 : 1;
3440       } else {
3441         if (cpi->svc.number_spatial_layers == 1 &&
3442             cpi->svc.number_temporal_layers == 1)
3443           features->disable_cdf_update =
3444               !((cm->current_frame.frame_number % 2) == 0);
3445         else if (cpi->svc.number_temporal_layers > 1)
3446           // Disable only on top temporal enhancement layer for now.
3447           features->disable_cdf_update = (cpi->svc.temporal_layer_id ==
3448                                           cpi->svc.number_temporal_layers - 1);
3449       }
3450       break;
3451   }
3452 
3453 #if CONFIG_FRAME_PARALLEL_ENCODE
3454 #if CONFIG_FRAME_PARALLEL_ENCODE_2
3455   // Disable cdf update for the INTNL_ARF_UPDATE frame with
3456   // frame_parallel_level 1.
3457   if (!cpi->do_frame_data_update &&
3458       cpi->ppi->gf_group.update_type[cpi->gf_frame_index] == INTNL_ARF_UPDATE) {
3459     assert(cpi->ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] == 1);
3460     features->disable_cdf_update = 1;
3461   }
3462 #endif  // CONFIG_FRAME_PARALLEL_ENCODE_2
3463 #endif  // CONFIG_FRAME_PARALLEL_ENCODE
3464 
3465   int largest_tile_id = 0;
3466   if (av1_superres_in_recode_allowed(cpi)) {
3467     if (encode_with_and_without_superres(cpi, size, dest, &largest_tile_id) !=
3468         AOM_CODEC_OK) {
3469       return AOM_CODEC_ERROR;
3470     }
3471   } else {
3472     const aom_superres_mode orig_superres_mode = cpi->superres_mode;  // save
3473     cpi->superres_mode = cpi->oxcf.superres_cfg.superres_mode;
3474     if (encode_with_recode_loop_and_filter(cpi, size, dest, NULL, NULL,
3475                                            &largest_tile_id) != AOM_CODEC_OK) {
3476       return AOM_CODEC_ERROR;
3477     }
3478     cpi->superres_mode = orig_superres_mode;  // restore
3479   }
3480 
3481   // Update reference frame ids for reference frames this frame will overwrite
3482   if (seq_params->frame_id_numbers_present_flag) {
3483     for (int i = 0; i < REF_FRAMES; i++) {
3484       if ((current_frame->refresh_frame_flags >> i) & 1) {
3485         cm->ref_frame_id[i] = cm->current_frame_id;
3486       }
3487     }
3488   }
3489 
3490   if (cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1)
3491     cpi->svc.num_encoded_top_layer++;
3492 
3493 #if DUMP_RECON_FRAMES == 1
3494   // NOTE(zoeliu): For debug - Output the filtered reconstructed video.
3495   av1_dump_filtered_recon_frames(cpi);
3496 #endif  // DUMP_RECON_FRAMES
3497 
3498   if (cm->seg.enabled) {
3499     if (cm->seg.update_map) {
3500       update_reference_segmentation_map(cpi);
3501     } else if (cm->last_frame_seg_map) {
3502       memcpy(cm->cur_frame->seg_map, cm->last_frame_seg_map,
3503              cm->cur_frame->mi_cols * cm->cur_frame->mi_rows *
3504                  sizeof(*cm->cur_frame->seg_map));
3505     }
3506   }
3507 
3508 #if CONFIG_FRAME_PARALLEL_ENCODE
3509   if (cpi->ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] == 0) {
3510 #else
3511   {
3512 #endif
3513     if (frame_is_intra_only(cm) == 0) {
3514       release_scaled_references(cpi);
3515     }
3516   }
3517 #if CONFIG_AV1_TEMPORAL_DENOISING
3518   av1_denoiser_update_ref_frame(cpi);
3519 #endif
3520 
3521   // NOTE: Save the new show frame buffer index for --test-code=warn, i.e.,
3522   //       for the purpose to verify no mismatch between encoder and decoder.
3523   if (cm->show_frame) cpi->last_show_frame_buf = cm->cur_frame;
3524 
3525   if (features->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD) {
3526     *cm->fc = cpi->tile_data[largest_tile_id].tctx;
3527     av1_reset_cdf_symbol_counters(cm->fc);
3528   }
3529   if (!cm->tiles.large_scale) {
3530     cm->cur_frame->frame_context = *cm->fc;
3531   }
3532 
3533   if (tile_cfg->enable_ext_tile_debug) {
3534     // (yunqing) This test ensures the correctness of large scale tile coding.
3535     if (cm->tiles.large_scale && is_stat_consumption_stage(cpi)) {
3536       char fn[20] = "./fc";
3537       fn[4] = current_frame->frame_number / 100 + '0';
3538       fn[5] = (current_frame->frame_number % 100) / 10 + '0';
3539       fn[6] = (current_frame->frame_number % 10) + '0';
3540       fn[7] = '\0';
3541       av1_print_frame_contexts(cm->fc, fn);
3542     }
3543   }
3544 
3545   cpi->last_frame_type = current_frame->frame_type;
3546 
3547   // Clear the one shot update flags for segmentation map and mode/ref loop
3548   // filter deltas.
3549   cm->seg.update_map = 0;
3550   cm->seg.update_data = 0;
3551   cm->lf.mode_ref_delta_update = 0;
3552 
3553   // A droppable frame might not be shown but it always
3554   // takes a space in the gf group. Therefore, even when
3555   // it is not shown, we still need update the count down.
3556   if (cm->show_frame) {
3557     update_frame_index_set(&cpi->frame_index_set, cm->show_frame);
3558     ++current_frame->frame_number;
3559   }
3560 
3561 #if CONFIG_COLLECT_COMPONENT_TIMING
3562   end_timing(cpi, encode_frame_to_data_rate_time);
3563 #endif
3564 
3565   return AOM_CODEC_OK;
3566 }
3567 
3568 int av1_encode(AV1_COMP *const cpi, uint8_t *const dest,
3569                const EncodeFrameInput *const frame_input,
3570                const EncodeFrameParams *const frame_params,
3571                EncodeFrameResults *const frame_results) {
3572   AV1_COMMON *const cm = &cpi->common;
3573   CurrentFrame *const current_frame = &cm->current_frame;
3574 
3575   cpi->unscaled_source = frame_input->source;
3576   cpi->source = frame_input->source;
3577   cpi->unscaled_last_source = frame_input->last_source;
3578 
3579   current_frame->refresh_frame_flags = frame_params->refresh_frame_flags;
3580   cm->features.error_resilient_mode = frame_params->error_resilient_mode;
3581   cm->features.primary_ref_frame = frame_params->primary_ref_frame;
3582   cm->current_frame.frame_type = frame_params->frame_type;
3583   cm->show_frame = frame_params->show_frame;
3584   cpi->ref_frame_flags = frame_params->ref_frame_flags;
3585   cpi->speed = frame_params->speed;
3586   cm->show_existing_frame = frame_params->show_existing_frame;
3587   cpi->existing_fb_idx_to_show = frame_params->existing_fb_idx_to_show;
3588 
3589   memcpy(cm->remapped_ref_idx, frame_params->remapped_ref_idx,
3590          REF_FRAMES * sizeof(*cm->remapped_ref_idx));
3591 
3592   memcpy(&cpi->refresh_frame, &frame_params->refresh_frame,
3593          sizeof(cpi->refresh_frame));
3594 
3595   if (current_frame->frame_type == KEY_FRAME &&
3596       cpi->ppi->gf_group.refbuf_state[cpi->gf_frame_index] == REFBUF_RESET) {
3597     current_frame->frame_number = 0;
3598   }
3599 
3600   current_frame->order_hint =
3601       current_frame->frame_number + frame_params->order_offset;
3602 
3603   current_frame->display_order_hint = current_frame->order_hint;
3604   current_frame->order_hint %=
3605       (1 << (cm->seq_params->order_hint_info.order_hint_bits_minus_1 + 1));
3606 
3607 #if CONFIG_FRAME_PARALLEL_ENCODE
3608   current_frame->pyramid_level = get_true_pyr_level(
3609       cpi->ppi->gf_group.layer_depth[cpi->gf_frame_index],
3610       current_frame->display_order_hint, cpi->ppi->gf_group.max_layer_depth);
3611 #endif  // CONFIG_FRAME_PARALLEL_ENCODE
3612 
3613   if (is_stat_generation_stage(cpi)) {
3614 #if !CONFIG_REALTIME_ONLY
3615     av1_first_pass(cpi, frame_input->ts_duration);
3616 #endif
3617   } else if (cpi->oxcf.pass == AOM_RC_ONE_PASS ||
3618              cpi->oxcf.pass >= AOM_RC_SECOND_PASS) {
3619     if (encode_frame_to_data_rate(cpi, &frame_results->size, dest) !=
3620         AOM_CODEC_OK) {
3621       return AOM_CODEC_ERROR;
3622     }
3623   } else {
3624     return AOM_CODEC_ERROR;
3625   }
3626 
3627   return AOM_CODEC_OK;
3628 }
3629 
3630 #if CONFIG_DENOISE
3631 static int apply_denoise_2d(AV1_COMP *cpi, YV12_BUFFER_CONFIG *sd,
3632                             int block_size, float noise_level,
3633                             int64_t time_stamp, int64_t end_time) {
3634   AV1_COMMON *const cm = &cpi->common;
3635   if (!cpi->denoise_and_model) {
3636     cpi->denoise_and_model = aom_denoise_and_model_alloc(
3637         cm->seq_params->bit_depth, block_size, noise_level);
3638     if (!cpi->denoise_and_model) {
3639       aom_internal_error(cm->error, AOM_CODEC_MEM_ERROR,
3640                          "Error allocating denoise and model");
3641       return -1;
3642     }
3643   }
3644   if (!cpi->film_grain_table) {
3645     cpi->film_grain_table = aom_malloc(sizeof(*cpi->film_grain_table));
3646     if (!cpi->film_grain_table) {
3647       aom_internal_error(cm->error, AOM_CODEC_MEM_ERROR,
3648                          "Error allocating grain table");
3649       return -1;
3650     }
3651     memset(cpi->film_grain_table, 0, sizeof(*cpi->film_grain_table));
3652   }
3653   if (aom_denoise_and_model_run(cpi->denoise_and_model, sd,
3654                                 &cm->film_grain_params,
3655                                 cpi->oxcf.enable_dnl_denoising)) {
3656     if (cm->film_grain_params.apply_grain) {
3657       aom_film_grain_table_append(cpi->film_grain_table, time_stamp, end_time,
3658                                   &cm->film_grain_params);
3659     }
3660   }
3661   return 0;
3662 }
3663 #endif
3664 
3665 int av1_receive_raw_frame(AV1_COMP *cpi, aom_enc_frame_flags_t frame_flags,
3666                           YV12_BUFFER_CONFIG *sd, int64_t time_stamp,
3667                           int64_t end_time) {
3668   AV1_COMMON *const cm = &cpi->common;
3669   const SequenceHeader *const seq_params = cm->seq_params;
3670   int res = 0;
3671   const int subsampling_x = sd->subsampling_x;
3672   const int subsampling_y = sd->subsampling_y;
3673   const int use_highbitdepth = (sd->flags & YV12_FLAG_HIGHBITDEPTH) != 0;
3674 
3675 #if CONFIG_TUNE_VMAF
3676   if (!is_stat_generation_stage(cpi) &&
3677       cpi->oxcf.tune_cfg.tuning == AOM_TUNE_VMAF_WITH_PREPROCESSING) {
3678     av1_vmaf_frame_preprocessing(cpi, sd);
3679   }
3680   if (!is_stat_generation_stage(cpi) &&
3681       cpi->oxcf.tune_cfg.tuning == AOM_TUNE_VMAF_MAX_GAIN) {
3682     av1_vmaf_blk_preprocessing(cpi, sd);
3683   }
3684 #endif
3685 
3686 #if CONFIG_INTERNAL_STATS
3687   struct aom_usec_timer timer;
3688   aom_usec_timer_start(&timer);
3689 #endif
3690 
3691 #if CONFIG_AV1_TEMPORAL_DENOISING
3692   setup_denoiser_buffer(cpi);
3693 #endif
3694 
3695 #if CONFIG_DENOISE
3696   // even if denoise_noise_level is > 0, we don't need need to denoise on pass
3697   // 1 of 2 if enable_dnl_denoising is disabled since the 2nd pass will be
3698   // encoding the original (non-denoised) frame
3699   if (cpi->oxcf.noise_level > 0 &&
3700       !(cpi->oxcf.pass == AOM_RC_FIRST_PASS && !cpi->oxcf.enable_dnl_denoising))
3701     if (apply_denoise_2d(cpi, sd, cpi->oxcf.noise_block_size,
3702                          cpi->oxcf.noise_level, time_stamp, end_time) < 0)
3703       res = -1;
3704 #endif  //  CONFIG_DENOISE
3705 
3706   if (av1_lookahead_push(cpi->ppi->lookahead, sd, time_stamp, end_time,
3707                          use_highbitdepth, frame_flags))
3708     res = -1;
3709 #if CONFIG_INTERNAL_STATS
3710   aom_usec_timer_mark(&timer);
3711   cpi->ppi->total_time_receive_data += aom_usec_timer_elapsed(&timer);
3712 #endif
3713 
3714   // Note: Regarding profile setting, the following checks are added to help
3715   // choose a proper profile for the input video. The criterion is that all
3716   // bitstreams must be designated as the lowest profile that match its content.
3717   // E.G. A bitstream that contains 4:4:4 video must be designated as High
3718   // Profile in the seq header, and likewise a bitstream that contains 4:2:2
3719   // bitstream must be designated as Professional Profile in the sequence
3720   // header.
3721   if ((seq_params->profile == PROFILE_0) && !seq_params->monochrome &&
3722       (subsampling_x != 1 || subsampling_y != 1)) {
3723     aom_internal_error(cm->error, AOM_CODEC_INVALID_PARAM,
3724                        "Non-4:2:0 color format requires profile 1 or 2");
3725     res = -1;
3726   }
3727   if ((seq_params->profile == PROFILE_1) &&
3728       !(subsampling_x == 0 && subsampling_y == 0)) {
3729     aom_internal_error(cm->error, AOM_CODEC_INVALID_PARAM,
3730                        "Profile 1 requires 4:4:4 color format");
3731     res = -1;
3732   }
3733   if ((seq_params->profile == PROFILE_2) &&
3734       (seq_params->bit_depth <= AOM_BITS_10) &&
3735       !(subsampling_x == 1 && subsampling_y == 0)) {
3736     aom_internal_error(cm->error, AOM_CODEC_INVALID_PARAM,
3737                        "Profile 2 bit-depth <= 10 requires 4:2:2 color format");
3738     res = -1;
3739   }
3740 
3741   return res;
3742 }
3743 
3744 #if CONFIG_ENTROPY_STATS
3745 void print_entropy_stats(AV1_PRIMARY *const ppi) {
3746   if (!ppi->cpi) return;
3747 
3748   if (ppi->cpi->oxcf.pass != 1 &&
3749       ppi->cpi->common.current_frame.frame_number > 0) {
3750     fprintf(stderr, "Writing counts.stt\n");
3751     FILE *f = fopen("counts.stt", "wb");
3752     fwrite(&ppi->aggregate_fc, sizeof(ppi->aggregate_fc), 1, f);
3753     fclose(f);
3754   }
3755 }
3756 #endif  // CONFIG_ENTROPY_STATS
3757 
3758 #if CONFIG_INTERNAL_STATS
3759 extern double av1_get_blockiness(const unsigned char *img1, int img1_pitch,
3760                                  const unsigned char *img2, int img2_pitch,
3761                                  int width, int height);
3762 
3763 static void adjust_image_stat(double y, double u, double v, double all,
3764                               ImageStat *s) {
3765   s->stat[STAT_Y] += y;
3766   s->stat[STAT_U] += u;
3767   s->stat[STAT_V] += v;
3768   s->stat[STAT_ALL] += all;
3769   s->worst = AOMMIN(s->worst, all);
3770 }
3771 
3772 static void compute_internal_stats(AV1_COMP *cpi, int frame_bytes) {
3773   AV1_PRIMARY *const ppi = cpi->ppi;
3774   AV1_COMMON *const cm = &cpi->common;
3775   double samples = 0.0;
3776   const uint32_t in_bit_depth = cpi->oxcf.input_cfg.input_bit_depth;
3777   const uint32_t bit_depth = cpi->td.mb.e_mbd.bd;
3778 
3779   if (cpi->ppi->use_svc &&
3780       cpi->svc.spatial_layer_id < cpi->svc.number_spatial_layers - 1)
3781     return;
3782 
3783 #if CONFIG_INTER_STATS_ONLY
3784   if (cm->current_frame.frame_type == KEY_FRAME) return;  // skip key frame
3785 #endif
3786   cpi->bytes += frame_bytes;
3787   if (cm->show_frame) {
3788     const YV12_BUFFER_CONFIG *orig = cpi->source;
3789     const YV12_BUFFER_CONFIG *recon = &cpi->common.cur_frame->buf;
3790     double y, u, v, frame_all;
3791 
3792     ppi->count[0]++;
3793     ppi->count[1]++;
3794     if (cpi->ppi->b_calculate_psnr) {
3795       PSNR_STATS psnr;
3796       double weight[2] = { 0.0, 0.0 };
3797       double frame_ssim2[2] = { 0.0, 0.0 };
3798 #if CONFIG_AV1_HIGHBITDEPTH
3799       aom_calc_highbd_psnr(orig, recon, &psnr, bit_depth, in_bit_depth);
3800 #else
3801       aom_calc_psnr(orig, recon, &psnr);
3802 #endif
3803       adjust_image_stat(psnr.psnr[1], psnr.psnr[2], psnr.psnr[3], psnr.psnr[0],
3804                         &(ppi->psnr[0]));
3805       ppi->total_sq_error[0] += psnr.sse[0];
3806       ppi->total_samples[0] += psnr.samples[0];
3807       samples = psnr.samples[0];
3808 
3809       aom_calc_ssim(orig, recon, bit_depth, in_bit_depth,
3810                     cm->seq_params->use_highbitdepth, weight, frame_ssim2);
3811 
3812       ppi->worst_ssim = AOMMIN(ppi->worst_ssim, frame_ssim2[0]);
3813       ppi->summed_quality += frame_ssim2[0] * weight[0];
3814       ppi->summed_weights += weight[0];
3815 
3816 #if CONFIG_AV1_HIGHBITDEPTH
3817       // Compute PSNR based on stream bit depth
3818       if ((cpi->source->flags & YV12_FLAG_HIGHBITDEPTH) &&
3819           (in_bit_depth < bit_depth)) {
3820         adjust_image_stat(psnr.psnr_hbd[1], psnr.psnr_hbd[2], psnr.psnr_hbd[3],
3821                           psnr.psnr_hbd[0], &ppi->psnr[1]);
3822         ppi->total_sq_error[1] += psnr.sse_hbd[0];
3823         ppi->total_samples[1] += psnr.samples_hbd[0];
3824 
3825         ppi->worst_ssim_hbd = AOMMIN(ppi->worst_ssim_hbd, frame_ssim2[1]);
3826         ppi->summed_quality_hbd += frame_ssim2[1] * weight[1];
3827         ppi->summed_weights_hbd += weight[1];
3828       }
3829 #endif
3830 
3831 #if 0
3832       {
3833         FILE *f = fopen("q_used.stt", "a");
3834         double y2 = psnr.psnr[1];
3835         double u2 = psnr.psnr[2];
3836         double v2 = psnr.psnr[3];
3837         double frame_psnr2 = psnr.psnr[0];
3838         fprintf(f, "%5d : Y%f7.3:U%f7.3:V%f7.3:F%f7.3:S%7.3f\n",
3839                 cm->current_frame.frame_number, y2, u2, v2,
3840                 frame_psnr2, frame_ssim2);
3841         fclose(f);
3842       }
3843 #endif
3844     }
3845     if (ppi->b_calculate_blockiness) {
3846       if (!cm->seq_params->use_highbitdepth) {
3847         const double frame_blockiness =
3848             av1_get_blockiness(orig->y_buffer, orig->y_stride, recon->y_buffer,
3849                                recon->y_stride, orig->y_width, orig->y_height);
3850         ppi->worst_blockiness = AOMMAX(ppi->worst_blockiness, frame_blockiness);
3851         ppi->total_blockiness += frame_blockiness;
3852       }
3853 
3854       if (ppi->b_calculate_consistency) {
3855         if (!cm->seq_params->use_highbitdepth) {
3856           const double this_inconsistency = aom_get_ssim_metrics(
3857               orig->y_buffer, orig->y_stride, recon->y_buffer, recon->y_stride,
3858               orig->y_width, orig->y_height, ppi->ssim_vars, &ppi->metrics, 1);
3859 
3860           const double peak = (double)((1 << in_bit_depth) - 1);
3861           const double consistency =
3862               aom_sse_to_psnr(samples, peak, ppi->total_inconsistency);
3863           if (consistency > 0.0)
3864             ppi->worst_consistency =
3865                 AOMMIN(ppi->worst_consistency, consistency);
3866           ppi->total_inconsistency += this_inconsistency;
3867         }
3868       }
3869     }
3870 
3871     frame_all =
3872         aom_calc_fastssim(orig, recon, &y, &u, &v, bit_depth, in_bit_depth);
3873     adjust_image_stat(y, u, v, frame_all, &ppi->fastssim);
3874     frame_all = aom_psnrhvs(orig, recon, &y, &u, &v, bit_depth, in_bit_depth);
3875     adjust_image_stat(y, u, v, frame_all, &ppi->psnrhvs);
3876   }
3877 }
3878 
3879 void print_internal_stats(AV1_PRIMARY *const ppi) {
3880   if (!ppi->cpi) return;
3881   AV1_COMP *const cpi = ppi->cpi;
3882 
3883   if (ppi->cpi->oxcf.pass != 1 &&
3884       ppi->cpi->common.current_frame.frame_number > 0) {
3885     char headings[512] = { 0 };
3886     char results[512] = { 0 };
3887     FILE *f = fopen("opsnr.stt", "a");
3888     double time_encoded =
3889         (cpi->time_stamps.prev_ts_end - cpi->time_stamps.first_ts_start) /
3890         10000000.000;
3891     double total_encode_time =
3892         (ppi->total_time_receive_data + ppi->total_time_compress_data) /
3893         1000.000;
3894     const double dr =
3895         (double)ppi->total_bytes * (double)8 / (double)1000 / time_encoded;
3896     const double peak =
3897         (double)((1 << ppi->cpi->oxcf.input_cfg.input_bit_depth) - 1);
3898     const double target_rate =
3899         (double)ppi->cpi->oxcf.rc_cfg.target_bandwidth / 1000;
3900     const double rate_err = ((100.0 * (dr - target_rate)) / target_rate);
3901 
3902     if (ppi->b_calculate_psnr) {
3903       const double total_psnr = aom_sse_to_psnr(
3904           (double)ppi->total_samples[0], peak, (double)ppi->total_sq_error[0]);
3905       const double total_ssim =
3906           100 * pow(ppi->summed_quality / ppi->summed_weights, 8.0);
3907       snprintf(headings, sizeof(headings),
3908                "Bitrate\tAVGPsnr\tGLBPsnr\tAVPsnrP\tGLPsnrP\t"
3909                "AOMSSIM\tVPSSIMP\tFASTSIM\tPSNRHVS\t"
3910                "WstPsnr\tWstSsim\tWstFast\tWstHVS\t"
3911                "AVPsrnY\tAPsnrCb\tAPsnrCr");
3912       snprintf(results, sizeof(results),
3913                "%7.2f\t%7.3f\t%7.3f\t%7.3f\t%7.3f\t"
3914                "%7.3f\t%7.3f\t%7.3f\t%7.3f\t"
3915                "%7.3f\t%7.3f\t%7.3f\t%7.3f\t"
3916                "%7.3f\t%7.3f\t%7.3f",
3917                dr, ppi->psnr[0].stat[STAT_ALL] / ppi->count[0], total_psnr,
3918                ppi->psnr[0].stat[STAT_ALL] / ppi->count[0], total_psnr,
3919                total_ssim, total_ssim,
3920                ppi->fastssim.stat[STAT_ALL] / ppi->count[0],
3921                ppi->psnrhvs.stat[STAT_ALL] / ppi->count[0], ppi->psnr[0].worst,
3922                ppi->worst_ssim, ppi->fastssim.worst, ppi->psnrhvs.worst,
3923                ppi->psnr[0].stat[STAT_Y] / ppi->count[0],
3924                ppi->psnr[0].stat[STAT_U] / ppi->count[0],
3925                ppi->psnr[0].stat[STAT_V] / ppi->count[0]);
3926 
3927       if (ppi->b_calculate_blockiness) {
3928         SNPRINT(headings, "\t  Block\tWstBlck");
3929         SNPRINT2(results, "\t%7.3f", ppi->total_blockiness / ppi->count[0]);
3930         SNPRINT2(results, "\t%7.3f", ppi->worst_blockiness);
3931       }
3932 
3933       if (ppi->b_calculate_consistency) {
3934         double consistency =
3935             aom_sse_to_psnr((double)ppi->total_samples[0], peak,
3936                             (double)ppi->total_inconsistency);
3937 
3938         SNPRINT(headings, "\tConsist\tWstCons");
3939         SNPRINT2(results, "\t%7.3f", consistency);
3940         SNPRINT2(results, "\t%7.3f", ppi->worst_consistency);
3941       }
3942 
3943       SNPRINT(headings, "\t   Time\tRcErr\tAbsErr");
3944       SNPRINT2(results, "\t%8.0f", total_encode_time);
3945       SNPRINT2(results, " %7.2f", rate_err);
3946       SNPRINT2(results, " %7.2f", fabs(rate_err));
3947 
3948       SNPRINT(headings, "\tAPsnr611");
3949       SNPRINT2(results, " %7.3f",
3950                (6 * ppi->psnr[0].stat[STAT_Y] + ppi->psnr[0].stat[STAT_U] +
3951                 ppi->psnr[0].stat[STAT_V]) /
3952                    (ppi->count[0] * 8));
3953 
3954 #if CONFIG_AV1_HIGHBITDEPTH
3955       const uint32_t in_bit_depth = ppi->cpi->oxcf.input_cfg.input_bit_depth;
3956       const uint32_t bit_depth = ppi->seq_params.bit_depth;
3957       // Since cpi->source->flags is not available here, but total_samples[1]
3958       // will be non-zero if cpi->source->flags & YV12_FLAG_HIGHBITDEPTH was
3959       // true in compute_internal_stats
3960       if ((ppi->total_samples[1] > 0) && (in_bit_depth < bit_depth)) {
3961         const double peak_hbd = (double)((1 << bit_depth) - 1);
3962         const double total_psnr_hbd =
3963             aom_sse_to_psnr((double)ppi->total_samples[1], peak_hbd,
3964                             (double)ppi->total_sq_error[1]);
3965         const double total_ssim_hbd =
3966             100 * pow(ppi->summed_quality_hbd / ppi->summed_weights_hbd, 8.0);
3967         SNPRINT(headings,
3968                 "\t AVGPsnrH GLBPsnrH AVPsnrPH GLPsnrPH"
3969                 " AVPsnrYH APsnrCbH APsnrCrH WstPsnrH"
3970                 " AOMSSIMH VPSSIMPH WstSsimH");
3971         SNPRINT2(results, "\t%7.3f",
3972                  ppi->psnr[1].stat[STAT_ALL] / ppi->count[1]);
3973         SNPRINT2(results, "  %7.3f", total_psnr_hbd);
3974         SNPRINT2(results, "  %7.3f",
3975                  ppi->psnr[1].stat[STAT_ALL] / ppi->count[1]);
3976         SNPRINT2(results, "  %7.3f", total_psnr_hbd);
3977         SNPRINT2(results, "  %7.3f", ppi->psnr[1].stat[STAT_Y] / ppi->count[1]);
3978         SNPRINT2(results, "  %7.3f", ppi->psnr[1].stat[STAT_U] / ppi->count[1]);
3979         SNPRINT2(results, "  %7.3f", ppi->psnr[1].stat[STAT_V] / ppi->count[1]);
3980         SNPRINT2(results, "  %7.3f", ppi->psnr[1].worst);
3981         SNPRINT2(results, "  %7.3f", total_ssim_hbd);
3982         SNPRINT2(results, "  %7.3f", total_ssim_hbd);
3983         SNPRINT2(results, "  %7.3f", ppi->worst_ssim_hbd);
3984       }
3985 #endif
3986       fprintf(f, "%s\n", headings);
3987       fprintf(f, "%s\n", results);
3988     }
3989 
3990     fclose(f);
3991 
3992     if (ppi->ssim_vars != NULL) {
3993       aom_free(ppi->ssim_vars);
3994       ppi->ssim_vars = NULL;
3995     }
3996   }
3997 }
3998 #endif  // CONFIG_INTERNAL_STATS
3999 
4000 static AOM_INLINE void update_keyframe_counters(AV1_COMP *cpi) {
4001   if (cpi->common.show_frame && cpi->rc.frames_to_key) {
4002 #if !CONFIG_REALTIME_ONLY
4003     FIRSTPASS_INFO *firstpass_info = &cpi->ppi->twopass.firstpass_info;
4004     if (firstpass_info->past_stats_count > FIRSTPASS_INFO_STATS_PAST_MIN) {
4005       av1_firstpass_info_move_cur_index_and_pop(firstpass_info);
4006     } else {
4007       // When there is not enough past stats, we move the current
4008       // index without popping the past stats
4009       av1_firstpass_info_move_cur_index(firstpass_info);
4010     }
4011 #endif
4012     cpi->rc.frames_since_key++;
4013     cpi->rc.frames_to_key--;
4014     cpi->rc.frames_to_fwd_kf--;
4015   }
4016 }
4017 
4018 static AOM_INLINE void update_frames_till_gf_update(AV1_COMP *cpi) {
4019   // TODO(weitinglin): Updating this counter for is_frame_droppable
4020   // is a work-around to handle the condition when a frame is drop.
4021   // We should fix the cpi->common.show_frame flag
4022   // instead of checking the other condition to update the counter properly.
4023   if (cpi->common.show_frame ||
4024       is_frame_droppable(&cpi->svc, &cpi->ext_flags.refresh_frame)) {
4025     // Decrement count down till next gf
4026     if (cpi->rc.frames_till_gf_update_due > 0)
4027       cpi->rc.frames_till_gf_update_due--;
4028   }
4029 }
4030 
4031 static AOM_INLINE void update_gf_group_index(AV1_COMP *cpi) {
4032   // Increment the gf group index ready for the next frame.
4033   ++cpi->gf_frame_index;
4034 }
4035 
4036 static void update_fb_of_context_type(const AV1_COMP *const cpi,
4037                                       int *const fb_of_context_type) {
4038   const AV1_COMMON *const cm = &cpi->common;
4039   const int current_frame_ref_type = get_current_frame_ref_type(cpi);
4040 
4041   if (frame_is_intra_only(cm) || cm->features.error_resilient_mode ||
4042       cpi->ext_flags.use_primary_ref_none) {
4043     for (int i = 0; i < REF_FRAMES; i++) {
4044       fb_of_context_type[i] = -1;
4045     }
4046     fb_of_context_type[current_frame_ref_type] =
4047         cm->show_frame ? get_ref_frame_map_idx(cm, GOLDEN_FRAME)
4048                        : get_ref_frame_map_idx(cm, ALTREF_FRAME);
4049   }
4050 
4051   if (!encode_show_existing_frame(cm)) {
4052     // Refresh fb_of_context_type[]: see encoder.h for explanation
4053     if (cm->current_frame.frame_type == KEY_FRAME) {
4054       // All ref frames are refreshed, pick one that will live long enough
4055       fb_of_context_type[current_frame_ref_type] = 0;
4056     } else {
4057       // If more than one frame is refreshed, it doesn't matter which one we
4058       // pick so pick the first.  LST sometimes doesn't refresh any: this is ok
4059 
4060       for (int i = 0; i < REF_FRAMES; i++) {
4061         if (cm->current_frame.refresh_frame_flags & (1 << i)) {
4062           fb_of_context_type[current_frame_ref_type] = i;
4063           break;
4064         }
4065       }
4066     }
4067   }
4068 }
4069 
4070 static void update_rc_counts(AV1_COMP *cpi) {
4071   update_keyframe_counters(cpi);
4072   update_frames_till_gf_update(cpi);
4073   update_gf_group_index(cpi);
4074 }
4075 
4076 #if CONFIG_FRAME_PARALLEL_ENCODE
4077 static void update_end_of_frame_stats(AV1_COMP *cpi) {
4078   if (cpi->do_frame_data_update) {
4079     // Store current frame loopfilter levels in ppi, if update flag is set.
4080     if (!cpi->common.show_existing_frame) {
4081       AV1_COMMON *const cm = &cpi->common;
4082       struct loopfilter *const lf = &cm->lf;
4083       cpi->ppi->filter_level[0] = lf->filter_level[0];
4084       cpi->ppi->filter_level[1] = lf->filter_level[1];
4085       cpi->ppi->filter_level_u = lf->filter_level_u;
4086       cpi->ppi->filter_level_v = lf->filter_level_v;
4087     }
4088   }
4089 
4090   // Store frame level mv_stats from cpi to ppi.
4091   cpi->ppi->mv_stats = cpi->mv_stats;
4092 }
4093 #endif
4094 
4095 void av1_post_encode_updates(AV1_COMP *const cpi,
4096                              const AV1_COMP_DATA *const cpi_data) {
4097   AV1_PRIMARY *const ppi = cpi->ppi;
4098   AV1_COMMON *const cm = &cpi->common;
4099 
4100 #if !CONFIG_REALTIME_ONLY
4101   // Update the total stats remaining structure.
4102   if (cpi->twopass_frame.this_frame != NULL &&
4103       ppi->twopass.stats_buf_ctx->total_left_stats) {
4104     subtract_stats(ppi->twopass.stats_buf_ctx->total_left_stats,
4105                    cpi->twopass_frame.this_frame);
4106   }
4107 #endif
4108 
4109   if (!is_stat_generation_stage(cpi) && !cpi->is_dropped_frame) {
4110 #if CONFIG_FRAME_PARALLEL_ENCODE
4111 #if CONFIG_FRAME_PARALLEL_ENCODE_2
4112     // Before calling refresh_reference_frames(), copy ppi->ref_frame_map_copy
4113     // to cm->ref_frame_map for frame_parallel_level 2 frame in a parallel
4114     // encode set of lower layer frames.
4115     // TODO(Remya): Move ref_frame_map from AV1_COMMON to AV1_PRIMARY to avoid
4116     // copy.
4117     if (ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] == 2 &&
4118         ppi->gf_group.frame_parallel_level[cpi->gf_frame_index - 1] == 1 &&
4119         ppi->gf_group.update_type[cpi->gf_frame_index - 1] ==
4120             INTNL_ARF_UPDATE) {
4121       memcpy(cm->ref_frame_map, ppi->ref_frame_map_copy,
4122              sizeof(cm->ref_frame_map));
4123     }
4124 #endif  // CONFIG_FRAME_PARALLEL_ENCODE_2
4125 #endif  // CONFIG_FRAME_PARALLEL_ENCODE
4126     refresh_reference_frames(cpi);
4127 #if CONFIG_FRAME_PARALLEL_ENCODE
4128 #if CONFIG_FRAME_PARALLEL_ENCODE_2
4129     // For frame_parallel_level 1 frame in a parallel encode set of lower layer
4130     // frames, store the updated cm->ref_frame_map in ppi->ref_frame_map_copy.
4131     if (ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] == 1 &&
4132         ppi->gf_group.update_type[cpi->gf_frame_index] == INTNL_ARF_UPDATE) {
4133       memcpy(ppi->ref_frame_map_copy, cm->ref_frame_map,
4134              sizeof(cm->ref_frame_map));
4135     }
4136 #endif  // CONFIG_FRAME_PARALLEL_ENCODE_2
4137 #endif  // CONFIG_FRAME_PARALLEL_ENCODE
4138     av1_rc_postencode_update(cpi, cpi_data->frame_size);
4139   }
4140 
4141   if (cpi_data->pop_lookahead == 1) {
4142     av1_lookahead_pop(cpi->ppi->lookahead, cpi_data->flush,
4143                       cpi->compressor_stage);
4144   }
4145 #if CONFIG_FRAME_PARALLEL_ENCODE
4146   if (cpi->common.show_frame) {
4147     cpi->ppi->ts_start_last_show_frame = cpi_data->ts_frame_start;
4148     cpi->ppi->ts_end_last_show_frame = cpi_data->ts_frame_end;
4149   }
4150 #endif  // CONFIG_FRAME_PARALLEL_ENCODE
4151   if (ppi->level_params.keep_level_stats && !is_stat_generation_stage(cpi)) {
4152     // Initialize level info. at the beginning of each sequence.
4153     if (cm->current_frame.frame_type == KEY_FRAME &&
4154         ppi->gf_group.refbuf_state[cpi->gf_frame_index] == REFBUF_RESET) {
4155       av1_init_level_info(cpi);
4156     }
4157     av1_update_level_info(cpi, cpi_data->frame_size, cpi_data->ts_frame_start,
4158                           cpi_data->ts_frame_end);
4159   }
4160 
4161   if (!is_stat_generation_stage(cpi)) {
4162 #if !CONFIG_REALTIME_ONLY
4163     if (!has_no_stats_stage(cpi)) av1_twopass_postencode_update(cpi);
4164 #endif
4165     update_fb_of_context_type(cpi, ppi->fb_of_context_type);
4166     update_rc_counts(cpi);
4167 #if CONFIG_FRAME_PARALLEL_ENCODE
4168     update_end_of_frame_stats(cpi);
4169 #endif
4170   }
4171 
4172   if (cpi->oxcf.pass == AOM_RC_THIRD_PASS && cpi->third_pass_ctx) {
4173     av1_pop_third_pass_info(cpi->third_pass_ctx);
4174   }
4175 
4176   if (ppi->use_svc) av1_save_layer_context(cpi);
4177 
4178   // Note *size = 0 indicates a dropped frame for which psnr is not calculated
4179   if (ppi->b_calculate_psnr && cpi_data->frame_size > 0) {
4180     if (cm->show_existing_frame ||
4181         (!is_stat_generation_stage(cpi) && cm->show_frame)) {
4182       generate_psnr_packet(cpi);
4183     }
4184   }
4185 
4186 #if CONFIG_INTERNAL_STATS
4187   if (!is_stat_generation_stage(cpi)) {
4188     compute_internal_stats(cpi, (int)cpi_data->frame_size);
4189   }
4190 #endif  // CONFIG_INTERNAL_STATS
4191 }
4192 
4193 int av1_get_compressed_data(AV1_COMP *cpi, AV1_COMP_DATA *const cpi_data) {
4194   const AV1EncoderConfig *const oxcf = &cpi->oxcf;
4195   AV1_COMMON *const cm = &cpi->common;
4196 
4197 #if CONFIG_FRAME_PARALLEL_ENCODE
4198   // The jmp_buf is valid only for the duration of the function that calls
4199   // setjmp(). Therefore, this function must reset the 'setjmp' field to 0
4200   // before it returns.
4201   if (setjmp(cm->error->jmp)) {
4202     cm->error->setjmp = 0;
4203     return cm->error->error_code;
4204   }
4205   cm->error->setjmp = 1;
4206 #endif  // CONFIG_FRAME_PARALLEL_ENCODE
4207 
4208 #if CONFIG_INTERNAL_STATS
4209   cpi->frame_recode_hits = 0;
4210   cpi->time_compress_data = 0;
4211   cpi->bytes = 0;
4212 #endif
4213 #if CONFIG_ENTROPY_STATS
4214   if (cpi->compressor_stage == ENCODE_STAGE) {
4215     av1_zero(cpi->counts);
4216   }
4217 #endif
4218 
4219 #if CONFIG_BITSTREAM_DEBUG
4220   assert(cpi->oxcf.max_threads <= 1 &&
4221          "bitstream debug tool does not support multithreading");
4222   bitstream_queue_record_write();
4223   aom_bitstream_queue_set_frame_write(cm->current_frame.order_hint * 2 +
4224                                       cm->show_frame);
4225 #endif
4226   if (cpi->ppi->use_svc && cpi->ppi->number_spatial_layers > 1) {
4227     av1_one_pass_cbr_svc_start_layer(cpi);
4228   }
4229 
4230   cpi->is_dropped_frame = false;
4231   cm->showable_frame = 0;
4232   cpi_data->frame_size = 0;
4233   cpi->available_bs_size = cpi_data->cx_data_sz;
4234 #if CONFIG_INTERNAL_STATS
4235   struct aom_usec_timer cmptimer;
4236   aom_usec_timer_start(&cmptimer);
4237 #endif
4238   av1_set_high_precision_mv(cpi, 1, 0);
4239 
4240   // Normal defaults
4241   cm->features.refresh_frame_context =
4242       oxcf->tool_cfg.frame_parallel_decoding_mode
4243           ? REFRESH_FRAME_CONTEXT_DISABLED
4244           : REFRESH_FRAME_CONTEXT_BACKWARD;
4245   if (oxcf->tile_cfg.enable_large_scale_tile)
4246     cm->features.refresh_frame_context = REFRESH_FRAME_CONTEXT_DISABLED;
4247 
4248   if (assign_cur_frame_new_fb(cm) == NULL) {
4249 #if CONFIG_FRAME_PARALLEL_ENCODE
4250     aom_internal_error(cpi->common.error, AOM_CODEC_ERROR,
4251                        "Failed to allocate new cur_frame");
4252 #else
4253     return AOM_CODEC_ERROR;
4254 #endif  // CONFIG_FRAME_PARALLEL_ENCODE
4255   }
4256 
4257 #if CONFIG_COLLECT_COMPONENT_TIMING
4258   // Accumulate 2nd pass time in 2-pass case or 1 pass time in 1-pass case.
4259   if (cpi->oxcf.pass == 2 || cpi->oxcf.pass == 0)
4260     start_timing(cpi, av1_encode_strategy_time);
4261 #endif
4262 
4263   const int result = av1_encode_strategy(
4264       cpi, &cpi_data->frame_size, cpi_data->cx_data, &cpi_data->lib_flags,
4265       &cpi_data->ts_frame_start, &cpi_data->ts_frame_end,
4266       cpi_data->timestamp_ratio, &cpi_data->pop_lookahead, cpi_data->flush);
4267 
4268 #if CONFIG_COLLECT_COMPONENT_TIMING
4269   if (cpi->oxcf.pass == 2 || cpi->oxcf.pass == 0)
4270     end_timing(cpi, av1_encode_strategy_time);
4271 
4272   // Print out timing information.
4273   // Note: Use "cpi->frame_component_time[0] > 100 us" to avoid showing of
4274   // show_existing_frame and lag-in-frames.
4275   if ((cpi->oxcf.pass == 2 || cpi->oxcf.pass == 0) &&
4276       cpi->frame_component_time[0] > 100) {
4277     int i;
4278     uint64_t frame_total = 0, total = 0;
4279 
4280     fprintf(stderr,
4281             "\n Frame number: %d, Frame type: %s, Show Frame: %d, Q: %d\n",
4282             cm->current_frame.frame_number,
4283             get_frame_type_enum(cm->current_frame.frame_type), cm->show_frame,
4284             cm->quant_params.base_qindex);
4285     for (i = 0; i < kTimingComponents; i++) {
4286       cpi->component_time[i] += cpi->frame_component_time[i];
4287       // Use av1_encode_strategy_time (i = 0) as the total time.
4288       if (i == 0) {
4289         frame_total = cpi->frame_component_time[0];
4290         total = cpi->component_time[0];
4291       }
4292       fprintf(stderr,
4293               " %50s:  %15" PRId64 " us [%6.2f%%] (total: %15" PRId64
4294               " us [%6.2f%%])\n",
4295               get_component_name(i), cpi->frame_component_time[i],
4296               (float)((float)cpi->frame_component_time[i] * 100.0 /
4297                       (float)frame_total),
4298               cpi->component_time[i],
4299               (float)((float)cpi->component_time[i] * 100.0 / (float)total));
4300       cpi->frame_component_time[i] = 0;
4301     }
4302   }
4303 #endif
4304 
4305   if (result == -1) {
4306 #if CONFIG_FRAME_PARALLEL_ENCODE
4307     cm->error->setjmp = 0;
4308 #endif
4309     // Returning -1 indicates no frame encoded; more input is required
4310     return -1;
4311   }
4312   if (result != AOM_CODEC_OK) {
4313 #if CONFIG_FRAME_PARALLEL_ENCODE
4314     aom_internal_error(cpi->common.error, AOM_CODEC_ERROR,
4315                        "Failed to encode frame");
4316 #else
4317     return AOM_CODEC_ERROR;
4318 #endif  // CONFIG_FRAME_PARALLEL_ENCODE
4319   }
4320 #if CONFIG_INTERNAL_STATS
4321   aom_usec_timer_mark(&cmptimer);
4322   cpi->time_compress_data += aom_usec_timer_elapsed(&cmptimer);
4323 #endif  // CONFIG_INTERNAL_STATS
4324 
4325 #if CONFIG_SPEED_STATS
4326   if (!is_stat_generation_stage(cpi) && !cm->show_existing_frame) {
4327     cpi->tx_search_count += cpi->td.mb.txfm_search_info.tx_search_count;
4328     cpi->td.mb.txfm_search_info.tx_search_count = 0;
4329   }
4330 #endif  // CONFIG_SPEED_STATS
4331 
4332 #if CONFIG_FRAME_PARALLEL_ENCODE
4333   cm->error->setjmp = 0;
4334 #endif
4335   return AOM_CODEC_OK;
4336 }
4337 
4338 #if CONFIG_FRAME_PARALLEL_ENCODE
4339 // Populates cpi->scaled_ref_buf corresponding to frames in a parallel encode
4340 // set. Also sets the bitmask 'ref_buffers_used_map'.
4341 void av1_scale_references_fpmt(AV1_COMP *cpi, int *ref_buffers_used_map) {
4342   AV1_COMMON *cm = &cpi->common;
4343   MV_REFERENCE_FRAME ref_frame;
4344 
4345   for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
4346     // Need to convert from AOM_REFFRAME to index into ref_mask (subtract 1).
4347     if (cpi->ref_frame_flags & av1_ref_frame_flag_list[ref_frame]) {
4348       const YV12_BUFFER_CONFIG *const ref =
4349           get_ref_frame_yv12_buf(cm, ref_frame);
4350 
4351       if (ref == NULL) {
4352         cpi->scaled_ref_buf[ref_frame - 1] = NULL;
4353         continue;
4354       }
4355 
4356       // FPMT does not support scaling yet.
4357       assert(ref->y_crop_width == cm->width &&
4358              ref->y_crop_height == cm->height);
4359 
4360       RefCntBuffer *buf = get_ref_frame_buf(cm, ref_frame);
4361       cpi->scaled_ref_buf[ref_frame - 1] = buf;
4362       for (int i = 0; i < FRAME_BUFFERS; ++i) {
4363         if (&cm->buffer_pool->frame_bufs[i] == buf) {
4364           *ref_buffers_used_map |= (1 << i);
4365         }
4366       }
4367     } else {
4368       if (!has_no_stats_stage(cpi)) cpi->scaled_ref_buf[ref_frame - 1] = NULL;
4369     }
4370   }
4371 }
4372 
4373 // Increments the ref_count of frame buffers referenced by cpi->scaled_ref_buf
4374 // corresponding to frames in a parallel encode set.
4375 void av1_increment_scaled_ref_counts_fpmt(BufferPool *buffer_pool,
4376                                           int ref_buffers_used_map) {
4377   for (int i = 0; i < FRAME_BUFFERS; ++i) {
4378     if (ref_buffers_used_map & (1 << i)) {
4379       ++buffer_pool->frame_bufs[i].ref_count;
4380     }
4381   }
4382 }
4383 
4384 // Releases cpi->scaled_ref_buf corresponding to frames in a parallel encode
4385 // set.
4386 void av1_release_scaled_references_fpmt(AV1_COMP *cpi) {
4387   // TODO(isbs): only refresh the necessary frames, rather than all of them
4388   for (int i = 0; i < INTER_REFS_PER_FRAME; ++i) {
4389     RefCntBuffer *const buf = cpi->scaled_ref_buf[i];
4390     if (buf != NULL) {
4391       cpi->scaled_ref_buf[i] = NULL;
4392     }
4393   }
4394 }
4395 
4396 // Decrements the ref_count of frame buffers referenced by cpi->scaled_ref_buf
4397 // corresponding to frames in a parallel encode set.
4398 void av1_decrement_ref_counts_fpmt(BufferPool *buffer_pool,
4399                                    int ref_buffers_used_map) {
4400   for (int i = 0; i < FRAME_BUFFERS; ++i) {
4401     if (ref_buffers_used_map & (1 << i)) {
4402       --buffer_pool->frame_bufs[i].ref_count;
4403     }
4404   }
4405 }
4406 
4407 // Initialize parallel frame contexts with screen content decisions.
4408 void av1_init_sc_decisions(AV1_PRIMARY *const ppi) {
4409   AV1_COMP *const first_cpi = ppi->cpi;
4410   for (int i = 1; i < ppi->num_fp_contexts; ++i) {
4411     AV1_COMP *cur_cpi = ppi->parallel_cpi[i];
4412     cur_cpi->common.features.allow_screen_content_tools =
4413         first_cpi->common.features.allow_screen_content_tools;
4414     cur_cpi->common.features.allow_intrabc =
4415         first_cpi->common.features.allow_intrabc;
4416     cur_cpi->use_screen_content_tools = first_cpi->use_screen_content_tools;
4417     cur_cpi->is_screen_content_type = first_cpi->is_screen_content_type;
4418   }
4419 }
4420 
4421 AV1_COMP *av1_get_parallel_frame_enc_data(AV1_PRIMARY *const ppi,
4422                                           AV1_COMP_DATA *const first_cpi_data) {
4423   int cpi_idx = 0;
4424 
4425   // Loop over parallel_cpi to find the cpi that processed the current
4426   // gf_frame_index ahead of time.
4427   for (int i = 1; i < ppi->num_fp_contexts; i++) {
4428     if (ppi->cpi->gf_frame_index == ppi->parallel_cpi[i]->gf_frame_index) {
4429       cpi_idx = i;
4430       break;
4431     }
4432   }
4433 
4434   assert(cpi_idx > 0);
4435   assert(!ppi->parallel_cpi[cpi_idx]->common.show_existing_frame);
4436 
4437   // Release the previously-used frame-buffer.
4438   if (ppi->cpi->common.cur_frame != NULL) {
4439     --ppi->cpi->common.cur_frame->ref_count;
4440     ppi->cpi->common.cur_frame = NULL;
4441   }
4442 
4443   // Swap the appropriate parallel_cpi with the parallel_cpi[0].
4444   ppi->cpi = ppi->parallel_cpi[cpi_idx];
4445   ppi->parallel_cpi[cpi_idx] = ppi->parallel_cpi[0];
4446   ppi->parallel_cpi[0] = ppi->cpi;
4447 
4448   // Copy appropriate parallel_frames_data to local data.
4449   {
4450     AV1_COMP_DATA *data = &ppi->parallel_frames_data[cpi_idx - 1];
4451     assert(data->frame_size > 0);
4452     assert(first_cpi_data->cx_data_sz > data->frame_size);
4453 
4454     first_cpi_data->lib_flags = data->lib_flags;
4455     first_cpi_data->ts_frame_start = data->ts_frame_start;
4456     first_cpi_data->ts_frame_end = data->ts_frame_end;
4457     memcpy(first_cpi_data->cx_data, data->cx_data, data->frame_size);
4458     first_cpi_data->frame_size = data->frame_size;
4459     if (ppi->cpi->common.show_frame) {
4460       first_cpi_data->pop_lookahead = 1;
4461     }
4462   }
4463 
4464   return ppi->cpi;
4465 }
4466 
4467 // Initialises frames belonging to a parallel encode set.
4468 int av1_init_parallel_frame_context(const AV1_COMP_DATA *const first_cpi_data,
4469                                     AV1_PRIMARY *const ppi,
4470                                     int *ref_buffers_used_map) {
4471   AV1_COMP *const first_cpi = ppi->cpi;
4472   GF_GROUP *const gf_group = &ppi->gf_group;
4473   int gf_index_start = first_cpi->gf_frame_index;
4474   assert(gf_group->frame_parallel_level[gf_index_start] == 1);
4475   int parallel_frame_count = 0;
4476   int cur_frame_num = first_cpi->common.current_frame.frame_number;
4477   int show_frame_count = first_cpi->frame_index_set.show_frame_count;
4478   int frames_since_key = first_cpi->rc.frames_since_key;
4479   int frames_to_key = first_cpi->rc.frames_to_key;
4480   int frames_to_fwd_kf = first_cpi->rc.frames_to_fwd_kf;
4481   int cur_frame_disp = cur_frame_num + gf_group->arf_src_offset[gf_index_start];
4482   const FIRSTPASS_STATS *stats_in = first_cpi->twopass_frame.stats_in;
4483 
4484   assert(*ref_buffers_used_map == 0);
4485 
4486   // Release the previously used frame-buffer by a frame_parallel_level 1 frame.
4487   if (first_cpi->common.cur_frame != NULL) {
4488     --first_cpi->common.cur_frame->ref_count;
4489     first_cpi->common.cur_frame = NULL;
4490   }
4491 
4492   RefFrameMapPair ref_frame_map_pairs[REF_FRAMES];
4493   RefFrameMapPair first_ref_frame_map_pairs[REF_FRAMES];
4494   init_ref_map_pair(first_cpi, first_ref_frame_map_pairs);
4495   memcpy(ref_frame_map_pairs, first_ref_frame_map_pairs,
4496          sizeof(RefFrameMapPair) * REF_FRAMES);
4497 
4498 #if CONFIG_FRAME_PARALLEL_ENCODE_2
4499   // Store the reference refresh index of frame_parallel_level 1 frame in a
4500   // parallel encode set of lower layer frames.
4501   if (gf_group->update_type[gf_index_start] == INTNL_ARF_UPDATE) {
4502     first_cpi->ref_refresh_index = av1_calc_refresh_idx_for_intnl_arf(
4503         first_cpi, ref_frame_map_pairs, gf_index_start);
4504     assert(first_cpi->ref_refresh_index != INVALID_IDX &&
4505            first_cpi->ref_refresh_index < REF_FRAMES);
4506     first_cpi->refresh_idx_available = true;
4507     // Update ref_frame_map_pairs.
4508     ref_frame_map_pairs[first_cpi->ref_refresh_index].disp_order =
4509         gf_group->display_idx[gf_index_start];
4510     ref_frame_map_pairs[first_cpi->ref_refresh_index].pyr_level =
4511         gf_group->layer_depth[gf_index_start];
4512   }
4513 #endif  // CONFIG_FRAME_PARALLEL_ENCODE_2
4514 
4515   // Set do_frame_data_update flag as false for frame_parallel_level 1 frame.
4516   first_cpi->do_frame_data_update = false;
4517   if (gf_group->arf_src_offset[gf_index_start] == 0) {
4518     first_cpi->time_stamps.prev_ts_start = ppi->ts_start_last_show_frame;
4519     first_cpi->time_stamps.prev_ts_end = ppi->ts_end_last_show_frame;
4520   }
4521 
4522   av1_get_ref_frames(NULL, first_ref_frame_map_pairs, cur_frame_disp,
4523 #if CONFIG_FRAME_PARALLEL_ENCODE_2
4524                      first_cpi, gf_index_start, 1,
4525 #endif  // CONFIG_FRAME_PARALLEL_ENCODE_2
4526                      first_cpi->common.remapped_ref_idx);
4527 
4528   av1_scale_references_fpmt(first_cpi, ref_buffers_used_map);
4529   parallel_frame_count++;
4530 
4531   // Iterate through the GF_GROUP to find the remaining frame_parallel_level 2
4532   // frames which are part of the current parallel encode set and initialize the
4533   // required cpi elements.
4534   for (int i = gf_index_start + 1; i < gf_group->size; i++) {
4535     // Update frame counters if previous frame was show frame or show existing
4536     // frame.
4537     if (gf_group->arf_src_offset[i - 1] == 0) {
4538       cur_frame_num++;
4539       show_frame_count++;
4540       if (frames_to_fwd_kf <= 0)
4541         frames_to_fwd_kf = first_cpi->oxcf.kf_cfg.fwd_kf_dist;
4542       if (frames_to_key) {
4543         frames_since_key++;
4544         frames_to_key--;
4545         frames_to_fwd_kf--;
4546       }
4547       stats_in++;
4548     }
4549     cur_frame_disp = cur_frame_num + gf_group->arf_src_offset[i];
4550     if (gf_group->frame_parallel_level[i] == 2) {
4551       AV1_COMP *cur_cpi = ppi->parallel_cpi[parallel_frame_count];
4552       AV1_COMP_DATA *cur_cpi_data =
4553           &ppi->parallel_frames_data[parallel_frame_count - 1];
4554       cur_cpi->gf_frame_index = i;
4555       cur_cpi->common.current_frame.frame_number = cur_frame_num;
4556       cur_cpi->frame_index_set.show_frame_count = show_frame_count;
4557       cur_cpi->rc.frames_since_key = frames_since_key;
4558       cur_cpi->rc.frames_to_key = frames_to_key;
4559       cur_cpi->rc.frames_to_fwd_kf = frames_to_fwd_kf;
4560       cur_cpi->rc.active_worst_quality = first_cpi->rc.active_worst_quality;
4561       cur_cpi->mv_search_params.max_mv_magnitude =
4562           first_cpi->mv_search_params.max_mv_magnitude;
4563       if (gf_group->update_type[cur_cpi->gf_frame_index] == INTNL_ARF_UPDATE) {
4564         cur_cpi->common.lf.mode_ref_delta_enabled = 1;
4565       }
4566       cur_cpi->do_frame_data_update = false;
4567       // Initialize prev_ts_start and prev_ts_end for show frame(s) and show
4568       // existing frame(s).
4569       if (gf_group->arf_src_offset[i] == 0) {
4570         // Choose source of prev frame.
4571         int src_index = gf_group->src_offset[i];
4572         struct lookahead_entry *prev_source = av1_lookahead_peek(
4573             ppi->lookahead, src_index - 1, cur_cpi->compressor_stage);
4574         // Save timestamps of prev frame.
4575         cur_cpi->time_stamps.prev_ts_start = prev_source->ts_start;
4576         cur_cpi->time_stamps.prev_ts_end = prev_source->ts_end;
4577       }
4578       cur_cpi->time_stamps.first_ts_start =
4579           first_cpi->time_stamps.first_ts_start;
4580 
4581       memcpy(cur_cpi->common.ref_frame_map, first_cpi->common.ref_frame_map,
4582              sizeof(first_cpi->common.ref_frame_map));
4583       cur_cpi_data->lib_flags = 0;
4584       cur_cpi_data->timestamp_ratio = first_cpi_data->timestamp_ratio;
4585       cur_cpi_data->flush = first_cpi_data->flush;
4586       cur_cpi_data->frame_size = 0;
4587 #if CONFIG_FRAME_PARALLEL_ENCODE_2
4588       if (gf_group->update_type[gf_index_start] == INTNL_ARF_UPDATE) {
4589         // If the first frame in a parallel encode set is INTNL_ARF_UPDATE
4590         // frame, initialize lib_flags of frame_parallel_level 2 frame in the
4591         // set with that of frame_parallel_level 1 frame.
4592         cur_cpi_data->lib_flags = first_cpi_data->lib_flags;
4593         // Store the reference refresh index of frame_parallel_level 2 frame in
4594         // a parallel encode set of lower layer frames.
4595         cur_cpi->ref_refresh_index =
4596             av1_calc_refresh_idx_for_intnl_arf(cur_cpi, ref_frame_map_pairs, i);
4597         cur_cpi->refresh_idx_available = true;
4598         // Skip the reference frame which will be refreshed by
4599         // frame_parallel_level 1 frame in a parallel encode set of lower layer
4600         // frames.
4601         cur_cpi->ref_idx_to_skip = first_cpi->ref_refresh_index;
4602       } else {
4603         cur_cpi->ref_idx_to_skip = INVALID_IDX;
4604         cur_cpi->ref_refresh_index = INVALID_IDX;
4605         cur_cpi->refresh_idx_available = false;
4606       }
4607 #endif  // CONFIG_FRAME_PARALLEL_ENCODE_2
4608       cur_cpi->twopass_frame.stats_in = stats_in;
4609 
4610       av1_get_ref_frames(NULL, first_ref_frame_map_pairs, cur_frame_disp,
4611 #if CONFIG_FRAME_PARALLEL_ENCODE_2
4612                          cur_cpi, i, 1,
4613 #endif  // CONFIG_FRAME_PARALLEL_ENCODE_2
4614                          cur_cpi->common.remapped_ref_idx);
4615       av1_scale_references_fpmt(cur_cpi, ref_buffers_used_map);
4616       parallel_frame_count++;
4617     }
4618 
4619     // Set do_frame_data_update to true for the last frame_parallel_level 2
4620     // frame in the current parallel encode set.
4621     if (i == (gf_group->size - 1) ||
4622         (gf_group->frame_parallel_level[i + 1] == 0 &&
4623          (gf_group->update_type[i + 1] == ARF_UPDATE ||
4624           gf_group->update_type[i + 1] == INTNL_ARF_UPDATE)) ||
4625         gf_group->frame_parallel_level[i + 1] == 1) {
4626       ppi->parallel_cpi[parallel_frame_count - 1]->do_frame_data_update = true;
4627       break;
4628     }
4629   }
4630 
4631   av1_increment_scaled_ref_counts_fpmt(first_cpi->common.buffer_pool,
4632                                        *ref_buffers_used_map);
4633 
4634   // Return the number of frames in the parallel encode set.
4635   return parallel_frame_count;
4636 }
4637 #endif  // CONFIG_FRAME_PARALLEL_ENCODE
4638 
4639 int av1_get_preview_raw_frame(AV1_COMP *cpi, YV12_BUFFER_CONFIG *dest) {
4640   AV1_COMMON *cm = &cpi->common;
4641   if (!cm->show_frame) {
4642     return -1;
4643   } else {
4644     int ret;
4645     if (cm->cur_frame != NULL) {
4646       *dest = cm->cur_frame->buf;
4647       dest->y_width = cm->width;
4648       dest->y_height = cm->height;
4649       dest->uv_width = cm->width >> cm->seq_params->subsampling_x;
4650       dest->uv_height = cm->height >> cm->seq_params->subsampling_y;
4651       ret = 0;
4652     } else {
4653       ret = -1;
4654     }
4655     return ret;
4656   }
4657 }
4658 
4659 int av1_get_last_show_frame(AV1_COMP *cpi, YV12_BUFFER_CONFIG *frame) {
4660   if (cpi->last_show_frame_buf == NULL) return -1;
4661 
4662   *frame = cpi->last_show_frame_buf->buf;
4663   return 0;
4664 }
4665 
4666 aom_codec_err_t av1_copy_new_frame_enc(AV1_COMMON *cm,
4667                                        YV12_BUFFER_CONFIG *new_frame,
4668                                        YV12_BUFFER_CONFIG *sd) {
4669   const int num_planes = av1_num_planes(cm);
4670   if (!equal_dimensions_and_border(new_frame, sd))
4671     aom_internal_error(cm->error, AOM_CODEC_ERROR,
4672                        "Incorrect buffer dimensions");
4673   else
4674     aom_yv12_copy_frame(new_frame, sd, num_planes);
4675 
4676   return cm->error->error_code;
4677 }
4678 
4679 int av1_set_internal_size(AV1EncoderConfig *const oxcf,
4680                           ResizePendingParams *resize_pending_params,
4681                           AOM_SCALING horiz_mode, AOM_SCALING vert_mode) {
4682   int hr = 0, hs = 0, vr = 0, vs = 0;
4683 
4684   if (horiz_mode > ONETWO || vert_mode > ONETWO) return -1;
4685 
4686   Scale2Ratio(horiz_mode, &hr, &hs);
4687   Scale2Ratio(vert_mode, &vr, &vs);
4688 
4689   // always go to the next whole number
4690   resize_pending_params->width = (hs - 1 + oxcf->frm_dim_cfg.width * hr) / hs;
4691   resize_pending_params->height = (vs - 1 + oxcf->frm_dim_cfg.height * vr) / vs;
4692 
4693   if (horiz_mode != NORMAL || vert_mode != NORMAL) {
4694     oxcf->resize_cfg.resize_mode = RESIZE_FIXED;
4695     oxcf->algo_cfg.enable_tpl_model = 0;
4696   }
4697   return 0;
4698 }
4699 
4700 int av1_get_quantizer(AV1_COMP *cpi) {
4701   return cpi->common.quant_params.base_qindex;
4702 }
4703 
4704 int av1_convert_sect5obus_to_annexb(uint8_t *buffer, size_t *frame_size) {
4705   size_t output_size = 0;
4706   size_t total_bytes_read = 0;
4707   size_t remaining_size = *frame_size;
4708   uint8_t *buff_ptr = buffer;
4709 
4710   // go through each OBUs
4711   while (total_bytes_read < *frame_size) {
4712     uint8_t saved_obu_header[2];
4713     uint64_t obu_payload_size;
4714     size_t length_of_payload_size;
4715     size_t length_of_obu_size;
4716     uint32_t obu_header_size = (buff_ptr[0] >> 2) & 0x1 ? 2 : 1;
4717     size_t obu_bytes_read = obu_header_size;  // bytes read for current obu
4718 
4719     // save the obu header (1 or 2 bytes)
4720     memmove(saved_obu_header, buff_ptr, obu_header_size);
4721     // clear the obu_has_size_field
4722     saved_obu_header[0] = saved_obu_header[0] & (~0x2);
4723 
4724     // get the payload_size and length of payload_size
4725     if (aom_uleb_decode(buff_ptr + obu_header_size, remaining_size,
4726                         &obu_payload_size, &length_of_payload_size) != 0) {
4727       return AOM_CODEC_ERROR;
4728     }
4729     obu_bytes_read += length_of_payload_size;
4730 
4731     // calculate the length of size of the obu header plus payload
4732     length_of_obu_size =
4733         aom_uleb_size_in_bytes((uint64_t)(obu_header_size + obu_payload_size));
4734 
4735     // move the rest of data to new location
4736     memmove(buff_ptr + length_of_obu_size + obu_header_size,
4737             buff_ptr + obu_bytes_read, remaining_size - obu_bytes_read);
4738     obu_bytes_read += (size_t)obu_payload_size;
4739 
4740     // write the new obu size
4741     const uint64_t obu_size = obu_header_size + obu_payload_size;
4742     size_t coded_obu_size;
4743     if (aom_uleb_encode(obu_size, sizeof(obu_size), buff_ptr,
4744                         &coded_obu_size) != 0) {
4745       return AOM_CODEC_ERROR;
4746     }
4747 
4748     // write the saved (modified) obu_header following obu size
4749     memmove(buff_ptr + length_of_obu_size, saved_obu_header, obu_header_size);
4750 
4751     total_bytes_read += obu_bytes_read;
4752     remaining_size -= obu_bytes_read;
4753     buff_ptr += length_of_obu_size + obu_size;
4754     output_size += length_of_obu_size + (size_t)obu_size;
4755   }
4756 
4757   *frame_size = output_size;
4758   return AOM_CODEC_OK;
4759 }
4760 
4761 static void svc_set_updates_ref_frame_config(
4762     ExtRefreshFrameFlagsInfo *const ext_refresh_frame_flags, SVC *const svc) {
4763   ext_refresh_frame_flags->update_pending = 1;
4764   ext_refresh_frame_flags->last_frame = svc->refresh[svc->ref_idx[0]];
4765   ext_refresh_frame_flags->golden_frame = svc->refresh[svc->ref_idx[3]];
4766   ext_refresh_frame_flags->bwd_ref_frame = svc->refresh[svc->ref_idx[4]];
4767   ext_refresh_frame_flags->alt2_ref_frame = svc->refresh[svc->ref_idx[5]];
4768   ext_refresh_frame_flags->alt_ref_frame = svc->refresh[svc->ref_idx[6]];
4769   svc->non_reference_frame = 1;
4770   for (int i = 0; i < REF_FRAMES; i++) {
4771     if (svc->refresh[i] == 1) {
4772       svc->non_reference_frame = 0;
4773       break;
4774     }
4775   }
4776 }
4777 
4778 static int svc_set_references_external_ref_frame_config(AV1_COMP *cpi) {
4779   // LAST_FRAME (0), LAST2_FRAME(1), LAST3_FRAME(2), GOLDEN_FRAME(3),
4780   // BWDREF_FRAME(4), ALTREF2_FRAME(5), ALTREF_FRAME(6).
4781   int ref = AOM_REFFRAME_ALL;
4782   for (int i = 0; i < INTER_REFS_PER_FRAME; i++) {
4783     if (!cpi->svc.reference[i]) ref ^= (1 << i);
4784   }
4785   return ref;
4786 }
4787 
4788 void av1_apply_encoding_flags(AV1_COMP *cpi, aom_enc_frame_flags_t flags) {
4789   // TODO(yunqingwang): For what references to use, external encoding flags
4790   // should be consistent with internal reference frame selection. Need to
4791   // ensure that there is not conflict between the two. In AV1 encoder, the
4792   // priority rank for 7 reference frames are: LAST, ALTREF, LAST2, LAST3,
4793   // GOLDEN, BWDREF, ALTREF2.
4794 
4795   ExternalFlags *const ext_flags = &cpi->ext_flags;
4796   ExtRefreshFrameFlagsInfo *const ext_refresh_frame_flags =
4797       &ext_flags->refresh_frame;
4798   ext_flags->ref_frame_flags = AOM_REFFRAME_ALL;
4799   if (flags &
4800       (AOM_EFLAG_NO_REF_LAST | AOM_EFLAG_NO_REF_LAST2 | AOM_EFLAG_NO_REF_LAST3 |
4801        AOM_EFLAG_NO_REF_GF | AOM_EFLAG_NO_REF_ARF | AOM_EFLAG_NO_REF_BWD |
4802        AOM_EFLAG_NO_REF_ARF2)) {
4803     int ref = AOM_REFFRAME_ALL;
4804 
4805     if (flags & AOM_EFLAG_NO_REF_LAST) ref ^= AOM_LAST_FLAG;
4806     if (flags & AOM_EFLAG_NO_REF_LAST2) ref ^= AOM_LAST2_FLAG;
4807     if (flags & AOM_EFLAG_NO_REF_LAST3) ref ^= AOM_LAST3_FLAG;
4808 
4809     if (flags & AOM_EFLAG_NO_REF_GF) ref ^= AOM_GOLD_FLAG;
4810 
4811     if (flags & AOM_EFLAG_NO_REF_ARF) {
4812       ref ^= AOM_ALT_FLAG;
4813       ref ^= AOM_BWD_FLAG;
4814       ref ^= AOM_ALT2_FLAG;
4815     } else {
4816       if (flags & AOM_EFLAG_NO_REF_BWD) ref ^= AOM_BWD_FLAG;
4817       if (flags & AOM_EFLAG_NO_REF_ARF2) ref ^= AOM_ALT2_FLAG;
4818     }
4819 
4820     av1_use_as_reference(&ext_flags->ref_frame_flags, ref);
4821   } else {
4822     if (cpi->svc.set_ref_frame_config) {
4823       int ref = svc_set_references_external_ref_frame_config(cpi);
4824       av1_use_as_reference(&ext_flags->ref_frame_flags, ref);
4825     }
4826   }
4827 
4828   if (flags &
4829       (AOM_EFLAG_NO_UPD_LAST | AOM_EFLAG_NO_UPD_GF | AOM_EFLAG_NO_UPD_ARF)) {
4830     int upd = AOM_REFFRAME_ALL;
4831 
4832     // Refreshing LAST/LAST2/LAST3 is handled by 1 common flag.
4833     if (flags & AOM_EFLAG_NO_UPD_LAST) upd ^= AOM_LAST_FLAG;
4834 
4835     if (flags & AOM_EFLAG_NO_UPD_GF) upd ^= AOM_GOLD_FLAG;
4836 
4837     if (flags & AOM_EFLAG_NO_UPD_ARF) {
4838       upd ^= AOM_ALT_FLAG;
4839       upd ^= AOM_BWD_FLAG;
4840       upd ^= AOM_ALT2_FLAG;
4841     }
4842 
4843     ext_refresh_frame_flags->last_frame = (upd & AOM_LAST_FLAG) != 0;
4844     ext_refresh_frame_flags->golden_frame = (upd & AOM_GOLD_FLAG) != 0;
4845     ext_refresh_frame_flags->alt_ref_frame = (upd & AOM_ALT_FLAG) != 0;
4846     ext_refresh_frame_flags->bwd_ref_frame = (upd & AOM_BWD_FLAG) != 0;
4847     ext_refresh_frame_flags->alt2_ref_frame = (upd & AOM_ALT2_FLAG) != 0;
4848     ext_refresh_frame_flags->update_pending = 1;
4849   } else {
4850     if (cpi->svc.set_ref_frame_config)
4851       svc_set_updates_ref_frame_config(ext_refresh_frame_flags, &cpi->svc);
4852     else
4853       ext_refresh_frame_flags->update_pending = 0;
4854   }
4855 
4856   ext_flags->use_ref_frame_mvs = cpi->oxcf.tool_cfg.enable_ref_frame_mvs &
4857                                  ((flags & AOM_EFLAG_NO_REF_FRAME_MVS) == 0);
4858   ext_flags->use_error_resilient = cpi->oxcf.tool_cfg.error_resilient_mode |
4859                                    ((flags & AOM_EFLAG_ERROR_RESILIENT) != 0);
4860   ext_flags->use_s_frame =
4861       cpi->oxcf.kf_cfg.enable_sframe | ((flags & AOM_EFLAG_SET_S_FRAME) != 0);
4862   ext_flags->use_primary_ref_none =
4863       (flags & AOM_EFLAG_SET_PRIMARY_REF_NONE) != 0;
4864 
4865   if (flags & AOM_EFLAG_NO_UPD_ENTROPY) {
4866     update_entropy(&ext_flags->refresh_frame_context,
4867                    &ext_flags->refresh_frame_context_pending, 0);
4868   }
4869 }
4870 
4871 aom_fixed_buf_t *av1_get_global_headers(AV1_PRIMARY *ppi) {
4872   if (!ppi) return NULL;
4873 
4874   uint8_t header_buf[512] = { 0 };
4875   const uint32_t sequence_header_size =
4876       av1_write_sequence_header_obu(&ppi->seq_params, &header_buf[0]);
4877   assert(sequence_header_size <= sizeof(header_buf));
4878   if (sequence_header_size == 0) return NULL;
4879 
4880   const size_t obu_header_size = 1;
4881   const size_t size_field_size = aom_uleb_size_in_bytes(sequence_header_size);
4882   const size_t payload_offset = obu_header_size + size_field_size;
4883 
4884   if (payload_offset + sequence_header_size > sizeof(header_buf)) return NULL;
4885   memmove(&header_buf[payload_offset], &header_buf[0], sequence_header_size);
4886 
4887   if (av1_write_obu_header(&ppi->level_params, &ppi->cpi->frame_header_count,
4888                            OBU_SEQUENCE_HEADER, 0,
4889                            &header_buf[0]) != obu_header_size) {
4890     return NULL;
4891   }
4892 
4893   size_t coded_size_field_size = 0;
4894   if (aom_uleb_encode(sequence_header_size, size_field_size,
4895                       &header_buf[obu_header_size],
4896                       &coded_size_field_size) != 0) {
4897     return NULL;
4898   }
4899   assert(coded_size_field_size == size_field_size);
4900 
4901   aom_fixed_buf_t *global_headers =
4902       (aom_fixed_buf_t *)malloc(sizeof(*global_headers));
4903   if (!global_headers) return NULL;
4904 
4905   const size_t global_header_buf_size =
4906       obu_header_size + size_field_size + sequence_header_size;
4907 
4908   global_headers->buf = malloc(global_header_buf_size);
4909   if (!global_headers->buf) {
4910     free(global_headers);
4911     return NULL;
4912   }
4913 
4914   memcpy(global_headers->buf, &header_buf[0], global_header_buf_size);
4915   global_headers->sz = global_header_buf_size;
4916   return global_headers;
4917 }
4918