tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

encoder_utils.c (72216B)


      1 /*
      2 * Copyright (c) 2020, 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 <string.h>
     13 
     14 #include "aom/aomcx.h"
     15 
     16 #include "av1/common/av1_common_int.h"
     17 #include "av1/encoder/bitstream.h"
     18 #include "av1/encoder/encodeframe.h"
     19 #include "av1/encoder/encoder.h"
     20 #include "av1/encoder/encoder_alloc.h"
     21 #include "av1/encoder/encodetxb.h"
     22 #include "av1/encoder/encoder_utils.h"
     23 #include "av1/encoder/firstpass.h"
     24 #include "av1/encoder/grain_test_vectors.h"
     25 #include "av1/encoder/mv_prec.h"
     26 #include "av1/encoder/pass2_strategy.h"
     27 #include "av1/encoder/ratectrl.h"
     28 #include "av1/encoder/rc_utils.h"
     29 #include "av1/encoder/rd.h"
     30 #include "av1/encoder/rdopt.h"
     31 #include "av1/encoder/segmentation.h"
     32 #include "av1/encoder/superres_scale.h"
     33 #include "av1/encoder/tpl_model.h"
     34 #include "av1/encoder/var_based_part.h"
     35 
     36 #if CONFIG_TUNE_VMAF
     37 #include "av1/encoder/tune_vmaf.h"
     38 #endif
     39 
     40 #define MIN_BOOST_COMBINE_FACTOR 4.0
     41 #define MAX_BOOST_COMBINE_FACTOR 12.0
     42 
     43 const int default_tx_type_probs[FRAME_UPDATE_TYPES][TX_SIZES_ALL][TX_TYPES] = {
     44  { { 221, 189, 214, 292, 0, 0, 0, 0, 0, 2, 38, 68, 0, 0, 0, 0 },
     45    { 262, 203, 216, 239, 0, 0, 0, 0, 0, 1, 37, 66, 0, 0, 0, 0 },
     46    { 315, 231, 239, 226, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0 },
     47    { 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
     48    { 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
     49    { 222, 188, 214, 287, 0, 0, 0, 0, 0, 2, 50, 61, 0, 0, 0, 0 },
     50    { 256, 182, 205, 282, 0, 0, 0, 0, 0, 2, 21, 76, 0, 0, 0, 0 },
     51    { 281, 214, 217, 222, 0, 0, 0, 0, 0, 1, 48, 41, 0, 0, 0, 0 },
     52    { 263, 194, 225, 225, 0, 0, 0, 0, 0, 2, 15, 100, 0, 0, 0, 0 },
     53    { 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
     54    { 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
     55    { 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
     56    { 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
     57    { 170, 192, 242, 293, 0, 0, 0, 0, 0, 1, 68, 58, 0, 0, 0, 0 },
     58    { 199, 210, 213, 291, 0, 0, 0, 0, 0, 1, 14, 96, 0, 0, 0, 0 },
     59    { 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
     60    { 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
     61    { 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
     62    { 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
     63  { { 106, 69, 107, 278, 9, 15, 20, 45, 49, 23, 23, 88, 36, 74, 25, 57 },
     64    { 105, 72, 81, 98, 45, 49, 47, 50, 56, 72, 30, 81, 33, 95, 27, 83 },
     65    { 211, 105, 109, 120, 57, 62, 43, 49, 52, 58, 42, 116, 0, 0, 0, 0 },
     66    { 1008, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0 },
     67    { 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
     68    { 131, 57, 98, 172, 19, 40, 37, 64, 69, 22, 41, 52, 51, 77, 35, 59 },
     69    { 176, 83, 93, 202, 22, 24, 28, 47, 50, 16, 12, 93, 26, 76, 17, 59 },
     70    { 136, 72, 89, 95, 46, 59, 47, 56, 61, 68, 35, 51, 32, 82, 26, 69 },
     71    { 122, 80, 87, 105, 49, 47, 46, 46, 57, 52, 13, 90, 19, 103, 15, 93 },
     72    { 1009, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0 },
     73    { 1011, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0 },
     74    { 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
     75    { 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
     76    { 202, 20, 84, 114, 14, 60, 41, 79, 99, 21, 41, 15, 50, 84, 34, 66 },
     77    { 196, 44, 23, 72, 30, 22, 28, 57, 67, 13, 4, 165, 15, 148, 9, 131 },
     78    { 882, 0, 0, 0, 0, 0, 0, 0, 0, 142, 0, 0, 0, 0, 0, 0 },
     79    { 840, 0, 0, 0, 0, 0, 0, 0, 0, 184, 0, 0, 0, 0, 0, 0 },
     80    { 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
     81    { 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
     82  { { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },
     83    { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },
     84    { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },
     85    { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },
     86    { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },
     87    { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },
     88    { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },
     89    { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },
     90    { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },
     91    { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },
     92    { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },
     93    { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },
     94    { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },
     95    { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },
     96    { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },
     97    { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },
     98    { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },
     99    { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },
    100    { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 } },
    101  { { 213, 110, 141, 269, 12, 16, 15, 19, 21, 11, 38, 68, 22, 29, 16, 24 },
    102    { 216, 119, 128, 143, 38, 41, 26, 30, 31, 30, 42, 70, 23, 36, 19, 32 },
    103    { 367, 149, 154, 154, 38, 35, 17, 21, 21, 10, 22, 36, 0, 0, 0, 0 },
    104    { 1022, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0 },
    105    { 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    106    { 219, 96, 127, 191, 21, 40, 25, 32, 34, 18, 45, 45, 33, 39, 26, 33 },
    107    { 296, 99, 122, 198, 23, 21, 19, 24, 25, 13, 20, 64, 23, 32, 18, 27 },
    108    { 275, 128, 142, 143, 35, 48, 23, 30, 29, 18, 42, 36, 18, 23, 14, 20 },
    109    { 239, 132, 166, 175, 36, 27, 19, 21, 24, 14, 13, 85, 9, 31, 8, 25 },
    110    { 1022, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0 },
    111    { 1022, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0 },
    112    { 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    113    { 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    114    { 309, 25, 79, 59, 25, 80, 34, 53, 61, 25, 49, 23, 43, 64, 36, 59 },
    115    { 270, 57, 40, 54, 50, 42, 41, 53, 56, 28, 17, 81, 45, 86, 34, 70 },
    116    { 1005, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0 },
    117    { 992, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0 },
    118    { 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    119    { 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
    120  { { 133, 63, 55, 83, 57, 87, 58, 72, 68, 16, 24, 35, 29, 105, 25, 114 },
    121    { 131, 75, 74, 60, 71, 77, 65, 66, 73, 33, 21, 79, 20, 83, 18, 78 },
    122    { 276, 95, 82, 58, 86, 93, 63, 60, 64, 17, 38, 92, 0, 0, 0, 0 },
    123    { 1006, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0 },
    124    { 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    125    { 147, 49, 75, 78, 50, 97, 60, 67, 76, 17, 42, 35, 31, 93, 27, 80 },
    126    { 157, 49, 58, 75, 61, 52, 56, 67, 69, 12, 15, 79, 24, 119, 11, 120 },
    127    { 178, 69, 83, 77, 69, 85, 72, 77, 77, 20, 35, 40, 25, 48, 23, 46 },
    128    { 174, 55, 64, 57, 73, 68, 62, 61, 75, 15, 12, 90, 17, 99, 16, 86 },
    129    { 1008, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0 },
    130    { 1018, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0 },
    131    { 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    132    { 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    133    { 266, 31, 63, 64, 21, 52, 39, 54, 63, 30, 52, 31, 48, 89, 46, 75 },
    134    { 272, 26, 32, 44, 29, 31, 32, 53, 51, 13, 13, 88, 22, 153, 16, 149 },
    135    { 923, 0, 0, 0, 0, 0, 0, 0, 0, 101, 0, 0, 0, 0, 0, 0 },
    136    { 969, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0 },
    137    { 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    138    { 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
    139  { { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },
    140    { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },
    141    { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },
    142    { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },
    143    { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },
    144    { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },
    145    { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },
    146    { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },
    147    { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },
    148    { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },
    149    { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },
    150    { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },
    151    { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },
    152    { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },
    153    { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },
    154    { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },
    155    { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },
    156    { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },
    157    { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 } },
    158  { { 158, 92, 125, 298, 12, 15, 20, 29, 31, 12, 29, 67, 34, 44, 23, 35 },
    159    { 147, 94, 103, 123, 45, 48, 38, 41, 46, 48, 37, 78, 33, 63, 27, 53 },
    160    { 268, 126, 125, 136, 54, 53, 31, 38, 38, 33, 35, 87, 0, 0, 0, 0 },
    161    { 1018, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0 },
    162    { 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    163    { 159, 72, 103, 194, 20, 35, 37, 50, 56, 21, 39, 40, 51, 61, 38, 48 },
    164    { 259, 86, 95, 188, 32, 20, 25, 34, 37, 13, 12, 85, 25, 53, 17, 43 },
    165    { 189, 99, 113, 123, 45, 59, 37, 46, 48, 44, 39, 41, 31, 47, 26, 37 },
    166    { 175, 110, 113, 128, 58, 38, 33, 33, 43, 29, 13, 100, 14, 68, 12, 57 },
    167    { 1017, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0 },
    168    { 1019, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0 },
    169    { 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    170    { 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    171    { 208, 22, 84, 101, 21, 59, 44, 70, 90, 25, 59, 13, 64, 67, 49, 48 },
    172    { 277, 52, 32, 63, 43, 26, 33, 48, 54, 11, 6, 130, 18, 119, 11, 101 },
    173    { 963, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 0, 0, 0, 0, 0 },
    174    { 979, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0 },
    175    { 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    176    { 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }
    177 };
    178 
    179 const int default_obmc_probs[FRAME_UPDATE_TYPES][BLOCK_SIZES_ALL] = {
    180  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    181  { 0,  0,  0,  106, 90, 90, 97, 67, 59, 70, 28,
    182    30, 38, 16, 16,  16, 0,  0,  44, 50, 26, 25 },
    183  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    184  { 0,  0,  0,  98, 93, 97, 68, 82, 85, 33, 30,
    185    33, 16, 16, 16, 16, 0,  0,  43, 37, 26, 16 },
    186  { 0,  0,  0,  91, 80, 76, 78, 55, 49, 24, 16,
    187    16, 16, 16, 16, 16, 0,  0,  29, 45, 16, 38 },
    188  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    189  { 0,  0,  0,  103, 89, 89, 89, 62, 63, 76, 34,
    190    35, 32, 19, 16,  16, 0,  0,  49, 55, 29, 19 }
    191 };
    192 
    193 const int default_warped_probs[FRAME_UPDATE_TYPES] = { 64, 64, 64, 64,
    194                                                       64, 64, 64 };
    195 
    196 // TODO(yunqing): the default probs can be trained later from better
    197 // performance.
    198 const int default_switchable_interp_probs[FRAME_UPDATE_TYPES]
    199                                         [SWITCHABLE_FILTER_CONTEXTS]
    200                                         [SWITCHABLE_FILTERS] = {
    201                                           { { 512, 512, 512 },
    202                                             { 512, 512, 512 },
    203                                             { 512, 512, 512 },
    204                                             { 512, 512, 512 },
    205                                             { 512, 512, 512 },
    206                                             { 512, 512, 512 },
    207                                             { 512, 512, 512 },
    208                                             { 512, 512, 512 },
    209                                             { 512, 512, 512 },
    210                                             { 512, 512, 512 },
    211                                             { 512, 512, 512 },
    212                                             { 512, 512, 512 },
    213                                             { 512, 512, 512 },
    214                                             { 512, 512, 512 },
    215                                             { 512, 512, 512 },
    216                                             { 512, 512, 512 } },
    217                                           { { 512, 512, 512 },
    218                                             { 512, 512, 512 },
    219                                             { 512, 512, 512 },
    220                                             { 512, 512, 512 },
    221                                             { 512, 512, 512 },
    222                                             { 512, 512, 512 },
    223                                             { 512, 512, 512 },
    224                                             { 512, 512, 512 },
    225                                             { 512, 512, 512 },
    226                                             { 512, 512, 512 },
    227                                             { 512, 512, 512 },
    228                                             { 512, 512, 512 },
    229                                             { 512, 512, 512 },
    230                                             { 512, 512, 512 },
    231                                             { 512, 512, 512 },
    232                                             { 512, 512, 512 } },
    233                                           { { 512, 512, 512 },
    234                                             { 512, 512, 512 },
    235                                             { 512, 512, 512 },
    236                                             { 512, 512, 512 },
    237                                             { 512, 512, 512 },
    238                                             { 512, 512, 512 },
    239                                             { 512, 512, 512 },
    240                                             { 512, 512, 512 },
    241                                             { 512, 512, 512 },
    242                                             { 512, 512, 512 },
    243                                             { 512, 512, 512 },
    244                                             { 512, 512, 512 },
    245                                             { 512, 512, 512 },
    246                                             { 512, 512, 512 },
    247                                             { 512, 512, 512 },
    248                                             { 512, 512, 512 } },
    249                                           { { 512, 512, 512 },
    250                                             { 512, 512, 512 },
    251                                             { 512, 512, 512 },
    252                                             { 512, 512, 512 },
    253                                             { 512, 512, 512 },
    254                                             { 512, 512, 512 },
    255                                             { 512, 512, 512 },
    256                                             { 512, 512, 512 },
    257                                             { 512, 512, 512 },
    258                                             { 512, 512, 512 },
    259                                             { 512, 512, 512 },
    260                                             { 512, 512, 512 },
    261                                             { 512, 512, 512 },
    262                                             { 512, 512, 512 },
    263                                             { 512, 512, 512 },
    264                                             { 512, 512, 512 } },
    265                                           { { 512, 512, 512 },
    266                                             { 512, 512, 512 },
    267                                             { 512, 512, 512 },
    268                                             { 512, 512, 512 },
    269                                             { 512, 512, 512 },
    270                                             { 512, 512, 512 },
    271                                             { 512, 512, 512 },
    272                                             { 512, 512, 512 },
    273                                             { 512, 512, 512 },
    274                                             { 512, 512, 512 },
    275                                             { 512, 512, 512 },
    276                                             { 512, 512, 512 },
    277                                             { 512, 512, 512 },
    278                                             { 512, 512, 512 },
    279                                             { 512, 512, 512 },
    280                                             { 512, 512, 512 } },
    281                                           { { 512, 512, 512 },
    282                                             { 512, 512, 512 },
    283                                             { 512, 512, 512 },
    284                                             { 512, 512, 512 },
    285                                             { 512, 512, 512 },
    286                                             { 512, 512, 512 },
    287                                             { 512, 512, 512 },
    288                                             { 512, 512, 512 },
    289                                             { 512, 512, 512 },
    290                                             { 512, 512, 512 },
    291                                             { 512, 512, 512 },
    292                                             { 512, 512, 512 },
    293                                             { 512, 512, 512 },
    294                                             { 512, 512, 512 },
    295                                             { 512, 512, 512 },
    296                                             { 512, 512, 512 } },
    297                                           { { 512, 512, 512 },
    298                                             { 512, 512, 512 },
    299                                             { 512, 512, 512 },
    300                                             { 512, 512, 512 },
    301                                             { 512, 512, 512 },
    302                                             { 512, 512, 512 },
    303                                             { 512, 512, 512 },
    304                                             { 512, 512, 512 },
    305                                             { 512, 512, 512 },
    306                                             { 512, 512, 512 },
    307                                             { 512, 512, 512 },
    308                                             { 512, 512, 512 },
    309                                             { 512, 512, 512 },
    310                                             { 512, 512, 512 },
    311                                             { 512, 512, 512 },
    312                                             { 512, 512, 512 } }
    313                                         };
    314 
    315 static void configure_static_seg_features(AV1_COMP *cpi) {
    316  AV1_COMMON *const cm = &cpi->common;
    317  const RATE_CONTROL *const rc = &cpi->rc;
    318  struct segmentation *const seg = &cm->seg;
    319 
    320  double avg_q;
    321 #if CONFIG_FPMT_TEST
    322  avg_q = ((cpi->ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] > 0) &&
    323           (cpi->ppi->fpmt_unit_test_cfg == PARALLEL_SIMULATION_ENCODE))
    324              ? cpi->ppi->p_rc.temp_avg_q
    325              : cpi->ppi->p_rc.avg_q;
    326 #else
    327  avg_q = cpi->ppi->p_rc.avg_q;
    328 #endif
    329 
    330  int high_q = (int)(avg_q > 48.0);
    331  int qi_delta;
    332 
    333  // Disable and clear down for KF
    334  if (cm->current_frame.frame_type == KEY_FRAME) {
    335    // Clear down the global segmentation map
    336    memset(cpi->enc_seg.map, 0, cm->mi_params.mi_rows * cm->mi_params.mi_cols);
    337    seg->update_map = 0;
    338    seg->update_data = 0;
    339 
    340    // Disable segmentation
    341    av1_disable_segmentation(seg);
    342 
    343    // Clear down the segment features.
    344    av1_clearall_segfeatures(seg);
    345  } else if (cpi->refresh_frame.alt_ref_frame) {
    346    // If this is an alt ref frame
    347    // Clear down the global segmentation map
    348    memset(cpi->enc_seg.map, 0, cm->mi_params.mi_rows * cm->mi_params.mi_cols);
    349    seg->update_map = 0;
    350    seg->update_data = 0;
    351 
    352    // Disable segmentation and individual segment features by default
    353    av1_disable_segmentation(seg);
    354    av1_clearall_segfeatures(seg);
    355 
    356    // If segmentation was enabled set those features needed for the
    357    // arf itself.
    358    if (seg->enabled) {
    359      seg->update_map = 1;
    360      seg->update_data = 1;
    361 
    362      qi_delta = av1_compute_qdelta(rc, avg_q, avg_q * 0.875,
    363                                    cm->seq_params->bit_depth);
    364      av1_set_segdata(seg, 1, SEG_LVL_ALT_Q, qi_delta - 2);
    365      av1_set_segdata(seg, 1, SEG_LVL_ALT_LF_Y_H, -2);
    366      av1_set_segdata(seg, 1, SEG_LVL_ALT_LF_Y_V, -2);
    367      av1_set_segdata(seg, 1, SEG_LVL_ALT_LF_U, -2);
    368      av1_set_segdata(seg, 1, SEG_LVL_ALT_LF_V, -2);
    369 
    370      av1_enable_segfeature(seg, 1, SEG_LVL_ALT_LF_Y_H);
    371      av1_enable_segfeature(seg, 1, SEG_LVL_ALT_LF_Y_V);
    372      av1_enable_segfeature(seg, 1, SEG_LVL_ALT_LF_U);
    373      av1_enable_segfeature(seg, 1, SEG_LVL_ALT_LF_V);
    374 
    375      av1_enable_segfeature(seg, 1, SEG_LVL_ALT_Q);
    376    }
    377  } else if (seg->enabled) {
    378    // All other frames if segmentation has been enabled
    379 
    380    // First normal frame in a valid gf or alt ref group
    381    if (rc->frames_since_golden == 0) {
    382      // Set up segment features for normal frames in an arf group
    383      // Disable segmentation and clear down features if alt ref
    384      // is not active for this group
    385 
    386      av1_disable_segmentation(seg);
    387 
    388      memset(cpi->enc_seg.map, 0,
    389             cm->mi_params.mi_rows * cm->mi_params.mi_cols);
    390 
    391      seg->update_map = 0;
    392      seg->update_data = 0;
    393 
    394      av1_clearall_segfeatures(seg);
    395    } else if (rc->is_src_frame_alt_ref) {
    396      // Special case where we are coding over the top of a previous
    397      // alt ref frame.
    398      // Segment coding disabled for compred testing
    399 
    400      // Enable ref frame features for segment 0 as well
    401      av1_enable_segfeature(seg, 0, SEG_LVL_REF_FRAME);
    402      av1_enable_segfeature(seg, 1, SEG_LVL_REF_FRAME);
    403 
    404      // All mbs should use ALTREF_FRAME
    405      av1_clear_segdata(seg, 0, SEG_LVL_REF_FRAME);
    406      av1_set_segdata(seg, 0, SEG_LVL_REF_FRAME, ALTREF_FRAME);
    407      av1_clear_segdata(seg, 1, SEG_LVL_REF_FRAME);
    408      av1_set_segdata(seg, 1, SEG_LVL_REF_FRAME, ALTREF_FRAME);
    409 
    410      // Skip all MBs if high Q (0,0 mv and skip coeffs)
    411      if (high_q) {
    412        av1_enable_segfeature(seg, 0, SEG_LVL_SKIP);
    413        av1_enable_segfeature(seg, 1, SEG_LVL_SKIP);
    414      }
    415      // Enable data update
    416      seg->update_data = 1;
    417    } else {
    418      // All other frames.
    419 
    420      // No updates.. leave things as they are.
    421      seg->update_map = 0;
    422      seg->update_data = 0;
    423    }
    424  }
    425 }
    426 
    427 void av1_apply_roi_map(AV1_COMP *cpi) {
    428  AV1_COMMON *cm = &cpi->common;
    429  struct segmentation *const seg = &cm->seg;
    430  unsigned char *const seg_map = cpi->enc_seg.map;
    431  aom_roi_map_t *roi = &cpi->roi;
    432  const int *delta_q = roi->delta_q;
    433  const int *delta_lf = roi->delta_lf;
    434  const int *skip = roi->skip;
    435  int ref_frame[8];
    436  int internal_delta_q[MAX_SEGMENTS];
    437  int skip_enabled = 0;
    438  int qindex = cm->quant_params.base_qindex;
    439 
    440  // Force disable of ROI if active_map is enabled. ROI for now
    441  // only supported/tested for realtime mode with speed >= 7.
    442  if (!roi->enabled || cpi->active_map.enabled || cpi->oxcf.speed < 7 ||
    443      cpi->oxcf.mode != REALTIME) {
    444    roi->enabled = 0;
    445    roi->delta_qp_enabled = 0;
    446    roi->reference_enabled = 0;
    447    return;
    448  }
    449 
    450  memcpy(&ref_frame, roi->ref_frame, sizeof(ref_frame));
    451  roi->reference_enabled = 0;
    452  roi->delta_qp_enabled = 0;
    453 
    454  av1_enable_segmentation(seg);
    455  av1_clearall_segfeatures(seg);
    456 
    457  memcpy(seg_map, roi->roi_map,
    458         (cm->mi_params.mi_rows * cm->mi_params.mi_cols));
    459 
    460  for (int i = 0; i < MAX_SEGMENTS; ++i) {
    461    // Default: disable all feautures.
    462    av1_disable_segfeature(seg, i, SEG_LVL_ALT_Q);
    463    av1_disable_segfeature(seg, i, SEG_LVL_SKIP);
    464    av1_disable_segfeature(seg, i, SEG_LVL_REF_FRAME);
    465    av1_disable_segfeature(seg, i, SEG_LVL_ALT_LF_Y_H);
    466    av1_disable_segfeature(seg, i, SEG_LVL_ALT_LF_Y_V);
    467    av1_disable_segfeature(seg, i, SEG_LVL_ALT_LF_U);
    468    av1_disable_segfeature(seg, i, SEG_LVL_ALT_LF_V);
    469    // Translate the external delta q values to internal values.
    470    internal_delta_q[i] = av1_quantizer_to_qindex(abs(delta_q[i]));
    471    if (delta_q[i] < 0) internal_delta_q[i] = -internal_delta_q[i];
    472    // Clamp to allowed best/worst quality. For best quality clamp to 1
    473    // to avoid qindex = 0 case (lossless segment) which can happen for
    474    // best_quality = 0.
    475    if (qindex + internal_delta_q[i] <= cpi->rc.best_quality)
    476      internal_delta_q[i] = AOMMAX(1, cpi->rc.best_quality) - qindex;
    477    if (qindex + internal_delta_q[i] > cpi->rc.worst_quality)
    478      internal_delta_q[i] =
    479          cpi->rc.worst_quality - cm->quant_params.base_qindex;
    480    if (internal_delta_q[i] != 0) {
    481      av1_enable_segfeature(seg, i, SEG_LVL_ALT_Q);
    482      av1_set_segdata(seg, i, SEG_LVL_ALT_Q, internal_delta_q[i]);
    483      roi->delta_qp_enabled = 1;
    484      qindex = cm->quant_params.base_qindex + internal_delta_q[i];
    485    }
    486    if (delta_lf[i] != 0) {
    487      // Disable loopfilter delta from ROI, as it requires
    488      // additional changes and settings: DELTAQ_MODE and DELTALF_MODE
    489      // are needed to be enabled, along with additional internal fix.
    490      return;
    491    }
    492    // Skip only allowed on delta frames.
    493    if (skip[i] != 0 && !frame_is_intra_only(cm)) {
    494      av1_enable_segfeature(seg, i, SEG_LVL_SKIP);
    495      // Also force skip on loopfilter.
    496      av1_enable_segfeature(seg, i, SEG_LVL_ALT_LF_Y_H);
    497      av1_enable_segfeature(seg, i, SEG_LVL_ALT_LF_Y_V);
    498      av1_enable_segfeature(seg, i, SEG_LVL_ALT_LF_U);
    499      av1_enable_segfeature(seg, i, SEG_LVL_ALT_LF_V);
    500      av1_set_segdata(seg, i, SEG_LVL_ALT_LF_Y_H, -MAX_LOOP_FILTER);
    501      av1_set_segdata(seg, i, SEG_LVL_ALT_LF_Y_V, -MAX_LOOP_FILTER);
    502      av1_set_segdata(seg, i, SEG_LVL_ALT_LF_U, -MAX_LOOP_FILTER);
    503      av1_set_segdata(seg, i, SEG_LVL_ALT_LF_V, -MAX_LOOP_FILTER);
    504      skip_enabled = 1;
    505    }
    506    if (ref_frame[i] >= 0 && !frame_is_intra_only(cm)) {
    507      // Only allowed for LAST, GOLDEN, and ALTREF, and check that if either
    508      // is set as a reference.
    509      if ((ref_frame[i] == LAST_FRAME &&
    510           cpi->ref_frame_flags & AOM_LAST_FLAG) ||
    511          (ref_frame[i] == GOLDEN_FRAME &&
    512           cpi->ref_frame_flags & AOM_GOLD_FLAG) ||
    513          (ref_frame[i] == ALTREF_FRAME &&
    514           cpi->ref_frame_flags & AOM_ALT_FLAG)) {
    515        av1_enable_segfeature(seg, i, SEG_LVL_REF_FRAME);
    516        av1_set_segdata(seg, i, SEG_LVL_REF_FRAME, ref_frame[i]);
    517        roi->reference_enabled = 1;
    518      }
    519    }
    520  }
    521  if (roi->delta_qp_enabled || skip_enabled || roi->reference_enabled) {
    522    roi->enabled = 1;
    523    if (roi->delta_qp_enabled) {
    524      roi->rdmult_delta_qp = av1_compute_rd_mult(
    525          qindex, cm->seq_params->bit_depth,
    526          cpi->ppi->gf_group.update_type[cpi->gf_frame_index], 0, 15,
    527          INTER_FRAME, cpi->oxcf.q_cfg.use_fixed_qp_offsets,
    528          is_stat_consumption_stage(cpi), cpi->oxcf.tune_cfg.tuning);
    529    }
    530  } else {
    531    av1_disable_segmentation(seg);
    532    roi->enabled = 0;
    533  }
    534 }
    535 
    536 void av1_apply_active_map(AV1_COMP *cpi) {
    537  struct segmentation *const seg = &cpi->common.seg;
    538  unsigned char *const seg_map = cpi->enc_seg.map;
    539  const unsigned char *const active_map = cpi->active_map.map;
    540 
    541  assert(AM_SEGMENT_ID_ACTIVE == CR_SEGMENT_ID_BASE);
    542 
    543  // Disable the active_maps on intra_only frames or if the
    544  // input map for the current frame has no inactive blocks.
    545  if (frame_is_intra_only(&cpi->common) ||
    546      cpi->rc.percent_blocks_inactive == 0) {
    547    cpi->active_map.enabled = 0;
    548    cpi->active_map.update = 1;
    549  }
    550 
    551  if (cpi->active_map.update) {
    552    if (cpi->active_map.enabled) {
    553      const int num_mis =
    554          cpi->common.mi_params.mi_rows * cpi->common.mi_params.mi_cols;
    555      memcpy(seg_map, active_map, sizeof(active_map[0]) * num_mis);
    556      av1_enable_segmentation(seg);
    557      av1_enable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_SKIP);
    558      av1_enable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF_Y_H);
    559      av1_enable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF_Y_V);
    560      av1_enable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF_U);
    561      av1_enable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF_V);
    562 
    563      av1_set_segdata(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF_Y_H,
    564                      -MAX_LOOP_FILTER);
    565      av1_set_segdata(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF_Y_V,
    566                      -MAX_LOOP_FILTER);
    567      av1_set_segdata(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF_U,
    568                      -MAX_LOOP_FILTER);
    569      av1_set_segdata(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF_V,
    570                      -MAX_LOOP_FILTER);
    571    } else {
    572      av1_disable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_SKIP);
    573      av1_disable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF_Y_H);
    574      av1_disable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF_Y_V);
    575      av1_disable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF_U);
    576      av1_disable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF_V);
    577      if (seg->enabled) {
    578        seg->update_data = 1;
    579        seg->update_map = 1;
    580      }
    581    }
    582    cpi->active_map.update = 0;
    583  }
    584 }
    585 
    586 #if !CONFIG_REALTIME_ONLY
    587 static void process_tpl_stats_frame(AV1_COMP *cpi) {
    588  GF_GROUP *const gf_group = &cpi->ppi->gf_group;
    589  AV1_COMMON *const cm = &cpi->common;
    590 
    591  assert(IMPLIES(gf_group->size > 0, cpi->gf_frame_index < gf_group->size));
    592 
    593  const int tpl_idx = cpi->gf_frame_index;
    594  TplParams *const tpl_data = &cpi->ppi->tpl_data;
    595  TplDepFrame *tpl_frame = &tpl_data->tpl_frame[tpl_idx];
    596  TplDepStats *tpl_stats = tpl_frame->tpl_stats_ptr;
    597 
    598  if (tpl_frame->is_valid) {
    599    int tpl_stride = tpl_frame->stride;
    600    double intra_cost_base = 0;
    601    double mc_dep_cost_base = 0;
    602    double cbcmp_base = 1;
    603    const int step = 1 << tpl_data->tpl_stats_block_mis_log2;
    604    const int row_step = step;
    605    const int col_step_sr =
    606        coded_to_superres_mi(step, cm->superres_scale_denominator);
    607    const int mi_cols_sr = av1_pixels_to_mi(cm->superres_upscaled_width);
    608 
    609    for (int row = 0; row < cm->mi_params.mi_rows; row += row_step) {
    610      for (int col = 0; col < mi_cols_sr; col += col_step_sr) {
    611        TplDepStats *this_stats = &tpl_stats[av1_tpl_ptr_pos(
    612            row, col, tpl_stride, tpl_data->tpl_stats_block_mis_log2)];
    613        double cbcmp = (double)(this_stats->srcrf_dist);
    614        int64_t mc_dep_delta =
    615            RDCOST(tpl_frame->base_rdmult, this_stats->mc_dep_rate,
    616                   this_stats->mc_dep_dist);
    617        double dist_scaled = (double)(this_stats->recrf_dist << RDDIV_BITS);
    618        intra_cost_base += log(dist_scaled) * cbcmp;
    619        mc_dep_cost_base += log(dist_scaled + mc_dep_delta) * cbcmp;
    620        cbcmp_base += cbcmp;
    621      }
    622    }
    623 
    624    if (mc_dep_cost_base == 0) {
    625      tpl_frame->is_valid = 0;
    626    } else {
    627      cpi->rd.r0 = exp((intra_cost_base - mc_dep_cost_base) / cbcmp_base);
    628      if (is_frame_tpl_eligible(gf_group, cpi->gf_frame_index)) {
    629        if (cpi->ppi->lap_enabled) {
    630          double min_boost_factor = sqrt(cpi->ppi->p_rc.baseline_gf_interval);
    631          const int gfu_boost = get_gfu_boost_from_r0_lap(
    632              min_boost_factor, MAX_GFUBOOST_FACTOR, cpi->rd.r0,
    633              cpi->ppi->p_rc.num_stats_required_for_gfu_boost);
    634          cpi->ppi->p_rc.gfu_boost = combine_prior_with_tpl_boost(
    635              min_boost_factor, MAX_BOOST_COMBINE_FACTOR,
    636              cpi->ppi->p_rc.gfu_boost, gfu_boost,
    637              cpi->ppi->p_rc.num_stats_used_for_gfu_boost);
    638        } else {
    639          // TPL may only look at a subset of frame in the gf group when the
    640          // speed feature 'reduce_num_frames' is on, which affects the r0
    641          // calcuation. Thus, to compensate for TPL not using all frames a
    642          // factor to adjust r0 is used.
    643          const int gfu_boost =
    644              (int)(200.0 * cpi->ppi->tpl_data.r0_adjust_factor / cpi->rd.r0);
    645 
    646          if (cpi->oxcf.algo_cfg.sharpness == 3 &&
    647              gf_group->update_type[cpi->gf_frame_index] != KF_UPDATE) {
    648            cpi->ppi->p_rc.gfu_boost = gfu_boost;
    649 
    650            RATE_CONTROL *const rc = &cpi->rc;
    651            PRIMARY_RATE_CONTROL *const p_rc = &cpi->ppi->p_rc;
    652            av1_gop_bit_allocation(cpi, rc, gf_group, rc->frames_since_key == 0,
    653                                   gf_group->arf_index != -1,
    654                                   p_rc->gf_group_bits);
    655            av1_setup_target_rate(cpi);
    656          } else {
    657            cpi->ppi->p_rc.gfu_boost = combine_prior_with_tpl_boost(
    658                MIN_BOOST_COMBINE_FACTOR, MAX_BOOST_COMBINE_FACTOR,
    659                cpi->ppi->p_rc.gfu_boost, gfu_boost, cpi->rc.frames_to_key);
    660          }
    661        }
    662      }
    663    }
    664  }
    665 }
    666 #endif  // !CONFIG_REALTIME_ONLY
    667 
    668 void av1_set_size_dependent_vars(AV1_COMP *cpi, int *q, int *bottom_index,
    669                                 int *top_index) {
    670  AV1_COMMON *const cm = &cpi->common;
    671 
    672  // Setup variables that depend on the dimensions of the frame.
    673  av1_set_speed_features_framesize_dependent(cpi, cpi->speed);
    674 
    675 #if !CONFIG_REALTIME_ONLY
    676  GF_GROUP *gf_group = &cpi->ppi->gf_group;
    677  if (cpi->oxcf.algo_cfg.enable_tpl_model &&
    678      av1_tpl_stats_ready(&cpi->ppi->tpl_data, cpi->gf_frame_index)) {
    679    process_tpl_stats_frame(cpi);
    680    av1_tpl_rdmult_setup(cpi);
    681  }
    682 #endif
    683 
    684  // Decide q and q bounds.
    685  *q = av1_rc_pick_q_and_bounds(cpi, cm->width, cm->height, cpi->gf_frame_index,
    686                                bottom_index, top_index);
    687 
    688  if (cpi->oxcf.rc_cfg.mode == AOM_CBR && cpi->rc.force_max_q) {
    689    *q = cpi->rc.worst_quality;
    690    cpi->rc.force_max_q = 0;
    691  }
    692 
    693 #if !CONFIG_REALTIME_ONLY
    694  if (cpi->oxcf.rc_cfg.mode == AOM_Q &&
    695      cpi->ppi->tpl_data.tpl_frame[cpi->gf_frame_index].is_valid &&
    696      !is_lossless_requested(&cpi->oxcf.rc_cfg)) {
    697    const RateControlCfg *const rc_cfg = &cpi->oxcf.rc_cfg;
    698    const int tpl_q = av1_tpl_get_q_index(
    699        &cpi->ppi->tpl_data, cpi->gf_frame_index, cpi->rc.active_worst_quality,
    700        cm->seq_params->bit_depth);
    701    *q = clamp(tpl_q, rc_cfg->best_allowed_q, rc_cfg->worst_allowed_q);
    702    *top_index = *bottom_index = *q;
    703    if (gf_group->update_type[cpi->gf_frame_index] == ARF_UPDATE)
    704      cpi->ppi->p_rc.arf_q = *q;
    705  }
    706 
    707  if (cpi->oxcf.q_cfg.use_fixed_qp_offsets && cpi->oxcf.rc_cfg.mode == AOM_Q) {
    708    if (is_frame_tpl_eligible(gf_group, cpi->gf_frame_index)) {
    709      const double qratio_grad =
    710          cpi->ppi->p_rc.baseline_gf_interval > 20 ? 0.2 : 0.3;
    711      const double qstep_ratio =
    712          0.2 +
    713          (1.0 - (double)cpi->rc.active_worst_quality / MAXQ) * qratio_grad;
    714      *q = av1_get_q_index_from_qstep_ratio(
    715          cpi->rc.active_worst_quality, qstep_ratio, cm->seq_params->bit_depth);
    716      *top_index = *bottom_index = *q;
    717      if (gf_group->update_type[cpi->gf_frame_index] == ARF_UPDATE ||
    718          gf_group->update_type[cpi->gf_frame_index] == KF_UPDATE ||
    719          gf_group->update_type[cpi->gf_frame_index] == GF_UPDATE)
    720        cpi->ppi->p_rc.arf_q = *q;
    721    } else if (gf_group->layer_depth[cpi->gf_frame_index] <
    722               gf_group->max_layer_depth) {
    723      int this_height = gf_group->layer_depth[cpi->gf_frame_index];
    724      int arf_q = cpi->ppi->p_rc.arf_q;
    725      while (this_height > 1) {
    726        arf_q = (arf_q + cpi->oxcf.rc_cfg.cq_level + 1) / 2;
    727        --this_height;
    728      }
    729      *top_index = *bottom_index = *q = arf_q;
    730    }
    731  }
    732 #endif
    733 
    734  // Configure experimental use of segmentation for enhanced coding of
    735  // static regions if indicated.
    736  // Only allowed in the second pass of a two pass encode, as it requires
    737  // lagged coding, and if the relevant speed feature flag is set.
    738  if (is_stat_consumption_stage_twopass(cpi) &&
    739      cpi->sf.hl_sf.static_segmentation)
    740    configure_static_seg_features(cpi);
    741 }
    742 
    743 #if !CONFIG_REALTIME_ONLY
    744 static void reset_film_grain_chroma_params(aom_film_grain_t *pars) {
    745  pars->num_cr_points = 0;
    746  pars->cr_mult = 0;
    747  pars->cr_luma_mult = 0;
    748  memset(pars->scaling_points_cr, 0, sizeof(pars->scaling_points_cr));
    749  memset(pars->ar_coeffs_cr, 0, sizeof(pars->ar_coeffs_cr));
    750  pars->num_cb_points = 0;
    751  pars->cb_mult = 0;
    752  pars->cb_luma_mult = 0;
    753  pars->chroma_scaling_from_luma = 0;
    754  memset(pars->scaling_points_cb, 0, sizeof(pars->scaling_points_cb));
    755  memset(pars->ar_coeffs_cb, 0, sizeof(pars->ar_coeffs_cb));
    756 }
    757 
    758 void av1_update_film_grain_parameters_seq(struct AV1_PRIMARY *ppi,
    759                                          const AV1EncoderConfig *oxcf) {
    760  SequenceHeader *const seq_params = &ppi->seq_params;
    761  const TuneCfg *const tune_cfg = &oxcf->tune_cfg;
    762 
    763  if (tune_cfg->film_grain_test_vector || tune_cfg->film_grain_table_filename ||
    764      tune_cfg->content == AOM_CONTENT_FILM) {
    765    seq_params->film_grain_params_present = 1;
    766  } else {
    767 #if CONFIG_DENOISE
    768    seq_params->film_grain_params_present = (oxcf->noise_level > 0);
    769 #else
    770    seq_params->film_grain_params_present = 0;
    771 #endif
    772  }
    773 }
    774 
    775 void av1_update_film_grain_parameters(struct AV1_COMP *cpi,
    776                                      const AV1EncoderConfig *oxcf) {
    777  AV1_COMMON *const cm = &cpi->common;
    778  const TuneCfg *const tune_cfg = &oxcf->tune_cfg;
    779 
    780  if (cpi->film_grain_table) {
    781    aom_film_grain_table_free(cpi->film_grain_table);
    782    aom_free(cpi->film_grain_table);
    783    cpi->film_grain_table = NULL;
    784  }
    785 
    786  if (tune_cfg->film_grain_test_vector) {
    787    if (cm->current_frame.frame_type == KEY_FRAME) {
    788      cm->film_grain_params =
    789          film_grain_test_vectors[tune_cfg->film_grain_test_vector - 1];
    790      if (oxcf->tool_cfg.enable_monochrome)
    791        reset_film_grain_chroma_params(&cm->film_grain_params);
    792      cm->film_grain_params.bit_depth = cm->seq_params->bit_depth;
    793      if (cm->seq_params->color_range == AOM_CR_FULL_RANGE) {
    794        cm->film_grain_params.clip_to_restricted_range = 0;
    795      }
    796    }
    797  } else if (tune_cfg->film_grain_table_filename) {
    798    CHECK_MEM_ERROR(cm, cpi->film_grain_table,
    799                    aom_calloc(1, sizeof(*cpi->film_grain_table)));
    800 
    801    aom_film_grain_table_read(cpi->film_grain_table,
    802                              tune_cfg->film_grain_table_filename, cm->error);
    803  } else if (tune_cfg->content == AOM_CONTENT_FILM) {
    804    cm->film_grain_params.bit_depth = cm->seq_params->bit_depth;
    805    if (oxcf->tool_cfg.enable_monochrome)
    806      reset_film_grain_chroma_params(&cm->film_grain_params);
    807    if (cm->seq_params->color_range == AOM_CR_FULL_RANGE)
    808      cm->film_grain_params.clip_to_restricted_range = 0;
    809  } else {
    810    memset(&cm->film_grain_params, 0, sizeof(cm->film_grain_params));
    811  }
    812 }
    813 #endif  // !CONFIG_REALTIME_ONLY
    814 
    815 void av1_scale_references(AV1_COMP *cpi, const InterpFilter filter,
    816                          const int phase, const int use_optimized_scaler) {
    817  AV1_COMMON *cm = &cpi->common;
    818  const int num_planes = av1_num_planes(cm);
    819  MV_REFERENCE_FRAME ref_frame;
    820 
    821  for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
    822    // Need to convert from AOM_REFFRAME to index into ref_mask (subtract 1).
    823    if (cpi->ref_frame_flags & av1_ref_frame_flag_list[ref_frame]) {
    824      BufferPool *const pool = cm->buffer_pool;
    825      const YV12_BUFFER_CONFIG *const ref =
    826          get_ref_frame_yv12_buf(cm, ref_frame);
    827 
    828      if (ref == NULL) {
    829        cpi->scaled_ref_buf[ref_frame - 1] = NULL;
    830        continue;
    831      }
    832 
    833      // For RTC-SVC: if force_zero_mode_spatial_ref is enabled, check if the
    834      // motion search can be skipped for the references: last, golden,
    835      // altref. If so, we can skip scaling that reference.
    836      if (cpi->ppi->use_svc && cpi->svc.force_zero_mode_spatial_ref &&
    837          cpi->ppi->rtc_ref.set_ref_frame_config) {
    838        if (ref_frame == LAST_FRAME && cpi->svc.skip_mvsearch_last) continue;
    839        if (ref_frame == GOLDEN_FRAME && cpi->svc.skip_mvsearch_gf) continue;
    840        if (ref_frame == ALTREF_FRAME && cpi->svc.skip_mvsearch_altref)
    841          continue;
    842      }
    843      // For RTC with superres on: golden reference only needs to be scaled
    844      // if it was refreshed in previous frame.
    845      if (is_one_pass_rt_params(cpi) &&
    846          cpi->oxcf.superres_cfg.enable_superres && ref_frame == GOLDEN_FRAME &&
    847          cpi->rc.frame_num_last_gf_refresh <
    848              (int)cm->current_frame.frame_number - 1) {
    849        continue;
    850      }
    851 
    852      if (ref->y_crop_width != cm->width || ref->y_crop_height != cm->height) {
    853        // Replace the reference buffer with a copy having a thicker border,
    854        // if the reference buffer is higher resolution than the current
    855        // frame, and the border is thin.
    856        if ((ref->y_crop_width > cm->width ||
    857             ref->y_crop_height > cm->height) &&
    858            ref->border < AOM_BORDER_IN_PIXELS) {
    859          RefCntBuffer *ref_fb = get_ref_frame_buf(cm, ref_frame);
    860          if (aom_yv12_realloc_with_new_border(
    861                  &ref_fb->buf, AOM_BORDER_IN_PIXELS,
    862                  cm->features.byte_alignment, cpi->alloc_pyramid,
    863                  num_planes) != 0) {
    864            aom_internal_error(cm->error, AOM_CODEC_MEM_ERROR,
    865                               "Failed to allocate frame buffer");
    866          }
    867        }
    868        int force_scaling = 0;
    869        RefCntBuffer *new_fb = cpi->scaled_ref_buf[ref_frame - 1];
    870        if (new_fb == NULL) {
    871          const int new_fb_idx = get_free_fb(cm);
    872          if (new_fb_idx == INVALID_IDX) {
    873            aom_internal_error(cm->error, AOM_CODEC_MEM_ERROR,
    874                               "Unable to find free frame buffer");
    875          }
    876          force_scaling = 1;
    877          new_fb = &pool->frame_bufs[new_fb_idx];
    878        }
    879 
    880        if (force_scaling || new_fb->buf.y_crop_width != cm->width ||
    881            new_fb->buf.y_crop_height != cm->height) {
    882          if (aom_realloc_frame_buffer(
    883                  &new_fb->buf, cm->width, cm->height,
    884                  cm->seq_params->subsampling_x, cm->seq_params->subsampling_y,
    885                  cm->seq_params->use_highbitdepth, AOM_BORDER_IN_PIXELS,
    886                  cm->features.byte_alignment, NULL, NULL, NULL, false, 0)) {
    887            if (force_scaling) {
    888              // Release the reference acquired in the get_free_fb() call
    889              // above.
    890              --new_fb->ref_count;
    891            }
    892            aom_internal_error(cm->error, AOM_CODEC_MEM_ERROR,
    893                               "Failed to allocate frame buffer");
    894          }
    895          bool has_optimized_scaler = av1_has_optimized_scaler(
    896              ref->y_crop_width, ref->y_crop_height, new_fb->buf.y_crop_width,
    897              new_fb->buf.y_crop_height);
    898          if (num_planes > 1) {
    899            has_optimized_scaler =
    900                has_optimized_scaler &&
    901                av1_has_optimized_scaler(
    902                    ref->uv_crop_width, ref->uv_crop_height,
    903                    new_fb->buf.uv_crop_width, new_fb->buf.uv_crop_height);
    904          }
    905 #if CONFIG_AV1_HIGHBITDEPTH
    906          if (use_optimized_scaler && has_optimized_scaler &&
    907              cm->seq_params->bit_depth == AOM_BITS_8) {
    908            av1_resize_and_extend_frame(ref, &new_fb->buf, filter, phase,
    909                                        num_planes);
    910          } else if (!av1_resize_and_extend_frame_nonnormative(
    911                         ref, &new_fb->buf, (int)cm->seq_params->bit_depth,
    912                         num_planes)) {
    913            aom_internal_error(cm->error, AOM_CODEC_MEM_ERROR,
    914                               "Failed to allocate buffer during resize");
    915          }
    916 #else
    917          if (use_optimized_scaler && has_optimized_scaler) {
    918            av1_resize_and_extend_frame(ref, &new_fb->buf, filter, phase,
    919                                        num_planes);
    920          } else if (!av1_resize_and_extend_frame_nonnormative(
    921                         ref, &new_fb->buf, (int)cm->seq_params->bit_depth,
    922                         num_planes)) {
    923            aom_internal_error(cm->error, AOM_CODEC_MEM_ERROR,
    924                               "Failed to allocate buffer during resize");
    925          }
    926 #endif
    927          cpi->scaled_ref_buf[ref_frame - 1] = new_fb;
    928          alloc_frame_mvs(cm, new_fb);
    929        }
    930      } else {
    931        RefCntBuffer *buf = get_ref_frame_buf(cm, ref_frame);
    932        buf->buf.y_crop_width = ref->y_crop_width;
    933        buf->buf.y_crop_height = ref->y_crop_height;
    934        cpi->scaled_ref_buf[ref_frame - 1] = buf;
    935        ++buf->ref_count;
    936      }
    937    } else {
    938      if (!has_no_stats_stage(cpi)) cpi->scaled_ref_buf[ref_frame - 1] = NULL;
    939    }
    940  }
    941 }
    942 
    943 BLOCK_SIZE av1_select_sb_size(const AV1EncoderConfig *const oxcf, int width,
    944                              int height, int number_spatial_layers) {
    945  if (oxcf->tool_cfg.superblock_size == AOM_SUPERBLOCK_SIZE_64X64) {
    946    return BLOCK_64X64;
    947  }
    948  if (oxcf->tool_cfg.superblock_size == AOM_SUPERBLOCK_SIZE_128X128) {
    949    return BLOCK_128X128;
    950  }
    951 #if CONFIG_TFLITE
    952  if (oxcf->q_cfg.deltaq_mode == DELTA_Q_USER_RATING_BASED) return BLOCK_64X64;
    953 #endif
    954  // Force 64x64 superblock size to increase resolution in perceptual
    955  // AQ and user rating based modes.
    956  if (oxcf->mode == ALLINTRA &&
    957      (oxcf->q_cfg.deltaq_mode == DELTA_Q_PERCEPTUAL_AI ||
    958       oxcf->q_cfg.deltaq_mode == DELTA_Q_USER_RATING_BASED)) {
    959    return BLOCK_64X64;
    960  }
    961  // Variance Boost only supports 64x64 superblocks.
    962  if (oxcf->q_cfg.deltaq_mode == DELTA_Q_VARIANCE_BOOST) {
    963    return BLOCK_64X64;
    964  }
    965  assert(oxcf->tool_cfg.superblock_size == AOM_SUPERBLOCK_SIZE_DYNAMIC);
    966 
    967  if (number_spatial_layers > 1) {
    968    // For spatial layers better selection may be done given the resolutions
    969    // used across the layers, but for now use 64x64 for spatial layers.
    970    return BLOCK_64X64;
    971  } else if (oxcf->resize_cfg.resize_mode != RESIZE_NONE) {
    972    // Use the configured size (top resolution) for resize.
    973    return AOMMIN(oxcf->frm_dim_cfg.width, oxcf->frm_dim_cfg.height) > 720
    974               ? BLOCK_128X128
    975               : BLOCK_64X64;
    976  } else if (oxcf->mode == REALTIME) {
    977    if (oxcf->tune_cfg.content == AOM_CONTENT_SCREEN) {
    978      const TileConfig *const tile_cfg = &oxcf->tile_cfg;
    979      const int num_tiles =
    980          (1 << tile_cfg->tile_columns) * (1 << tile_cfg->tile_rows);
    981      // For multi-thread encode: if the number of (128x128) superblocks
    982      // per tile is low use 64X64 superblock.
    983      if (oxcf->row_mt == 1 && oxcf->max_threads >= 4 &&
    984          oxcf->max_threads >= num_tiles && AOMMIN(width, height) >= 720 &&
    985          (width * height) / (128 * 128 * num_tiles) < 40)
    986        return BLOCK_64X64;
    987      else
    988        return AOMMIN(width, height) >= 720 ? BLOCK_128X128 : BLOCK_64X64;
    989    } else {
    990      return AOMMIN(width, height) > 720 ? BLOCK_128X128 : BLOCK_64X64;
    991    }
    992  }
    993 
    994  // TODO(any): Possibly could improve this with a heuristic.
    995  // When superres / resize is on, 'cm->width / height' can change between
    996  // calls, so we don't apply this heuristic there.
    997  // Things break if superblock size changes between the first pass and second
    998  // pass encoding, which is why this heuristic is not configured as a
    999  // speed-feature.
   1000  if (oxcf->superres_cfg.superres_mode == AOM_SUPERRES_NONE &&
   1001      oxcf->resize_cfg.resize_mode == RESIZE_NONE) {
   1002    int is_480p_or_lesser = AOMMIN(width, height) <= 480;
   1003    if (oxcf->speed >= 1 && is_480p_or_lesser) return BLOCK_64X64;
   1004 
   1005    // For 1080p and lower resolutions, choose SB size adaptively based on
   1006    // resolution and speed level for multi-thread encode.
   1007    int is_1080p_or_lesser = AOMMIN(width, height) <= 1080;
   1008    if (!is_480p_or_lesser && is_1080p_or_lesser && oxcf->mode == GOOD &&
   1009        oxcf->row_mt == 1 && oxcf->max_threads > 1 && oxcf->speed >= 5)
   1010      return BLOCK_64X64;
   1011 
   1012    // For allintra encode, since the maximum partition size is set to 32X32
   1013    // for speed>=6, superblock size is set to 64X64 instead of 128X128. This
   1014    // improves the multithread performance due to reduction in top right
   1015    // delay and thread sync wastage. Currently, this setting is selectively
   1016    // enabled only for speed>=9 and resolutions less than 4k since cost
   1017    // update frequency is set to INTERNAL_COST_UPD_OFF in these cases.
   1018    const int is_4k_or_larger = AOMMIN(width, height) >= 2160;
   1019    if (oxcf->mode == ALLINTRA && oxcf->speed >= 9 && !is_4k_or_larger)
   1020      return BLOCK_64X64;
   1021  }
   1022  return BLOCK_128X128;
   1023 }
   1024 
   1025 void av1_setup_frame(AV1_COMP *cpi) {
   1026  AV1_COMMON *const cm = &cpi->common;
   1027  // Set up entropy context depending on frame type. The decoder mandates
   1028  // the use of the default context, index 0, for keyframes and inter
   1029  // frames where the error_resilient_mode or intra_only flag is set. For
   1030  // other inter-frames the encoder currently uses only two contexts;
   1031  // context 1 for ALTREF frames and context 0 for the others.
   1032 
   1033  if (frame_is_intra_only(cm) || cm->features.error_resilient_mode ||
   1034      cpi->ext_flags.use_primary_ref_none) {
   1035    av1_setup_past_independence(cm);
   1036  }
   1037 
   1038  if ((cm->current_frame.frame_type == KEY_FRAME && cm->show_frame) ||
   1039      frame_is_sframe(cm)) {
   1040    if (!cpi->ppi->seq_params_locked) {
   1041      set_sb_size(cm->seq_params,
   1042                  av1_select_sb_size(&cpi->oxcf, cm->width, cm->height,
   1043                                     cpi->ppi->number_spatial_layers));
   1044    }
   1045  } else {
   1046    const RefCntBuffer *const primary_ref_buf = get_primary_ref_frame_buf(cm);
   1047    if (primary_ref_buf == NULL) {
   1048      av1_setup_past_independence(cm);
   1049      cm->seg.update_map = 1;
   1050      cm->seg.update_data = 1;
   1051    } else {
   1052      *cm->fc = primary_ref_buf->frame_context;
   1053    }
   1054  }
   1055 
   1056  av1_zero(cm->cur_frame->interp_filter_selected);
   1057  cm->prev_frame = get_primary_ref_frame_buf(cm);
   1058  cpi->vaq_refresh = 0;
   1059 }
   1060 
   1061 #if !CONFIG_REALTIME_ONLY
   1062 static int get_interp_filter_selected(const AV1_COMMON *const cm,
   1063                                      MV_REFERENCE_FRAME ref,
   1064                                      InterpFilter ifilter) {
   1065  const RefCntBuffer *const buf = get_ref_frame_buf(cm, ref);
   1066  if (buf == NULL) return 0;
   1067  return buf->interp_filter_selected[ifilter];
   1068 }
   1069 
   1070 uint16_t av1_setup_interp_filter_search_mask(AV1_COMP *cpi) {
   1071  const AV1_COMMON *const cm = &cpi->common;
   1072  int ref_total[REF_FRAMES] = { 0 };
   1073  uint16_t mask = ALLOW_ALL_INTERP_FILT_MASK;
   1074 
   1075  if (cpi->last_frame_type == KEY_FRAME || cpi->refresh_frame.alt_ref_frame)
   1076    return mask;
   1077 
   1078  for (MV_REFERENCE_FRAME ref = LAST_FRAME; ref <= ALTREF_FRAME; ++ref) {
   1079    for (InterpFilter ifilter = EIGHTTAP_REGULAR; ifilter <= MULTITAP_SHARP;
   1080         ++ifilter) {
   1081      ref_total[ref] += get_interp_filter_selected(cm, ref, ifilter);
   1082    }
   1083  }
   1084  int ref_total_total = (ref_total[LAST2_FRAME] + ref_total[LAST3_FRAME] +
   1085                         ref_total[GOLDEN_FRAME] + ref_total[BWDREF_FRAME] +
   1086                         ref_total[ALTREF2_FRAME] + ref_total[ALTREF_FRAME]);
   1087 
   1088  for (InterpFilter ifilter = EIGHTTAP_REGULAR; ifilter <= MULTITAP_SHARP;
   1089       ++ifilter) {
   1090    int last_score = get_interp_filter_selected(cm, LAST_FRAME, ifilter) * 30;
   1091    if (ref_total[LAST_FRAME] && last_score <= ref_total[LAST_FRAME]) {
   1092      int filter_score =
   1093          get_interp_filter_selected(cm, LAST2_FRAME, ifilter) * 20 +
   1094          get_interp_filter_selected(cm, LAST3_FRAME, ifilter) * 20 +
   1095          get_interp_filter_selected(cm, GOLDEN_FRAME, ifilter) * 20 +
   1096          get_interp_filter_selected(cm, BWDREF_FRAME, ifilter) * 10 +
   1097          get_interp_filter_selected(cm, ALTREF2_FRAME, ifilter) * 10 +
   1098          get_interp_filter_selected(cm, ALTREF_FRAME, ifilter) * 10;
   1099      if (filter_score < ref_total_total) {
   1100        DUAL_FILTER_TYPE filt_type = ifilter + SWITCHABLE_FILTERS * ifilter;
   1101        reset_interp_filter_allowed_mask(&mask, filt_type);
   1102      }
   1103    }
   1104  }
   1105  return mask;
   1106 }
   1107 
   1108 #define STRICT_PSNR_DIFF_THRESH 0.9
   1109 // Encode key frame with/without screen content tools to determine whether
   1110 // screen content tools should be enabled for this key frame group or not.
   1111 // The first encoding is without screen content tools.
   1112 // The second encoding is with screen content tools.
   1113 // We compare the psnr and frame size to make the decision.
   1114 static void screen_content_tools_determination(
   1115    AV1_COMP *cpi, const int allow_screen_content_tools_orig_decision,
   1116    const int allow_intrabc_orig_decision,
   1117    const int use_screen_content_tools_orig_decision,
   1118    const int is_screen_content_type_orig_decision, const int pass,
   1119    int *projected_size_pass, PSNR_STATS *psnr) {
   1120  AV1_COMMON *const cm = &cpi->common;
   1121  FeatureFlags *const features = &cm->features;
   1122 
   1123 #if CONFIG_FPMT_TEST
   1124  projected_size_pass[pass] =
   1125      ((cpi->ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] > 0) &&
   1126       (cpi->ppi->fpmt_unit_test_cfg == PARALLEL_SIMULATION_ENCODE))
   1127          ? cpi->ppi->p_rc.temp_projected_frame_size
   1128          : cpi->rc.projected_frame_size;
   1129 #else
   1130  projected_size_pass[pass] = cpi->rc.projected_frame_size;
   1131 #endif
   1132 
   1133 #if CONFIG_AV1_HIGHBITDEPTH
   1134  const uint32_t in_bit_depth = cpi->oxcf.input_cfg.input_bit_depth;
   1135  const uint32_t bit_depth = cpi->td.mb.e_mbd.bd;
   1136  aom_calc_highbd_psnr(cpi->source, &cpi->common.cur_frame->buf, &psnr[pass],
   1137                       bit_depth, in_bit_depth);
   1138 #else
   1139  aom_calc_psnr(cpi->source, &cpi->common.cur_frame->buf, &psnr[pass]);
   1140 #endif
   1141  if (pass != 1) return;
   1142 
   1143  const double psnr_diff = psnr[1].psnr[0] - psnr[0].psnr[0];
   1144  // Calculate % of palette mode to be chosen in a frame from mode decision.
   1145  const double palette_ratio =
   1146      (double)cpi->palette_pixel_num / (double)(cm->height * cm->width);
   1147  const int psnr_diff_is_large = (psnr_diff > STRICT_PSNR_DIFF_THRESH);
   1148  const int ratio_is_large =
   1149      ((palette_ratio >= 0.0001) && ((psnr_diff / palette_ratio) > 4));
   1150  const int is_sc_encoding_much_better = (psnr_diff_is_large || ratio_is_large);
   1151  if (is_sc_encoding_much_better) {
   1152    // Use screen content tools, if we get coding gain.
   1153    features->allow_screen_content_tools = 1;
   1154    features->allow_intrabc = cpi->intrabc_used;
   1155    cpi->use_screen_content_tools = 1;
   1156    cpi->is_screen_content_type = 1;
   1157  } else {
   1158    // Use original screen content decision.
   1159    features->allow_screen_content_tools =
   1160        allow_screen_content_tools_orig_decision;
   1161    features->allow_intrabc = allow_intrabc_orig_decision;
   1162    cpi->use_screen_content_tools = use_screen_content_tools_orig_decision;
   1163    cpi->is_screen_content_type = is_screen_content_type_orig_decision;
   1164  }
   1165 }
   1166 
   1167 // Set some encoding parameters to make the encoding process fast.
   1168 // A fixed block partition size, and a large q is used.
   1169 static void set_encoding_params_for_screen_content(AV1_COMP *cpi,
   1170                                                   const int pass) {
   1171  AV1_COMMON *const cm = &cpi->common;
   1172  if (pass == 0) {
   1173    // In the first pass, encode without screen content tools.
   1174    // Use a high q, and a fixed block size for fast encoding.
   1175    cm->features.allow_screen_content_tools = 0;
   1176    cm->features.allow_intrabc = 0;
   1177    cpi->use_screen_content_tools = 0;
   1178    cpi->sf.part_sf.partition_search_type = FIXED_PARTITION;
   1179    cpi->sf.part_sf.fixed_partition_size = BLOCK_32X32;
   1180    return;
   1181  }
   1182  assert(pass == 1);
   1183  // In the second pass, encode with screen content tools.
   1184  // Use a high q, and a fixed block size for fast encoding.
   1185  cm->features.allow_screen_content_tools = 1;
   1186  // TODO(chengchen): turn intrabc on could lead to data race issue.
   1187  // cm->allow_intrabc = 1;
   1188  cpi->use_screen_content_tools = 1;
   1189  cpi->sf.part_sf.partition_search_type = FIXED_PARTITION;
   1190  cpi->sf.part_sf.fixed_partition_size = BLOCK_32X32;
   1191 }
   1192 
   1193 // Determines whether to use screen content tools for the key frame group.
   1194 // This function modifies "cm->features.allow_screen_content_tools",
   1195 // "cm->features.allow_intrabc" and "cpi->use_screen_content_tools".
   1196 void av1_determine_sc_tools_with_encoding(AV1_COMP *cpi, const int q_orig) {
   1197  AV1_COMMON *const cm = &cpi->common;
   1198  const AV1EncoderConfig *const oxcf = &cpi->oxcf;
   1199  const QuantizationCfg *const q_cfg = &oxcf->q_cfg;
   1200  // Variables to help determine if we should allow screen content tools.
   1201  int projected_size_pass[3] = { 0 };
   1202  PSNR_STATS psnr[3];
   1203  const int is_key_frame = cm->current_frame.frame_type == KEY_FRAME;
   1204  const int allow_screen_content_tools_orig_decision =
   1205      cm->features.allow_screen_content_tools;
   1206  const int allow_intrabc_orig_decision = cm->features.allow_intrabc;
   1207  const int use_screen_content_tools_orig_decision =
   1208      cpi->use_screen_content_tools;
   1209  const int is_screen_content_type_orig_decision = cpi->is_screen_content_type;
   1210  // Turn off the encoding trial for forward key frame and superres.
   1211  if (cpi->sf.rt_sf.use_nonrd_pick_mode || oxcf->kf_cfg.fwd_kf_enabled ||
   1212      cpi->superres_mode != AOM_SUPERRES_NONE || oxcf->mode == REALTIME ||
   1213      use_screen_content_tools_orig_decision || !is_key_frame) {
   1214    return;
   1215  }
   1216 
   1217  // Multiple encoding for the lossless mode is time
   1218  // consuming. Find a better way to determine whether screen content tools
   1219  // should be used for lossless coding. Use a high q and a fixed partition to
   1220  // do quick encoding.
   1221  const int q_for_screen_content_quick_run =
   1222      is_lossless_requested(&oxcf->rc_cfg) ? q_orig : AOMMAX(q_orig, 244);
   1223  const int partition_search_type_orig = cpi->sf.part_sf.partition_search_type;
   1224  const BLOCK_SIZE fixed_partition_block_size_orig =
   1225      cpi->sf.part_sf.fixed_partition_size;
   1226 
   1227  // Setup necessary params for encoding, including frame source, etc.
   1228 
   1229  cpi->source = av1_realloc_and_scale_if_required(
   1230      cm, cpi->unscaled_source, &cpi->scaled_source, cm->features.interp_filter,
   1231      0, false, false, cpi->oxcf.border_in_pixels, cpi->alloc_pyramid);
   1232  if (cpi->unscaled_last_source != NULL) {
   1233    cpi->last_source = av1_realloc_and_scale_if_required(
   1234        cm, cpi->unscaled_last_source, &cpi->scaled_last_source,
   1235        cm->features.interp_filter, 0, false, false, cpi->oxcf.border_in_pixels,
   1236        cpi->alloc_pyramid);
   1237  }
   1238 
   1239  av1_setup_frame(cpi);
   1240 
   1241  if (cm->seg.enabled) {
   1242    if (!cm->seg.update_data && cm->prev_frame) {
   1243      segfeatures_copy(&cm->seg, &cm->prev_frame->seg);
   1244      cm->seg.enabled = cm->prev_frame->seg.enabled;
   1245    } else {
   1246      av1_calculate_segdata(&cm->seg);
   1247    }
   1248  } else {
   1249    memset(&cm->seg, 0, sizeof(cm->seg));
   1250  }
   1251  segfeatures_copy(&cm->cur_frame->seg, &cm->seg);
   1252  cm->cur_frame->seg.enabled = cm->seg.enabled;
   1253 
   1254  // The two encoding passes aim to help determine whether to use screen
   1255  // content tools, with a high q and fixed partition.
   1256  for (int pass = 0; pass < 2; ++pass) {
   1257    set_encoding_params_for_screen_content(cpi, pass);
   1258    av1_set_quantizer(cm, q_cfg->qm_minlevel, q_cfg->qm_maxlevel,
   1259                      q_for_screen_content_quick_run,
   1260                      q_cfg->enable_chroma_deltaq, q_cfg->enable_hdr_deltaq,
   1261                      oxcf->mode == ALLINTRA, oxcf->tune_cfg.tuning);
   1262    av1_set_speed_features_qindex_dependent(cpi, oxcf->speed);
   1263 
   1264    av1_init_quantizer(&cpi->enc_quant_dequant_params, &cm->quant_params,
   1265                       cm->seq_params->bit_depth, oxcf->algo_cfg.sharpness);
   1266 
   1267    av1_set_variance_partition_thresholds(cpi, q_for_screen_content_quick_run,
   1268                                          0);
   1269    // transform / motion compensation build reconstruction frame
   1270    av1_encode_frame(cpi);
   1271    // Screen content decision
   1272    screen_content_tools_determination(
   1273        cpi, allow_screen_content_tools_orig_decision,
   1274        allow_intrabc_orig_decision, use_screen_content_tools_orig_decision,
   1275        is_screen_content_type_orig_decision, pass, projected_size_pass, psnr);
   1276  }
   1277 
   1278  // Set partition speed feature back.
   1279  cpi->sf.part_sf.partition_search_type = partition_search_type_orig;
   1280  cpi->sf.part_sf.fixed_partition_size = fixed_partition_block_size_orig;
   1281 
   1282  // Free token related info if screen content coding tools are not enabled.
   1283  if (!cm->features.allow_screen_content_tools)
   1284    free_token_info(&cpi->token_info);
   1285 }
   1286 #endif  // CONFIG_REALTIME_ONLY
   1287 
   1288 static void fix_interp_filter(InterpFilter *const interp_filter,
   1289                              const FRAME_COUNTS *const counts) {
   1290  if (*interp_filter == SWITCHABLE) {
   1291    // Check to see if only one of the filters is actually used
   1292    int count[SWITCHABLE_FILTERS] = { 0 };
   1293    int num_filters_used = 0;
   1294    for (int i = 0; i < SWITCHABLE_FILTERS; ++i) {
   1295      for (int j = 0; j < SWITCHABLE_FILTER_CONTEXTS; ++j)
   1296        count[i] += counts->switchable_interp[j][i];
   1297      num_filters_used += (count[i] > 0);
   1298    }
   1299    if (num_filters_used == 1) {
   1300      // Only one filter is used. So set the filter at frame level
   1301      for (int i = 0; i < SWITCHABLE_FILTERS; ++i) {
   1302        if (count[i]) {
   1303          *interp_filter = i;
   1304          break;
   1305        }
   1306      }
   1307    }
   1308  }
   1309 }
   1310 
   1311 void av1_finalize_encoded_frame(AV1_COMP *const cpi) {
   1312  AV1_COMMON *const cm = &cpi->common;
   1313  CurrentFrame *const current_frame = &cm->current_frame;
   1314 
   1315  if (!cm->seq_params->reduced_still_picture_hdr &&
   1316      encode_show_existing_frame(cm)) {
   1317    RefCntBuffer *const frame_to_show =
   1318        cm->ref_frame_map[cpi->existing_fb_idx_to_show];
   1319 
   1320    if (frame_to_show == NULL) {
   1321      aom_internal_error(cm->error, AOM_CODEC_UNSUP_BITSTREAM,
   1322                         "Buffer does not contain a reconstructed frame");
   1323    }
   1324    assert(frame_to_show->ref_count > 0);
   1325    assign_frame_buffer_p(&cm->cur_frame, frame_to_show);
   1326  }
   1327 
   1328  if (!encode_show_existing_frame(cm) &&
   1329      cm->seq_params->film_grain_params_present &&
   1330      (cm->show_frame || cm->showable_frame)) {
   1331    // Copy the current frame's film grain params to the its corresponding
   1332    // RefCntBuffer slot.
   1333    cm->cur_frame->film_grain_params = cm->film_grain_params;
   1334 
   1335    // We must update the parameters if this is not an INTER_FRAME
   1336    if (current_frame->frame_type != INTER_FRAME)
   1337      cm->cur_frame->film_grain_params.update_parameters = 1;
   1338 
   1339    // Iterate the random seed for the next frame.
   1340    cm->film_grain_params.random_seed += 3381;
   1341    if (cm->film_grain_params.random_seed == 0)
   1342      cm->film_grain_params.random_seed = 7391;
   1343  }
   1344 
   1345  // Initialise all tiles' contexts from the global frame context
   1346  for (int tile_col = 0; tile_col < cm->tiles.cols; tile_col++) {
   1347    for (int tile_row = 0; tile_row < cm->tiles.rows; tile_row++) {
   1348      const int tile_idx = tile_row * cm->tiles.cols + tile_col;
   1349      cpi->tile_data[tile_idx].tctx = *cm->fc;
   1350    }
   1351  }
   1352 
   1353  if (!frame_is_intra_only(cm))
   1354    fix_interp_filter(&cm->features.interp_filter, cpi->td.counts);
   1355 }
   1356 
   1357 int av1_is_integer_mv(const YV12_BUFFER_CONFIG *cur_picture,
   1358                      const YV12_BUFFER_CONFIG *last_picture,
   1359                      ForceIntegerMVInfo *const force_intpel_info) {
   1360  // check use hash ME
   1361  int k;
   1362 
   1363  const int block_size = FORCE_INT_MV_DECISION_BLOCK_SIZE;
   1364  const double threshold_current = 0.8;
   1365  const double threshold_average = 0.95;
   1366  const int max_history_size = 32;
   1367  int T = 0;  // total block
   1368  int C = 0;  // match with collocated block
   1369  int S = 0;  // smooth region but not match with collocated block
   1370 
   1371  const int pic_width = cur_picture->y_width;
   1372  const int pic_height = cur_picture->y_height;
   1373  for (int i = 0; i + block_size <= pic_height; i += block_size) {
   1374    for (int j = 0; j + block_size <= pic_width; j += block_size) {
   1375      const int x_pos = j;
   1376      const int y_pos = i;
   1377      int match = 1;
   1378      T++;
   1379 
   1380      // check whether collocated block match with current
   1381      uint8_t *p_cur = cur_picture->y_buffer;
   1382      uint8_t *p_ref = last_picture->y_buffer;
   1383      int stride_cur = cur_picture->y_stride;
   1384      int stride_ref = last_picture->y_stride;
   1385      p_cur += (y_pos * stride_cur + x_pos);
   1386      p_ref += (y_pos * stride_ref + x_pos);
   1387 
   1388      if (cur_picture->flags & YV12_FLAG_HIGHBITDEPTH) {
   1389        uint16_t *p16_cur = CONVERT_TO_SHORTPTR(p_cur);
   1390        uint16_t *p16_ref = CONVERT_TO_SHORTPTR(p_ref);
   1391        for (int tmpY = 0; tmpY < block_size && match; tmpY++) {
   1392          for (int tmpX = 0; tmpX < block_size && match; tmpX++) {
   1393            if (p16_cur[tmpX] != p16_ref[tmpX]) {
   1394              match = 0;
   1395            }
   1396          }
   1397          p16_cur += stride_cur;
   1398          p16_ref += stride_ref;
   1399        }
   1400      } else {
   1401        for (int tmpY = 0; tmpY < block_size && match; tmpY++) {
   1402          for (int tmpX = 0; tmpX < block_size && match; tmpX++) {
   1403            if (p_cur[tmpX] != p_ref[tmpX]) {
   1404              match = 0;
   1405            }
   1406          }
   1407          p_cur += stride_cur;
   1408          p_ref += stride_ref;
   1409        }
   1410      }
   1411 
   1412      if (match) {
   1413        C++;
   1414        continue;
   1415      }
   1416 
   1417      if (av1_hash_is_horizontal_perfect(cur_picture, block_size, x_pos,
   1418                                         y_pos) ||
   1419          av1_hash_is_vertical_perfect(cur_picture, block_size, x_pos, y_pos)) {
   1420        S++;
   1421        continue;
   1422      }
   1423    }
   1424  }
   1425 
   1426  assert(T > 0);
   1427  double cs_rate = ((double)(C + S)) / ((double)(T));
   1428 
   1429  force_intpel_info->cs_rate_array[force_intpel_info->rate_index] = cs_rate;
   1430 
   1431  force_intpel_info->rate_index =
   1432      (force_intpel_info->rate_index + 1) % max_history_size;
   1433  force_intpel_info->rate_size++;
   1434  force_intpel_info->rate_size =
   1435      AOMMIN(force_intpel_info->rate_size, max_history_size);
   1436 
   1437  if (cs_rate < threshold_current) {
   1438    return 0;
   1439  }
   1440 
   1441  if (C == T) {
   1442    return 1;
   1443  }
   1444 
   1445  double cs_average = 0.0;
   1446 
   1447  for (k = 0; k < force_intpel_info->rate_size; k++) {
   1448    cs_average += force_intpel_info->cs_rate_array[k];
   1449  }
   1450  cs_average /= force_intpel_info->rate_size;
   1451 
   1452  if (cs_average < threshold_average) {
   1453    return 0;
   1454  }
   1455 
   1456  if ((T - C - S) < 0) {
   1457    return 1;
   1458  }
   1459 
   1460  if (cs_average > 1.01) {
   1461    return 1;
   1462  }
   1463 
   1464  return 0;
   1465 }
   1466 
   1467 void av1_set_mb_ssim_rdmult_scaling(AV1_COMP *cpi) {
   1468  const CommonModeInfoParams *const mi_params = &cpi->common.mi_params;
   1469  const MACROBLOCKD *const xd = &cpi->td.mb.e_mbd;
   1470  uint8_t *y_buffer = cpi->source->y_buffer;
   1471  const int y_stride = cpi->source->y_stride;
   1472  const int block_size = BLOCK_16X16;
   1473 
   1474  const int num_mi_w = mi_size_wide[block_size];
   1475  const int num_mi_h = mi_size_high[block_size];
   1476  const int num_cols = (mi_params->mi_cols + num_mi_w - 1) / num_mi_w;
   1477  const int num_rows = (mi_params->mi_rows + num_mi_h - 1) / num_mi_h;
   1478  double log_sum = 0.0;
   1479 
   1480  // Loop through each 16x16 block.
   1481  for (int row = 0; row < num_rows; ++row) {
   1482    for (int col = 0; col < num_cols; ++col) {
   1483      double var = 0.0, num_of_var = 0.0;
   1484      const int index = row * num_cols + col;
   1485 
   1486      // Loop through each 8x8 block.
   1487      for (int mi_row = row * num_mi_h;
   1488           mi_row < mi_params->mi_rows && mi_row < (row + 1) * num_mi_h;
   1489           mi_row += 2) {
   1490        for (int mi_col = col * num_mi_w;
   1491             mi_col < mi_params->mi_cols && mi_col < (col + 1) * num_mi_w;
   1492             mi_col += 2) {
   1493          struct buf_2d buf;
   1494          const int row_offset_y = mi_row << 2;
   1495          const int col_offset_y = mi_col << 2;
   1496 
   1497          buf.buf = y_buffer + row_offset_y * y_stride + col_offset_y;
   1498          buf.stride = y_stride;
   1499 
   1500          var += av1_get_perpixel_variance_facade(cpi, xd, &buf, BLOCK_8X8,
   1501                                                  AOM_PLANE_Y);
   1502          num_of_var += 1.0;
   1503        }
   1504      }
   1505      var = var / num_of_var;
   1506 
   1507      // Curve fitting with an exponential model on all 16x16 blocks from the
   1508      // midres dataset.
   1509      var = 67.035434 * (1 - exp(-0.0021489 * var)) + 17.492222;
   1510 
   1511      // As per the above computation, var will be in the range of
   1512      // [17.492222, 84.527656], assuming the data type is of infinite
   1513      // precision. The following assert conservatively checks if var is in
   1514      // the range of [17.0, 85.0] to avoid any issues due to the precision of
   1515      // the relevant data type.
   1516      assert(var > 17.0 && var < 85.0);
   1517      cpi->ssim_rdmult_scaling_factors[index] = var;
   1518      log_sum += log(var);
   1519    }
   1520  }
   1521 
   1522  // As log_sum holds the geometric mean, it will be in the range
   1523  // [17.492222, 84.527656]. Hence, in the below loop, the value of
   1524  // cpi->ssim_rdmult_scaling_factors[index] would be in the range
   1525  // [0.2069, 4.8323].
   1526  log_sum = exp(log_sum / (double)(num_rows * num_cols));
   1527 
   1528  for (int row = 0; row < num_rows; ++row) {
   1529    for (int col = 0; col < num_cols; ++col) {
   1530      const int index = row * num_cols + col;
   1531      cpi->ssim_rdmult_scaling_factors[index] /= log_sum;
   1532    }
   1533  }
   1534 }
   1535 
   1536 // Coding context that only needs to be saved when recode loop includes
   1537 // filtering (deblocking, CDEF, superres post-encode upscale and/or loop
   1538 // restoraton).
   1539 static void save_extra_coding_context(AV1_COMP *cpi) {
   1540  CODING_CONTEXT *const cc = &cpi->coding_context;
   1541  AV1_COMMON *cm = &cpi->common;
   1542 
   1543  cc->lf = cm->lf;
   1544  cc->cdef_info = cm->cdef_info;
   1545  cc->rc = cpi->rc;
   1546  cc->mv_stats = cpi->ppi->mv_stats;
   1547 }
   1548 
   1549 void av1_save_all_coding_context(AV1_COMP *cpi) {
   1550  save_extra_coding_context(cpi);
   1551  if (!frame_is_intra_only(&cpi->common)) release_scaled_references(cpi);
   1552 }
   1553 
   1554 #if DUMP_RECON_FRAMES == 1
   1555 
   1556 // NOTE(zoeliu): For debug - Output the filtered reconstructed video.
   1557 void av1_dump_filtered_recon_frames(AV1_COMP *cpi) {
   1558  AV1_COMMON *const cm = &cpi->common;
   1559  const CurrentFrame *const current_frame = &cm->current_frame;
   1560  const YV12_BUFFER_CONFIG *recon_buf = &cm->cur_frame->buf;
   1561 
   1562  if (recon_buf == NULL) {
   1563    printf("Frame %d is not ready.\n", current_frame->frame_number);
   1564    return;
   1565  }
   1566 
   1567  static const int flag_list[REF_FRAMES] = { 0,
   1568                                             AOM_LAST_FLAG,
   1569                                             AOM_LAST2_FLAG,
   1570                                             AOM_LAST3_FLAG,
   1571                                             AOM_GOLD_FLAG,
   1572                                             AOM_BWD_FLAG,
   1573                                             AOM_ALT2_FLAG,
   1574                                             AOM_ALT_FLAG };
   1575  printf(
   1576      "\n***Frame=%d (frame_offset=%d, show_frame=%d, "
   1577      "show_existing_frame=%d) "
   1578      "[LAST LAST2 LAST3 GOLDEN BWD ALT2 ALT]=[",
   1579      current_frame->frame_number, current_frame->order_hint, cm->show_frame,
   1580      cm->show_existing_frame);
   1581  for (int ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
   1582    const RefCntBuffer *const buf = get_ref_frame_buf(cm, ref_frame);
   1583    const int ref_offset = buf != NULL ? (int)buf->order_hint : -1;
   1584    printf(" %d(%c)", ref_offset,
   1585           (cpi->ref_frame_flags & flag_list[ref_frame]) ? 'Y' : 'N');
   1586  }
   1587  printf(" ]\n");
   1588 
   1589  if (!cm->show_frame) {
   1590    printf("Frame %d is a no show frame, so no image dump.\n",
   1591           current_frame->frame_number);
   1592    return;
   1593  }
   1594 
   1595  int h;
   1596  char file_name[256] = "/tmp/enc_filtered_recon.yuv";
   1597  FILE *f_recon = NULL;
   1598 
   1599  if (current_frame->frame_number == 0) {
   1600    if ((f_recon = fopen(file_name, "wb")) == NULL) {
   1601      printf("Unable to open file %s to write.\n", file_name);
   1602      return;
   1603    }
   1604  } else {
   1605    if ((f_recon = fopen(file_name, "ab")) == NULL) {
   1606      printf("Unable to open file %s to append.\n", file_name);
   1607      return;
   1608    }
   1609  }
   1610  printf(
   1611      "\nFrame=%5d, encode_update_type[%5d]=%1d, frame_offset=%d, "
   1612      "show_frame=%d, show_existing_frame=%d, source_alt_ref_active=%d, "
   1613      "refresh_alt_ref_frame=%d, "
   1614      "y_stride=%4d, uv_stride=%4d, cm->width=%4d, cm->height=%4d\n\n",
   1615      current_frame->frame_number, cpi->gf_frame_index,
   1616      cpi->ppi->gf_group.update_type[cpi->gf_frame_index],
   1617      current_frame->order_hint, cm->show_frame, cm->show_existing_frame,
   1618      cpi->rc.source_alt_ref_active, cpi->refresh_frame.alt_ref_frame,
   1619      recon_buf->y_stride, recon_buf->uv_stride, cm->width, cm->height);
   1620 #if 0
   1621  int ref_frame;
   1622  printf("get_ref_frame_map_idx: [");
   1623  for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame)
   1624    printf(" %d", get_ref_frame_map_idx(cm, ref_frame));
   1625  printf(" ]\n");
   1626 #endif  // 0
   1627 
   1628  // --- Y ---
   1629  for (h = 0; h < cm->height; ++h) {
   1630    fwrite(&recon_buf->y_buffer[h * recon_buf->y_stride], 1, cm->width,
   1631           f_recon);
   1632  }
   1633  // --- U ---
   1634  for (h = 0; h < (cm->height >> 1); ++h) {
   1635    fwrite(&recon_buf->u_buffer[h * recon_buf->uv_stride], 1, (cm->width >> 1),
   1636           f_recon);
   1637  }
   1638  // --- V ---
   1639  for (h = 0; h < (cm->height >> 1); ++h) {
   1640    fwrite(&recon_buf->v_buffer[h * recon_buf->uv_stride], 1, (cm->width >> 1),
   1641           f_recon);
   1642  }
   1643 
   1644  fclose(f_recon);
   1645 }
   1646 #endif  // DUMP_RECON_FRAMES