LCOV - code coverage report
Current view: top level - Codec - EbModeDecisionConfigurationProcess.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1118 1501 74.5 %
Date: 2019-11-25 17:38:06 Functions: 41 49 83.7 %

          Line data    Source code
       1             : /*
       2             : * Copyright(c) 2019 Intel Corporation
       3             : * SPDX - License - Identifier: BSD - 2 - Clause - Patent
       4             : */
       5             : 
       6             : /*
       7             : * Copyright (c) 2016, Alliance for Open Media. All rights reserved
       8             : *
       9             : * This source code is subject to the terms of the BSD 2 Clause License and
      10             : * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
      11             : * was not distributed with this source code in the LICENSE file, you can
      12             : * obtain it at www.aomedia.org/license/software. If the Alliance for Open
      13             : * Media Patent License 1.0 was not distributed with this source code in the
      14             : * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
      15             : */
      16             : 
      17             : #include <stdlib.h>
      18             : 
      19             : #include "EbDefinitions.h"
      20             : #include "EbUtility.h"
      21             : #include "EbSequenceControlSet.h"
      22             : #include "EbPictureControlSet.h"
      23             : #include "EbModeDecisionConfigurationProcess.h"
      24             : #include "EbRateControlResults.h"
      25             : #include "EbEncDecTasks.h"
      26             : #include "EbModeDecisionConfiguration.h"
      27             : #include "EbReferenceObject.h"
      28             : #include "EbModeDecisionProcess.h"
      29             : #include "av1me.h"
      30             : #include "EbCommonUtils.h"
      31             : 
      32             : #define MAX_MESH_SPEED 5  // Max speed setting for mesh motion method
      33             : static MeshPattern
      34             : good_quality_mesh_patterns[MAX_MESH_SPEED + 1][MAX_MESH_STEP] = {
      35             :     { { 64, 8 }, { 28, 4 }, { 15, 1 }, { 7, 1 } },
      36             :     { { 64, 8 }, { 28, 4 }, { 15, 1 }, { 7, 1 } },
      37             :     { { 64, 8 }, { 14, 2 }, { 7, 1 }, { 7, 1 } },
      38             :     { { 64, 16 }, { 24, 8 }, { 12, 4 }, { 7, 1 } },
      39             :     { { 64, 16 }, { 24, 8 }, { 12, 4 }, { 7, 1 } },
      40             :     { { 64, 16 }, { 24, 8 }, { 12, 4 }, { 7, 1 } },
      41             : };
      42             : static unsigned char good_quality_max_mesh_pct[MAX_MESH_SPEED + 1] = {
      43             :     50, 50, 25, 15, 5, 1
      44             : };
      45             : // TODO: These settings are pretty relaxed, tune them for
      46             : // each speed setting
      47             : static MeshPattern intrabc_mesh_patterns[MAX_MESH_SPEED + 1][MAX_MESH_STEP] = {
      48             :   { { 256, 1 }, { 256, 1 }, { 0, 0 }, { 0, 0 } },
      49             :   { { 256, 1 }, { 256, 1 }, { 0, 0 }, { 0, 0 } },
      50             :   { { 64, 1 }, { 64, 1 }, { 0, 0 }, { 0, 0 } },
      51             :   { { 64, 1 }, { 64, 1 }, { 0, 0 }, { 0, 0 } },
      52             :   { { 64, 4 }, { 16, 1 }, { 0, 0 }, { 0, 0 } },
      53             :   { { 64, 4 }, { 16, 1 }, { 0, 0 }, { 0, 0 } },
      54             : };
      55             : static uint8_t intrabc_max_mesh_pct[MAX_MESH_SPEED + 1] = { 100, 100, 100,
      56             :                                                             25,  25,  10 };
      57             : 
      58             : // Adaptive Depth Partitioning
      59             : // Shooting states
      60             : #define UNDER_SHOOTING                        0
      61             : #define OVER_SHOOTING                         1
      62             : #define TBD_SHOOTING                          2
      63             : 
      64             : #define SB_PRED_OPEN_LOOP_COST      100 // Let's assume PRED_OPEN_LOOP_COST costs ~100 U
      65             : #define U_101                       101
      66             : #define U_102                       102
      67             : #define U_103                       103
      68             : #define U_104                       104
      69             : #define U_105                       105
      70             : #define U_107                       107
      71             : #define SB_FAST_OPEN_LOOP_COST      108
      72             : #define U_109                       109
      73             : #define SB_OPEN_LOOP_COST           110 // F_MDC is ~10% slower than PRED_OPEN_LOOP_COST
      74             : #define U_111                       111
      75             : #define U_112                       112
      76             : #define U_113                       113
      77             : #define U_114                       114
      78             : #define U_115                       115
      79             : #define U_116                       116
      80             : #define U_117                       117
      81             : #define U_118                       118
      82             : #define U_119                       119
      83             : #define U_120                       120
      84             : #define U_121                       121
      85             : #define U_122                       122
      86             : #define U_125                       125
      87             : #define U_127                       127
      88             : #define U_130                       130
      89             : #define U_132                       132
      90             : #define U_133                       133
      91             : #define U_134                       134
      92             : #define U_140                       140
      93             : #define U_145                       145
      94             : #define U_150                       150
      95             : #define U_152                       152
      96             : #define SQ_NON4_BLOCKS_SEARCH_COST  155
      97             : #define SQ_BLOCKS_SEARCH_COST       190
      98             : #define HIGH_SB_SCORE             60000
      99             : #define MEDIUM_SB_SCORE           16000
     100             : #define LOW_SB_SCORE               6000
     101             : #define MAX_LUMINOSITY_BOOST         10
     102             : int32_t budget_per_sb_boost[MAX_SUPPORTED_MODES] = { 55,55,55,55,55,55,5,5,0,0,0,0,0 };
     103             : 
     104             : // Coefficient scaling and quantization with AV1 TX are tailored to
     105             : // the AV1 TX transforms.  Regardless of the bit-depth of the input,
     106             : // the transform stages scale the coefficient values up by a factor of
     107             : // 8 (3 bits) over the scale of the pixel values.  Thus, for 8-bit
     108             : // input, the coefficients have effectively 11 bits of scale depth
     109             : // (8+3), 10-bit input pixels result in 13-bit coefficient depth
     110             : // (10+3) and 12-bit pixels yield 15-bit (12+3) coefficient depth.
     111             : // All quantizers are built using this invariant of x8, 3-bit scaling,
     112             : // thus the Q3 suffix.
     113             : 
     114             : // A partial exception to this rule is large transforms; to avoid
     115             : // overflow, TX blocks with > 256 pels (>16x16) are scaled only
     116             : // 4-times unity (2 bits) over the pixel depth, and TX blocks with
     117             : // over 1024 pixels (>32x32) are scaled up only 2x unity (1 bit).
     118             : // This descaling is found via av1_tx_get_scale().  Thus, 16x32, 32x16
     119             : // and 32x32 transforms actually return Q2 coefficients, and 32x64,
     120             : // 64x32 and 64x64 transforms return Q1 coefficients.  However, the
     121             : // quantizers are de-scaled down on-the-fly by the same amount
     122             : // (av1_tx_get_scale()) during quantization, and as such the
     123             : // dequantized/decoded coefficients, even for large TX blocks, are always
     124             : // effectively Q3. Meanwhile, quantized/coded coefficients are Q0
     125             : // because Qn quantizers are applied to Qn tx coefficients.
     126             : 
     127             : // Note that encoder decision making (which uses the quantizer to
     128             : // generate several bespoke lamdas for RDO and other heuristics)
     129             : // expects quantizers to be larger for higher-bitdepth input.  In
     130             : // addition, the minimum allowable quantizer is 4; smaller values will
     131             : // underflow to 0 in the actual quantization routines.
     132             : 
     133             : static const int16_t dc_qlookup_Q3[QINDEX_RANGE] = {
     134             :     4, 8, 8, 9, 10, 11, 12, 12, 13, 14, 15, 16, 17, 18,
     135             :     19, 19, 20, 21, 22, 23, 24, 25, 26, 26, 27, 28, 29, 30,
     136             :     31, 32, 32, 33, 34, 35, 36, 37, 38, 38, 39, 40, 41, 42,
     137             :     43, 43, 44, 45, 46, 47, 48, 48, 49, 50, 51, 52, 53, 53,
     138             :     54, 55, 56, 57, 57, 58, 59, 60, 61, 62, 62, 63, 64, 65,
     139             :     66, 66, 67, 68, 69, 70, 70, 71, 72, 73, 74, 74, 75, 76,
     140             :     77, 78, 78, 79, 80, 81, 81, 82, 83, 84, 85, 85, 87, 88,
     141             :     90, 92, 93, 95, 96, 98, 99, 101, 102, 104, 105, 107, 108, 110,
     142             :     111, 113, 114, 116, 117, 118, 120, 121, 123, 125, 127, 129, 131, 134,
     143             :     136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 161, 164,
     144             :     166, 169, 172, 174, 177, 180, 182, 185, 187, 190, 192, 195, 199, 202,
     145             :     205, 208, 211, 214, 217, 220, 223, 226, 230, 233, 237, 240, 243, 247,
     146             :     250, 253, 257, 261, 265, 269, 272, 276, 280, 284, 288, 292, 296, 300,
     147             :     304, 309, 313, 317, 322, 326, 330, 335, 340, 344, 349, 354, 359, 364,
     148             :     369, 374, 379, 384, 389, 395, 400, 406, 411, 417, 423, 429, 435, 441,
     149             :     447, 454, 461, 467, 475, 482, 489, 497, 505, 513, 522, 530, 539, 549,
     150             :     559, 569, 579, 590, 602, 614, 626, 640, 654, 668, 684, 700, 717, 736,
     151             :     755, 775, 796, 819, 843, 869, 896, 925, 955, 988, 1022, 1058, 1098, 1139,
     152             :     1184, 1232, 1282, 1336,
     153             : };
     154             : 
     155             : static const int16_t dc_qlookup_10_Q3[QINDEX_RANGE] = {
     156             :     4, 9, 10, 13, 15, 17, 20, 22, 25, 28, 31, 34, 37,
     157             :     40, 43, 47, 50, 53, 57, 60, 64, 68, 71, 75, 78, 82,
     158             :     86, 90, 93, 97, 101, 105, 109, 113, 116, 120, 124, 128, 132,
     159             :     136, 140, 143, 147, 151, 155, 159, 163, 166, 170, 174, 178, 182,
     160             :     185, 189, 193, 197, 200, 204, 208, 212, 215, 219, 223, 226, 230,
     161             :     233, 237, 241, 244, 248, 251, 255, 259, 262, 266, 269, 273, 276,
     162             :     280, 283, 287, 290, 293, 297, 300, 304, 307, 310, 314, 317, 321,
     163             :     324, 327, 331, 334, 337, 343, 350, 356, 362, 369, 375, 381, 387,
     164             :     394, 400, 406, 412, 418, 424, 430, 436, 442, 448, 454, 460, 466,
     165             :     472, 478, 484, 490, 499, 507, 516, 525, 533, 542, 550, 559, 567,
     166             :     576, 584, 592, 601, 609, 617, 625, 634, 644, 655, 666, 676, 687,
     167             :     698, 708, 718, 729, 739, 749, 759, 770, 782, 795, 807, 819, 831,
     168             :     844, 856, 868, 880, 891, 906, 920, 933, 947, 961, 975, 988, 1001,
     169             :     1015, 1030, 1045, 1061, 1076, 1090, 1105, 1120, 1137, 1153, 1170, 1186, 1202,
     170             :     1218, 1236, 1253, 1271, 1288, 1306, 1323, 1342, 1361, 1379, 1398, 1416, 1436,
     171             :     1456, 1476, 1496, 1516, 1537, 1559, 1580, 1601, 1624, 1647, 1670, 1692, 1717,
     172             :     1741, 1766, 1791, 1817, 1844, 1871, 1900, 1929, 1958, 1990, 2021, 2054, 2088,
     173             :     2123, 2159, 2197, 2236, 2276, 2319, 2363, 2410, 2458, 2508, 2561, 2616, 2675,
     174             :     2737, 2802, 2871, 2944, 3020, 3102, 3188, 3280, 3375, 3478, 3586, 3702, 3823,
     175             :     3953, 4089, 4236, 4394, 4559, 4737, 4929, 5130, 5347,
     176             : };
     177             : 
     178             : static const int16_t dc_qlookup_12_Q3[QINDEX_RANGE] = {
     179             :     4, 12, 18, 25, 33, 41, 50, 60, 70, 80, 91,
     180             :     103, 115, 127, 140, 153, 166, 180, 194, 208, 222, 237,
     181             :     251, 266, 281, 296, 312, 327, 343, 358, 374, 390, 405,
     182             :     421, 437, 453, 469, 484, 500, 516, 532, 548, 564, 580,
     183             :     596, 611, 627, 643, 659, 674, 690, 706, 721, 737, 752,
     184             :     768, 783, 798, 814, 829, 844, 859, 874, 889, 904, 919,
     185             :     934, 949, 964, 978, 993, 1008, 1022, 1037, 1051, 1065, 1080,
     186             :     1094, 1108, 1122, 1136, 1151, 1165, 1179, 1192, 1206, 1220, 1234,
     187             :     1248, 1261, 1275, 1288, 1302, 1315, 1329, 1342, 1368, 1393, 1419,
     188             :     1444, 1469, 1494, 1519, 1544, 1569, 1594, 1618, 1643, 1668, 1692,
     189             :     1717, 1741, 1765, 1789, 1814, 1838, 1862, 1885, 1909, 1933, 1957,
     190             :     1992, 2027, 2061, 2096, 2130, 2165, 2199, 2233, 2267, 2300, 2334,
     191             :     2367, 2400, 2434, 2467, 2499, 2532, 2575, 2618, 2661, 2704, 2746,
     192             :     2788, 2830, 2872, 2913, 2954, 2995, 3036, 3076, 3127, 3177, 3226,
     193             :     3275, 3324, 3373, 3421, 3469, 3517, 3565, 3621, 3677, 3733, 3788,
     194             :     3843, 3897, 3951, 4005, 4058, 4119, 4181, 4241, 4301, 4361, 4420,
     195             :     4479, 4546, 4612, 4677, 4742, 4807, 4871, 4942, 5013, 5083, 5153,
     196             :     5222, 5291, 5367, 5442, 5517, 5591, 5665, 5745, 5825, 5905, 5984,
     197             :     6063, 6149, 6234, 6319, 6404, 6495, 6587, 6678, 6769, 6867, 6966,
     198             :     7064, 7163, 7269, 7376, 7483, 7599, 7715, 7832, 7958, 8085, 8214,
     199             :     8352, 8492, 8635, 8788, 8945, 9104, 9275, 9450, 9639, 9832, 10031,
     200             :     10245, 10465, 10702, 10946, 11210, 11482, 11776, 12081, 12409, 12750, 13118,
     201             :     13501, 13913, 14343, 14807, 15290, 15812, 16356, 16943, 17575, 18237, 18949,
     202             :     19718, 20521, 21387,
     203             : };
     204             : static const int16_t ac_qlookup_Q3[QINDEX_RANGE] = {
     205             :     4, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
     206             :     20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
     207             :     33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
     208             :     46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
     209             :     59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
     210             :     72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
     211             :     85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
     212             :     98, 99, 100, 101, 102, 104, 106, 108, 110, 112, 114, 116, 118,
     213             :     120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144,
     214             :     146, 148, 150, 152, 155, 158, 161, 164, 167, 170, 173, 176, 179,
     215             :     182, 185, 188, 191, 194, 197, 200, 203, 207, 211, 215, 219, 223,
     216             :     227, 231, 235, 239, 243, 247, 251, 255, 260, 265, 270, 275, 280,
     217             :     285, 290, 295, 300, 305, 311, 317, 323, 329, 335, 341, 347, 353,
     218             :     359, 366, 373, 380, 387, 394, 401, 408, 416, 424, 432, 440, 448,
     219             :     456, 465, 474, 483, 492, 501, 510, 520, 530, 540, 550, 560, 571,
     220             :     582, 593, 604, 615, 627, 639, 651, 663, 676, 689, 702, 715, 729,
     221             :     743, 757, 771, 786, 801, 816, 832, 848, 864, 881, 898, 915, 933,
     222             :     951, 969, 988, 1007, 1026, 1046, 1066, 1087, 1108, 1129, 1151, 1173, 1196,
     223             :     1219, 1243, 1267, 1292, 1317, 1343, 1369, 1396, 1423, 1451, 1479, 1508, 1537,
     224             :     1567, 1597, 1628, 1660, 1692, 1725, 1759, 1793, 1828,
     225             : };
     226             : 
     227             : static const int16_t ac_qlookup_10_Q3[QINDEX_RANGE] = {
     228             :     4, 9, 11, 13, 16, 18, 21, 24, 27, 30, 33, 37, 40,
     229             :     44, 48, 51, 55, 59, 63, 67, 71, 75, 79, 83, 88, 92,
     230             :     96, 100, 105, 109, 114, 118, 122, 127, 131, 136, 140, 145, 149,
     231             :     154, 158, 163, 168, 172, 177, 181, 186, 190, 195, 199, 204, 208,
     232             :     213, 217, 222, 226, 231, 235, 240, 244, 249, 253, 258, 262, 267,
     233             :     271, 275, 280, 284, 289, 293, 297, 302, 306, 311, 315, 319, 324,
     234             :     328, 332, 337, 341, 345, 349, 354, 358, 362, 367, 371, 375, 379,
     235             :     384, 388, 392, 396, 401, 409, 417, 425, 433, 441, 449, 458, 466,
     236             :     474, 482, 490, 498, 506, 514, 523, 531, 539, 547, 555, 563, 571,
     237             :     579, 588, 596, 604, 616, 628, 640, 652, 664, 676, 688, 700, 713,
     238             :     725, 737, 749, 761, 773, 785, 797, 809, 825, 841, 857, 873, 889,
     239             :     905, 922, 938, 954, 970, 986, 1002, 1018, 1038, 1058, 1078, 1098, 1118,
     240             :     1138, 1158, 1178, 1198, 1218, 1242, 1266, 1290, 1314, 1338, 1362, 1386, 1411,
     241             :     1435, 1463, 1491, 1519, 1547, 1575, 1603, 1631, 1663, 1695, 1727, 1759, 1791,
     242             :     1823, 1859, 1895, 1931, 1967, 2003, 2039, 2079, 2119, 2159, 2199, 2239, 2283,
     243             :     2327, 2371, 2415, 2459, 2507, 2555, 2603, 2651, 2703, 2755, 2807, 2859, 2915,
     244             :     2971, 3027, 3083, 3143, 3203, 3263, 3327, 3391, 3455, 3523, 3591, 3659, 3731,
     245             :     3803, 3876, 3952, 4028, 4104, 4184, 4264, 4348, 4432, 4516, 4604, 4692, 4784,
     246             :     4876, 4972, 5068, 5168, 5268, 5372, 5476, 5584, 5692, 5804, 5916, 6032, 6148,
     247             :     6268, 6388, 6512, 6640, 6768, 6900, 7036, 7172, 7312,
     248             : };
     249             : 
     250             : static const int16_t ac_qlookup_12_Q3[QINDEX_RANGE] = {
     251             :     4, 13, 19, 27, 35, 44, 54, 64, 75, 87, 99,
     252             :     112, 126, 139, 154, 168, 183, 199, 214, 230, 247, 263,
     253             :     280, 297, 314, 331, 349, 366, 384, 402, 420, 438, 456,
     254             :     475, 493, 511, 530, 548, 567, 586, 604, 623, 642, 660,
     255             :     679, 698, 716, 735, 753, 772, 791, 809, 828, 846, 865,
     256             :     884, 902, 920, 939, 957, 976, 994, 1012, 1030, 1049, 1067,
     257             :     1085, 1103, 1121, 1139, 1157, 1175, 1193, 1211, 1229, 1246, 1264,
     258             :     1282, 1299, 1317, 1335, 1352, 1370, 1387, 1405, 1422, 1440, 1457,
     259             :     1474, 1491, 1509, 1526, 1543, 1560, 1577, 1595, 1627, 1660, 1693,
     260             :     1725, 1758, 1791, 1824, 1856, 1889, 1922, 1954, 1987, 2020, 2052,
     261             :     2085, 2118, 2150, 2183, 2216, 2248, 2281, 2313, 2346, 2378, 2411,
     262             :     2459, 2508, 2556, 2605, 2653, 2701, 2750, 2798, 2847, 2895, 2943,
     263             :     2992, 3040, 3088, 3137, 3185, 3234, 3298, 3362, 3426, 3491, 3555,
     264             :     3619, 3684, 3748, 3812, 3876, 3941, 4005, 4069, 4149, 4230, 4310,
     265             :     4390, 4470, 4550, 4631, 4711, 4791, 4871, 4967, 5064, 5160, 5256,
     266             :     5352, 5448, 5544, 5641, 5737, 5849, 5961, 6073, 6185, 6297, 6410,
     267             :     6522, 6650, 6778, 6906, 7034, 7162, 7290, 7435, 7579, 7723, 7867,
     268             :     8011, 8155, 8315, 8475, 8635, 8795, 8956, 9132, 9308, 9484, 9660,
     269             :     9836, 10028, 10220, 10412, 10604, 10812, 11020, 11228, 11437, 11661, 11885,
     270             :     12109, 12333, 12573, 12813, 13053, 13309, 13565, 13821, 14093, 14365, 14637,
     271             :     14925, 15213, 15502, 15806, 16110, 16414, 16734, 17054, 17390, 17726, 18062,
     272             :     18414, 18766, 19134, 19502, 19886, 20270, 20670, 21070, 21486, 21902, 22334,
     273             :     22766, 23214, 23662, 24126, 24590, 25070, 25551, 26047, 26559, 27071, 27599,
     274             :     28143, 28687, 29247,
     275             : };
     276             : 
     277             : #if PREDICT_NSQ_SHAPE
     278             : EbErrorType open_loop_partitioning_sb(
     279             :     SequenceControlSet                *sequence_control_set_ptr,
     280             :     PictureControlSet                 *picture_control_set_ptr,
     281             :     ModeDecisionConfigurationContext  *context_ptr,
     282             :     MdcLcuData                        *mdc_result_tb_ptr,
     283             :     uint32_t                           sb_originx,
     284             :     uint32_t                           sb_originy,
     285             :     uint32_t                           sb_index);
     286             : 
     287             : #endif
     288      429799 : int16_t eb_av1_dc_quant_Q3(int32_t qindex, int32_t delta, AomBitDepth bit_depth) {
     289      429799 :     switch (bit_depth) {
     290      429803 :     case AOM_BITS_8: return dc_qlookup_Q3[clamp(qindex + delta, 0, MAXQ)];
     291           0 :     case AOM_BITS_10: return dc_qlookup_10_Q3[clamp(qindex + delta, 0, MAXQ)];
     292           0 :     case AOM_BITS_12: return dc_qlookup_12_Q3[clamp(qindex + delta, 0, MAXQ)];
     293           0 :     default:
     294           0 :         assert(0 && "bit_depth should be AOM_BITS_8, AOM_BITS_10 or AOM_BITS_12");
     295             :         return -1;
     296             :     }
     297             : }
     298      553207 : int16_t eb_av1_ac_quant_Q3(int32_t qindex, int32_t delta, AomBitDepth bit_depth) {
     299      553207 :     switch (bit_depth) {
     300      553227 :     case AOM_BITS_8: return ac_qlookup_Q3[clamp(qindex + delta, 0, MAXQ)];
     301           0 :     case AOM_BITS_10: return ac_qlookup_10_Q3[clamp(qindex + delta, 0, MAXQ)];
     302           0 :     case AOM_BITS_12: return ac_qlookup_12_Q3[clamp(qindex + delta, 0, MAXQ)];
     303           0 :     default:
     304           0 :         assert(0 && "bit_depth should be AOM_BITS_8, AOM_BITS_10 or AOM_BITS_12");
     305             :         return -1;
     306             :     }
     307             : }
     308             : 
     309       60962 : static int32_t get_qzbin_factor(int32_t q, AomBitDepth bit_depth) {
     310       60962 :     const int32_t quant = eb_av1_dc_quant_Q3(q, 0, bit_depth);
     311       60988 :     switch (bit_depth) {
     312       60990 :     case AOM_BITS_8: return q == 0 ? 64 : (quant < 148 ? 84 : 80);
     313           0 :     case AOM_BITS_10: return q == 0 ? 64 : (quant < 592 ? 84 : 80);
     314           0 :     case AOM_BITS_12: return q == 0 ? 64 : (quant < 2368 ? 84 : 80);
     315           0 :     default:
     316           0 :         assert(0 && "bit_depth should be AOM_BITS_8, AOM_BITS_10 or AOM_BITS_12");
     317             :         return -1;
     318             :     }
     319             : }
     320             : 
     321             : // In AV1 TX, the coefficients are always scaled up a factor of 8 (3
     322             : // bits), so QTX == Q3.
     323             : 
     324      182839 : int16_t eb_av1_dc_quant_QTX(int32_t qindex, int32_t delta, AomBitDepth bit_depth) {
     325      182839 :     return eb_av1_dc_quant_Q3(qindex, delta, bit_depth);
     326             : }
     327      183065 : int16_t eb_av1_ac_quant_QTX(int32_t qindex, int32_t delta, AomBitDepth bit_depth) {
     328      183065 :     return eb_av1_ac_quant_Q3(qindex, delta, bit_depth);
     329             : }
     330             : 
     331      364452 : static void invert_quant(int16_t *quant, int16_t *shift, int32_t d) {
     332             :     uint32_t t;
     333             :     int32_t l, m;
     334      364452 :     t = d;
     335     2843680 :     for (l = 0; t > 1; l++) t >>= 1;
     336      364452 :     m = 1 + (1 << (16 + l)) / d;
     337      364452 :     *quant = (int16_t)(m - (1 << 16));
     338      364452 :     *shift = 1 << (16 - l);
     339      364452 : }
     340             : 
     341         240 : static INLINE int32_t aom_get_qmlevel(int32_t qindex, int32_t first, int32_t last) {
     342         240 :     return first + (qindex * (last + 1 - first)) / QINDEX_RANGE;
     343             : }
     344             : 
     345         120 : void SetGlobalMotionField(
     346             :     PictureControlSet                    *picture_control_set_ptr)
     347             : {
     348             :     // Init Global Motion Vector
     349             :     uint8_t frameIndex;
     350        1080 :     for (frameIndex = INTRA_FRAME; frameIndex <= ALTREF_FRAME; ++frameIndex) {
     351         960 :         picture_control_set_ptr->parent_pcs_ptr->global_motion[frameIndex].wmtype = IDENTITY;
     352         960 :         picture_control_set_ptr->parent_pcs_ptr->global_motion[frameIndex].alpha = 0;
     353         960 :         picture_control_set_ptr->parent_pcs_ptr->global_motion[frameIndex].beta = 0;
     354         960 :         picture_control_set_ptr->parent_pcs_ptr->global_motion[frameIndex].delta = 0;
     355         960 :         picture_control_set_ptr->parent_pcs_ptr->global_motion[frameIndex].gamma = 0;
     356         960 :         picture_control_set_ptr->parent_pcs_ptr->global_motion[frameIndex].invalid = 0;
     357         960 :         picture_control_set_ptr->parent_pcs_ptr->global_motion[frameIndex].wmmat[0] = 0;
     358         960 :         picture_control_set_ptr->parent_pcs_ptr->global_motion[frameIndex].wmmat[1] = 0;
     359         960 :         picture_control_set_ptr->parent_pcs_ptr->global_motion[frameIndex].wmmat[2] = (1 << WARPEDMODEL_PREC_BITS);
     360         960 :         picture_control_set_ptr->parent_pcs_ptr->global_motion[frameIndex].wmmat[3] = 0;
     361         960 :         picture_control_set_ptr->parent_pcs_ptr->global_motion[frameIndex].wmmat[4] = 0;
     362         960 :         picture_control_set_ptr->parent_pcs_ptr->global_motion[frameIndex].wmmat[5] = (1 << WARPEDMODEL_PREC_BITS);
     363         960 :         picture_control_set_ptr->parent_pcs_ptr->global_motion[frameIndex].wmmat[6] = 0;
     364         960 :         picture_control_set_ptr->parent_pcs_ptr->global_motion[frameIndex].wmmat[7] = 0;
     365             :     }
     366             : 
     367             :     //Update MV
     368             : #if GLOBAL_WARPED_MOTION
     369         120 :     PictureParentControlSet *parent_pcs_ptr = picture_control_set_ptr->parent_pcs_ptr;
     370             : 
     371         120 :     if (parent_pcs_ptr->is_global_motion[get_list_idx(LAST_FRAME)][get_ref_frame_idx(LAST_FRAME)])
     372             :         parent_pcs_ptr->global_motion[LAST_FRAME]
     373          58 :             = parent_pcs_ptr->global_motion_estimation[get_list_idx(LAST_FRAME)][get_ref_frame_idx(LAST_FRAME)];
     374         120 :     if (parent_pcs_ptr->is_global_motion[get_list_idx(BWDREF_FRAME)][get_ref_frame_idx(BWDREF_FRAME)])
     375             :         parent_pcs_ptr->global_motion[BWDREF_FRAME]
     376          55 :             = parent_pcs_ptr->global_motion_estimation[get_list_idx(BWDREF_FRAME)][get_ref_frame_idx(BWDREF_FRAME)];
     377             : #else
     378             :     if (picture_control_set_ptr->parent_pcs_ptr->is_pan && picture_control_set_ptr->parent_pcs_ptr->is_tilt) {
     379             :         picture_control_set_ptr->parent_pcs_ptr->global_motion[LAST_FRAME].wmtype = TRANSLATION;
     380             :         picture_control_set_ptr->parent_pcs_ptr->global_motion[LAST_FRAME].wmmat[1] = ((picture_control_set_ptr->parent_pcs_ptr->panMvx + picture_control_set_ptr->parent_pcs_ptr->tiltMvx) / 2) << 1 << GM_TRANS_ONLY_PREC_DIFF;
     381             :         picture_control_set_ptr->parent_pcs_ptr->global_motion[LAST_FRAME].wmmat[0] = ((picture_control_set_ptr->parent_pcs_ptr->panMvy + picture_control_set_ptr->parent_pcs_ptr->tiltMvy) / 2) << 1 << GM_TRANS_ONLY_PREC_DIFF;
     382             :     }
     383             :     else if (picture_control_set_ptr->parent_pcs_ptr->is_pan) {
     384             :         picture_control_set_ptr->parent_pcs_ptr->global_motion[LAST_FRAME].wmtype = TRANSLATION;
     385             :         picture_control_set_ptr->parent_pcs_ptr->global_motion[LAST_FRAME].wmmat[1] = picture_control_set_ptr->parent_pcs_ptr->panMvx << 1 << GM_TRANS_ONLY_PREC_DIFF;
     386             :         picture_control_set_ptr->parent_pcs_ptr->global_motion[LAST_FRAME].wmmat[0] = picture_control_set_ptr->parent_pcs_ptr->panMvy << 1 << GM_TRANS_ONLY_PREC_DIFF;
     387             :     }
     388             :     else if (picture_control_set_ptr->parent_pcs_ptr->is_tilt) {
     389             :         picture_control_set_ptr->parent_pcs_ptr->global_motion[LAST_FRAME].wmtype = TRANSLATION;
     390             :         picture_control_set_ptr->parent_pcs_ptr->global_motion[LAST_FRAME].wmmat[1] = picture_control_set_ptr->parent_pcs_ptr->tiltMvx << 1 << GM_TRANS_ONLY_PREC_DIFF;
     391             :         picture_control_set_ptr->parent_pcs_ptr->global_motion[LAST_FRAME].wmmat[0] = picture_control_set_ptr->parent_pcs_ptr->tiltMvy << 1 << GM_TRANS_ONLY_PREC_DIFF;
     392             :     }
     393             : 
     394             :     picture_control_set_ptr->parent_pcs_ptr->global_motion[LAST_FRAME].wmmat[1] = (int32_t)clamp(picture_control_set_ptr->parent_pcs_ptr->global_motion[LAST_FRAME].wmmat[1], GM_TRANS_MIN*GM_TRANS_DECODE_FACTOR, GM_TRANS_MAX*GM_TRANS_DECODE_FACTOR);
     395             :     picture_control_set_ptr->parent_pcs_ptr->global_motion[LAST_FRAME].wmmat[0] = (int32_t)clamp(picture_control_set_ptr->parent_pcs_ptr->global_motion[LAST_FRAME].wmmat[0], GM_TRANS_MIN*GM_TRANS_DECODE_FACTOR, GM_TRANS_MAX*GM_TRANS_DECODE_FACTOR);
     396             : 
     397             :     picture_control_set_ptr->parent_pcs_ptr->global_motion[BWDREF_FRAME].wmtype = TRANSLATION;
     398             :     picture_control_set_ptr->parent_pcs_ptr->global_motion[BWDREF_FRAME].wmmat[1] = 0 - picture_control_set_ptr->parent_pcs_ptr->global_motion[LAST_FRAME].wmmat[1];
     399             :     picture_control_set_ptr->parent_pcs_ptr->global_motion[BWDREF_FRAME].wmmat[0] = 0 - picture_control_set_ptr->parent_pcs_ptr->global_motion[LAST_FRAME].wmmat[0];
     400             :     picture_control_set_ptr->parent_pcs_ptr->global_motion[BWDREF_FRAME].wmmat[1] = (int32_t)clamp(picture_control_set_ptr->parent_pcs_ptr->global_motion[BWDREF_FRAME].wmmat[1], GM_TRANS_MIN*GM_TRANS_DECODE_FACTOR, GM_TRANS_MAX*GM_TRANS_DECODE_FACTOR);
     401             :     picture_control_set_ptr->parent_pcs_ptr->global_motion[BWDREF_FRAME].wmmat[0] = (int32_t)clamp(picture_control_set_ptr->parent_pcs_ptr->global_motion[BWDREF_FRAME].wmmat[0], GM_TRANS_MIN*GM_TRANS_DECODE_FACTOR, GM_TRANS_MAX*GM_TRANS_DECODE_FACTOR);
     402             : 
     403             :     //convert_to_trans_prec(
     404             :     //    picture_control_set_ptr->parent_pcs_ptr->allow_high_precision_mv,
     405             :     //    picture_control_set_ptr->parent_pcs_ptr->global_motion[LAST_FRAME].wmmat[0]) *GM_TRANS_ONLY_DECODE_FACTOR;
     406             : 
     407             :     //convert_to_trans_prec(
     408             :     //    picture_control_set_ptr->parent_pcs_ptr->allow_high_precision_mv,
     409             :     //    picture_control_set_ptr->parent_pcs_ptr->global_motion[LAST_FRAME].wmmat[1]) *GM_TRANS_ONLY_DECODE_FACTOR;
     410             : #endif
     411         120 : }
     412             : 
     413         120 : void eb_av1_set_quantizer(
     414             :     PictureParentControlSet                    *picture_control_set_ptr,
     415             :     int32_t q)
     416             : {
     417             :     // quantizer has to be reinitialized with av1_init_quantizer() if any
     418             :     // delta_q changes.
     419         120 :     FrameHeader*frm_hdr = &picture_control_set_ptr->frm_hdr;
     420             : 
     421         120 :     frm_hdr->quantization_params.using_qmatrix = 0;
     422         120 :     picture_control_set_ptr->min_qmlevel = 5;
     423         120 :     picture_control_set_ptr->max_qmlevel = 9;
     424             : 
     425         120 :     frm_hdr->quantization_params.base_q_idx = AOMMAX(frm_hdr->delta_q_params.delta_q_present, q);
     426         120 :     frm_hdr->quantization_params.delta_q_y_dc = 0;
     427         120 :     frm_hdr->quantization_params.delta_q_u_dc = 0;
     428         120 :     frm_hdr->quantization_params.delta_q_u_ac = 0;
     429         120 :     frm_hdr->quantization_params.delta_q_v_dc = 0;
     430         120 :     frm_hdr->quantization_params.delta_q_v_ac = 0;
     431         120 :     frm_hdr->quantization_params.qm_y = aom_get_qmlevel(frm_hdr->quantization_params.base_q_idx, picture_control_set_ptr->min_qmlevel, picture_control_set_ptr->max_qmlevel);
     432         120 :     frm_hdr->quantization_params.qm_u = aom_get_qmlevel(frm_hdr->quantization_params.base_q_idx + frm_hdr->quantization_params.delta_q_u_ac,
     433             :         picture_control_set_ptr->min_qmlevel, picture_control_set_ptr->max_qmlevel);
     434             : 
     435         120 :     if (!picture_control_set_ptr->separate_uv_delta_q)
     436         120 :         frm_hdr->quantization_params.qm_v = frm_hdr->quantization_params.qm_u;
     437             :     else
     438           0 :         frm_hdr->quantization_params.qm_v = aom_get_qmlevel(frm_hdr->quantization_params.base_q_idx + frm_hdr->quantization_params.delta_q_v_ac,
     439             :             picture_control_set_ptr->min_qmlevel, picture_control_set_ptr->max_qmlevel);
     440         120 : }
     441             : 
     442         240 : void eb_av1_build_quantizer(
     443             :     AomBitDepth bit_depth,
     444             :     int32_t y_dc_delta_q,
     445             :     int32_t u_dc_delta_q,
     446             :     int32_t u_ac_delta_q,
     447             :     int32_t v_dc_delta_q,
     448             :     int32_t v_ac_delta_q,
     449             :     Quants *const quants,
     450             :     Dequants *const deq)
     451             : {
     452             :     int32_t i, q, quant_Q3, quant_QTX;
     453             : 
     454       61277 :     for (q = 0; q < QINDEX_RANGE; q++) {
     455       60942 :         const int32_t qzbin_factor = get_qzbin_factor(q, bit_depth);
     456       60989 :         const int32_t qrounding_factor = q == 0 ? 64 : 48;
     457             : 
     458      183262 :         for (i = 0; i < 2; ++i) {
     459      122225 :             int32_t qrounding_factor_fp = 64;
     460             :             // y quantizer setup with original coeff shift of Q3
     461       60993 :             quant_Q3 = i == 0 ? eb_av1_dc_quant_Q3(q, y_dc_delta_q, bit_depth)
     462      183266 :                 : eb_av1_ac_quant_Q3(q, 0, bit_depth);
     463             :             // y quantizer with TX scale
     464       61038 :             quant_QTX = i == 0 ? eb_av1_dc_quant_QTX(q, y_dc_delta_q, bit_depth)
     465      183334 :                 : eb_av1_ac_quant_QTX(q, 0, bit_depth);
     466      122205 :             invert_quant(&quants->y_quant[q][i], &quants->y_quant_shift[q][i],
     467             :                 quant_QTX);
     468      122203 :             quants->y_quant_fp[q][i] = (int16_t)((1 << 16) / quant_QTX);
     469      122203 :             quants->y_round_fp[q][i] = (int16_t)((qrounding_factor_fp * quant_QTX) >> 7);
     470      122203 :             quants->y_zbin[q][i] = (int16_t)ROUND_POWER_OF_TWO(qzbin_factor * quant_QTX, 7);
     471      122203 :             quants->y_round[q][i] = (int16_t)((qrounding_factor * quant_QTX) >> 7);
     472      122203 :             deq->y_dequant_QTX[q][i] = (int16_t)quant_QTX;
     473      122203 :             deq->y_dequant_Q3[q][i] = (int16_t)quant_Q3;
     474             : 
     475             :             // u quantizer setup with original coeff shift of Q3
     476       61212 :             quant_Q3 = i == 0 ? eb_av1_dc_quant_Q3(q, u_dc_delta_q, bit_depth)
     477      183410 :                 : eb_av1_ac_quant_Q3(q, u_ac_delta_q, bit_depth);
     478             :             // u quantizer with TX scale
     479       61211 :             quant_QTX = i == 0 ? eb_av1_dc_quant_QTX(q, u_dc_delta_q, bit_depth)
     480      183582 :                 : eb_av1_ac_quant_QTX(q, u_ac_delta_q, bit_depth);
     481      122324 :             invert_quant(&quants->u_quant[q][i], &quants->u_quant_shift[q][i],
     482             :                 quant_QTX);
     483      122249 :             quants->u_quant_fp[q][i] = (int16_t)((1 << 16) / quant_QTX);
     484      122249 :             quants->u_round_fp[q][i] = (int16_t)((qrounding_factor_fp * quant_QTX) >> 7);
     485      122249 :             quants->u_zbin[q][i] = (int16_t)ROUND_POWER_OF_TWO(qzbin_factor * quant_QTX, 7);
     486      122249 :             quants->u_round[q][i] = (int16_t)((qrounding_factor * quant_QTX) >> 7);
     487      122249 :             deq->u_dequant_QTX[q][i] = (int16_t)quant_QTX;
     488      122249 :             deq->u_dequant_Q3[q][i] = (int16_t)quant_Q3;
     489             : 
     490             :             // v quantizer setup with original coeff shift of Q3
     491       61225 :             quant_Q3 = i == 0 ? eb_av1_dc_quant_Q3(q, v_dc_delta_q, bit_depth)
     492      183476 :                 : eb_av1_ac_quant_Q3(q, v_ac_delta_q, bit_depth);
     493             :             // v quantizer with TX scale
     494       61227 :             quant_QTX = i == 0 ? eb_av1_dc_quant_QTX(q, v_dc_delta_q, bit_depth)
     495      183632 :                 : eb_av1_ac_quant_QTX(q, v_ac_delta_q, bit_depth);
     496      122356 :             invert_quant(&quants->v_quant[q][i], &quants->v_quant_shift[q][i],
     497             :                 quant_QTX);
     498      122273 :             quants->v_quant_fp[q][i] = (int16_t)((1 << 16) / quant_QTX);
     499      122273 :             quants->v_round_fp[q][i] = (int16_t)((qrounding_factor_fp * quant_QTX) >> 7);
     500      122273 :             quants->v_zbin[q][i] = (int16_t)ROUND_POWER_OF_TWO(qzbin_factor * quant_QTX, 7);
     501      122273 :             quants->v_round[q][i] = (int16_t)((qrounding_factor * quant_QTX) >> 7);
     502      122273 :             deq->v_dequant_QTX[q][i] = (int16_t)quant_QTX;
     503      122273 :             deq->v_dequant_Q3[q][i] = (int16_t)quant_Q3;
     504             :         }
     505             : 
     506      424548 :         for (i = 2; i < 8; i++) {  // 8: SIMD width
     507      363511 :             quants->y_quant[q][i] = quants->y_quant[q][1];
     508      363511 :             quants->y_quant_fp[q][i] = quants->y_quant_fp[q][1];
     509      363511 :             quants->y_round_fp[q][i] = quants->y_round_fp[q][1];
     510      363511 :             quants->y_quant_shift[q][i] = quants->y_quant_shift[q][1];
     511      363511 :             quants->y_zbin[q][i] = quants->y_zbin[q][1];
     512      363511 :             quants->y_round[q][i] = quants->y_round[q][1];
     513      363511 :             deq->y_dequant_QTX[q][i] = deq->y_dequant_QTX[q][1];
     514      363511 :             deq->y_dequant_Q3[q][i] = deq->y_dequant_Q3[q][1];
     515             : 
     516      363511 :             quants->u_quant[q][i] = quants->u_quant[q][1];
     517      363511 :             quants->u_quant_fp[q][i] = quants->u_quant_fp[q][1];
     518      363511 :             quants->u_round_fp[q][i] = quants->u_round_fp[q][1];
     519      363511 :             quants->u_quant_shift[q][i] = quants->u_quant_shift[q][1];
     520      363511 :             quants->u_zbin[q][i] = quants->u_zbin[q][1];
     521      363511 :             quants->u_round[q][i] = quants->u_round[q][1];
     522      363511 :             deq->u_dequant_QTX[q][i] = deq->u_dequant_QTX[q][1];
     523      363511 :             deq->u_dequant_Q3[q][i] = deq->u_dequant_Q3[q][1];
     524      363511 :             quants->v_quant[q][i] = quants->u_quant[q][1];
     525      363511 :             quants->v_quant_fp[q][i] = quants->v_quant_fp[q][1];
     526      363511 :             quants->v_round_fp[q][i] = quants->v_round_fp[q][1];
     527      363511 :             quants->v_quant_shift[q][i] = quants->v_quant_shift[q][1];
     528      363511 :             quants->v_zbin[q][i] = quants->v_zbin[q][1];
     529      363511 :             quants->v_round[q][i] = quants->v_round[q][1];
     530      363511 :             deq->v_dequant_QTX[q][i] = deq->v_dequant_QTX[q][1];
     531      363511 :             deq->v_dequant_Q3[q][i] = deq->v_dequant_Q3[q][1];
     532             :         }
     533             :     }
     534         335 : }
     535             : 
     536         120 : void eb_av1_qm_init(
     537             :     PictureParentControlSet                   *picture_control_set_ptr
     538             : )
     539             : {
     540         120 :     const uint8_t num_planes = 3;// MAX_MB_PLANE;// NM- No monochroma
     541             :     uint8_t q, c, t;
     542             :     int32_t current;
     543        2032 :     for (q = 0; q < NUM_QM_LEVELS; ++q) {
     544        7663 :         for (c = 0; c < num_planes; ++c) {
     545        5751 :             current = 0;
     546      114442 :             for (t = 0; t < TX_SIZES_ALL; ++t) {
     547      108698 :                 const int32_t size = tx_size_2d[t];
     548      108698 :                 const TxSize qm_tx_size = av1_get_adjusted_tx_size(t);
     549      108691 :                 if (q == NUM_QM_LEVELS - 1) {
     550        6840 :                     picture_control_set_ptr->gqmatrix[q][c][t] = NULL;
     551        6840 :                     picture_control_set_ptr->giqmatrix[q][c][t] = NULL;
     552             :                 }
     553      101851 :                 else if (t != qm_tx_size) {  // Reuse matrices for 'qm_tx_size'
     554       26878 :                     picture_control_set_ptr->gqmatrix[q][c][t] = picture_control_set_ptr->gqmatrix[q][c][qm_tx_size];
     555       26878 :                     picture_control_set_ptr->giqmatrix[q][c][t] = picture_control_set_ptr->giqmatrix[q][c][qm_tx_size];
     556             :                 }
     557             :                 else {
     558       74973 :                     assert(current + size <= QM_TOTAL_SIZE);
     559       74973 :                     picture_control_set_ptr->gqmatrix[q][c][t] = &wt_matrix_ref[q][c >= 1][current];
     560       74973 :                     picture_control_set_ptr->giqmatrix[q][c][t] = &iwt_matrix_ref[q][c >= 1][current];
     561       74973 :                     current += size;
     562             :                 }
     563             :             }
     564             :         }
     565             :     }
     566         113 : }
     567             : 
     568             : /******************************************************
     569             : * Compute picture and slice level chroma QP offsets
     570             : ******************************************************/
     571         120 : void SetSliceAndPictureChromaQpOffsets(
     572             :     PictureControlSet                    *picture_control_set_ptr
     573             : )
     574             : {
     575             :     // This is a picture level chroma QP offset and is sent in the PPS
     576         120 :     picture_control_set_ptr->cb_qp_offset = 0;
     577         120 :     picture_control_set_ptr->cr_qp_offset = 0;
     578             : 
     579             :     //In order to have QP offsets for chroma at a slice level set slice_level_chroma_qp_flag flag in picture_control_set_ptr (can be done in the PCS Ctor)
     580             : 
     581             :     // The below are slice level chroma QP offsets and is sent for each slice when slice_level_chroma_qp_flag is set
     582             : 
     583             :     // IMPORTANT: Lambda tables assume that the cb and cr have the same QP offsets.
     584             :     // However the offsets for each component can be very different for ENC DEC and we are conformant.
     585         120 :     picture_control_set_ptr->slice_cb_qp_offset = 0;
     586         120 :     picture_control_set_ptr->slice_cr_qp_offset = 0;
     587             : 
     588         120 :     if (picture_control_set_ptr->parent_pcs_ptr->pic_noise_class >= PIC_NOISE_CLASS_6) {
     589           0 :         picture_control_set_ptr->slice_cb_qp_offset = 10;
     590           0 :         picture_control_set_ptr->slice_cr_qp_offset = 10;
     591             :     }
     592         120 :     else if (picture_control_set_ptr->parent_pcs_ptr->pic_noise_class >= PIC_NOISE_CLASS_4) {
     593           0 :         picture_control_set_ptr->slice_cb_qp_offset = 8;
     594           0 :         picture_control_set_ptr->slice_cr_qp_offset = 8;
     595             :     }
     596             :     else {
     597         120 :         if (picture_control_set_ptr->temporal_layer_index == 1) {
     598           8 :             picture_control_set_ptr->slice_cb_qp_offset = 2;
     599           8 :             picture_control_set_ptr->slice_cr_qp_offset = 2;
     600             :         }
     601             :         else {
     602         112 :             picture_control_set_ptr->slice_cb_qp_offset = 0;
     603         112 :             picture_control_set_ptr->slice_cr_qp_offset = 0;
     604             :         }
     605             :     }
     606         120 : }
     607             : 
     608             : /******************************************************
     609             : * Set the reference sg ep for a given picture
     610             : ******************************************************/
     611         120 : void set_reference_sg_ep(
     612             :     PictureControlSet                    *picture_control_set_ptr)
     613             : {
     614         120 :     Av1Common* cm = picture_control_set_ptr->parent_pcs_ptr->av1_cm;
     615             :     EbReferenceObject  * refObjL0, *refObjL1;
     616         120 :     memset(cm->sg_frame_ep_cnt, 0, SGRPROJ_PARAMS * sizeof(int32_t));
     617         120 :     cm->sg_frame_ep = 0;
     618             : 
     619             :     // NADER: set cm->sg_ref_frame_ep[0] = cm->sg_ref_frame_ep[1] = -1 to perform all iterations
     620         120 :     switch(picture_control_set_ptr->slice_type){
     621           4 :     case I_SLICE:
     622           4 :         cm->sg_ref_frame_ep[0] = -1;
     623           4 :         cm->sg_ref_frame_ep[1] = -1;
     624           4 :         break;
     625         110 :     case B_SLICE:
     626         110 :         refObjL0 = (EbReferenceObject*)picture_control_set_ptr->ref_pic_ptr_array[REF_LIST_0][0]->object_ptr;
     627         110 :         refObjL1 = (EbReferenceObject*)picture_control_set_ptr->ref_pic_ptr_array[REF_LIST_1][0]->object_ptr;
     628         110 :         cm->sg_ref_frame_ep[0] = refObjL0->sg_frame_ep;
     629         110 :         cm->sg_ref_frame_ep[1] = refObjL1->sg_frame_ep;
     630         110 :         break;
     631           6 :     case P_SLICE:
     632           6 :         refObjL0 = (EbReferenceObject*)picture_control_set_ptr->ref_pic_ptr_array[REF_LIST_0][0]->object_ptr;
     633           6 :         cm->sg_ref_frame_ep[0] = refObjL0->sg_frame_ep;
     634           6 :         cm->sg_ref_frame_ep[1] = 0;
     635           6 :         break;
     636           0 :     default:
     637           0 :         printf("SG: Not supported picture type");
     638           0 :         break;
     639             :     }
     640         120 : }
     641             : 
     642             : /******************************************************
     643             : * Set the reference cdef strength for a given picture
     644             : ******************************************************/
     645         120 : void set_reference_cdef_strength(
     646             :     PictureControlSet                    *picture_control_set_ptr)
     647             : {
     648             :     EbReferenceObject  * refObjL0, *refObjL1;
     649             :     int32_t strength;
     650             :     // NADER: set picture_control_set_ptr->parent_pcs_ptr->use_ref_frame_cdef_strength 0 to test all strengths
     651         120 :     switch (picture_control_set_ptr->slice_type) {
     652           4 :     case I_SLICE:
     653           4 :         picture_control_set_ptr->parent_pcs_ptr->use_ref_frame_cdef_strength = 0;
     654           4 :         picture_control_set_ptr->parent_pcs_ptr->cdf_ref_frame_strenght = 0;
     655           4 :         break;
     656         110 :     case B_SLICE:
     657         110 :         refObjL0 = (EbReferenceObject*)picture_control_set_ptr->ref_pic_ptr_array[REF_LIST_0][0]->object_ptr;
     658         110 :         refObjL1 = (EbReferenceObject*)picture_control_set_ptr->ref_pic_ptr_array[REF_LIST_1][0]->object_ptr;
     659         110 :         strength = (refObjL0->cdef_frame_strength + refObjL1->cdef_frame_strength) / 2;
     660         110 :         picture_control_set_ptr->parent_pcs_ptr->use_ref_frame_cdef_strength = 1;
     661         110 :         picture_control_set_ptr->parent_pcs_ptr->cdf_ref_frame_strenght = strength;
     662         110 :         break;
     663           6 :     case P_SLICE:
     664           6 :         refObjL0 = (EbReferenceObject*)picture_control_set_ptr->ref_pic_ptr_array[REF_LIST_0][0]->object_ptr;
     665           6 :         strength = refObjL0->cdef_frame_strength;
     666           6 :         picture_control_set_ptr->parent_pcs_ptr->use_ref_frame_cdef_strength = 1;
     667           6 :         picture_control_set_ptr->parent_pcs_ptr->cdf_ref_frame_strenght = strength;
     668           6 :         break;
     669           0 :     default:
     670           0 :         printf("CDEF: Not supported picture type");
     671           0 :         break;
     672             :     }
     673         120 : }
     674             : 
     675             : /******************************************************
     676             : * Compute Tc, and Beta offsets for a given picture
     677             : ******************************************************/
     678             : 
     679           6 : static void mode_decision_configuration_context_dctor(EbPtr p)
     680             : {
     681           6 :     ModeDecisionConfigurationContext *obj = (ModeDecisionConfigurationContext*)p;
     682             : 
     683           6 :     if (obj->is_md_rate_estimation_ptr_owner)
     684           0 :         EB_FREE_ARRAY(obj->md_rate_estimation_ptr);
     685           6 :     EB_FREE_ARRAY(obj->sb_score_array);
     686           6 :     EB_FREE_ARRAY(obj->sb_cost_array);
     687           6 :     EB_FREE_ARRAY(obj->mdc_candidate_ptr);
     688           6 :     EB_FREE_ARRAY(obj->mdc_ref_mv_stack);
     689           6 :     EB_FREE_ARRAY(obj->mdc_cu_ptr->av1xd);
     690           6 :     EB_FREE_ARRAY(obj->mdc_cu_ptr);
     691           6 :     EB_DELETE(obj->candidate_buffer);
     692           6 :     EB_FREE_ARRAY(obj->fast_candidate_array);
     693           6 :     EB_FREE_ARRAY(obj->fast_candidate_ptr_array);
     694           6 :     EB_DELETE(obj->trans_quant_buffers_ptr);
     695           6 :     EB_FREE(obj->transform_inner_array_ptr);
     696           6 : }
     697             : /******************************************************
     698             :  * Mode Decision Configuration Context Constructor
     699             :  ******************************************************/
     700           6 : EbErrorType mode_decision_configuration_context_ctor(
     701             :     ModeDecisionConfigurationContext  *context_ptr,
     702             :     EbFifo                            *rate_control_input_fifo_ptr,
     703             :     EbFifo                            *mode_decision_configuration_output_fifo_ptr,
     704             :     uint16_t                                 sb_total_count)
     705             : 
     706             : {
     707             : #if ADD_MDC_FULL_COST
     708           6 :     EbErrorType return_error = EB_ErrorNone;
     709           6 :     EB_MALLOC(context_ptr->candidate_buffer, sizeof(ModeDecisionCandidateBuffer));
     710           6 :     uint64_t fast_cost_array = MAX_MODE_COST;
     711           6 :     uint64_t full_cost_array = MAX_MODE_COST;
     712           6 :     uint64_t full_cost_skip_ptr = MAX_MODE_COST;
     713           6 :     uint64_t full_cost_merge_ptr = MAX_MODE_COST;
     714             : #define MDC_MODE_DECISION_CANDIDATE_MAX_COUNT 1
     715             :     // Fast Candidate Array
     716           6 :     EB_MALLOC_ARRAY(context_ptr->fast_candidate_array,MDC_MODE_DECISION_CANDIDATE_MAX_COUNT);
     717           6 :     EB_MALLOC_ARRAY( context_ptr->fast_candidate_ptr_array, MDC_MODE_DECISION_CANDIDATE_MAX_COUNT);
     718             :     uint16_t candidateIndex;
     719          12 :     for (candidateIndex = 0; candidateIndex < MDC_MODE_DECISION_CANDIDATE_MAX_COUNT; ++candidateIndex) {
     720           6 :         context_ptr->fast_candidate_ptr_array[candidateIndex] = &context_ptr->fast_candidate_array[candidateIndex];
     721           6 :         context_ptr->fast_candidate_ptr_array[candidateIndex]->md_rate_estimation_ptr = context_ptr->md_rate_estimation_ptr;
     722             :     }
     723           6 :     return_error = mode_decision_candidate_buffer_ctor(
     724             :         context_ptr->candidate_buffer,
     725             :         EB_8BIT,
     726             :         &fast_cost_array,
     727             :         &full_cost_array,
     728             :         &full_cost_skip_ptr,
     729             :         &full_cost_merge_ptr);
     730           6 :     if (return_error == EB_ErrorInsufficientResources)
     731           0 :         return EB_ErrorInsufficientResources;
     732             :     // Transform and Quantization Buffers
     733           6 :     EB_MALLOC(context_ptr->trans_quant_buffers_ptr, sizeof(EbTransQuantBuffers));
     734           6 :     return_error = eb_trans_quant_buffers_ctor(
     735             :         context_ptr->trans_quant_buffers_ptr);
     736             :     // Trasform Scratch Memory
     737           6 :     EB_MALLOC(context_ptr->transform_inner_array_ptr, 3152); //refer to EbInvTransform_SSE2.as. case 32x32
     738             :     // MD rate Estimation tables
     739             : #endif
     740           6 :     context_ptr->dctor = mode_decision_configuration_context_dctor;
     741             :     // Input/Output System Resource Manager FIFOs
     742           6 :     context_ptr->rate_control_input_fifo_ptr = rate_control_input_fifo_ptr;
     743           6 :     context_ptr->mode_decision_configuration_output_fifo_ptr = mode_decision_configuration_output_fifo_ptr;
     744             :     // Rate estimation
     745           6 :     EB_MALLOC_ARRAY(context_ptr->md_rate_estimation_ptr, 1);
     746           6 :     context_ptr->is_md_rate_estimation_ptr_owner = EB_TRUE;
     747             : 
     748             :     // Adaptive Depth Partitioning
     749           6 :     EB_MALLOC_ARRAY(context_ptr->sb_score_array, sb_total_count);
     750           6 :     EB_MALLOC_ARRAY(context_ptr->sb_cost_array, sb_total_count);
     751             : 
     752             :     // Open Loop Partitioning
     753           6 :     EB_MALLOC_ARRAY(context_ptr->mdc_candidate_ptr, 1);
     754           6 :     EB_MALLOC_ARRAY(context_ptr->mdc_ref_mv_stack, 1);
     755           6 :     EB_MALLOC_ARRAY(context_ptr->mdc_cu_ptr, 1);
     756           6 :     context_ptr->mdc_cu_ptr->av1xd = NULL;
     757           6 :     EB_MALLOC_ARRAY(context_ptr->mdc_cu_ptr->av1xd, 1);
     758           6 :     return EB_ErrorNone;
     759             : }
     760             : 
     761             : /******************************************************
     762             : * Predict the SB partitionning
     763             : ******************************************************/
     764           0 : void PerformEarlyLcuPartitionning(
     765             :     ModeDecisionConfigurationContext     *context_ptr,
     766             :     SequenceControlSet                   *sequence_control_set_ptr,
     767             :     PictureControlSet                    *picture_control_set_ptr) {
     768             :     LargestCodingUnit            *sb_ptr;
     769             :     uint32_t                         sb_index;
     770           0 :     picture_control_set_ptr->parent_pcs_ptr->average_qp = (uint8_t)picture_control_set_ptr->parent_pcs_ptr->picture_qp;
     771             : 
     772             :     // SB Loop : Partitionnig Decision
     773           0 :     for (sb_index = 0; sb_index < picture_control_set_ptr->sb_total_count; ++sb_index) {
     774           0 :         sb_ptr = picture_control_set_ptr->sb_ptr_array[sb_index];
     775           0 :         early_mode_decision_lcu(
     776             :             sequence_control_set_ptr,
     777             :             picture_control_set_ptr,
     778             :             sb_ptr,
     779             :             sb_index,
     780             :             context_ptr);
     781             :     } // End of SB Loop
     782           0 : }
     783        2625 : void PerformEarlyLcuPartitionningLcu(
     784             :     ModeDecisionConfigurationContext     *context_ptr,
     785             :     SequenceControlSet                   *sequence_control_set_ptr,
     786             :     PictureControlSet                    *picture_control_set_ptr,
     787             :     uint32_t                                    sb_index) {
     788             :     LargestCodingUnit            *sb_ptr;
     789             : 
     790             :     // SB Loop : Partitionnig Decision
     791        2625 :     sb_ptr = picture_control_set_ptr->sb_ptr_array[sb_index];
     792        2625 :     early_mode_decision_lcu(
     793             :         sequence_control_set_ptr,
     794             :         picture_control_set_ptr,
     795             :         sb_ptr,
     796             :         sb_index,
     797             :         context_ptr);
     798        2625 : }
     799             : 
     800           0 : void Forward85CuToModeDecisionLCU(
     801             :     SequenceControlSet  *sequence_control_set_ptr,
     802             :     PictureControlSet   *picture_control_set_ptr,
     803             :     uint32_t                 sb_index) {
     804             :     const CodedUnitStats  *cuStatsPtr;
     805             :     EbBool split_flag;
     806             :     // SB Loop : Partitionnig Decision
     807             : 
     808           0 :     SbParams  *sb_params = &sequence_control_set_ptr->sb_params_array[sb_index];
     809           0 :     MdcLcuData *resultsPtr = &picture_control_set_ptr->mdc_sb_array[sb_index];
     810             :     uint32_t cuIndexInRaterScan;   uint16_t cuVar;
     811             : 
     812           0 :     resultsPtr->leaf_count = 0;
     813           0 :     uint8_t cu_index = 0;
     814           0 :     while (cu_index < CU_MAX_COUNT)
     815             :     {
     816           0 :         split_flag = EB_TRUE;
     817           0 :         cuStatsPtr = get_coded_unit_stats(cu_index);
     818           0 :         if (sb_params->raster_scan_cu_validity[md_scan_to_raster_scan[cu_index]])
     819             :         {
     820           0 :             switch (cuStatsPtr->depth) {
     821           0 :             case 0:
     822             : 
     823           0 :                 resultsPtr->leaf_data_array[resultsPtr->leaf_count].leaf_index = cu_index;
     824           0 :                 resultsPtr->leaf_data_array[resultsPtr->leaf_count++].split_flag = split_flag = EB_TRUE;
     825             : 
     826           0 :                 break;
     827           0 :             case 1:
     828           0 :                 cuIndexInRaterScan = md_scan_to_raster_scan[cu_index];
     829           0 :                 cuVar = (picture_control_set_ptr->parent_pcs_ptr->variance[sb_index][cuIndexInRaterScan]);
     830           0 :                 if (picture_control_set_ptr->slice_type == I_SLICE && cuVar > 40)
     831           0 :                     split_flag = EB_TRUE;
     832             :                 else {
     833           0 :                     resultsPtr->leaf_data_array[resultsPtr->leaf_count].leaf_index = cu_index;
     834           0 :                     resultsPtr->leaf_data_array[resultsPtr->leaf_count++].split_flag = split_flag = EB_TRUE;
     835             :                 }
     836             : 
     837           0 :                 break;
     838             : 
     839           0 :             case 2:
     840             : 
     841           0 :                 resultsPtr->leaf_data_array[resultsPtr->leaf_count].leaf_index = cu_index;
     842           0 :                 resultsPtr->leaf_data_array[resultsPtr->leaf_count++].split_flag = split_flag = EB_TRUE;
     843             : 
     844           0 :                 break;
     845           0 :             case 3:
     846             : 
     847           0 :                 resultsPtr->leaf_data_array[resultsPtr->leaf_count].leaf_index = cu_index;
     848           0 :                 resultsPtr->leaf_data_array[resultsPtr->leaf_count++].split_flag = split_flag = EB_FALSE;
     849             : 
     850           0 :                 break;
     851             : 
     852           0 :             default:
     853           0 :                 resultsPtr->leaf_data_array[resultsPtr->leaf_count].leaf_index = cu_index;
     854           0 :                 resultsPtr->leaf_data_array[resultsPtr->leaf_count++].split_flag = split_flag = EB_TRUE;
     855           0 :                 break;
     856             :             }
     857           0 :         }
     858             : 
     859           0 :         cu_index += (split_flag == EB_TRUE) ? 1 : depth_offset[cuStatsPtr->depth];
     860             :     } // End CU Loop
     861           0 : }
     862             : 
     863           0 : void Forward84CuToModeDecisionLCU(
     864             :     SequenceControlSet  *sequence_control_set_ptr,
     865             :     PictureControlSet   *picture_control_set_ptr,
     866             :     uint32_t                 sb_index) {
     867             :     const CodedUnitStats  *cuStatsPtr;
     868             :     EbBool split_flag;
     869             :     // SB Loop : Partitionnig Decision
     870             : 
     871           0 :     SbParams  *sb_params = &sequence_control_set_ptr->sb_params_array[sb_index];
     872           0 :     MdcLcuData *resultsPtr = &picture_control_set_ptr->mdc_sb_array[sb_index];
     873             :     uint32_t cuIndexInRaterScan;   uint16_t cuVar;
     874             : 
     875           0 :     resultsPtr->leaf_count = 0;
     876           0 :     uint8_t cu_index = 0;
     877           0 :     while (cu_index < CU_MAX_COUNT)
     878             :     {
     879           0 :         split_flag = EB_TRUE;
     880           0 :         cuStatsPtr = get_coded_unit_stats(cu_index);
     881           0 :         if (sb_params->raster_scan_cu_validity[md_scan_to_raster_scan[cu_index]])
     882             :         {
     883           0 :             switch (cuStatsPtr->depth) {
     884           0 :             case 0:
     885             : 
     886           0 :                 split_flag = EB_TRUE;
     887             : 
     888           0 :                 break;
     889           0 :             case 1:
     890           0 :                 cuIndexInRaterScan = md_scan_to_raster_scan[cu_index];
     891           0 :                 cuVar = (picture_control_set_ptr->parent_pcs_ptr->variance[sb_index][cuIndexInRaterScan]);
     892           0 :                 if (picture_control_set_ptr->slice_type == I_SLICE && cuVar > 40)
     893           0 :                     split_flag = EB_TRUE;
     894             :                 else {
     895           0 :                     resultsPtr->leaf_data_array[resultsPtr->leaf_count].leaf_index = cu_index;
     896           0 :                     resultsPtr->leaf_data_array[resultsPtr->leaf_count++].split_flag = split_flag = EB_TRUE;
     897             :                 }
     898             : 
     899           0 :                 break;
     900             : 
     901           0 :             case 2:
     902             : 
     903           0 :                 resultsPtr->leaf_data_array[resultsPtr->leaf_count].leaf_index = cu_index;
     904           0 :                 resultsPtr->leaf_data_array[resultsPtr->leaf_count++].split_flag = split_flag = EB_TRUE;
     905             : 
     906           0 :                 break;
     907           0 :             case 3:
     908             : 
     909           0 :                 resultsPtr->leaf_data_array[resultsPtr->leaf_count].leaf_index = cu_index;
     910           0 :                 resultsPtr->leaf_data_array[resultsPtr->leaf_count++].split_flag = split_flag = EB_FALSE;
     911             : 
     912           0 :                 break;
     913             : 
     914           0 :             default:
     915           0 :                 resultsPtr->leaf_data_array[resultsPtr->leaf_count].leaf_index = cu_index;
     916           0 :                 resultsPtr->leaf_data_array[resultsPtr->leaf_count++].split_flag = split_flag = EB_TRUE;
     917           0 :                 break;
     918             :             }
     919           0 :         }
     920             : 
     921           0 :         cu_index += (split_flag == EB_TRUE) ? 1 : depth_offset[cuStatsPtr->depth];
     922             :     } // End CU Loop
     923           0 : }
     924             : 
     925          60 : void forward_all_blocks_to_md(
     926             :     SequenceControlSet                   *sequence_control_set_ptr,
     927             :     PictureControlSet                    *picture_control_set_ptr)
     928             : {
     929             :     uint32_t                   sb_index;
     930             :     EbBool                  split_flag;
     931             : 
     932             :     UNUSED(split_flag);
     933             : 
     934        3656 :     for (sb_index = 0; sb_index < sequence_control_set_ptr->sb_tot_cnt; ++sb_index)
     935             :     {
     936        3600 :         MdcLcuData *resultsPtr = &picture_control_set_ptr->mdc_sb_array[sb_index];
     937             : 
     938        3600 :         resultsPtr->leaf_count = 0;
     939             : 
     940        3600 :         uint32_t  blk_index = 0;
     941             : 
     942     3963960 :         while (blk_index < sequence_control_set_ptr->max_block_cnt)
     943             :         {
     944     3960370 :             split_flag = EB_TRUE;
     945             : 
     946     3960370 :             const BlockGeom * blk_geom = get_blk_geom_mds(blk_index);
     947             : 
     948             :             //if the parentSq is inside inject this block
     949     3960360 :             uint8_t is_blk_allowed = picture_control_set_ptr->slice_type != I_SLICE ? 1 : (blk_geom->sq_size < 128) ? 1 : 0;
     950             : 
     951     3960360 :             if (sequence_control_set_ptr->sb_geom[sb_index].block_is_inside_md_scan[blk_index] && is_blk_allowed)
     952             : 
     953             :             {
     954     3960360 :                 resultsPtr->leaf_data_array[resultsPtr->leaf_count].tot_d1_blocks =
     955             : 
     956     7920720 :                     blk_geom->sq_size == 128 ? 17 :
     957     3960360 :                     blk_geom->sq_size > 8 ? 25 :
     958     2072560 :                     blk_geom->sq_size == 8 ? 5 : 1;
     959             : 
     960     3960360 :                 resultsPtr->leaf_data_array[resultsPtr->leaf_count].leaf_index = 0;//valid only for square 85 world. will be removed.
     961     3960360 :                 resultsPtr->leaf_data_array[resultsPtr->leaf_count].mds_idx = blk_index;
     962     3960360 :                 if (blk_geom->sq_size > 4)
     963             :                 {
     964     3039860 :                     resultsPtr->leaf_data_array[resultsPtr->leaf_count++].split_flag = EB_TRUE;
     965     3039860 :                     split_flag = EB_TRUE;
     966             :                 }
     967             :                 else {
     968      920497 :                     resultsPtr->leaf_data_array[resultsPtr->leaf_count++].split_flag = EB_FALSE;
     969      920497 :                     split_flag = EB_FALSE;
     970             :                 }
     971             :             }
     972             : 
     973     3960360 :             blk_index++;
     974             :         }
     975             :     }
     976             : 
     977          56 :     picture_control_set_ptr->parent_pcs_ptr->average_qp = (uint8_t)picture_control_set_ptr->parent_pcs_ptr->picture_qp;
     978          56 : }
     979             : 
     980           0 : void forward_sq_blocks_to_md(
     981             :     SequenceControlSet                   *sequence_control_set_ptr,
     982             :     PictureControlSet                    *picture_control_set_ptr)
     983             : {
     984             :     uint32_t                   sb_index;
     985             :     EbBool                  split_flag;
     986             : 
     987           0 :     for (sb_index = 0; sb_index < sequence_control_set_ptr->sb_tot_cnt; ++sb_index)
     988             :     {
     989           0 :         MdcLcuData *resultsPtr = &picture_control_set_ptr->mdc_sb_array[sb_index];
     990             : 
     991           0 :         resultsPtr->leaf_count = 0;
     992             : 
     993           0 :         uint32_t  blk_index = picture_control_set_ptr->slice_type == I_SLICE && sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128 ? 17 : 0;
     994             : 
     995           0 :         while (blk_index < sequence_control_set_ptr->max_block_cnt)
     996             :         {
     997           0 :             split_flag = EB_TRUE;
     998             : 
     999           0 :             const BlockGeom * blk_geom = get_blk_geom_mds(blk_index);
    1000             : 
    1001             :             //if the parentSq is inside inject this block
    1002           0 :             if (sequence_control_set_ptr->sb_geom[sb_index].block_is_inside_md_scan[blk_index])
    1003             : 
    1004             :             {
    1005             :                 //int32_t offset_d1 = ns_blk_offset[(int32_t)from_shape_to_part[blk_geom->shape]]; //cu_ptr->best_d1_blk; // TOCKECK
    1006             :                 //int32_t num_d1_block = ns_blk_num[(int32_t)from_shape_to_part[blk_geom->shape]]; // context_ptr->blk_geom->totns; // TOCKECK
    1007             :                 //
    1008             :                 //                                                  // for (int32_t d1_itr = blk_it; d1_itr < blk_it + num_d1_block; d1_itr++) {
    1009             :                 // for (int32_t d1_itr = (int32_t)blk_index ; d1_itr < (int32_t)blk_index +  num_d1_block ; d1_itr++) {
    1010           0 :                 resultsPtr->leaf_data_array[resultsPtr->leaf_count].tot_d1_blocks = 1;
    1011             : 
    1012           0 :                 resultsPtr->leaf_data_array[resultsPtr->leaf_count].leaf_index = 0;//valid only for square 85 world. will be removed.
    1013           0 :                 resultsPtr->leaf_data_array[resultsPtr->leaf_count].mds_idx = blk_index;
    1014             : 
    1015           0 :                 if (blk_geom->sq_size > 4)
    1016             :                 {
    1017           0 :                     resultsPtr->leaf_data_array[resultsPtr->leaf_count++].split_flag = EB_TRUE;
    1018           0 :                     split_flag = EB_TRUE;
    1019             :                 }
    1020             :                 else {
    1021           0 :                     resultsPtr->leaf_data_array[resultsPtr->leaf_count++].split_flag = EB_FALSE;
    1022           0 :                     split_flag = EB_FALSE;
    1023             :                 }
    1024             :             }
    1025           0 :             blk_index += split_flag ? d1_depth_offset[sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128][blk_geom->depth] : ns_depth_offset[sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128][blk_geom->depth];
    1026             :         }
    1027             :     }
    1028             : 
    1029           0 :     picture_control_set_ptr->parent_pcs_ptr->average_qp = (uint8_t)picture_control_set_ptr->parent_pcs_ptr->picture_qp;
    1030           0 : }
    1031             : 
    1032           0 : void sb_forward_sq_blocks_to_md(
    1033             :     SequenceControlSet *sequence_control_set_ptr,
    1034             :     PictureControlSet  *picture_control_set_ptr,
    1035             :     uint32_t              sb_index)
    1036             : {
    1037             :     EbBool   split_flag;
    1038           0 :     MdcLcuData *resultsPtr = &picture_control_set_ptr->mdc_sb_array[sb_index];
    1039           0 :     resultsPtr->leaf_count = 0;
    1040           0 :     uint32_t  blk_index = picture_control_set_ptr->slice_type == I_SLICE && sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128 ? 17 : 0;
    1041             : 
    1042           0 :     while (blk_index < sequence_control_set_ptr->max_block_cnt)
    1043             :     {
    1044           0 :         split_flag = EB_TRUE;
    1045             : 
    1046           0 :         const BlockGeom * blk_geom = get_blk_geom_mds(blk_index);
    1047             : 
    1048           0 :         if (sequence_control_set_ptr->sb_geom[sb_index].block_is_inside_md_scan[blk_index])
    1049             :         {
    1050           0 :             resultsPtr->leaf_data_array[resultsPtr->leaf_count].tot_d1_blocks = 1;
    1051           0 :             resultsPtr->leaf_data_array[resultsPtr->leaf_count].leaf_index = 0;//valid only for square 85 world. will be removed.
    1052           0 :             resultsPtr->leaf_data_array[resultsPtr->leaf_count].mds_idx = blk_index;
    1053             : 
    1054           0 :             if (blk_geom->sq_size > 4)
    1055             :             {
    1056           0 :                 resultsPtr->leaf_data_array[resultsPtr->leaf_count++].split_flag = EB_TRUE;
    1057           0 :                 split_flag = EB_TRUE;
    1058             :             }
    1059             :             else {
    1060           0 :                 resultsPtr->leaf_data_array[resultsPtr->leaf_count++].split_flag = EB_FALSE;
    1061           0 :                 split_flag = EB_FALSE;
    1062             :             }
    1063             :         }
    1064           0 :         blk_index += split_flag ? d1_depth_offset[sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128][blk_geom->depth] : ns_depth_offset[sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128][blk_geom->depth];
    1065             :     }
    1066           0 :     picture_control_set_ptr->parent_pcs_ptr->average_qp = (uint8_t)picture_control_set_ptr->parent_pcs_ptr->picture_qp;
    1067           0 : }
    1068             : 
    1069             : #if PREDICT_NSQ_SHAPE
    1070             : #if ADD_MDC_REFINEMENT_LOOP
    1071             : #if MDC_ADAPTIVE_LEVEL
    1072       77422 : void  set_parent_to_be_considered(
    1073             :     MdcLcuData *resultsPtr,
    1074             :     uint32_t    blk_index,
    1075             :     int32_t     sb_size,
    1076             :     int8_t      depth_step) {
    1077             :     uint32_t  parent_depth_idx_mds, block_1d_idx;
    1078       77422 :     const BlockGeom * blk_geom = get_blk_geom_mds(blk_index);
    1079       77422 :     if (blk_geom->sq_size < ((sb_size == BLOCK_128X128) ? 128 : 64)) {
    1080             :         //Set parent to be considered
    1081       71246 :         parent_depth_idx_mds = (blk_geom->sqi_mds - (blk_geom->quadi - 3) * ns_depth_offset[sb_size == BLOCK_128X128][blk_geom->depth]) - parent_depth_offset[sb_size == BLOCK_128X128][blk_geom->depth];
    1082       71246 :         const BlockGeom * parent_blk_geom = get_blk_geom_mds(parent_depth_idx_mds);
    1083       71246 :         uint32_t parent_tot_d1_blocks =
    1084      142492 :             parent_blk_geom->sq_size == 128 ? 17 :
    1085       71246 :             parent_blk_geom->sq_size > 8 ? 25 :
    1086       55864 :             parent_blk_geom->sq_size == 8 ? 5 : 1;
    1087      735116 :         for (block_1d_idx = 0; block_1d_idx < parent_tot_d1_blocks; block_1d_idx++) {
    1088      663870 :             resultsPtr->leaf_data_array[parent_depth_idx_mds + block_1d_idx].consider_block = 1;
    1089             :         }
    1090             : 
    1091       71246 :         if (depth_step < -1)
    1092        7654 :             set_parent_to_be_considered(
    1093             :                 resultsPtr,
    1094             :                 parent_depth_idx_mds,
    1095             :                 sb_size,
    1096        7654 :                 depth_step + 1);
    1097             :     }
    1098       77422 : }
    1099             : #endif
    1100             : 
    1101      122172 : void set_child_to_be_considered(
    1102             :     MdcLcuData *resultsPtr,
    1103             :     uint32_t    blk_index,
    1104             :     int32_t     sb_size,
    1105             :     int8_t      depth_step) {
    1106             :     uint32_t child_block_idx_1, child_block_idx_2, child_block_idx_3, child_block_idx_4;
    1107             :     uint32_t tot_d1_blocks, block_1d_idx;
    1108      122172 :     const BlockGeom * blk_geom = get_blk_geom_mds(blk_index);
    1109      122172 :     tot_d1_blocks =
    1110      244344 :         blk_geom->sq_size == 128 ? 17 :
    1111      122172 :         blk_geom->sq_size > 8 ? 25 :
    1112      104242 :         blk_geom->sq_size == 8 ? 5 : 1;
    1113      122172 :     if (blk_geom->sq_size > 4) {
    1114      615136 :         for (block_1d_idx = 0; block_1d_idx < tot_d1_blocks; block_1d_idx++) {
    1115      572380 :             resultsPtr->leaf_data_array[blk_index + block_1d_idx].consider_block = 1;
    1116      572380 :             resultsPtr->leaf_data_array[blk_index + block_1d_idx].refined_split_flag = EB_TRUE;
    1117             :         }
    1118             :         //Set first child to be considered
    1119       42756 :         child_block_idx_1 = blk_index + d1_depth_offset[sb_size == BLOCK_128X128][blk_geom->depth];
    1120       42756 :         const BlockGeom * child1_blk_geom = get_blk_geom_mds(child_block_idx_1);
    1121       42756 :         uint32_t child1_tot_d1_blocks =
    1122       85512 :             child1_blk_geom->sq_size == 128 ? 17 :
    1123       42756 :             child1_blk_geom->sq_size > 8 ? 25 :
    1124       34744 :             child1_blk_geom->sq_size == 8 ? 5 : 1;
    1125             : 
    1126      317472 :         for (block_1d_idx = 0; block_1d_idx < child1_tot_d1_blocks; block_1d_idx++) {
    1127      274716 :             resultsPtr->leaf_data_array[child_block_idx_1 + block_1d_idx].consider_block = 1;
    1128      274716 :             resultsPtr->leaf_data_array[child_block_idx_1 + block_1d_idx].refined_split_flag = EB_FALSE;
    1129             :         }
    1130       42756 :         if (depth_step > 1)
    1131       13177 :             set_child_to_be_considered(
    1132             :                 resultsPtr,
    1133             :                 child_block_idx_1,
    1134             :                 sb_size,
    1135       13177 :                 depth_step - 1);
    1136             :         //Set second child to be considered
    1137       42756 :         child_block_idx_2 = child_block_idx_1 + ns_depth_offset[sb_size == BLOCK_128X128][blk_geom->depth + 1];
    1138       42756 :         const BlockGeom * child2_blk_geom = get_blk_geom_mds(child_block_idx_2);
    1139       42756 :         uint32_t child2_tot_d1_blocks =
    1140       85512 :             child2_blk_geom->sq_size == 128 ? 17 :
    1141       42756 :             child2_blk_geom->sq_size > 8 ? 25 :
    1142       34744 :             child2_blk_geom->sq_size == 8 ? 5 : 1;
    1143      317472 :         for (block_1d_idx = 0; block_1d_idx < child2_tot_d1_blocks; block_1d_idx++) {
    1144      274716 :             resultsPtr->leaf_data_array[child_block_idx_2 + block_1d_idx].consider_block = 1;
    1145      274716 :             resultsPtr->leaf_data_array[child_block_idx_2 + block_1d_idx].refined_split_flag = EB_FALSE;
    1146             :         }
    1147       42756 :         if (depth_step > 1)
    1148       13177 :             set_child_to_be_considered(
    1149             :                 resultsPtr,
    1150             :                 child_block_idx_2,
    1151             :                 sb_size,
    1152       13177 :                 depth_step - 1);
    1153             :         //Set third child to be considered
    1154       42756 :         child_block_idx_3 = child_block_idx_2 + ns_depth_offset[sb_size == BLOCK_128X128][blk_geom->depth + 1];
    1155       42756 :         const BlockGeom * child3_blk_geom = get_blk_geom_mds(child_block_idx_3);
    1156       42756 :         uint32_t child3_tot_d1_blocks =
    1157       85512 :             child3_blk_geom->sq_size == 128 ? 17 :
    1158       42756 :             child3_blk_geom->sq_size > 8 ? 25 :
    1159       34744 :             child3_blk_geom->sq_size == 8 ? 5 : 1;
    1160             : 
    1161      317472 :         for (block_1d_idx = 0; block_1d_idx < child3_tot_d1_blocks; block_1d_idx++) {
    1162      274716 :             resultsPtr->leaf_data_array[child_block_idx_3 + block_1d_idx].consider_block = 1;
    1163      274716 :             resultsPtr->leaf_data_array[child_block_idx_3 + block_1d_idx].refined_split_flag = EB_FALSE;
    1164             :         }
    1165       42756 :         if (depth_step > 1)
    1166       13177 :             set_child_to_be_considered(
    1167             :                 resultsPtr,
    1168             :                 child_block_idx_3,
    1169             :                 sb_size,
    1170       13177 :                 depth_step - 1);
    1171             :         //Set forth child to be considered
    1172       42756 :         child_block_idx_4 = child_block_idx_3 + ns_depth_offset[sb_size == BLOCK_128X128][blk_geom->depth + 1];
    1173       42756 :         const BlockGeom * child4_blk_geom = get_blk_geom_mds(child_block_idx_4);
    1174       42756 :         uint32_t child4_tot_d1_blocks =
    1175       85512 :             child4_blk_geom->sq_size == 128 ? 17 :
    1176       42756 :             child4_blk_geom->sq_size > 8 ? 25 :
    1177       34744 :             child4_blk_geom->sq_size == 8 ? 5 : 1;
    1178      317472 :         for (block_1d_idx = 0; block_1d_idx < child4_tot_d1_blocks; block_1d_idx++) {
    1179      274716 :             resultsPtr->leaf_data_array[child_block_idx_4 + block_1d_idx].consider_block = 1;
    1180      274716 :             resultsPtr->leaf_data_array[child_block_idx_4 + block_1d_idx].refined_split_flag = EB_FALSE;
    1181             :         }
    1182       42756 :         if (depth_step > 1)
    1183       13177 :             set_child_to_be_considered(
    1184             :                 resultsPtr,
    1185             :                 child_block_idx_4,
    1186             :                 sb_size,
    1187       13177 :                 depth_step - 1);
    1188             :     }
    1189      122172 : }
    1190             : 
    1191             : #if MDC_ADAPTIVE_LEVEL
    1192             : #define MDC_COST_WEIGHT 50000
    1193             : 
    1194             : uint64_t  mdc_tab[9][2][3] = {
    1195             :     {{150,80,40},{150,80,40}},
    1196             :     {{150,80,40},{150,80,40}},
    1197             :     {{100,20,0},{150,50,0}},
    1198             :     {{100,20,0},{150,50,0}},
    1199             :     {{100,20,0},{150,50,0}},
    1200             :     {{100,20,0},{150,50,0}},
    1201             :     {{100,20,0},{150,50,0}},
    1202             :     {{100,20,0},{150,50,0}},
    1203             :     {{100,20,0},{150,50,0}}
    1204             : };
    1205             : 
    1206             : // Update MDC refinement
    1207        8081 : uint8_t update_mdc_level(
    1208             :     PictureControlSet  *picture_control_set_ptr,
    1209             :     LargestCodingUnit  *sb_ptr,
    1210             :     uint32_t sb_size,
    1211             :     const BlockGeom * blk_geom,
    1212             :     uint8_t mdc_depth_level) {
    1213        8081 :     uint8_t depth_offset = sb_size == BLOCK_128X128 ? 0 : 1;
    1214        8081 :     int8_t depth = blk_geom->depth + depth_offset;
    1215        8081 :     uint8_t adjusted_depth_level = mdc_depth_level;
    1216        8081 :     uint8_t depth_refinement_mode = mdc_depth_level;
    1217        8081 :     uint8_t encode_mode = picture_control_set_ptr->parent_pcs_ptr->enc_mode;
    1218        8081 :     int8_t start_depth = sb_size == BLOCK_128X128 ? 0 : 1;
    1219        8081 :     int8_t end_depth = 5;
    1220        8081 :     int8_t depthp1 = depth + 1 <= end_depth ? depth + 1 : depth;
    1221        8081 :     int8_t depthp2 = depth + 2 <= end_depth ? depth + 2 : depth + 1 <= end_depth ? depth + 1 : depth;
    1222        8081 :     int8_t depthp3 = depth + 3 <= end_depth ? depth + 3 : depth + 2 <= end_depth ? depth + 2 : depth + 1 <= end_depth ? depth + 1 : depth;
    1223        8081 :     uint8_t depthm1 = depth - 1 >= start_depth ? depth - 1 : depth;
    1224        8081 :     uint8_t depthm2 = depth - 2 >= start_depth ? depth - 2 : depth - 1 >= start_depth ? depth - 1 : depth;
    1225        8081 :     uint8_t depthm3 = depth - 3 >= start_depth ? depth - 3 : depth - 2 >= start_depth ? depth - 2 : depth - 1 >= start_depth ? depth - 1 : depth;
    1226        8081 :     adjusted_depth_level = 13;
    1227             : 
    1228        8081 :     uint64_t max_distance = 0xFFFFFFFFFFFFFFFF;
    1229        8081 :     uint64_t mth01 = mdc_tab[encode_mode][0][0];
    1230        8081 :     uint64_t mth02 = mdc_tab[encode_mode][0][1];
    1231        8081 :     uint64_t mth03 = mdc_tab[encode_mode][0][2];
    1232        8081 :     uint64_t pth01 = mdc_tab[encode_mode][1][0];
    1233        8081 :     uint64_t pth02 = mdc_tab[encode_mode][1][1];
    1234        8081 :     uint64_t pth03 = mdc_tab[encode_mode][1][2];
    1235        8081 :     uint64_t dist_001 = sb_ptr->depth_cost[depth] != 0 ? (ABS((int64_t)sb_ptr->depth_cost[depth] - (int64_t)sb_ptr->depth_cost[depthp1]) * 100) / sb_ptr->depth_cost[depth] : max_distance;
    1236        8081 :     uint64_t dist_100 = sb_ptr->depth_cost[depth] != 0 ? (ABS((int64_t)sb_ptr->depth_cost[depth] - (int64_t)sb_ptr->depth_cost[depthm1]) * 100) / sb_ptr->depth_cost[depth] : max_distance;
    1237        8081 :     uint64_t dist_002 = sb_ptr->depth_cost[depth] != 0 ? (ABS((int64_t)sb_ptr->depth_cost[depth] - (int64_t)sb_ptr->depth_cost[depthp2]) * 100) / sb_ptr->depth_cost[depth] : max_distance;
    1238        8081 :     uint64_t dist_200 = sb_ptr->depth_cost[depth] != 0 ? (ABS((int64_t)sb_ptr->depth_cost[depth] - (int64_t)sb_ptr->depth_cost[depthm2]) * 100) / sb_ptr->depth_cost[depth] : max_distance;
    1239        8081 :     uint64_t dist_003 = sb_ptr->depth_cost[depth] != 0 ? (ABS((int64_t)sb_ptr->depth_cost[depth] - (int64_t)sb_ptr->depth_cost[depthp3]) * 100) / sb_ptr->depth_cost[depth] : max_distance;
    1240        8081 :     uint64_t dist_300 = sb_ptr->depth_cost[depth] != 0 ? (ABS((int64_t)sb_ptr->depth_cost[depth] - (int64_t)sb_ptr->depth_cost[depthm3]) * 100) / sb_ptr->depth_cost[depth] : max_distance;
    1241             : 
    1242        8081 :     int8_t s_depth = -3;
    1243        8081 :     int8_t e_depth = 3;
    1244        8081 :     if (dist_300 < mth03)
    1245        6596 :         s_depth = -3;
    1246        1485 :     else if (dist_200 < mth02)
    1247        1104 :         s_depth = -2;
    1248         381 :     else if (dist_100 < mth01)
    1249         381 :         s_depth = -1;
    1250             :     else
    1251           0 :         s_depth = 0;
    1252             : 
    1253        8081 :     if (dist_003 < pth03)
    1254         447 :         e_depth = 3;
    1255        7634 :     else if (dist_002 < pth02)
    1256        1527 :         e_depth = 2;
    1257        6107 :     else if (dist_001 < pth01)
    1258        4706 :         e_depth = 1;
    1259             :     else
    1260        1401 :         e_depth = 0;
    1261             : 
    1262        8081 :     if (s_depth == 0 && e_depth == 0)
    1263           0 :         adjusted_depth_level = 0; // Pred only
    1264        8081 :     else if (s_depth == -1 && e_depth == 0)
    1265         156 :         adjusted_depth_level = 8; // Pred -1
    1266        7925 :     else if (s_depth == -2 && e_depth == 0)
    1267         148 :         adjusted_depth_level = 9; // Pred -2
    1268        7777 :     else if (s_depth == -3 && e_depth == 0)
    1269        1097 :         adjusted_depth_level = 14; // Pred -3
    1270        6680 :     else if (s_depth == -3 && e_depth == 1)
    1271        3660 :         adjusted_depth_level = 15; // Pred -3 + 1
    1272        3020 :     else if (s_depth == -2 && e_depth == 1)
    1273         822 :         adjusted_depth_level = 10; // Pred -2 + 1
    1274        2198 :     else if (s_depth == -1 && e_depth == 1)
    1275         224 :         adjusted_depth_level = 4; // Pred -1 + 1
    1276        1974 :     else if (s_depth == 0 && e_depth == 1)
    1277           0 :         adjusted_depth_level = 1; // Pred + 1
    1278        1974 :     else if (s_depth == -3 && e_depth == 2)
    1279        1432 :         adjusted_depth_level = 12; // Pred -3 + 2
    1280         542 :     else if (s_depth == -2 && e_depth == 2)
    1281          94 :         adjusted_depth_level = 11; // Pred -2 + 2
    1282         448 :     else if (s_depth == -1 && e_depth == 2)
    1283           1 :         adjusted_depth_level = 5; // Pred -1 + 2
    1284         447 :     else if (s_depth == 0 && e_depth == 2)
    1285           0 :         adjusted_depth_level = 2; // Pred + 2
    1286         447 :     else if (s_depth == -3 && e_depth == 3)
    1287         407 :         adjusted_depth_level = 13; // Pred -3 + 3
    1288          40 :     else if (s_depth == -2 && e_depth == 3)
    1289          40 :         adjusted_depth_level = 7; // Pred -2 + 3
    1290           0 :     else if (s_depth == -1 && e_depth == 3)
    1291           0 :         adjusted_depth_level = 6; // Pred -1 + 3
    1292           0 :     else if (s_depth == 0 && e_depth == 3)
    1293           0 :         adjusted_depth_level = 3; // Pred + 3
    1294             :     else
    1295           0 :         printf("Error: unvalid s_depth && e_depth");
    1296             : 
    1297        8081 :     switch (adjusted_depth_level) {
    1298           0 :     case 0:
    1299           0 :         depth_refinement_mode = Pred;
    1300           0 :         break;
    1301           0 :     case 1:
    1302           0 :         depth_refinement_mode = Predp1;
    1303           0 :         break;
    1304           0 :     case 2:
    1305           0 :         depth_refinement_mode = Predp2;
    1306           0 :         break;
    1307           0 :     case 3:
    1308           0 :         depth_refinement_mode = Predp3;
    1309           0 :         break;
    1310         224 :     case 4:
    1311         224 :         depth_refinement_mode = Predm1p1;
    1312         224 :         break;
    1313           1 :     case 5:
    1314           1 :         depth_refinement_mode = Predm1p2;
    1315           1 :         break;
    1316           0 :     case 6:
    1317           0 :         depth_refinement_mode = Predm1p3;
    1318           0 :         break;
    1319          40 :     case 7:
    1320          40 :         depth_refinement_mode = Predm2p3;
    1321          40 :         break;
    1322         156 :     case 8:
    1323         156 :         depth_refinement_mode = Predm1;
    1324         156 :         break;
    1325         148 :     case 9:
    1326         148 :         depth_refinement_mode = Predm2;
    1327         148 :         break;
    1328         822 :     case 10:
    1329         822 :         depth_refinement_mode = Predm2p1;
    1330         822 :         break;
    1331          94 :     case 11:
    1332          94 :         depth_refinement_mode = Predm2p2;
    1333          94 :         break;
    1334        1432 :     case 12:
    1335        1432 :         depth_refinement_mode = Predm3p2;
    1336        1432 :         break;
    1337         407 :     case 13:
    1338         407 :         depth_refinement_mode = Predm3p3;
    1339         407 :         break;
    1340        1097 :     case 14:
    1341        1097 :         depth_refinement_mode = Predm3;
    1342        1097 :         break;
    1343        3660 :     case 15:
    1344        3660 :         depth_refinement_mode = Predm3p1;
    1345        3660 :         break;
    1346           0 :     default:
    1347           0 :         printf("Not supported refined mdc_depth_level");
    1348           0 :         break;
    1349             :     }
    1350        8081 :     return depth_refinement_mode;
    1351             : }
    1352             : #endif
    1353        3480 : void init_considered_block(
    1354             :     SequenceControlSet *sequence_control_set_ptr,
    1355             :     PictureControlSet  *picture_control_set_ptr,
    1356             :     ModeDecisionConfigurationContext *context_ptr,
    1357             :     uint32_t            sb_index) {
    1358        3480 :     MdcLcuData *resultsPtr = &picture_control_set_ptr->mdc_sb_array[sb_index];
    1359        3480 :     resultsPtr->leaf_count = 0;
    1360        3480 :     uint32_t  blk_index = 0;
    1361             : 
    1362             : #if MDC_ADAPTIVE_LEVEL
    1363        3480 :     LargestCodingUnit  *sb_ptr = picture_control_set_ptr->sb_ptr_array[sb_index];
    1364             : #else
    1365             :     uint32_t  parent_depth_idx_mds, sparent_depth_idx_mds, ssparent_depth_idx_mds, child_block_idx_1, child_block_idx_2, child_block_idx_3, child_block_idx_4;
    1366             : #endif
    1367        3480 :     SbParams *sb_params = &sequence_control_set_ptr->sb_params_array[sb_index];
    1368        3480 :     uint8_t  is_complete_sb = sb_params->is_complete_sb;
    1369             :     uint32_t tot_d1_blocks, block_1d_idx;
    1370             :     EbBool split_flag;
    1371             : #if MDC_ADAPTIVE_LEVEL
    1372        3480 :     uint32_t depth_refinement_mode = Predm1p3;
    1373             : #else
    1374             :     uint32_t depth_refinement_mode = AllD;
    1375             : 
    1376             :     switch (picture_control_set_ptr->parent_pcs_ptr->mdc_depth_level) {
    1377             :     case 0:
    1378             :         depth_refinement_mode = is_complete_sb ? Pred : AllD;
    1379             :         break;
    1380             :     case 1:
    1381             :         depth_refinement_mode = is_complete_sb ? Predp1 : AllD;
    1382             :         break;
    1383             :     case 2:
    1384             :         depth_refinement_mode = is_complete_sb ? Predp2 : AllD;
    1385             :         break;
    1386             :     case 3:
    1387             :         depth_refinement_mode = is_complete_sb ? Predp3 : AllD;
    1388             :         break;
    1389             :     case 4:
    1390             :         depth_refinement_mode = is_complete_sb ? Predm1p1 : AllD;
    1391             :         break;
    1392             :     case 5:
    1393             :         depth_refinement_mode = is_complete_sb ? Predm1p2 : AllD;
    1394             :         break;
    1395             :     case 6:
    1396             :         depth_refinement_mode = is_complete_sb ? Predm1p3 : AllD;
    1397             :         break;
    1398             :     case 7:
    1399             :         depth_refinement_mode = is_complete_sb ? Predm2p3 : AllD;
    1400             :         break;
    1401             :     case MAX_MDC_LEVEL:
    1402             :         depth_refinement_mode = AllD;
    1403             :         break;
    1404             :     default:
    1405             :         printf("not supported mdc_depth_level");
    1406             :         break;
    1407             :     }
    1408             : #endif
    1409       95344 :     while (blk_index < sequence_control_set_ptr->max_block_cnt) {
    1410       91864 :         const BlockGeom * blk_geom = get_blk_geom_mds(blk_index);
    1411       91864 :         tot_d1_blocks =
    1412      183728 :             blk_geom->sq_size == 128 ? 17 :
    1413       91864 :             blk_geom->sq_size > 8 ? 25 :
    1414       75184 :             blk_geom->sq_size == 8 ? 5 : 1;
    1415             :         //if the parent square is inside inject this block
    1416       91864 :         uint8_t is_blk_allowed = picture_control_set_ptr->slice_type != I_SLICE ? 1 : (blk_geom->sq_size < 128) ? 1 : 0;
    1417       91864 :         if (depth_refinement_mode == AllD)
    1418           0 :             split_flag = blk_geom->sq_size > 4 ? EB_TRUE : EB_FALSE;
    1419             :         else
    1420       91864 :             split_flag = context_ptr->local_cu_array[blk_index].early_split_flag;
    1421       91864 :         if (sequence_control_set_ptr->sb_geom[sb_index].block_is_inside_md_scan[blk_index] && is_blk_allowed) {
    1422       91864 :             if (blk_geom->shape == PART_N) {
    1423             : #if MDC_ADAPTIVE_LEVEL
    1424             :                 // Update MDC refinement
    1425       91864 :                 uint8_t adjusted_refinement_mode = depth_refinement_mode;
    1426       91864 :                 if (picture_control_set_ptr->parent_pcs_ptr->enable_adaptive_ol_partitioning)
    1427       91864 :                     if (is_complete_sb && (context_ptr->local_cu_array[blk_index].early_split_flag == EB_FALSE))
    1428        8081 :                         adjusted_refinement_mode = update_mdc_level(
    1429             :                             picture_control_set_ptr,
    1430             :                             sb_ptr,
    1431        8081 :                             sequence_control_set_ptr->seq_header.sb_size,
    1432             :                             blk_geom,
    1433             :                             depth_refinement_mode);
    1434             : 
    1435       91864 :                 switch (adjusted_refinement_mode) {
    1436             : #else
    1437             :                 switch (depth_refinement_mode) {
    1438             : #endif
    1439           0 :                 case Pred:
    1440             :                     // Set predicted block to be considered
    1441           0 :                     if (context_ptr->local_cu_array[blk_index].early_split_flag == EB_FALSE) {
    1442           0 :                         for (block_1d_idx = 0; block_1d_idx < tot_d1_blocks; block_1d_idx++) {
    1443             :                             // NADER - FORCE SHAPE
    1444           0 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].consider_block = 1;
    1445           0 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].refined_split_flag = EB_FALSE;
    1446             :                         }
    1447             :                     }
    1448           0 :                     break;
    1449           0 :                 case Predp1:
    1450           0 :                     if (context_ptr->local_cu_array[blk_index].early_split_flag == EB_FALSE) {
    1451           0 :                         for (block_1d_idx = 0; block_1d_idx < tot_d1_blocks; block_1d_idx++) {
    1452           0 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].consider_block = 1;
    1453           0 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].refined_split_flag = EB_FALSE;
    1454             :                         }
    1455           0 :                         set_child_to_be_considered(
    1456             :                             resultsPtr,
    1457             :                             blk_index,
    1458           0 :                             sequence_control_set_ptr->seq_header.sb_size,
    1459             :                             1);
    1460             :                     }
    1461           0 :                     break;
    1462           0 :                 case Predp2:
    1463           0 :                     if (context_ptr->local_cu_array[blk_index].early_split_flag == EB_FALSE) {
    1464           0 :                         for (block_1d_idx = 0; block_1d_idx < tot_d1_blocks; block_1d_idx++) {
    1465           0 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].consider_block = 1;
    1466           0 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].refined_split_flag = EB_FALSE;
    1467             :                         }
    1468           0 :                         set_child_to_be_considered(
    1469             :                             resultsPtr,
    1470             :                             blk_index,
    1471           0 :                             sequence_control_set_ptr->seq_header.sb_size,
    1472             :                             2);
    1473             :                     }
    1474           0 :                     break;
    1475           0 :                 case Predp3:
    1476           0 :                     if (context_ptr->local_cu_array[blk_index].early_split_flag == EB_FALSE) {
    1477           0 :                         for (block_1d_idx = 0; block_1d_idx < tot_d1_blocks; block_1d_idx++) {
    1478           0 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].consider_block = 1;
    1479           0 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].refined_split_flag = EB_FALSE;
    1480             :                         }
    1481           0 :                         set_child_to_be_considered(
    1482             :                             resultsPtr,
    1483             :                             blk_index,
    1484           0 :                             sequence_control_set_ptr->seq_header.sb_size,
    1485             :                             3);
    1486             :                     }
    1487           0 :                     break;
    1488           1 :                 case Predm1p2:
    1489           1 :                     if (context_ptr->local_cu_array[blk_index].early_split_flag == EB_FALSE) {
    1490          26 :                         for (block_1d_idx = 0; block_1d_idx < tot_d1_blocks; block_1d_idx++) {
    1491          25 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].consider_block = 1;
    1492          25 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].refined_split_flag = EB_FALSE;
    1493             :                         }
    1494             : #if MDC_ADAPTIVE_LEVEL
    1495           1 :                         set_parent_to_be_considered(
    1496             :                             resultsPtr,
    1497             :                             blk_index,
    1498           1 :                             sequence_control_set_ptr->seq_header.sb_size,
    1499             :                             -1);
    1500             : #else
    1501             :                         if (blk_geom->sq_size < (sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128 ? 128 : 64) && blk_geom->sq_size > 4) {
    1502             :                             //Set parent to be considered
    1503             :                             parent_depth_idx_mds = (blk_geom->sqi_mds - (blk_geom->quadi - 3) * ns_depth_offset[sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128][blk_geom->depth]) - parent_depth_offset[sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128][blk_geom->depth];
    1504             :                             const BlockGeom * parent_blk_geom = get_blk_geom_mds(parent_depth_idx_mds);
    1505             :                             uint32_t parent_tot_d1_blocks =
    1506             :                                 parent_blk_geom->sq_size == 128 ? 17 :
    1507             :                                 parent_blk_geom->sq_size > 8 ? 25 :
    1508             :                                 parent_blk_geom->sq_size == 8 ? 5 : 1;
    1509             :                             for (block_1d_idx = 0; block_1d_idx < parent_tot_d1_blocks; block_1d_idx++) {
    1510             :                                 resultsPtr->leaf_data_array[parent_depth_idx_mds + block_1d_idx].consider_block = 1;
    1511             :                             }
    1512             :                         }
    1513             : #endif
    1514          26 :                         for (block_1d_idx = 0; block_1d_idx < tot_d1_blocks; block_1d_idx++) {
    1515          25 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].consider_block = 1;
    1516          25 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].refined_split_flag = EB_FALSE;
    1517             :                         }
    1518           1 :                         set_child_to_be_considered(
    1519             :                             resultsPtr,
    1520             :                             blk_index,
    1521           1 :                             sequence_control_set_ptr->seq_header.sb_size,
    1522             :                             2);
    1523             :                     }
    1524           1 :                     break;
    1525       83783 :                 case Predm1p3:
    1526       83783 :                     if (context_ptr->local_cu_array[blk_index].early_split_flag == EB_FALSE) {
    1527      172790 :                         for (block_1d_idx = 0; block_1d_idx < tot_d1_blocks; block_1d_idx++) {
    1528      111103 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].consider_block = 1;
    1529      111103 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].refined_split_flag = EB_FALSE;
    1530             :                         }
    1531             : #if MDC_ADAPTIVE_LEVEL
    1532       61687 :                         set_parent_to_be_considered(
    1533             :                             resultsPtr,
    1534             :                             blk_index,
    1535       61687 :                             sequence_control_set_ptr->seq_header.sb_size,
    1536             :                             -1);
    1537             : #else
    1538             :                         if (blk_geom->sq_size < (sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128 ? 128 : 64) && blk_geom->sq_size > 4) {
    1539             :                             //Set parent to be considered
    1540             :                             parent_depth_idx_mds = (blk_geom->sqi_mds - (blk_geom->quadi - 3) * ns_depth_offset[sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128][blk_geom->depth]) - parent_depth_offset[sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128][blk_geom->depth];
    1541             :                             const BlockGeom * parent_blk_geom = get_blk_geom_mds(parent_depth_idx_mds);
    1542             :                             uint32_t parent_tot_d1_blocks =
    1543             :                                 parent_blk_geom->sq_size == 128 ? 17 :
    1544             :                                 parent_blk_geom->sq_size > 8 ? 25 :
    1545             :                                 parent_blk_geom->sq_size == 8 ? 5 : 1;
    1546             :                             for (block_1d_idx = 0; block_1d_idx < parent_tot_d1_blocks; block_1d_idx++) {
    1547             :                                 resultsPtr->leaf_data_array[parent_depth_idx_mds + block_1d_idx].consider_block = 1;
    1548             :                             }
    1549             :                         }
    1550             : #endif
    1551      172790 :                         for (block_1d_idx = 0; block_1d_idx < tot_d1_blocks; block_1d_idx++) {
    1552      111103 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].consider_block = 1;
    1553      111103 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].refined_split_flag = EB_FALSE;
    1554             :                         }
    1555       61687 :                         set_child_to_be_considered(
    1556             :                             resultsPtr,
    1557             :                             blk_index,
    1558       61687 :                             sequence_control_set_ptr->seq_header.sb_size,
    1559             :                             3);
    1560             :                     }
    1561       83783 :                     break;
    1562          40 :                 case Predm2p3:
    1563          40 :                     if (context_ptr->local_cu_array[blk_index].early_split_flag == EB_FALSE) {
    1564          80 :                         for (block_1d_idx = 0; block_1d_idx < tot_d1_blocks; block_1d_idx++) {
    1565          40 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].consider_block = 1;
    1566          40 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].refined_split_flag = EB_FALSE;
    1567             :                         }
    1568             : #if MDC_ADAPTIVE_LEVEL
    1569          40 :                         set_parent_to_be_considered(
    1570             :                             resultsPtr,
    1571             :                             blk_index,
    1572          40 :                             sequence_control_set_ptr->seq_header.sb_size,
    1573             :                             -2);
    1574             : #else
    1575             :                         if (blk_geom->sq_size < (sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128 ? 128 : 64) && blk_geom->sq_size > 4) {
    1576             :                             //Set parent to be considered
    1577             :                             parent_depth_idx_mds = (blk_geom->sqi_mds - (blk_geom->quadi - 3) * ns_depth_offset[sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128][blk_geom->depth]) - parent_depth_offset[sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128][blk_geom->depth];
    1578             :                             const BlockGeom * parent_blk_geom = get_blk_geom_mds(parent_depth_idx_mds);
    1579             :                             uint32_t parent_tot_d1_blocks =
    1580             :                                 parent_blk_geom->sq_size == 128 ? 17 :
    1581             :                                 parent_blk_geom->sq_size > 8 ? 25 :
    1582             :                                 parent_blk_geom->sq_size == 8 ? 5 : 1;
    1583             :                             for (block_1d_idx = 0; block_1d_idx < parent_tot_d1_blocks; block_1d_idx++) {
    1584             :                                 resultsPtr->leaf_data_array[parent_depth_idx_mds + block_1d_idx].consider_block = 1;
    1585             :                             }
    1586             :                             if (parent_blk_geom->sq_size < (sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128 ? 128 : 64) && parent_blk_geom->sq_size > 4) {
    1587             :                                 //Set parent to be considered
    1588             :                                 sparent_depth_idx_mds = (parent_blk_geom->sqi_mds - (parent_blk_geom->quadi - 3) * ns_depth_offset[sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128][parent_blk_geom->depth]) - parent_depth_offset[sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128][parent_blk_geom->depth];
    1589             :                                 uint32_t sparent_tot_d1_blocks =
    1590             :                                     parent_blk_geom->sq_size == 128 ? 17 :
    1591             :                                     parent_blk_geom->sq_size > 8 ? 25 :
    1592             :                                     parent_blk_geom->sq_size == 8 ? 5 : 1;
    1593             :                                 for (block_1d_idx = 0; block_1d_idx < sparent_tot_d1_blocks; block_1d_idx++)
    1594             :                                     resultsPtr->leaf_data_array[sparent_depth_idx_mds + block_1d_idx].consider_block = 1;
    1595             :                             }
    1596             :                         }
    1597             : #endif
    1598          80 :                         for (block_1d_idx = 0; block_1d_idx < tot_d1_blocks; block_1d_idx++) {
    1599          40 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].consider_block = 1;
    1600          40 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].refined_split_flag = EB_FALSE;
    1601             :                         }
    1602          40 :                         set_child_to_be_considered(
    1603             :                             resultsPtr,
    1604             :                             blk_index,
    1605          40 :                             sequence_control_set_ptr->seq_header.sb_size,
    1606             :                             3);
    1607             :                     }
    1608          40 :                     break;
    1609         156 :                 case Predm1:
    1610             :                     // Set predicted block to be considered
    1611         156 :                     if (context_ptr->local_cu_array[blk_index].early_split_flag == EB_FALSE) {
    1612        4056 :                         for (block_1d_idx = 0; block_1d_idx < tot_d1_blocks; block_1d_idx++) {
    1613        3900 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].consider_block = 1;
    1614        3900 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].refined_split_flag = EB_FALSE;
    1615             :                         }
    1616             : #if MDC_ADAPTIVE_LEVEL
    1617         156 :                         set_parent_to_be_considered(
    1618             :                             resultsPtr,
    1619             :                             blk_index,
    1620         156 :                             sequence_control_set_ptr->seq_header.sb_size,
    1621             :                             -1);
    1622        4056 :                         for (block_1d_idx = 0; block_1d_idx < tot_d1_blocks; block_1d_idx++) {
    1623        3900 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].consider_block = 1;
    1624        3900 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].refined_split_flag = EB_FALSE;
    1625             :                         }
    1626             : #else
    1627             :                         if (blk_geom->sq_size < (sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128 ? 128 : 64) && blk_geom->sq_size > 4) {
    1628             :                             //Set parent to be considered
    1629             :                             parent_depth_idx_mds = (blk_geom->sqi_mds - (blk_geom->quadi - 3) * ns_depth_offset[sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128][blk_geom->depth]) - parent_depth_offset[sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128][blk_geom->depth];
    1630             :                             const BlockGeom * parent_blk_geom = get_blk_geom_mds(parent_depth_idx_mds);
    1631             :                             uint32_t parent_tot_d1_blocks =
    1632             :                                 parent_blk_geom->sq_size == 128 ? 17 :
    1633             :                                 parent_blk_geom->sq_size > 8 ? 25 :
    1634             :                                 parent_blk_geom->sq_size == 8 ? 5 : 1;
    1635             :                             for (block_1d_idx = 0; block_1d_idx < parent_tot_d1_blocks; block_1d_idx++) {
    1636             :                                 resultsPtr->leaf_data_array[parent_depth_idx_mds + block_1d_idx].consider_block = 1;
    1637             :                             }
    1638             :                         }
    1639             : #endif
    1640             :                     }
    1641         156 :                     break;
    1642         148 :                 case Predm2:
    1643         148 :                     if (context_ptr->local_cu_array[blk_index].early_split_flag == EB_FALSE) {
    1644        3288 :                         for (block_1d_idx = 0; block_1d_idx < tot_d1_blocks; block_1d_idx++) {
    1645        3140 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].consider_block = 1;
    1646        3140 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].refined_split_flag = EB_FALSE;
    1647             :                         }
    1648             : #if MDC_ADAPTIVE_LEVEL
    1649         148 :                         set_parent_to_be_considered(
    1650             :                             resultsPtr,
    1651             :                             blk_index,
    1652         148 :                             sequence_control_set_ptr->seq_header.sb_size,
    1653             :                             -2);
    1654             : 
    1655             : #else
    1656             :                         if (blk_geom->sq_size < (sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128 ? 128 : 64) && blk_geom->sq_size > 4) {
    1657             :                             //Set parent to be considered
    1658             :                             parent_depth_idx_mds = (blk_geom->sqi_mds - (blk_geom->quadi - 3) * ns_depth_offset[sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128][blk_geom->depth]) - parent_depth_offset[sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128][blk_geom->depth];
    1659             :                             const BlockGeom * parent_blk_geom = get_blk_geom_mds(parent_depth_idx_mds);
    1660             :                             uint32_t parent_tot_d1_blocks =
    1661             :                                 parent_blk_geom->sq_size == 128 ? 17 :
    1662             :                                 parent_blk_geom->sq_size > 8 ? 25 :
    1663             :                                 parent_blk_geom->sq_size == 8 ? 5 : 1;
    1664             :                             for (block_1d_idx = 0; block_1d_idx < parent_tot_d1_blocks; block_1d_idx++) {
    1665             :                                 resultsPtr->leaf_data_array[parent_depth_idx_mds + block_1d_idx].consider_block = 1;
    1666             :                             }
    1667             :                             if (parent_blk_geom->sq_size < (sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128 ? 128 : 64) && parent_blk_geom->sq_size > 4) {
    1668             :                                 //Set parent to be considered
    1669             :                                 sparent_depth_idx_mds = (parent_blk_geom->sqi_mds - (parent_blk_geom->quadi - 3) * ns_depth_offset[sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128][parent_blk_geom->depth]) - parent_depth_offset[sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128][parent_blk_geom->depth];
    1670             :                                 uint32_t sparent_tot_d1_blocks =
    1671             :                                     parent_blk_geom->sq_size == 128 ? 17 :
    1672             :                                     parent_blk_geom->sq_size > 8 ? 25 :
    1673             :                                     parent_blk_geom->sq_size == 8 ? 5 : 1;
    1674             :                                 for (block_1d_idx = 0; block_1d_idx < sparent_tot_d1_blocks; block_1d_idx++)
    1675             :                                     resultsPtr->leaf_data_array[sparent_depth_idx_mds + block_1d_idx].consider_block = 1;
    1676             :                             }
    1677             :                         }
    1678             : #endif
    1679        3288 :                         for (block_1d_idx = 0; block_1d_idx < tot_d1_blocks; block_1d_idx++) {
    1680        3140 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].consider_block = 1;
    1681        3140 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].refined_split_flag = EB_FALSE;
    1682             :                         }
    1683             :                     }
    1684         148 :                     break;
    1685         224 :                 case Predm1p1:
    1686             :                     // Set predicted block to be considered
    1687         224 :                     if (context_ptr->local_cu_array[blk_index].early_split_flag == EB_FALSE) {
    1688        5824 :                         for (block_1d_idx = 0; block_1d_idx < tot_d1_blocks; block_1d_idx++) {
    1689        5600 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].consider_block = 1;
    1690        5600 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].refined_split_flag = EB_FALSE;
    1691             :                         }
    1692             : #if MDC_ADAPTIVE_LEVEL
    1693         224 :                         set_parent_to_be_considered(
    1694             :                             resultsPtr,
    1695             :                             blk_index,
    1696         224 :                             sequence_control_set_ptr->seq_header.sb_size,
    1697             :                             -1);
    1698        5824 :                         for (block_1d_idx = 0; block_1d_idx < tot_d1_blocks; block_1d_idx++) {
    1699        5600 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].consider_block = 1;
    1700        5600 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].refined_split_flag = EB_FALSE;
    1701             :                         }
    1702         224 :                         set_child_to_be_considered(
    1703             :                             resultsPtr,
    1704             :                             blk_index,
    1705         224 :                             sequence_control_set_ptr->seq_header.sb_size,
    1706             :                             1);
    1707             : #else
    1708             :                         if (blk_geom->sq_size < (sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128 ? 128 : 64) && blk_geom->sq_size > 4) {
    1709             :                             //Set parent to be considered
    1710             :                             parent_depth_idx_mds = (blk_geom->sqi_mds - (blk_geom->quadi - 3) * ns_depth_offset[sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128][blk_geom->depth]) - parent_depth_offset[sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128][blk_geom->depth];
    1711             :                             const BlockGeom * parent_blk_geom = get_blk_geom_mds(parent_depth_idx_mds);
    1712             :                             uint32_t parent_tot_d1_blocks =
    1713             :                                 parent_blk_geom->sq_size == 128 ? 17 :
    1714             :                                 parent_blk_geom->sq_size > 8 ? 25 :
    1715             :                                 parent_blk_geom->sq_size == 8 ? 5 : 1;
    1716             :                             for (block_1d_idx = 0; block_1d_idx < parent_tot_d1_blocks; block_1d_idx++) {
    1717             :                                 resultsPtr->leaf_data_array[parent_depth_idx_mds + block_1d_idx].consider_block = 1;
    1718             :                             }
    1719             :                         }
    1720             : 
    1721             :                         if (blk_geom->sq_size > 4) {
    1722             :                             // Set predicted block to be considered
    1723             :                             for (block_1d_idx = 0; block_1d_idx < tot_d1_blocks; block_1d_idx++) {
    1724             :                                 resultsPtr->leaf_data_array[blk_index + block_1d_idx].consider_block = 1;
    1725             :                                 resultsPtr->leaf_data_array[blk_index + block_1d_idx].refined_split_flag = EB_TRUE;
    1726             :                             }
    1727             :                             //Set first child to be considered
    1728             :                             child_block_idx_1 = blk_index + d1_depth_offset[sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128][blk_geom->depth];
    1729             :                             const BlockGeom * child1_blk_geom = get_blk_geom_mds(child_block_idx_1);
    1730             :                             uint32_t child1_tot_d1_blocks =
    1731             :                                 child1_blk_geom->sq_size == 128 ? 17 :
    1732             :                                 child1_blk_geom->sq_size > 8 ? 25 :
    1733             :                                 child1_blk_geom->sq_size == 8 ? 5 : 1;
    1734             : 
    1735             :                             for (block_1d_idx = 0; block_1d_idx < child1_tot_d1_blocks; block_1d_idx++) {
    1736             :                                 resultsPtr->leaf_data_array[child_block_idx_1 + block_1d_idx].consider_block = 1;
    1737             :                                 resultsPtr->leaf_data_array[child_block_idx_1 + block_1d_idx].refined_split_flag = EB_FALSE;
    1738             :                             }
    1739             :                             //Set second child to be considered
    1740             :                             child_block_idx_2 = child_block_idx_1 + ns_depth_offset[sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128][blk_geom->depth + 1];
    1741             :                             const BlockGeom * child2_blk_geom = get_blk_geom_mds(child_block_idx_2);
    1742             :                             uint32_t child2_tot_d1_blocks =
    1743             :                                 child2_blk_geom->sq_size == 128 ? 17 :
    1744             :                                 child2_blk_geom->sq_size > 8 ? 25 :
    1745             :                                 child2_blk_geom->sq_size == 8 ? 5 : 1;
    1746             :                             for (block_1d_idx = 0; block_1d_idx < child2_tot_d1_blocks; block_1d_idx++) {
    1747             :                                 resultsPtr->leaf_data_array[child_block_idx_2 + block_1d_idx].consider_block = 1;
    1748             :                                 resultsPtr->leaf_data_array[child_block_idx_2 + block_1d_idx].refined_split_flag = EB_FALSE;
    1749             :                             }
    1750             :                             //Set third child to be considered
    1751             :                             child_block_idx_3 = child_block_idx_2 + ns_depth_offset[sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128][blk_geom->depth + 1];
    1752             :                             const BlockGeom * child3_blk_geom = get_blk_geom_mds(child_block_idx_3);
    1753             :                             uint32_t child3_tot_d1_blocks =
    1754             :                                 child3_blk_geom->sq_size == 128 ? 17 :
    1755             :                                 child3_blk_geom->sq_size > 8 ? 25 :
    1756             :                                 child3_blk_geom->sq_size == 8 ? 5 : 1;
    1757             : 
    1758             :                             for (block_1d_idx = 0; block_1d_idx < child3_tot_d1_blocks; block_1d_idx++) {
    1759             :                                 resultsPtr->leaf_data_array[child_block_idx_3 + block_1d_idx].consider_block = 1;
    1760             :                                 resultsPtr->leaf_data_array[child_block_idx_3 + block_1d_idx].refined_split_flag = EB_FALSE;
    1761             :                             }
    1762             :                             //Set forth child to be considered
    1763             :                             child_block_idx_4 = child_block_idx_3 + ns_depth_offset[sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128][blk_geom->depth + 1];
    1764             :                             const BlockGeom * child4_blk_geom = get_blk_geom_mds(child_block_idx_4);
    1765             :                             uint32_t child4_tot_d1_blocks =
    1766             :                                 child4_blk_geom->sq_size == 128 ? 17 :
    1767             :                                 child4_blk_geom->sq_size > 8 ? 25 :
    1768             :                                 child4_blk_geom->sq_size == 8 ? 5 : 1;
    1769             :                             for (block_1d_idx = 0; block_1d_idx < child4_tot_d1_blocks; block_1d_idx++) {
    1770             :                                 resultsPtr->leaf_data_array[child_block_idx_4 + block_1d_idx].consider_block = 1;
    1771             :                                 resultsPtr->leaf_data_array[child_block_idx_4 + block_1d_idx].refined_split_flag = EB_FALSE;
    1772             :                             }
    1773             :                         }
    1774             : #endif
    1775             :                     }
    1776         224 :                     break;
    1777             : #if MDC_ADAPTIVE_LEVEL
    1778         822 :                 case Predm2p1:
    1779         822 :                     if (context_ptr->local_cu_array[blk_index].early_split_flag == EB_FALSE) {
    1780       20412 :                         for (block_1d_idx = 0; block_1d_idx < tot_d1_blocks; block_1d_idx++) {
    1781       19590 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].consider_block = 1;
    1782       19590 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].refined_split_flag = EB_FALSE;
    1783             :                         }
    1784         822 :                         set_parent_to_be_considered(
    1785             :                             resultsPtr,
    1786             :                             blk_index,
    1787         822 :                             sequence_control_set_ptr->seq_header.sb_size,
    1788             :                             -2);
    1789       20412 :                         for (block_1d_idx = 0; block_1d_idx < tot_d1_blocks; block_1d_idx++) {
    1790       19590 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].consider_block = 1;
    1791       19590 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].refined_split_flag = EB_FALSE;
    1792             :                         }
    1793         822 :                         set_child_to_be_considered(
    1794             :                             resultsPtr,
    1795             :                             blk_index,
    1796         822 :                             sequence_control_set_ptr->seq_header.sb_size,
    1797             :                             1);
    1798             :                     }
    1799         822 :                     break;
    1800          94 :                 case Predm2p2:
    1801          94 :                     if (context_ptr->local_cu_array[blk_index].early_split_flag == EB_FALSE) {
    1802        2124 :                         for (block_1d_idx = 0; block_1d_idx < tot_d1_blocks; block_1d_idx++) {
    1803        2030 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].consider_block = 1;
    1804        2030 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].refined_split_flag = EB_FALSE;
    1805             :                         }
    1806          94 :                         set_parent_to_be_considered(
    1807             :                             resultsPtr,
    1808             :                             blk_index,
    1809          94 :                             sequence_control_set_ptr->seq_header.sb_size,
    1810             :                             -2);
    1811        2124 :                         for (block_1d_idx = 0; block_1d_idx < tot_d1_blocks; block_1d_idx++) {
    1812        2030 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].consider_block = 1;
    1813        2030 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].refined_split_flag = EB_FALSE;
    1814             :                         }
    1815          94 :                         set_child_to_be_considered(
    1816             :                             resultsPtr,
    1817             :                             blk_index,
    1818          94 :                             sequence_control_set_ptr->seq_header.sb_size,
    1819             :                             2);
    1820             :                     }
    1821          94 :                     break;
    1822        1432 :                 case Predm3p2:
    1823        1432 :                     if (context_ptr->local_cu_array[blk_index].early_split_flag == EB_FALSE) {
    1824       35092 :                         for (block_1d_idx = 0; block_1d_idx < tot_d1_blocks; block_1d_idx++) {
    1825       33660 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].consider_block = 1;
    1826       33660 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].refined_split_flag = EB_FALSE;
    1827             :                         }
    1828        1432 :                         set_parent_to_be_considered(
    1829             :                             resultsPtr,
    1830             :                             blk_index,
    1831        1432 :                             sequence_control_set_ptr->seq_header.sb_size,
    1832             :                             -3);
    1833       35092 :                         for (block_1d_idx = 0; block_1d_idx < tot_d1_blocks; block_1d_idx++) {
    1834       33660 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].consider_block = 1;
    1835       33660 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].refined_split_flag = EB_FALSE;
    1836             :                         }
    1837        1432 :                         set_child_to_be_considered(
    1838             :                             resultsPtr,
    1839             :                             blk_index,
    1840        1432 :                             sequence_control_set_ptr->seq_header.sb_size,
    1841             :                             2);
    1842             :                     }
    1843        1432 :                     break;
    1844         407 :                 case Predm3p3:
    1845         407 :                     if (context_ptr->local_cu_array[blk_index].early_split_flag == EB_FALSE) {
    1846        3378 :                         for (block_1d_idx = 0; block_1d_idx < tot_d1_blocks; block_1d_idx++) {
    1847        2971 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].consider_block = 1;
    1848        2971 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].refined_split_flag = EB_FALSE;
    1849             :                         }
    1850         407 :                         set_parent_to_be_considered(
    1851             :                             resultsPtr,
    1852             :                             blk_index,
    1853         407 :                             sequence_control_set_ptr->seq_header.sb_size,
    1854             :                             -3);
    1855        3378 :                         for (block_1d_idx = 0; block_1d_idx < tot_d1_blocks; block_1d_idx++) {
    1856        2971 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].consider_block = 1;
    1857        2971 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].refined_split_flag = EB_FALSE;
    1858             :                         }
    1859         407 :                         set_child_to_be_considered(
    1860             :                             resultsPtr,
    1861             :                             blk_index,
    1862         407 :                             sequence_control_set_ptr->seq_header.sb_size,
    1863             :                             3);
    1864             :                     }
    1865         407 :                     break;
    1866        3660 :                 case Predm3p1:
    1867        3660 :                     if (context_ptr->local_cu_array[blk_index].early_split_flag == EB_FALSE) {
    1868       91200 :                         for (block_1d_idx = 0; block_1d_idx < tot_d1_blocks; block_1d_idx++) {
    1869       87540 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].consider_block = 1;
    1870       87540 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].refined_split_flag = EB_FALSE;
    1871             :                         }
    1872        3660 :                         set_parent_to_be_considered(
    1873             :                             resultsPtr,
    1874             :                             blk_index,
    1875        3660 :                             sequence_control_set_ptr->seq_header.sb_size,
    1876             :                             -3);
    1877       91200 :                         for (block_1d_idx = 0; block_1d_idx < tot_d1_blocks; block_1d_idx++) {
    1878       87540 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].consider_block = 1;
    1879       87540 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].refined_split_flag = EB_FALSE;
    1880             :                         }
    1881        3660 :                         set_child_to_be_considered(
    1882             :                             resultsPtr,
    1883             :                             blk_index,
    1884        3660 :                             sequence_control_set_ptr->seq_header.sb_size,
    1885             :                             1);
    1886             :                     }
    1887        3660 :                     break;
    1888        1097 :                 case Predm3:
    1889        1097 :                     if (context_ptr->local_cu_array[blk_index].early_split_flag == EB_FALSE) {
    1890       27882 :                         for (block_1d_idx = 0; block_1d_idx < tot_d1_blocks; block_1d_idx++) {
    1891       26785 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].consider_block = 1;
    1892       26785 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].refined_split_flag = EB_FALSE;
    1893             :                         }
    1894        1097 :                         set_parent_to_be_considered(
    1895             :                             resultsPtr,
    1896             :                             blk_index,
    1897        1097 :                             sequence_control_set_ptr->seq_header.sb_size,
    1898             :                             -3);
    1899       27882 :                         for (block_1d_idx = 0; block_1d_idx < tot_d1_blocks; block_1d_idx++) {
    1900       26785 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].consider_block = 1;
    1901       26785 :                             resultsPtr->leaf_data_array[blk_index + block_1d_idx].refined_split_flag = EB_FALSE;
    1902             :                         }
    1903        1097 :                         set_child_to_be_considered(
    1904             :                             resultsPtr,
    1905             :                             blk_index,
    1906        1097 :                             sequence_control_set_ptr->seq_header.sb_size,
    1907             :                             1);
    1908             :                     }
    1909        1097 :                     break;
    1910             : #endif
    1911           0 :                 case AllD:
    1912             :                     // Set all block to be considered
    1913           0 :                     for (block_1d_idx = 0; block_1d_idx < tot_d1_blocks; block_1d_idx++) {
    1914           0 :                         resultsPtr->leaf_data_array[blk_index + block_1d_idx].consider_block = 1;
    1915           0 :                         resultsPtr->leaf_data_array[blk_index + block_1d_idx].refined_split_flag = blk_geom->sq_size > 4 ? EB_TRUE : EB_FALSE;
    1916             :                     }
    1917           0 :                     break;
    1918           0 :                 default:
    1919           0 :                     printf("Error! invalid mdc_refinement_mode\n");
    1920           0 :                     break;
    1921             :                 }
    1922           0 :             }
    1923             :         }
    1924       91864 :         blk_index += split_flag ? d1_depth_offset[sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128][blk_geom->depth] : ns_depth_offset[sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128][blk_geom->depth];
    1925             :     }
    1926        3480 : }
    1927        3480 : void forward_considered_blocks(
    1928             :     SequenceControlSet *sequence_control_set_ptr,
    1929             :     PictureControlSet  *picture_control_set_ptr,
    1930             :     uint32_t            sb_index) {
    1931        3480 :     MdcLcuData *resultsPtr = &picture_control_set_ptr->mdc_sb_array[sb_index];
    1932        3480 :     resultsPtr->leaf_count = 0;
    1933        3480 :     uint32_t  blk_index = 0;
    1934        3480 :     uint32_t d1_blocks_accumlated, tot_d1_blocks = 0, d1_block_idx;
    1935             :     EbBool split_flag;
    1936      266368 :     while (blk_index < sequence_control_set_ptr->max_block_cnt) {
    1937      262888 :         const BlockGeom * blk_geom = get_blk_geom_mds(blk_index);
    1938      262888 :         split_flag = blk_geom->sq_size > 4 ? EB_TRUE : EB_FALSE;
    1939             :         //if the parent sq is inside inject this block
    1940      262888 :         uint8_t is_blk_allowed = picture_control_set_ptr->slice_type != I_SLICE ? 1 : (blk_geom->sq_size < 128) ? 1 : 0;
    1941             :         //init consider block flag
    1942      262888 :         if (sequence_control_set_ptr->sb_geom[sb_index].block_is_inside_md_scan[blk_index] && is_blk_allowed) {
    1943      262888 :             tot_d1_blocks =
    1944      525776 :                 blk_geom->sq_size == 128 ? 17 :
    1945      262888 :                 blk_geom->sq_size > 8 ? 25 :
    1946      214160 :                 blk_geom->sq_size == 8 ? 5 : 1;
    1947      262888 :             d1_blocks_accumlated = 0;
    1948     1931220 :             for (d1_block_idx = 0; d1_block_idx < tot_d1_blocks; d1_block_idx++)
    1949     1668330 :                 d1_blocks_accumlated += resultsPtr->leaf_data_array[blk_index + d1_block_idx].consider_block ? 1 : 0;
    1950             : 
    1951     1931220 :             for (uint32_t idx = 0; idx < tot_d1_blocks; ++idx) {
    1952     1668330 :                 if (resultsPtr->leaf_data_array[blk_index].consider_block) {
    1953     1580880 :                     resultsPtr->leaf_data_array[resultsPtr->leaf_count].tot_d1_blocks = d1_blocks_accumlated;
    1954     1580880 :                     resultsPtr->leaf_data_array[resultsPtr->leaf_count].leaf_index = 0;//valid only for square 85 world. will be removed.
    1955     1580880 :                     resultsPtr->leaf_data_array[resultsPtr->leaf_count].mds_idx = blk_index;
    1956     1580880 :                     split_flag = resultsPtr->leaf_data_array[blk_index].refined_split_flag;
    1957     1580880 :                     resultsPtr->leaf_data_array[resultsPtr->leaf_count++].split_flag = split_flag;
    1958             :                 }
    1959     1668330 :                 blk_index++;
    1960             :             }
    1961             :         }
    1962      262888 :         blk_index += split_flag ? d1_depth_offset[sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128][blk_geom->depth] - tot_d1_blocks : ns_depth_offset[sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128][blk_geom->depth] - tot_d1_blocks;
    1963             :     }
    1964        3480 : }
    1965             : #endif
    1966        3480 : void open_loop_partitioning_pass(
    1967             :     SequenceControlSet *sequence_control_set_ptr,
    1968             :     PictureControlSet  *picture_control_set_ptr,
    1969             :     ModeDecisionConfigurationContext *context_ptr,
    1970             :     uint32_t            sb_index) {
    1971             :     //EbBool split_flag;
    1972        3480 :     MdcLcuData *resultsPtr = &picture_control_set_ptr->mdc_sb_array[sb_index];
    1973        3480 :     resultsPtr->leaf_count = 0;
    1974        3480 :     uint32_t  blk_index = 0;
    1975     3834960 :     while (blk_index < sequence_control_set_ptr->max_block_cnt) {
    1976             :         //split_flag = EB_TRUE;
    1977     3831480 :         const BlockGeom * blk_geom = get_blk_geom_mds(blk_index);
    1978             :         //if the parentSq is inside inject this block
    1979     3831480 :         uint8_t is_blk_allowed = picture_control_set_ptr->slice_type != I_SLICE ? 1 : (blk_geom->sq_size < 128) ? 1 : 0;
    1980             :         //init ranking
    1981     3831480 :         resultsPtr->leaf_data_array[blk_index].early_split_flag = blk_geom->sq_size > 4 ? EB_TRUE : EB_FALSE;
    1982             : #if ADD_MDC_REFINEMENT_LOOP
    1983             :         //init consider block flag
    1984     3831480 :         resultsPtr->leaf_data_array[blk_index].consider_block = 0;
    1985     3831480 :         resultsPtr->leaf_data_array[blk_index].refined_split_flag = resultsPtr->leaf_data_array[blk_index].early_split_flag;
    1986     3831480 :         context_ptr->local_cu_array[blk_index].early_split_flag = resultsPtr->leaf_data_array[blk_index].early_split_flag;
    1987             : #endif
    1988     3831480 :         if (sequence_control_set_ptr->sb_geom[sb_index].block_is_inside_md_scan[blk_index] && is_blk_allowed) {
    1989     3831480 :             resultsPtr->leaf_data_array[resultsPtr->leaf_count].tot_d1_blocks =
    1990     7662960 :                 blk_geom->sq_size == 128 ? 17 :
    1991     3831480 :                 blk_geom->sq_size > 8 ? 25 :
    1992     2004480 :                 blk_geom->sq_size == 8 ? 5 : 1;
    1993     3831480 :             resultsPtr->leaf_data_array[resultsPtr->leaf_count].leaf_index = 0;//valid only for square 85 world. will be removed.
    1994     3831480 :             resultsPtr->leaf_data_array[resultsPtr->leaf_count].mds_idx = blk_index;
    1995     3831480 :             if (blk_geom->sq_size > 4) {
    1996     2940600 :                 resultsPtr->leaf_data_array[resultsPtr->leaf_count++].split_flag = EB_TRUE;
    1997             :                 //split_flag = EB_TRUE;
    1998             :             }
    1999             :             else {
    2000      890880 :                 resultsPtr->leaf_data_array[resultsPtr->leaf_count++].split_flag = EB_FALSE;
    2001             :                 //split_flag = EB_FALSE;
    2002             :             }
    2003             :         }
    2004     3831480 :         blk_index++;
    2005             :     }
    2006        3480 :     if (picture_control_set_ptr->slice_type != I_SLICE) {
    2007             :         LargestCodingUnit            *sb_ptr;
    2008             :         // SB Loop : Partitionnig Decision
    2009        3480 :         sb_ptr = picture_control_set_ptr->sb_ptr_array[sb_index];
    2010        3480 :         sb_ptr->qp = (uint8_t)picture_control_set_ptr->parent_pcs_ptr->picture_qp;
    2011             : #if MDC_ADAPTIVE_LEVEL
    2012        3480 :         uint32_t is_complete_sb = sequence_control_set_ptr->sb_geom[sb_index].is_complete_sb;
    2013        3480 :         if (sequence_control_set_ptr->over_boundary_block_mode == 1 || is_complete_sb) {
    2014             : #endif
    2015        3480 :             open_loop_partitioning_sb(
    2016             :                 sequence_control_set_ptr,
    2017             :                 picture_control_set_ptr,
    2018             :                 context_ptr,
    2019             :                 resultsPtr,
    2020        3480 :                 sb_ptr->origin_x,
    2021        3480 :                 sb_ptr->origin_y,
    2022             :                 sb_index);
    2023             : #if MDC_ADAPTIVE_LEVEL
    2024             :         }
    2025             : #endif
    2026             :     }
    2027        3480 :     picture_control_set_ptr->parent_pcs_ptr->average_qp = (uint8_t)picture_control_set_ptr->parent_pcs_ptr->picture_qp;
    2028        3480 : }
    2029             : #endif
    2030             : 
    2031           0 : void Forward85CuToModeDecision(
    2032             :     SequenceControlSet                   *sequence_control_set_ptr,
    2033             :     PictureControlSet                    *picture_control_set_ptr) {
    2034             :     const CodedUnitStats  *cuStatsPtr;
    2035             :     uint32_t                   sb_index;
    2036             :     EbBool split_flag;
    2037             :     // SB Loop : Partitionnig Decision
    2038           0 :     for (sb_index = 0; sb_index < picture_control_set_ptr->sb_total_count; ++sb_index) {
    2039           0 :         SbParams  *sb_params = &sequence_control_set_ptr->sb_params_array[sb_index];
    2040           0 :         MdcLcuData *resultsPtr = &picture_control_set_ptr->mdc_sb_array[sb_index];
    2041           0 :         resultsPtr->leaf_count = 0;
    2042           0 :         uint8_t cu_index = 0;
    2043           0 :         while (cu_index < CU_MAX_COUNT)
    2044             :         {
    2045           0 :             split_flag = EB_TRUE;
    2046           0 :             cuStatsPtr = get_coded_unit_stats(cu_index);
    2047           0 :             if (sb_params->raster_scan_cu_validity[md_scan_to_raster_scan[cu_index]])
    2048             :             {
    2049           0 :                 switch (cuStatsPtr->depth) {
    2050           0 :                 case 0:
    2051           0 :                     resultsPtr->leaf_data_array[resultsPtr->leaf_count].leaf_index = cu_index;
    2052           0 :                     resultsPtr->leaf_data_array[resultsPtr->leaf_count++].split_flag = split_flag = EB_TRUE;
    2053             : 
    2054           0 :                     break;
    2055           0 :                 case 1:
    2056           0 :                     resultsPtr->leaf_data_array[resultsPtr->leaf_count].leaf_index = cu_index;
    2057           0 :                     resultsPtr->leaf_data_array[resultsPtr->leaf_count++].split_flag = split_flag = EB_TRUE;
    2058           0 :                     break;
    2059             : 
    2060           0 :                 case 2:
    2061             : 
    2062           0 :                     resultsPtr->leaf_data_array[resultsPtr->leaf_count].leaf_index = cu_index;
    2063           0 :                     resultsPtr->leaf_data_array[resultsPtr->leaf_count++].split_flag = split_flag = EB_TRUE;
    2064             : 
    2065           0 :                     break;
    2066           0 :                 case 3:
    2067             : 
    2068           0 :                     resultsPtr->leaf_data_array[resultsPtr->leaf_count].leaf_index = cu_index;
    2069           0 :                     resultsPtr->leaf_data_array[resultsPtr->leaf_count++].split_flag = split_flag = EB_FALSE;
    2070             : 
    2071           0 :                     break;
    2072             : 
    2073           0 :                 default:
    2074           0 :                     resultsPtr->leaf_data_array[resultsPtr->leaf_count].leaf_index = cu_index;
    2075           0 :                     resultsPtr->leaf_data_array[resultsPtr->leaf_count++].split_flag = split_flag = EB_TRUE;
    2076           0 :                     break;
    2077             :                 }
    2078           0 :             }
    2079             : 
    2080           0 :             cu_index += (split_flag == EB_TRUE) ? 1 : depth_offset[cuStatsPtr->depth];
    2081             :         } // End CU Loop
    2082             :     }
    2083             : 
    2084           0 :     picture_control_set_ptr->parent_pcs_ptr->average_qp = (uint8_t)picture_control_set_ptr->parent_pcs_ptr->picture_qp;
    2085           0 : }
    2086             : 
    2087           0 : void Forward84CuToModeDecision(
    2088             :     SequenceControlSet                   *sequence_control_set_ptr,
    2089             :     PictureControlSet                    *picture_control_set_ptr) {
    2090             :     const CodedUnitStats  *cuStatsPtr;
    2091             :     uint32_t                   sb_index;
    2092             :     EbBool split_flag;
    2093             :     // SB Loop : Partitionnig Decision
    2094           0 :     for (sb_index = 0; sb_index < picture_control_set_ptr->sb_total_count; ++sb_index) {
    2095           0 :         SbParams  *sb_params = &sequence_control_set_ptr->sb_params_array[sb_index];
    2096           0 :         MdcLcuData *resultsPtr = &picture_control_set_ptr->mdc_sb_array[sb_index];
    2097             :         uint32_t cuIndexInRaterScan;   uint16_t cuVar;
    2098             : 
    2099           0 :         resultsPtr->leaf_count = 0;
    2100           0 :         uint8_t cu_index = 0;
    2101           0 :         while (cu_index < CU_MAX_COUNT)
    2102             :         {
    2103           0 :             split_flag = EB_TRUE;
    2104           0 :             cuStatsPtr = get_coded_unit_stats(cu_index);
    2105           0 :             if (sb_params->raster_scan_cu_validity[md_scan_to_raster_scan[cu_index]])
    2106             :             {
    2107           0 :                 switch (cuStatsPtr->depth) {
    2108           0 :                 case 0:
    2109           0 :                     if (picture_control_set_ptr->slice_type == I_SLICE)
    2110           0 :                         split_flag = EB_TRUE;
    2111             :                     else {
    2112           0 :                         resultsPtr->leaf_data_array[resultsPtr->leaf_count].leaf_index = cu_index;
    2113           0 :                         resultsPtr->leaf_data_array[resultsPtr->leaf_count++].split_flag = split_flag = EB_TRUE;
    2114             :                     }
    2115             : 
    2116           0 :                     break;
    2117           0 :                 case 1:
    2118             : 
    2119             :                     //OMK To revisit : add Varpart flag and move to MD
    2120           0 :                     cuIndexInRaterScan = md_scan_to_raster_scan[cu_index];
    2121           0 :                     cuVar = (picture_control_set_ptr->parent_pcs_ptr->variance[sb_index][cuIndexInRaterScan]);
    2122           0 :                     if ((picture_control_set_ptr->slice_type == I_SLICE && cuVar > 40) || (sequence_control_set_ptr->input_resolution < INPUT_SIZE_4K_RANGE&& picture_control_set_ptr->slice_type == I_SLICE && cuVar>40))
    2123           0 :                         split_flag = EB_TRUE;
    2124             :                     else {
    2125           0 :                         resultsPtr->leaf_data_array[resultsPtr->leaf_count].leaf_index = cu_index;
    2126           0 :                         resultsPtr->leaf_data_array[resultsPtr->leaf_count++].split_flag = split_flag = EB_TRUE;
    2127             :                     }
    2128             : 
    2129           0 :                     break;
    2130             : 
    2131           0 :                 case 2:
    2132             : 
    2133           0 :                     resultsPtr->leaf_data_array[resultsPtr->leaf_count].leaf_index = cu_index;
    2134           0 :                     resultsPtr->leaf_data_array[resultsPtr->leaf_count++].split_flag = split_flag = EB_TRUE;
    2135             : 
    2136           0 :                     break;
    2137           0 :                 case 3:
    2138             : 
    2139           0 :                     resultsPtr->leaf_data_array[resultsPtr->leaf_count].leaf_index = cu_index;
    2140           0 :                     resultsPtr->leaf_data_array[resultsPtr->leaf_count++].split_flag = split_flag = EB_FALSE;
    2141             : 
    2142           0 :                     break;
    2143             : 
    2144           0 :                 default:
    2145           0 :                     resultsPtr->leaf_data_array[resultsPtr->leaf_count].leaf_index = cu_index;
    2146           0 :                     resultsPtr->leaf_data_array[resultsPtr->leaf_count++].split_flag = split_flag = EB_TRUE;
    2147           0 :                     break;
    2148             :                 }
    2149           0 :             }
    2150             : 
    2151           0 :             cu_index += (split_flag == EB_TRUE) ? 1 : depth_offset[cuStatsPtr->depth];
    2152             :         } // End CU Loop
    2153             :     }
    2154             : 
    2155           0 :     picture_control_set_ptr->parent_pcs_ptr->average_qp = (uint8_t)picture_control_set_ptr->parent_pcs_ptr->picture_qp;
    2156           0 : }
    2157             : 
    2158             : /******************************************************
    2159             : * Derive MD parameters
    2160             : ******************************************************/
    2161         120 : void SetMdSettings(
    2162             :     SequenceControlSet                   *sequence_control_set_ptr,
    2163             :     PictureControlSet                    *picture_control_set_ptr) {
    2164             :     // Initialize the homogeneous area threshold
    2165             :     // Set the MD Open Loop Flag
    2166             :     // HG - to clean up the intra_md_open_loop_flag derivation
    2167             : 
    2168         120 :     picture_control_set_ptr->intra_md_open_loop_flag = picture_control_set_ptr->temporal_layer_index == 0 ? EB_FALSE : EB_TRUE;
    2169             : 
    2170         120 :     if (picture_control_set_ptr->parent_pcs_ptr->is_used_as_reference_flag == EB_TRUE && sequence_control_set_ptr->input_resolution < INPUT_SIZE_4K_RANGE)
    2171          68 :         picture_control_set_ptr->intra_md_open_loop_flag = EB_FALSE;
    2172             : 
    2173         120 :     picture_control_set_ptr->constrained_intra_flag = EB_FALSE;
    2174             : 
    2175         120 :     if (sequence_control_set_ptr->static_config.constrained_intra == EB_TRUE &&
    2176           0 :         picture_control_set_ptr->parent_pcs_ptr->is_used_as_reference_flag == EB_FALSE)
    2177             :     {
    2178           0 :         picture_control_set_ptr->constrained_intra_flag = EB_TRUE;
    2179             :     }
    2180         120 :     picture_control_set_ptr->limit_intra = EB_FALSE;
    2181         120 :     picture_control_set_ptr->intra_md_open_loop_flag = EB_FALSE;
    2182         120 : }
    2183             : /******************************************************
    2184             : * Load the cost of the different partitioning method into a local array and derive sensitive picture flag
    2185             :     Input   : the offline derived cost per search method, detection signals
    2186             :     Output  : valid cost_depth_mode and valid sensitivePicture
    2187             : ******************************************************/
    2188          58 : void configure_adp(
    2189             :     PictureControlSet                *picture_control_set_ptr,
    2190             :     ModeDecisionConfigurationContext *context_ptr){
    2191             :     UNUSED(picture_control_set_ptr);
    2192          58 :     context_ptr->cost_depth_mode[SB_SQ_BLOCKS_DEPTH_MODE      - 1]       = SQ_BLOCKS_SEARCH_COST;
    2193          58 :     context_ptr->cost_depth_mode[SB_SQ_NON4_BLOCKS_DEPTH_MODE - 1]       = SQ_NON4_BLOCKS_SEARCH_COST;
    2194          58 :     context_ptr->cost_depth_mode[SB_OPEN_LOOP_DEPTH_MODE      - 1]       = SB_OPEN_LOOP_COST;
    2195          58 :     context_ptr->cost_depth_mode[SB_FAST_OPEN_LOOP_DEPTH_MODE - 1]       = SB_FAST_OPEN_LOOP_COST;
    2196          58 :     context_ptr->cost_depth_mode[SB_PRED_OPEN_LOOP_DEPTH_MODE - 1]       = SB_PRED_OPEN_LOOP_COST;
    2197             : 
    2198             :     // Initialize the score based TH
    2199          58 :     context_ptr->score_th[0] = ~0;
    2200          58 :     context_ptr->score_th[1] = ~0;
    2201          58 :     context_ptr->score_th[2] = ~0;
    2202          58 :     context_ptr->score_th[3] = ~0;
    2203          58 :     context_ptr->score_th[4] = ~0;
    2204          58 :     context_ptr->score_th[5] = ~0;
    2205          58 :     context_ptr->score_th[6] = ~0;
    2206             : 
    2207             :     // Initialize the predicted budget
    2208          58 :     context_ptr->predicted_cost = (uint32_t)~0;
    2209          58 : }
    2210             : 
    2211             : /******************************************************
    2212             : * Assign a search method based on the allocated cost
    2213             :     Input   : allocated budget per LCU
    2214             :     Output  : search method per LCU
    2215             : ******************************************************/
    2216          58 : void derive_search_method(
    2217             :     PictureControlSet                *picture_control_set_ptr,
    2218             :     ModeDecisionConfigurationContext *context_ptr)
    2219             : {
    2220             :     uint32_t sb_index;
    2221             : 
    2222        3538 :     for (sb_index = 0; sb_index < picture_control_set_ptr->parent_pcs_ptr->sequence_control_set_ptr->sb_tot_cnt; sb_index++) {
    2223        3480 :         if (context_ptr->sb_cost_array[sb_index] == context_ptr->cost_depth_mode[SB_PRED_OPEN_LOOP_DEPTH_MODE - 1])
    2224         991 :             picture_control_set_ptr->parent_pcs_ptr->sb_depth_mode_array[sb_index] = SB_PRED_OPEN_LOOP_DEPTH_MODE;
    2225        2489 :         else if (context_ptr->sb_cost_array[sb_index] == context_ptr->cost_depth_mode[SB_FAST_OPEN_LOOP_DEPTH_MODE - 1])
    2226         853 :             picture_control_set_ptr->parent_pcs_ptr->sb_depth_mode_array[sb_index] = SB_FAST_OPEN_LOOP_DEPTH_MODE;
    2227        1636 :         else if (context_ptr->sb_cost_array[sb_index] == context_ptr->cost_depth_mode[SB_OPEN_LOOP_DEPTH_MODE - 1])
    2228         781 :             picture_control_set_ptr->parent_pcs_ptr->sb_depth_mode_array[sb_index] = SB_OPEN_LOOP_DEPTH_MODE;
    2229         855 :         else if (context_ptr->sb_cost_array[sb_index] == context_ptr->cost_depth_mode[SB_SQ_NON4_BLOCKS_DEPTH_MODE - 1])
    2230         855 :             picture_control_set_ptr->parent_pcs_ptr->sb_depth_mode_array[sb_index] = SB_SQ_NON4_BLOCKS_DEPTH_MODE;
    2231             :         else
    2232           0 :             picture_control_set_ptr->parent_pcs_ptr->sb_depth_mode_array[sb_index] = SB_SQ_BLOCKS_DEPTH_MODE;
    2233             :     }
    2234             : 
    2235             : #if ADP_STATS_PER_LAYER
    2236             :     SequenceControlSet *sequence_control_set_ptr = (SequenceControlSet *)picture_control_set_ptr->sequence_control_set_wrapper_ptr->object_ptr;
    2237             : 
    2238             :     for (sb_index = 0; sb_index < picture_control_set_ptr->parent_pcs_ptr->sequence_control_set_ptr->sb_tot_cnt; sb_index++) {
    2239             :         sequence_control_set_ptr->total_count[picture_control_set_ptr->parent_pcs_ptr->temporal_layer_index] ++;
    2240             : 
    2241             :         if (picture_control_set_ptr->parent_pcs_ptr->sb_depth_mode_array[sb_index] == SB_SQ_BLOCKS_DEPTH_MODE)
    2242             :             sequence_control_set_ptr->sq_search_count[picture_control_set_ptr->parent_pcs_ptr->temporal_layer_index]  ++;
    2243             :         else if (picture_control_set_ptr->parent_pcs_ptr->sb_depth_mode_array[sb_index] == SB_SQ_NON4_BLOCKS_DEPTH_MODE)
    2244             :             sequence_control_set_ptr->sq_non4_search_count[picture_control_set_ptr->parent_pcs_ptr->temporal_layer_index]  ++;
    2245             :         else if (picture_control_set_ptr->parent_pcs_ptr->sb_depth_mode_array[sb_index] == SB_OPEN_LOOP_DEPTH_MODE)
    2246             :             sequence_control_set_ptr->mdc_count[picture_control_set_ptr->parent_pcs_ptr->temporal_layer_index]  ++;
    2247             :         else if (picture_control_set_ptr->parent_pcs_ptr->sb_depth_mode_array[sb_index] == SB_FAST_OPEN_LOOP_DEPTH_MODE)
    2248             :             sequence_control_set_ptr->pred_count[picture_control_set_ptr->parent_pcs_ptr->temporal_layer_index]  ++;
    2249             :         else if (picture_control_set_ptr->parent_pcs_ptr->sb_depth_mode_array[sb_index] == SB_PRED_OPEN_LOOP_DEPTH_MODE)
    2250             :             sequence_control_set_ptr->pred1_nfl_count[picture_control_set_ptr->parent_pcs_ptr->temporal_layer_index]  ++;
    2251             :         else
    2252             :             SVT_LOG("error");
    2253             :     }
    2254             : #endif
    2255          58 : }
    2256             : 
    2257             : /******************************************************
    2258             : * Set LCU budget
    2259             :     Input   : LCU score, detection signals, iteration
    2260             :     Output  : predicted budget for the LCU
    2261             : ******************************************************/
    2262       66447 : void set_sb_budget(
    2263             :     SequenceControlSet               *sequence_control_set_ptr,
    2264             :     PictureControlSet                *picture_control_set_ptr,
    2265             :     LargestCodingUnit                *sb_ptr,
    2266             :     ModeDecisionConfigurationContext *context_ptr)
    2267             : {
    2268       66447 :     const uint32_t sb_index = sb_ptr->index;
    2269             :     uint32_t max_to_min_score, score_to_min;
    2270             :     UNUSED(sequence_control_set_ptr);
    2271             :     UNUSED(picture_control_set_ptr);
    2272             :     {
    2273       66447 :         context_ptr->sb_score_array[sb_index] = CLIP3(context_ptr->sb_min_score, context_ptr->sb_max_score, context_ptr->sb_score_array[sb_index]);
    2274       66447 :         score_to_min = context_ptr->sb_score_array[sb_index] - context_ptr->sb_min_score;
    2275       66447 :         max_to_min_score = context_ptr->sb_max_score - context_ptr->sb_min_score;
    2276             : 
    2277       66447 :         if ((score_to_min <= (max_to_min_score * context_ptr->score_th[0]) / 100 && context_ptr->score_th[0] != 0) || context_ptr->number_of_segments == 1 || context_ptr->score_th[1] == 100) {
    2278       33859 :             context_ptr->sb_cost_array[sb_index] = context_ptr->interval_cost[0];
    2279       33859 :             context_ptr->predicted_cost += context_ptr->interval_cost[0];
    2280             :         }
    2281       32588 :         else if ((score_to_min <= (max_to_min_score * context_ptr->score_th[1]) / 100 && context_ptr->score_th[1] != 0) || context_ptr->number_of_segments == 2 || context_ptr->score_th[2] == 100) {
    2282       19361 :             context_ptr->sb_cost_array[sb_index] = context_ptr->interval_cost[1];
    2283       19361 :             context_ptr->predicted_cost += context_ptr->interval_cost[1];
    2284             :         }
    2285       13227 :         else if ((score_to_min <= (max_to_min_score * context_ptr->score_th[2]) / 100 && context_ptr->score_th[2] != 0) || context_ptr->number_of_segments == 3 || context_ptr->score_th[3] == 100) {
    2286       12277 :             context_ptr->sb_cost_array[sb_index] = context_ptr->interval_cost[2];
    2287       12277 :             context_ptr->predicted_cost += context_ptr->interval_cost[2];
    2288             :         }
    2289         950 :         else if ((score_to_min <= (max_to_min_score * context_ptr->score_th[3]) / 100 && context_ptr->score_th[3] != 0) || context_ptr->number_of_segments == 4 || context_ptr->score_th[4] == 100) {
    2290         950 :             context_ptr->sb_cost_array[sb_index] = context_ptr->interval_cost[3];
    2291         950 :             context_ptr->predicted_cost += context_ptr->interval_cost[3];
    2292             :         }
    2293           0 :         else if ((score_to_min <= (max_to_min_score * context_ptr->score_th[4]) / 100 && context_ptr->score_th[4] != 0) || context_ptr->number_of_segments == 5 || context_ptr->score_th[5] == 100) {
    2294           0 :             context_ptr->sb_cost_array[sb_index] = context_ptr->interval_cost[4];
    2295           0 :             context_ptr->predicted_cost += context_ptr->interval_cost[4];
    2296             :         }
    2297           0 :         else if ((score_to_min <= (max_to_min_score * context_ptr->score_th[5]) / 100 && context_ptr->score_th[5] != 0) || context_ptr->number_of_segments == 6 || context_ptr->score_th[6] == 100) {
    2298           0 :             context_ptr->sb_cost_array[sb_index] = context_ptr->interval_cost[5];
    2299           0 :             context_ptr->predicted_cost += context_ptr->interval_cost[5];
    2300             :         }
    2301             :         else {
    2302           0 :             context_ptr->sb_cost_array[sb_index] = context_ptr->interval_cost[6];
    2303           0 :             context_ptr->predicted_cost += context_ptr->interval_cost[6];
    2304             :         }
    2305             :     }
    2306       66447 : }
    2307             : 
    2308             : /******************************************************
    2309             : * Loop multiple times over the LCUs in order to derive the optimal budget per LCU
    2310             :     Input   : budget per picture, ditortion, detection signals, iteration
    2311             :     Output  : optimal budget for each LCU
    2312             : ******************************************************/
    2313          58 : void  derive_optimal_budget_per_sb(
    2314             :     SequenceControlSet               *sequence_control_set_ptr,
    2315             :     PictureControlSet                *picture_control_set_ptr,
    2316             :     ModeDecisionConfigurationContext *context_ptr)
    2317             : {
    2318             :     uint32_t sb_index;
    2319             :     // Initialize the deviation between the picture predicted cost & the target budget to 100,
    2320          58 :     uint32_t deviation_to_target = 1000;
    2321             : 
    2322             :     // Set the adjustment step to 1 (could be increased for faster convergence),
    2323          58 :     int8_t  adjustement_step = 1;
    2324             : 
    2325             :     // Set the initial shooting state & the final shooting state to TBD
    2326          58 :     uint32_t initial_shooting = TBD_SHOOTING;
    2327          58 :     uint32_t final_shooting = TBD_SHOOTING;
    2328             : 
    2329          58 :     uint8_t max_adjustement_iteration = 100;
    2330          58 :     uint8_t adjustement_iteration = 0;
    2331             : 
    2332        1184 :     while (deviation_to_target != 0 && (initial_shooting == final_shooting) && adjustement_iteration <= max_adjustement_iteration) {
    2333        1137 :         if (context_ptr->predicted_cost < context_ptr->budget)
    2334        1079 :             initial_shooting = UNDER_SHOOTING;
    2335             :         else
    2336          58 :             initial_shooting = OVER_SHOOTING;
    2337             :         // reset running cost
    2338        1137 :         context_ptr->predicted_cost = 0;
    2339             : 
    2340       67569 :         for (sb_index = 0; sb_index < picture_control_set_ptr->parent_pcs_ptr->sequence_control_set_ptr->sb_tot_cnt; sb_index++) {
    2341       66443 :             LargestCodingUnit* sb_ptr = picture_control_set_ptr->sb_ptr_array[sb_index];
    2342             : 
    2343       66443 :             set_sb_budget(
    2344             :                 sequence_control_set_ptr,
    2345             :                 picture_control_set_ptr,
    2346             :                 sb_ptr,
    2347             :                 context_ptr);
    2348             :         }
    2349             : 
    2350             :         // Compute the deviation between the predicted budget & the target budget
    2351        1126 :         deviation_to_target = (ABS((int32_t)(context_ptr->predicted_cost - context_ptr->budget)) * 1000) / context_ptr->budget;
    2352             :         // Derive shooting status
    2353        1126 :         if (context_ptr->predicted_cost < context_ptr->budget) {
    2354        1086 :             context_ptr->score_th[0] = MAX((context_ptr->score_th[0] - adjustement_step), 0);
    2355        1086 :             context_ptr->score_th[1] = MAX((context_ptr->score_th[1] - adjustement_step), 0);
    2356        1086 :             context_ptr->score_th[2] = MAX((context_ptr->score_th[2] - adjustement_step), 0);
    2357        1086 :             context_ptr->score_th[3] = MAX((context_ptr->score_th[3] - adjustement_step), 0);
    2358        1086 :             context_ptr->score_th[4] = MAX((context_ptr->score_th[4] - adjustement_step), 0);
    2359        1086 :             final_shooting = UNDER_SHOOTING;
    2360             :         }
    2361             :         else {
    2362          40 :             context_ptr->score_th[0] = (context_ptr->score_th[0] == 0) ? 0 : MIN(context_ptr->score_th[0] + adjustement_step, 100);
    2363          40 :             context_ptr->score_th[1] = (context_ptr->score_th[1] == 0) ? 0 : MIN(context_ptr->score_th[1] + adjustement_step, 100);
    2364          40 :             context_ptr->score_th[2] = (context_ptr->score_th[2] == 0) ? 0 : MIN(context_ptr->score_th[2] + adjustement_step, 100);
    2365          40 :             context_ptr->score_th[3] = (context_ptr->score_th[3] == 0) ? 0 : MIN(context_ptr->score_th[3] + adjustement_step, 100);
    2366          40 :             context_ptr->score_th[4] = (context_ptr->score_th[4] == 0) ? 0 : MIN(context_ptr->score_th[4] + adjustement_step, 100);
    2367          40 :             final_shooting = OVER_SHOOTING;
    2368             :         }
    2369             : 
    2370        1126 :         if (adjustement_iteration == 0)
    2371          58 :             initial_shooting = final_shooting;
    2372             : 
    2373        1126 :         adjustement_iteration++;
    2374             :     }
    2375          47 : }
    2376             : 
    2377          58 : EbErrorType derive_default_segments(
    2378             :     SequenceControlSet               *sequence_control_set_ptr,
    2379             :     ModeDecisionConfigurationContext *context_ptr){
    2380          58 :     EbErrorType return_error = EB_ErrorNone;
    2381             : 
    2382          58 :     if (context_ptr->budget > (uint16_t)(sequence_control_set_ptr->sb_tot_cnt * U_140)) {
    2383           3 :         context_ptr->number_of_segments = 2;
    2384           3 :         context_ptr->score_th[0] = (int8_t)((1 * 100) / context_ptr->number_of_segments);
    2385           3 :         context_ptr->score_th[1] = (int8_t)((2 * 100) / context_ptr->number_of_segments);
    2386           3 :         context_ptr->score_th[2] = (int8_t)((3 * 100) / context_ptr->number_of_segments);
    2387           3 :         context_ptr->score_th[3] = (int8_t)((4 * 100) / context_ptr->number_of_segments);
    2388           3 :         context_ptr->interval_cost[0] = context_ptr->cost_depth_mode[SB_OPEN_LOOP_DEPTH_MODE      - 1];
    2389           3 :         context_ptr->interval_cost[1] = context_ptr->cost_depth_mode[SB_SQ_NON4_BLOCKS_DEPTH_MODE - 1];
    2390             :     }
    2391          55 :     else if (context_ptr->budget > (uint16_t)(sequence_control_set_ptr->sb_tot_cnt * U_115)) {
    2392          25 :         context_ptr->number_of_segments = 3;
    2393             : 
    2394          25 :         context_ptr->score_th[0] = (int8_t)((1 * 100) / context_ptr->number_of_segments);
    2395          25 :         context_ptr->score_th[1] = (int8_t)((2 * 100) / context_ptr->number_of_segments);
    2396          25 :         context_ptr->score_th[2] = (int8_t)((3 * 100) / context_ptr->number_of_segments);
    2397          25 :         context_ptr->score_th[3] = (int8_t)((4 * 100) / context_ptr->number_of_segments);
    2398             : 
    2399          25 :         context_ptr->interval_cost[0] = context_ptr->cost_depth_mode[SB_FAST_OPEN_LOOP_DEPTH_MODE - 1];
    2400          25 :         context_ptr->interval_cost[1] = context_ptr->cost_depth_mode[SB_OPEN_LOOP_DEPTH_MODE      - 1];
    2401          25 :         context_ptr->interval_cost[2] = context_ptr->cost_depth_mode[SB_SQ_NON4_BLOCKS_DEPTH_MODE - 1];
    2402             :     }
    2403             :     else {
    2404          30 :         context_ptr->number_of_segments = 4;
    2405             : 
    2406          30 :         context_ptr->score_th[0] = (int8_t)((1 * 100) / context_ptr->number_of_segments);
    2407          30 :         context_ptr->score_th[1] = (int8_t)((2 * 100) / context_ptr->number_of_segments);
    2408          30 :         context_ptr->score_th[2] = (int8_t)((3 * 100) / context_ptr->number_of_segments);
    2409          30 :         context_ptr->score_th[3] = (int8_t)((4 * 100) / context_ptr->number_of_segments);
    2410             : 
    2411          30 :         context_ptr->interval_cost[0] = context_ptr->cost_depth_mode[SB_PRED_OPEN_LOOP_DEPTH_MODE - 1];
    2412          30 :         context_ptr->interval_cost[1] = context_ptr->cost_depth_mode[SB_FAST_OPEN_LOOP_DEPTH_MODE - 1];
    2413          30 :         context_ptr->interval_cost[2] = context_ptr->cost_depth_mode[SB_OPEN_LOOP_DEPTH_MODE      - 1];
    2414          30 :         context_ptr->interval_cost[3] = context_ptr->cost_depth_mode[SB_SQ_NON4_BLOCKS_DEPTH_MODE - 1];
    2415             :     }
    2416             : 
    2417          58 :     return return_error;
    2418             : }
    2419             : /******************************************************
    2420             : * Compute the score of each LCU
    2421             :     Input   : distortion, detection signals
    2422             :     Output  : LCU score
    2423             : ******************************************************/
    2424          58 : void derive_sb_score(
    2425             :     SequenceControlSet               *sequence_control_set_ptr,
    2426             :     PictureControlSet                *picture_control_set_ptr,
    2427             :     ModeDecisionConfigurationContext *context_ptr)
    2428             : {
    2429             :     uint32_t  sb_index;
    2430          58 :     uint32_t  sb_score = 0;
    2431             :     uint32_t  distortion;
    2432          58 :     uint64_t  sb_tot_score = 0;
    2433          58 :     context_ptr->sb_min_score = ~0u;
    2434          58 :     context_ptr->sb_max_score = 0u;
    2435             : 
    2436        3529 :     for (sb_index = 0; sb_index < sequence_control_set_ptr->sb_tot_cnt; sb_index++) {
    2437        3471 :         SbParams *sb_params = &sequence_control_set_ptr->sb_params_array[sb_index];
    2438        3471 :         if (picture_control_set_ptr->slice_type == I_SLICE)
    2439           0 :             assert(0);
    2440             :         else {
    2441        3471 :             if (sb_params->raster_scan_cu_validity[RASTER_SCAN_CU_INDEX_64x64]== EB_FALSE) {
    2442             :                 uint8_t cu8x8Index;
    2443         580 :                 uint8_t validCu8x8Count = 0;
    2444         580 :                 distortion = 0;
    2445       37700 :                 for (cu8x8Index = RASTER_SCAN_CU_INDEX_8x8_0; cu8x8Index <= RASTER_SCAN_CU_INDEX_8x8_63; cu8x8Index++) {
    2446       37120 :                     if (sb_params->raster_scan_cu_validity[cu8x8Index]) {
    2447       23200 :                         distortion = picture_control_set_ptr->parent_pcs_ptr->me_results[sb_index]->me_candidate[cu8x8Index][0].distortion;
    2448       23200 :                         validCu8x8Count++;
    2449             :                     }
    2450             :                 }
    2451         580 :                 if (validCu8x8Count > 0)
    2452         580 :                     distortion = (distortion / validCu8x8Count) * 64;
    2453             : 
    2454             :                 // Do not perform SB score manipulation for incomplete SBs as not valid signals
    2455         580 :                 sb_score = distortion;
    2456             :             }
    2457             :             else {
    2458        2891 :                 distortion = picture_control_set_ptr->parent_pcs_ptr->me_results[sb_index]->me_candidate[RASTER_SCAN_CU_INDEX_64x64][0].distortion;
    2459             :                 // Perform SB score manipulation for incomplete SBs for SQ mode
    2460        2891 :                 sb_score = distortion;
    2461             :             }
    2462             :         }
    2463        3471 :         context_ptr->sb_score_array[sb_index] = sb_score;
    2464             :         // Track MIN and MAX LCU scores
    2465        3471 :         context_ptr->sb_min_score = MIN(sb_score, context_ptr->sb_min_score);
    2466        3471 :         context_ptr->sb_max_score = MAX(sb_score, context_ptr->sb_max_score);
    2467        3471 :         sb_tot_score += sb_score;
    2468             :     }
    2469          58 :     context_ptr->sb_average_score = (uint32_t)(sb_tot_score / sequence_control_set_ptr->sb_tot_cnt);
    2470          58 : }
    2471             : 
    2472             : /******************************************************
    2473             : * Set the target budget
    2474             : Input   : cost per depth
    2475             : Output  : budget per picture
    2476             : ******************************************************/
    2477          58 : void set_target_budget_oq(
    2478             :     SequenceControlSet               *sequence_control_set_ptr,
    2479             :     PictureControlSet                *picture_control_set_ptr,
    2480             :     ModeDecisionConfigurationContext *context_ptr)
    2481             : {
    2482             :     uint32_t budget;
    2483             : 
    2484             :     // Luminosity-based budget boost - if P or B only; add 1 U for each 1 current-to-ref diff
    2485          58 :     uint32_t luminosity_change_boost = 0;
    2486          58 :     if (picture_control_set_ptr->slice_type != I_SLICE) {
    2487          58 :         if (picture_control_set_ptr->parent_pcs_ptr->is_used_as_reference_flag) {
    2488             :             EbReferenceObject  * ref_obj_l0, *ref_obj_l1;
    2489          28 :             ref_obj_l0 = (EbReferenceObject*)picture_control_set_ptr->ref_pic_ptr_array[REF_LIST_0][0]->object_ptr;
    2490          28 :             ref_obj_l1 = (picture_control_set_ptr->parent_pcs_ptr->slice_type == B_SLICE) ? (EbReferenceObject*)picture_control_set_ptr->ref_pic_ptr_array[REF_LIST_1][0]->object_ptr : (EbReferenceObject*)EB_NULL;
    2491          28 :             luminosity_change_boost = ABS(picture_control_set_ptr->parent_pcs_ptr->average_intensity[0] - ref_obj_l0->average_intensity);
    2492          28 :             luminosity_change_boost += (ref_obj_l1 != EB_NULL) ? ABS(picture_control_set_ptr->parent_pcs_ptr->average_intensity[0] - ref_obj_l1->average_intensity) : 0;
    2493          28 :             luminosity_change_boost = MAX(MAX_LUMINOSITY_BOOST, luminosity_change_boost);
    2494             :         }
    2495             :     }
    2496             :     // Hsan: cross multiplication to derive budget_per_sb from sb_average_score; budget_per_sb range is [SB_PRED_OPEN_LOOP_COST,U_150], and sb_average_score range [0,HIGH_SB_SCORE]
    2497             :     // Hsan: 3 segments [0,LOW_SB_SCORE], [LOW_SB_SCORE,MEDIUM_SB_SCORE] and [MEDIUM_SB_SCORE,U_150]
    2498             :     uint32_t budget_per_sb;
    2499          58 :     if (context_ptr->sb_average_score <= LOW_SB_SCORE)
    2500          33 :         budget_per_sb = ((context_ptr->sb_average_score * (SB_OPEN_LOOP_COST - SB_PRED_OPEN_LOOP_COST)) / LOW_SB_SCORE) + SB_PRED_OPEN_LOOP_COST;
    2501          25 :     else if (context_ptr->sb_average_score <= MEDIUM_SB_SCORE)
    2502          19 :         budget_per_sb = (((context_ptr->sb_average_score - LOW_SB_SCORE) * (U_125 - SB_OPEN_LOOP_COST)) / (MEDIUM_SB_SCORE - LOW_SB_SCORE)) + SB_OPEN_LOOP_COST;
    2503             :     else
    2504           6 :         budget_per_sb = (((context_ptr->sb_average_score - MEDIUM_SB_SCORE) * (U_150 - U_125)) / (HIGH_SB_SCORE - MEDIUM_SB_SCORE)) + U_125;
    2505          58 :     budget_per_sb = CLIP3(SB_PRED_OPEN_LOOP_COST, U_150, budget_per_sb + budget_per_sb_boost[context_ptr->adp_level] + luminosity_change_boost);
    2506             : 
    2507             :     //printf("picture_number = %d\tsb_average_score = %d\n", picture_control_set_ptr->picture_number, budget_per_sb);
    2508          58 :     budget = sequence_control_set_ptr->sb_tot_cnt * budget_per_sb;
    2509             : 
    2510          58 :     context_ptr->budget = budget;
    2511          58 : }
    2512             : 
    2513             : /******************************************************
    2514             : * Assign a search method for each LCU
    2515             :     Input   : LCU score, detection signals
    2516             :     Output  : search method for each LCU
    2517             : ******************************************************/
    2518          58 : void derive_sb_md_mode(
    2519             :     SequenceControlSet               *sequence_control_set_ptr,
    2520             :     PictureControlSet                *picture_control_set_ptr,
    2521             :     ModeDecisionConfigurationContext *context_ptr) {
    2522             :     // Configure ADP
    2523          58 :     configure_adp(
    2524             :         picture_control_set_ptr,
    2525             :         context_ptr);
    2526             : 
    2527             :     // Derive SB score
    2528          58 :     derive_sb_score(
    2529             :         sequence_control_set_ptr,
    2530             :         picture_control_set_ptr,
    2531             :         context_ptr);
    2532             : 
    2533             :     // Set the target budget
    2534          58 :     set_target_budget_oq(
    2535             :         sequence_control_set_ptr,
    2536             :         picture_control_set_ptr,
    2537             :         context_ptr);
    2538             : 
    2539             :     // Set the percentage based thresholds
    2540          58 :     derive_default_segments(
    2541             :         sequence_control_set_ptr,
    2542             :         context_ptr);
    2543             :     // Perform Budgetting
    2544          58 :     derive_optimal_budget_per_sb(
    2545             :         sequence_control_set_ptr,
    2546             :         picture_control_set_ptr,
    2547             :         context_ptr);
    2548             : 
    2549             :     // Set the search method using the LCU cost (mapping)
    2550          58 :     derive_search_method(
    2551             :         picture_control_set_ptr,
    2552             :         context_ptr);
    2553          58 : }
    2554             : 
    2555             : /******************************************************
    2556             : * Derive Mode Decision Config Settings for OQ
    2557             : Input   : encoder mode and tune
    2558             : Output  : EncDec Kernel signal(s)
    2559             : ******************************************************/
    2560         120 : EbErrorType signal_derivation_mode_decision_config_kernel_oq(
    2561             :     SequenceControlSet               *sequence_control_set_ptr,
    2562             :     PictureControlSet                *picture_control_set_ptr,
    2563             :     ModeDecisionConfigurationContext *context_ptr)
    2564             : {
    2565             :     UNUSED(sequence_control_set_ptr);
    2566         120 :     EbErrorType return_error = EB_ErrorNone;
    2567             : 
    2568         120 :     context_ptr->adp_level = picture_control_set_ptr->parent_pcs_ptr->enc_mode;
    2569             : 
    2570         120 :     if (picture_control_set_ptr->parent_pcs_ptr->sc_content_detected)
    2571           0 :         if (picture_control_set_ptr->enc_mode <= ENC_M6)
    2572           0 :             picture_control_set_ptr->update_cdf = 1;
    2573             :         else
    2574           0 :             picture_control_set_ptr->update_cdf = 0;
    2575             :     else
    2576         120 :     picture_control_set_ptr->update_cdf = (picture_control_set_ptr->parent_pcs_ptr->enc_mode <= ENC_M5) ? 1 : 0;
    2577             : 
    2578         120 :     if(picture_control_set_ptr->update_cdf)
    2579          60 :         assert(sequence_control_set_ptr->cdf_mode == 0 && "use cdf_mode 0");
    2580             : #if FILTER_INTRA_FLAG
    2581             :     //Filter Intra Mode : 0: OFF  1: ON
    2582         120 :     if (sequence_control_set_ptr->seq_header.enable_filter_intra)
    2583          60 :         picture_control_set_ptr->pic_filter_intra_mode = picture_control_set_ptr->parent_pcs_ptr->sc_content_detected == 0 && picture_control_set_ptr->temporal_layer_index == 0 ? 1 : 0;
    2584             :     else
    2585          60 :         picture_control_set_ptr->pic_filter_intra_mode = 0;
    2586             : 
    2587             : #endif
    2588         120 :     return return_error;
    2589             : }
    2590             : 
    2591           2 : void forward_sq_non4_blocks_to_md(
    2592             :     SequenceControlSet                   *sequence_control_set_ptr,
    2593             :     PictureControlSet                    *picture_control_set_ptr)
    2594             : {
    2595             :     uint32_t                   sb_index;
    2596             :     EbBool                  split_flag;
    2597             : 
    2598         122 :     for (sb_index = 0; sb_index < sequence_control_set_ptr->sb_tot_cnt; ++sb_index)
    2599             :     {
    2600         120 :         MdcLcuData *resultsPtr = &picture_control_set_ptr->mdc_sb_array[sb_index];
    2601             : 
    2602         120 :         resultsPtr->leaf_count = 0;
    2603             : 
    2604         120 :         uint32_t  blk_index = picture_control_set_ptr->slice_type == I_SLICE && sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128 ? 17 : 0;
    2605             : 
    2606       12240 :         while (blk_index < sequence_control_set_ptr->max_block_cnt)
    2607             :         {
    2608       12120 :             split_flag = EB_TRUE;
    2609             : 
    2610       12120 :             const BlockGeom * blk_geom = get_blk_geom_mds(blk_index);
    2611             : 
    2612             :             //if the parentSq is inside inject this block
    2613       12120 :             if (sequence_control_set_ptr->sb_geom[sb_index].block_is_inside_md_scan[blk_index])
    2614             : 
    2615             :             {
    2616             :                 //int32_t offset_d1 = ns_blk_offset[(int32_t)from_shape_to_part[blk_geom->shape]]; //cu_ptr->best_d1_blk; // TOCKECK
    2617             :                 //int32_t num_d1_block = ns_blk_num[(int32_t)from_shape_to_part[blk_geom->shape]]; // context_ptr->blk_geom->totns; // TOCKECK
    2618             :                 //
    2619             :                 //                                                  // for (int32_t d1_itr = blk_it; d1_itr < blk_it + num_d1_block; d1_itr++) {
    2620             :                 // for (int32_t d1_itr = (int32_t)blk_index ; d1_itr < (int32_t)blk_index +  num_d1_block ; d1_itr++) {
    2621        9500 :                 resultsPtr->leaf_data_array[resultsPtr->leaf_count].tot_d1_blocks = 1;
    2622             : 
    2623        9500 :                 resultsPtr->leaf_data_array[resultsPtr->leaf_count].leaf_index = 0;//valid only for square 85 world. will be removed.
    2624        9500 :                 resultsPtr->leaf_data_array[resultsPtr->leaf_count].mds_idx = blk_index;
    2625             : 
    2626        9500 :                 if (blk_geom->sq_size > 8)
    2627             :                 {
    2628        2300 :                     resultsPtr->leaf_data_array[resultsPtr->leaf_count++].split_flag = EB_TRUE;
    2629        2300 :                     split_flag = EB_TRUE;
    2630             :                 }
    2631             :                 else {
    2632        7200 :                     resultsPtr->leaf_data_array[resultsPtr->leaf_count++].split_flag = EB_FALSE;
    2633        7200 :                     split_flag = EB_FALSE;
    2634             :                 }
    2635             :             }
    2636             : 
    2637       12120 :             blk_index += split_flag ? d1_depth_offset[sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128][blk_geom->depth] : ns_depth_offset[sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128][blk_geom->depth];
    2638             :         }
    2639             :     }
    2640             : 
    2641           2 :     picture_control_set_ptr->parent_pcs_ptr->average_qp = (uint8_t)picture_control_set_ptr->parent_pcs_ptr->picture_qp;
    2642           2 : }
    2643             : 
    2644         855 : void sb_forward_sq_non4_blocks_to_md(
    2645             :     SequenceControlSet *sequence_control_set_ptr,
    2646             :     PictureControlSet  *picture_control_set_ptr,
    2647             :     uint32_t              sb_index)
    2648             : {
    2649             :     EbBool split_flag;
    2650         855 :     MdcLcuData *resultsPtr = &picture_control_set_ptr->mdc_sb_array[sb_index];
    2651         855 :     resultsPtr->leaf_count = 0;
    2652         855 :     uint32_t blk_index = picture_control_set_ptr->slice_type == I_SLICE && sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128 ? 17 : 0;
    2653             : 
    2654       75162 :     while (blk_index < sequence_control_set_ptr->max_block_cnt)
    2655             :     {
    2656       74307 :         split_flag = EB_TRUE;
    2657       74307 :         const BlockGeom * blk_geom = get_blk_geom_mds(blk_index);
    2658       74307 :         if (sequence_control_set_ptr->sb_geom[sb_index].block_is_inside_md_scan[blk_index])
    2659             :         {
    2660       72080 :             resultsPtr->leaf_data_array[resultsPtr->leaf_count].tot_d1_blocks = 1;
    2661             : 
    2662       72080 :             resultsPtr->leaf_data_array[resultsPtr->leaf_count].leaf_index = 0;//valid only for square 85 world. will be removed.
    2663       72080 :             resultsPtr->leaf_data_array[resultsPtr->leaf_count].mds_idx = blk_index;
    2664             : 
    2665       72080 :             if (blk_geom->sq_size > 8)
    2666             :             {
    2667       17768 :                 resultsPtr->leaf_data_array[resultsPtr->leaf_count++].split_flag = EB_TRUE;
    2668       17768 :                 split_flag = EB_TRUE;
    2669             :             }
    2670             :             else {
    2671       54312 :                 resultsPtr->leaf_data_array[resultsPtr->leaf_count++].split_flag = EB_FALSE;
    2672       54312 :                 split_flag = EB_FALSE;
    2673             :             }
    2674             :         }
    2675       74307 :         blk_index += split_flag ? d1_depth_offset[sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128][blk_geom->depth] : ns_depth_offset[sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128][blk_geom->depth];
    2676             :     }
    2677         855 :     picture_control_set_ptr->parent_pcs_ptr->average_qp = (uint8_t)picture_control_set_ptr->parent_pcs_ptr->picture_qp;
    2678         855 : }
    2679             : 
    2680           0 : void forward_all_c_blocks_to_md(
    2681             :     SequenceControlSet   *sequence_control_set_ptr,
    2682             :     PictureControlSet    *picture_control_set_ptr){
    2683             :     uint32_t                sb_index;
    2684           0 :     for (sb_index = 0; sb_index < sequence_control_set_ptr->sb_tot_cnt; ++sb_index){
    2685           0 :         MdcLcuData *resultsPtr = &picture_control_set_ptr->mdc_sb_array[sb_index];
    2686           0 :         resultsPtr->leaf_count = 0;
    2687           0 :         uint32_t blk_index = 0;
    2688             :         uint32_t tot_d1_blocks;
    2689             : 
    2690           0 :         while (blk_index < sequence_control_set_ptr->max_block_cnt)
    2691             :         {
    2692           0 :             tot_d1_blocks = 0;
    2693           0 :             const BlockGeom * blk_geom = get_blk_geom_mds(blk_index);
    2694             : 
    2695             :             //if the parentSq is inside inject this block
    2696           0 :             uint8_t is_blk_allowed = picture_control_set_ptr->slice_type != I_SLICE ? 1 : (blk_geom->sq_size < 128) ? 1 : 0;
    2697             : 
    2698           0 :             if (sequence_control_set_ptr->sb_geom[sb_index].block_is_inside_md_scan[blk_index] && is_blk_allowed){
    2699           0 :                 tot_d1_blocks = resultsPtr->leaf_data_array[resultsPtr->leaf_count].tot_d1_blocks =
    2700             : 
    2701           0 :                     blk_geom->sq_size == 128 ? 17 :
    2702           0 :                     blk_geom->sq_size > 16 ? 25 :
    2703           0 :                     blk_geom->sq_size == 16 ? 17 :
    2704             :                     blk_geom->sq_size == 8 ? 1 : 1;
    2705             : 
    2706           0 :                 for (uint32_t idx = 0; idx < tot_d1_blocks; ++idx) {
    2707           0 :                     blk_geom = get_blk_geom_mds(blk_index);
    2708             : 
    2709             :                     //if the parentSq is inside inject this block
    2710           0 :                     if (sequence_control_set_ptr->sb_geom[sb_index].block_is_inside_md_scan[blk_index]){
    2711           0 :                         resultsPtr->leaf_data_array[resultsPtr->leaf_count].leaf_index = 0;//valid only for square 85 world. will be removed.
    2712           0 :                         resultsPtr->leaf_data_array[resultsPtr->leaf_count].mds_idx = blk_index;
    2713           0 :                         if (blk_geom->sq_size > 4)
    2714           0 :                             resultsPtr->leaf_data_array[resultsPtr->leaf_count++].split_flag = EB_TRUE;
    2715             :                         else
    2716           0 :                             resultsPtr->leaf_data_array[resultsPtr->leaf_count++].split_flag = EB_FALSE;
    2717             :                     }
    2718           0 :                     blk_index++;
    2719             :                 }
    2720             :             }
    2721           0 :             blk_index += (d1_depth_offset[sequence_control_set_ptr->seq_header.sb_size == BLOCK_128X128][blk_geom->depth] - tot_d1_blocks);
    2722             :         }
    2723             :     }
    2724             : 
    2725           0 :     picture_control_set_ptr->parent_pcs_ptr->average_qp = (uint8_t)picture_control_set_ptr->parent_pcs_ptr->picture_qp;
    2726           0 : }
    2727             : void av1_set_ref_frame(MvReferenceFrame *rf,
    2728             :     int8_t ref_frame_type);
    2729             : 
    2730        1430 : static INLINE int get_relative_dist(const OrderHintInfo *oh, int a, int b) {
    2731        1430 :     if (!oh->enable_order_hint) return 0;
    2732             : 
    2733        1430 :     const int bits = oh->order_hint_bits;
    2734             : 
    2735        1430 :     assert(bits >= 1);
    2736        1430 :     assert(a >= 0 && a < (1 << bits));
    2737        1430 :     assert(b >= 0 && b < (1 << bits));
    2738             : 
    2739        1430 :     int diff = a - b;
    2740        1430 :     const int m = 1 << (bits - 1);
    2741        1430 :     diff = (diff & (m - 1)) - (diff & m);
    2742        1430 :     return diff;
    2743             : }
    2744             : 
    2745      397892 : static int get_block_position(Av1Common *cm, int *mi_r, int *mi_c, int blk_row,
    2746             :     int blk_col, MV mv, int sign_bias) {
    2747      397892 :     const int base_blk_row = (blk_row >> 3) << 3;
    2748      397892 :     const int base_blk_col = (blk_col >> 3) << 3;
    2749             : 
    2750      916259 :     const int row_offset = (mv.row >= 0) ? (mv.row >> (4 + MI_SIZE_LOG2))
    2751      397892 :         : -((-mv.row) >> (4 + MI_SIZE_LOG2));
    2752             : 
    2753      807126 :     const int col_offset = (mv.col >= 0) ? (mv.col >> (4 + MI_SIZE_LOG2))
    2754      397892 :         : -((-mv.col) >> (4 + MI_SIZE_LOG2));
    2755             : 
    2756      397892 :     const int row =
    2757      397892 :         (sign_bias == 1) ? blk_row - row_offset : blk_row + row_offset;
    2758      397892 :     const int col =
    2759      397892 :         (sign_bias == 1) ? blk_col - col_offset : blk_col + col_offset;
    2760             : 
    2761      397892 :     if (row < 0 || row >= (cm->mi_rows >> 1) || col < 0 ||
    2762      396971 :         col >= (cm->mi_cols >> 1))
    2763        1288 :         return 0;
    2764             : 
    2765      396604 :     if (row < base_blk_row - (MAX_OFFSET_HEIGHT >> 3) ||
    2766      393629 :         row >= base_blk_row + 8 + (MAX_OFFSET_HEIGHT >> 3) ||
    2767      390776 :         col < base_blk_col - (MAX_OFFSET_WIDTH >> 3) ||
    2768      390778 :         col >= base_blk_col + 8 + (MAX_OFFSET_WIDTH >> 3))
    2769        5828 :         return 0;
    2770             : 
    2771      390776 :     *mi_r = row;
    2772      390776 :     *mi_c = col;
    2773             : 
    2774      390776 :     return 1;
    2775             : }
    2776             : 
    2777             : #define MFMV_STACK_SIZE 3
    2778             : 
    2779             : // Note: motion_filed_projection finds motion vectors of current frame's
    2780             : // reference frame, and projects them to current frame. To make it clear,
    2781             : // let's call current frame's reference frame as start frame.
    2782             : // Call Start frame's reference frames as reference frames.
    2783             : // Call ref_offset as frame distances between start frame and its reference
    2784             : // frames.
    2785         145 : static int motion_field_projection(Av1Common *cm, PictureControlSet       *picture_control_set_ptr,
    2786             :     MvReferenceFrame start_frame, int dir) {
    2787         145 :     TPL_MV_REF *tpl_mvs_base = picture_control_set_ptr->tpl_mvs;
    2788         145 :     int ref_offset[REF_FRAMES] = { 0 };
    2789             : 
    2790             :     MvReferenceFrame rf[2];
    2791         145 :     av1_set_ref_frame(rf, start_frame);
    2792             : 
    2793             :     uint8_t list_idx0, ref_idx_l0;
    2794         145 :     list_idx0 = get_list_idx(start_frame);
    2795         145 :     ref_idx_l0 = get_ref_frame_idx(start_frame);
    2796         145 :     EbReferenceObject *start_frame_buf = (EbReferenceObject*)picture_control_set_ptr->ref_pic_ptr_array[list_idx0][ref_idx_l0]->object_ptr;
    2797             : 
    2798         145 :     if (start_frame_buf == NULL) return 0;
    2799             : 
    2800         145 :     if (start_frame_buf->frame_type == KEY_FRAME ||
    2801         144 :         start_frame_buf->frame_type == INTRA_ONLY_FRAME)
    2802          25 :         return 0;
    2803             : 
    2804         120 :     const int start_frame_order_hint = start_frame_buf->order_hint;
    2805         120 :     const unsigned int *const ref_order_hints = &start_frame_buf->ref_order_hint[0];
    2806         120 :     const int cur_order_hint = picture_control_set_ptr->parent_pcs_ptr->cur_order_hint;
    2807         120 :     int start_to_current_frame_offset = get_relative_dist(
    2808         120 :         &picture_control_set_ptr->parent_pcs_ptr->sequence_control_set_ptr->seq_header.order_hint_info, start_frame_order_hint, cur_order_hint);
    2809             : 
    2810         960 :     for (MvReferenceFrame rf = LAST_FRAME; rf <= INTER_REFS_PER_FRAME; ++rf) {
    2811         840 :         ref_offset[rf] = get_relative_dist(&picture_control_set_ptr->parent_pcs_ptr->sequence_control_set_ptr->seq_header.order_hint_info,
    2812             :             start_frame_order_hint,
    2813         840 :             ref_order_hints[rf - LAST_FRAME]);
    2814             :     }
    2815             : 
    2816         120 :     if (dir == 2) start_to_current_frame_offset = -start_to_current_frame_offset;
    2817             : 
    2818         120 :     MV_REF *mv_ref_base = start_frame_buf->mvs;
    2819         120 :     const int mvs_rows = (cm->mi_rows + 1) >> 1;
    2820         120 :     const int mvs_cols = (cm->mi_cols + 1) >> 1;
    2821             : 
    2822        5590 :     for (int blk_row = 0; blk_row < mvs_rows; ++blk_row) {
    2823      435624 :         for (int blk_col = 0; blk_col < mvs_cols; ++blk_col) {
    2824      430154 :             MV_REF *mv_ref = &mv_ref_base[blk_row * mvs_cols + blk_col];
    2825      430154 :             MV fwd_mv = mv_ref->mv.as_mv;
    2826             : 
    2827      430154 :             if (mv_ref->ref_frame > INTRA_FRAME) {
    2828             :                 IntMv this_mv;
    2829             :                 int mi_r, mi_c;
    2830      396366 :                 const int ref_frame_offset = ref_offset[mv_ref->ref_frame];
    2831             : 
    2832      396366 :                 int pos_valid =
    2833      396366 :                     abs(ref_frame_offset) <= MAX_FRAME_DISTANCE &&
    2834     1188720 :                     ref_frame_offset > 0 &&
    2835      395988 :                     abs(start_to_current_frame_offset) <= MAX_FRAME_DISTANCE;
    2836             : 
    2837      396366 :                 if (pos_valid) {
    2838      395999 :                     get_mv_projection(&this_mv.as_mv, fwd_mv,
    2839             :                         start_to_current_frame_offset, ref_frame_offset);
    2840      395053 :                     pos_valid = get_block_position(cm, &mi_r, &mi_c, blk_row, blk_col,
    2841             :                         this_mv.as_mv, dir >> 1);
    2842             :                 }
    2843             : 
    2844      396437 :                 if (pos_valid) {
    2845      389806 :                     const int mi_offset = mi_r * (cm->mi_stride >> 1) + mi_c;
    2846             : 
    2847      389806 :                     tpl_mvs_base[mi_offset].mfmv0.as_mv.row = fwd_mv.row;
    2848      389806 :                     tpl_mvs_base[mi_offset].mfmv0.as_mv.col = fwd_mv.col;
    2849      389806 :                     tpl_mvs_base[mi_offset].ref_frame_offset = ref_frame_offset;
    2850             :                 }
    2851             :             }
    2852             :         }
    2853             :     }
    2854             : 
    2855         191 :     return 1;
    2856             : }
    2857          47 : void av1_setup_motion_field(
    2858             :     Av1Common               *cm,
    2859             :     PictureControlSet       *picture_control_set_ptr)
    2860             : {
    2861             : 
    2862          47 :     const OrderHintInfo *const order_hint_info = &picture_control_set_ptr->parent_pcs_ptr->sequence_control_set_ptr->seq_header.order_hint_info;
    2863          47 :     memset(picture_control_set_ptr->ref_frame_side, 0, sizeof(picture_control_set_ptr->ref_frame_side));
    2864          47 :     if (!order_hint_info->enable_order_hint) return;
    2865             : 
    2866          47 :     TPL_MV_REF *tpl_mvs_base = picture_control_set_ptr->tpl_mvs;
    2867          47 :     int size = ((cm->mi_rows + MAX_MIB_SIZE) >> 1) * (cm->mi_stride >> 1);
    2868      229407 :     for (int idx = 0; idx < size; ++idx) {
    2869      229360 :         tpl_mvs_base[idx].mfmv0.as_int = INVALID_MV;
    2870      229360 :         tpl_mvs_base[idx].ref_frame_offset = 0;
    2871             :     }
    2872             : 
    2873          47 :     const int cur_order_hint = picture_control_set_ptr->parent_pcs_ptr->cur_order_hint;
    2874             :     const EbReferenceObject *ref_buf[INTER_REFS_PER_FRAME];
    2875             :     int ref_order_hint[INTER_REFS_PER_FRAME];
    2876             : 
    2877         376 :     for (int ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++)
    2878             :     {
    2879         329 :         const int ref_idx = ref_frame - LAST_FRAME;
    2880         329 :         int order_hint = 0;
    2881             :         uint8_t list_idx0, ref_idx_l0;
    2882         329 :         list_idx0 = get_list_idx(ref_frame);
    2883         329 :         ref_idx_l0 = get_ref_frame_idx(ref_frame);
    2884         329 :         EbReferenceObject *buf = (EbReferenceObject*)picture_control_set_ptr->ref_pic_ptr_array[list_idx0][ref_idx_l0]->object_ptr;
    2885             : 
    2886         329 :         if (buf != NULL) order_hint = buf->order_hint;
    2887             : 
    2888         329 :         ref_buf[ref_idx] = buf;
    2889         329 :         ref_order_hint[ref_idx] = order_hint;
    2890             : 
    2891         329 :         if (get_relative_dist(order_hint_info, order_hint, cur_order_hint) > 0)
    2892         135 :             picture_control_set_ptr->ref_frame_side[ref_frame] = 1;
    2893         194 :         else if (order_hint == cur_order_hint)
    2894           0 :             picture_control_set_ptr->ref_frame_side[ref_frame] = -1;
    2895             :     }
    2896             : 
    2897          47 :     int ref_stamp = MFMV_STACK_SIZE - 1;
    2898             : 
    2899          47 :     if (ref_buf[LAST_FRAME - LAST_FRAME] != NULL) {
    2900          47 :         const int alt_of_lst_order_hint = ref_buf[LAST_FRAME - LAST_FRAME]->ref_order_hint[ALTREF_FRAME - LAST_FRAME];
    2901          47 :         const int is_lst_overlay = (alt_of_lst_order_hint == ref_order_hint[GOLDEN_FRAME - LAST_FRAME]);
    2902          47 :         if (!is_lst_overlay)
    2903          39 :             motion_field_projection(cm, picture_control_set_ptr, LAST_FRAME, 2);
    2904             : 
    2905          47 :         --ref_stamp;
    2906             :     }
    2907             : 
    2908          47 :     if (get_relative_dist(order_hint_info, ref_order_hint[BWDREF_FRAME - LAST_FRAME], cur_order_hint) > 0) {
    2909          45 :         if (motion_field_projection(cm, picture_control_set_ptr, BWDREF_FRAME, 0)) --ref_stamp;
    2910             :     }
    2911             : 
    2912          47 :     if (get_relative_dist(order_hint_info, ref_order_hint[ALTREF2_FRAME - LAST_FRAME], cur_order_hint) > 0) {
    2913          45 :         if (motion_field_projection(cm, picture_control_set_ptr, ALTREF2_FRAME, 0)) --ref_stamp;
    2914             :     }
    2915             : 
    2916          47 :     if (get_relative_dist(order_hint_info, ref_order_hint[ALTREF_FRAME - LAST_FRAME], cur_order_hint) > 0 && ref_stamp >= 0)
    2917          10 :         if (motion_field_projection(cm, picture_control_set_ptr, ALTREF_FRAME, 0)) --ref_stamp;
    2918             : 
    2919          47 :     if (ref_stamp >= 0) motion_field_projection(cm, picture_control_set_ptr, LAST2_FRAME, 2);
    2920             : }
    2921             : /******************************************************
    2922             :  * Mode Decision Configuration Kernel
    2923             :  ******************************************************/
    2924           6 : void* mode_decision_configuration_kernel(void *input_ptr)
    2925             : {
    2926             :     // Context & SCS & PCS
    2927           6 :     ModeDecisionConfigurationContext         *context_ptr = (ModeDecisionConfigurationContext*)input_ptr;
    2928             :     PictureControlSet                        *picture_control_set_ptr;
    2929             :     SequenceControlSet                       *sequence_control_set_ptr;
    2930             :     FrameHeader                              *frm_hdr;
    2931             :     // Input
    2932             :     EbObjectWrapper                          *rateControlResultsWrapperPtr;
    2933             :     RateControlResults                       *rateControlResultsPtr;
    2934             : 
    2935             :     // Output
    2936             :     EbObjectWrapper                          *encDecTasksWrapperPtr;
    2937             :     EncDecTasks                              *encDecTasksPtr;
    2938             : 
    2939         120 :     for (;;) {
    2940             :         // Get RateControl Results
    2941         126 :         eb_get_full_object(
    2942             :             context_ptr->rate_control_input_fifo_ptr,
    2943             :             &rateControlResultsWrapperPtr);
    2944             : 
    2945         120 :         rateControlResultsPtr = (RateControlResults*)rateControlResultsWrapperPtr->object_ptr;
    2946         120 :         picture_control_set_ptr = (PictureControlSet*)rateControlResultsPtr->picture_control_set_wrapper_ptr->object_ptr;
    2947         120 :         sequence_control_set_ptr = (SequenceControlSet*)picture_control_set_ptr->sequence_control_set_wrapper_ptr->object_ptr;
    2948         120 :         if (picture_control_set_ptr->parent_pcs_ptr->frm_hdr.use_ref_frame_mvs)
    2949          47 :             av1_setup_motion_field(picture_control_set_ptr->parent_pcs_ptr->av1_cm, picture_control_set_ptr);
    2950             : 
    2951         120 :         frm_hdr = &picture_control_set_ptr->parent_pcs_ptr->frm_hdr;
    2952             : 
    2953             :         // Mode Decision Configuration Kernel Signal(s) derivation
    2954         120 :         signal_derivation_mode_decision_config_kernel_oq(
    2955             :             sequence_control_set_ptr,
    2956             :             picture_control_set_ptr,
    2957             :             context_ptr);
    2958             : 
    2959         120 :         context_ptr->qp = picture_control_set_ptr->picture_qp;
    2960             : 
    2961         120 :         picture_control_set_ptr->parent_pcs_ptr->average_qp = 0;
    2962         120 :         picture_control_set_ptr->intra_coded_area = 0;
    2963             :         // Compute picture and slice level chroma QP offsets
    2964         120 :         SetSliceAndPictureChromaQpOffsets( // HT done
    2965             :             picture_control_set_ptr);
    2966             : 
    2967             :         // Compute Tc, and Beta offsets for a given picture
    2968             :         // Set reference cdef strength
    2969         120 :         set_reference_cdef_strength(
    2970             :             picture_control_set_ptr);
    2971             : 
    2972             :         // Set reference sg ep
    2973         120 :         set_reference_sg_ep(
    2974             :             picture_control_set_ptr);
    2975         120 :         SetGlobalMotionField(
    2976             :             picture_control_set_ptr);
    2977             : 
    2978         120 :         eb_av1_qm_init(
    2979         120 :             picture_control_set_ptr->parent_pcs_ptr);
    2980             : 
    2981         120 :         Quants *const quants = &picture_control_set_ptr->parent_pcs_ptr->quants;
    2982         120 :         Dequants *const dequants = &picture_control_set_ptr->parent_pcs_ptr->deq;
    2983             : 
    2984         120 :         eb_av1_set_quantizer(
    2985         120 :             picture_control_set_ptr->parent_pcs_ptr,
    2986         120 :             frm_hdr->quantization_params.base_q_idx);
    2987         120 :         eb_av1_build_quantizer(
    2988         120 :             (AomBitDepth)sequence_control_set_ptr->static_config.encoder_bit_depth,
    2989         120 :             frm_hdr->quantization_params.delta_q_y_dc,
    2990         120 :             frm_hdr->quantization_params.delta_q_u_dc,
    2991         120 :             frm_hdr->quantization_params.delta_q_u_ac,
    2992         120 :             frm_hdr->quantization_params.delta_q_v_dc,
    2993         120 :             frm_hdr->quantization_params.delta_q_v_ac,
    2994             :             quants,
    2995             :             dequants);
    2996             : 
    2997         120 :         Quants *const quantsMd = &picture_control_set_ptr->parent_pcs_ptr->quantsMd;
    2998         120 :         Dequants *const dequantsMd = &picture_control_set_ptr->parent_pcs_ptr->deqMd;
    2999         120 :         eb_av1_build_quantizer(
    3000         120 :             picture_control_set_ptr->hbd_mode_decision ? AOM_BITS_10 : AOM_BITS_8,
    3001         120 :             frm_hdr->quantization_params.delta_q_y_dc,
    3002         120 :             frm_hdr->quantization_params.delta_q_u_dc,
    3003         120 :             frm_hdr->quantization_params.delta_q_u_ac,
    3004         120 :             frm_hdr->quantization_params.delta_q_v_dc,
    3005         120 :             frm_hdr->quantization_params.delta_q_v_ac,
    3006             :             quantsMd,
    3007             :             dequantsMd);
    3008             : 
    3009             :         // Hsan: collapse spare code
    3010             :         MdRateEstimationContext   *md_rate_estimation_array;
    3011             :         uint32_t                     entropyCodingQp;
    3012             : 
    3013             :         // QP
    3014         120 :         context_ptr->qp = picture_control_set_ptr->picture_qp;
    3015             : 
    3016             :         // QP Index
    3017         120 :         context_ptr->qp_index = (uint8_t)frm_hdr->quantization_params.base_q_idx;
    3018             : 
    3019             :         // Lambda Assignement
    3020             :         uint32_t lambdaSse;
    3021             :         uint32_t lambdaSad;
    3022         120 :         (*av1_lambda_assignment_function_table[picture_control_set_ptr->parent_pcs_ptr->pred_structure])(
    3023             :             &lambdaSad,
    3024             :             &lambdaSse,
    3025             :             &lambdaSad,
    3026             :             &lambdaSse,
    3027         120 :             (uint8_t)picture_control_set_ptr->parent_pcs_ptr->enhanced_picture_ptr->bit_depth,
    3028         120 :             context_ptr->qp_index,
    3029         120 :             picture_control_set_ptr->hbd_mode_decision);
    3030         120 :         context_ptr->lambda = (uint64_t)lambdaSad;
    3031             : #if ADD_MDC_FULL_COST
    3032         120 :         context_ptr->full_lambda = (uint64_t)lambdaSse;
    3033             : #endif
    3034         120 :         md_rate_estimation_array = picture_control_set_ptr->md_rate_estimation_array;
    3035             :         // Reset MD rate Estimation table to initial values by copying from md_rate_estimation_array
    3036         120 :         if (context_ptr->is_md_rate_estimation_ptr_owner) {
    3037           6 :             EB_FREE_ARRAY(context_ptr->md_rate_estimation_ptr);
    3038           6 :             context_ptr->is_md_rate_estimation_ptr_owner = EB_FALSE;
    3039             :         }
    3040         120 :         context_ptr->md_rate_estimation_ptr = md_rate_estimation_array;
    3041             : 
    3042         120 :         entropyCodingQp = frm_hdr->quantization_params.base_q_idx;
    3043         120 :         if (picture_control_set_ptr->parent_pcs_ptr->frm_hdr.primary_ref_frame != PRIMARY_REF_NONE)
    3044          58 :             memcpy(picture_control_set_ptr->coeff_est_entropy_coder_ptr->fc, &picture_control_set_ptr->ref_frame_context[picture_control_set_ptr->parent_pcs_ptr->frm_hdr.primary_ref_frame], sizeof(FRAME_CONTEXT));
    3045             :         else
    3046          62 :             reset_entropy_coder(
    3047             :                 sequence_control_set_ptr->encode_context_ptr,
    3048             :                 picture_control_set_ptr->coeff_est_entropy_coder_ptr,
    3049             :                 entropyCodingQp,
    3050          62 :                 picture_control_set_ptr->slice_type);
    3051             : 
    3052             :         // Initial Rate Estimatimation of the syntax elements
    3053         120 :         av1_estimate_syntax_rate(
    3054             :             md_rate_estimation_array,
    3055         120 :             picture_control_set_ptr->slice_type == I_SLICE ? EB_TRUE : EB_FALSE,
    3056         120 :             picture_control_set_ptr->coeff_est_entropy_coder_ptr->fc);
    3057             : #if !FIX_ENABLE_CDF_UPDATE
    3058             :         // Initial Rate Estimatimation of the syntax elements
    3059             :         if (!md_rate_estimation_array->initialized)
    3060             :             av1_estimate_syntax_rate(
    3061             :                 md_rate_estimation_array,
    3062             :                 picture_control_set_ptr->slice_type == I_SLICE ? EB_TRUE : EB_FALSE,
    3063             :                 picture_control_set_ptr->coeff_est_entropy_coder_ptr->fc);
    3064             : #endif
    3065             :         // Initial Rate Estimatimation of the Motion vectors
    3066         120 :         av1_estimate_mv_rate(
    3067             :             picture_control_set_ptr,
    3068             :             md_rate_estimation_array,
    3069         120 :             &picture_control_set_ptr->coeff_est_entropy_coder_ptr->fc->nmvc);
    3070             : 
    3071             :         // Initial Rate Estimatimation of the quantized coefficients
    3072         120 :         av1_estimate_coefficients_rate(
    3073             :             md_rate_estimation_array,
    3074         120 :             picture_control_set_ptr->coeff_est_entropy_coder_ptr->fc);
    3075         120 :         if (picture_control_set_ptr->parent_pcs_ptr->pic_depth_mode == PIC_SB_SWITCH_DEPTH_MODE) {
    3076          58 :             derive_sb_md_mode(
    3077             :                 sequence_control_set_ptr,
    3078             :                 picture_control_set_ptr,
    3079             :                 context_ptr);
    3080             : 
    3081        3538 :             for (int sb_index = 0; sb_index < picture_control_set_ptr->sb_total_count; ++sb_index) {
    3082        3480 :                 if (picture_control_set_ptr->parent_pcs_ptr->sb_depth_mode_array[sb_index] == SB_SQ_BLOCKS_DEPTH_MODE) {
    3083           0 :                     sb_forward_sq_blocks_to_md(
    3084             :                         sequence_control_set_ptr,
    3085             :                         picture_control_set_ptr,
    3086             :                         sb_index);
    3087             :                 }
    3088        3480 :                 else if (picture_control_set_ptr->parent_pcs_ptr->sb_depth_mode_array[sb_index] == SB_SQ_NON4_BLOCKS_DEPTH_MODE) {
    3089         855 :                     sb_forward_sq_non4_blocks_to_md(
    3090             :                         sequence_control_set_ptr,
    3091             :                         picture_control_set_ptr,
    3092             :                         sb_index);
    3093             :                 }
    3094             :                 else {
    3095        2625 :                     PerformEarlyLcuPartitionningLcu(
    3096             :                         context_ptr,
    3097             :                         sequence_control_set_ptr,
    3098             :                         picture_control_set_ptr,
    3099             :                         sb_index);
    3100             :                 }
    3101             :             }
    3102             :         }
    3103             : 
    3104          62 :         else  if (picture_control_set_ptr->parent_pcs_ptr->pic_depth_mode == PIC_ALL_DEPTH_MODE) {
    3105          60 :             forward_all_blocks_to_md(
    3106             :                 sequence_control_set_ptr,
    3107             :                 picture_control_set_ptr);
    3108             :         }
    3109           2 :         else  if (picture_control_set_ptr->parent_pcs_ptr->pic_depth_mode == PIC_ALL_C_DEPTH_MODE) {
    3110           0 :             forward_all_c_blocks_to_md(
    3111             :                 sequence_control_set_ptr,
    3112             :                 picture_control_set_ptr);
    3113             :         }
    3114           2 :         else  if (picture_control_set_ptr->parent_pcs_ptr->pic_depth_mode == PIC_SQ_DEPTH_MODE) {
    3115           0 :             forward_sq_blocks_to_md(
    3116             :                 sequence_control_set_ptr,
    3117             :                 picture_control_set_ptr);
    3118             :         }
    3119           2 :         else  if (picture_control_set_ptr->parent_pcs_ptr->pic_depth_mode == PIC_SQ_NON4_DEPTH_MODE) {
    3120           2 :             forward_sq_non4_blocks_to_md(
    3121             :                 sequence_control_set_ptr,
    3122             :                 picture_control_set_ptr);
    3123             :         }
    3124           0 :         else if (picture_control_set_ptr->parent_pcs_ptr->pic_depth_mode >= PIC_OPEN_LOOP_DEPTH_MODE) {
    3125             :             // Predict the SB partitionning
    3126           0 :             PerformEarlyLcuPartitionning( // HT done
    3127             :                 context_ptr,
    3128             :                 sequence_control_set_ptr,
    3129             :                 picture_control_set_ptr);
    3130             :         }
    3131             :         else {   // (picture_control_set_ptr->parent_pcs_ptr->mdMode == PICT_BDP_DEPTH_MODE || picture_control_set_ptr->parent_pcs_ptr->mdMode == PICT_LIGHT_BDP_DEPTH_MODE )
    3132           0 :             picture_control_set_ptr->parent_pcs_ptr->average_qp = (uint8_t)picture_control_set_ptr->parent_pcs_ptr->picture_qp;
    3133             :         }
    3134             : #if ADD_MDC_REFINEMENT_LOOP
    3135         120 :         if (picture_control_set_ptr->parent_pcs_ptr->slice_type != I_SLICE) {
    3136             : #if MDC_ADAPTIVE_LEVEL
    3137         116 :             if (picture_control_set_ptr->parent_pcs_ptr->enable_adaptive_ol_partitioning) {
    3138             : #else
    3139             :             if (picture_control_set_ptr->parent_pcs_ptr->mdc_depth_level < MAX_MDC_LEVEL) {
    3140             : #endif
    3141             :                 // SB Constants
    3142          58 :                 uint8_t sb_sz = (uint8_t)sequence_control_set_ptr->sb_size_pix;
    3143          58 :                 uint8_t lcu_size_log_2 = (uint8_t)Log2f(sb_sz);
    3144          58 :                 uint32_t picture_height_in_sb = (sequence_control_set_ptr->seq_header.max_frame_height + sb_sz - 1) >> lcu_size_log_2;
    3145          58 :                 uint32_t picture_width_in_sb = (sequence_control_set_ptr->seq_header.max_frame_width + sb_sz - 1) >> lcu_size_log_2;
    3146             : 
    3147         406 :                 for (uint32_t y_lcu_index = 0; y_lcu_index < picture_height_in_sb; ++y_lcu_index) {
    3148        3828 :                     for (uint32_t x_lcu_index = 0; x_lcu_index < picture_width_in_sb; ++x_lcu_index) {
    3149        3480 :                         uint32_t sb_index = (uint16_t)(y_lcu_index * picture_width_in_sb + x_lcu_index);
    3150        3480 :                         LargestCodingUnit  *sb_ptr = picture_control_set_ptr->sb_ptr_array[sb_index];
    3151             : #if MDC_ADAPTIVE_LEVEL
    3152        3480 :                         uint32_t is_complete_sb = sequence_control_set_ptr->sb_geom[sb_index].is_complete_sb;
    3153             : #endif
    3154        3480 :                         sb_ptr->origin_x = x_lcu_index << lcu_size_log_2;
    3155        3480 :                         sb_ptr->origin_y = y_lcu_index << lcu_size_log_2;
    3156             : #if MDC_ADAPTIVE_LEVEL
    3157        3480 :                         if (sequence_control_set_ptr->over_boundary_block_mode == 1 || is_complete_sb) {
    3158             : #endif
    3159        3480 :                         open_loop_partitioning_pass(
    3160             :                             sequence_control_set_ptr,
    3161             :                             picture_control_set_ptr,
    3162             :                             context_ptr,
    3163             :                             sb_index);
    3164             : 
    3165        3480 :                             init_considered_block(
    3166             :                                 sequence_control_set_ptr,
    3167             :                                 picture_control_set_ptr,
    3168             :                                 context_ptr,
    3169             :                                 sb_index);
    3170        3480 :                             forward_considered_blocks(
    3171             :                                 sequence_control_set_ptr,
    3172             :                                 picture_control_set_ptr,
    3173             :                                 sb_index);
    3174             : #if MDC_ADAPTIVE_LEVEL
    3175             :                         }
    3176             : #endif
    3177             :                     }
    3178             :                 }
    3179             :             }
    3180             :         }
    3181             : #endif
    3182         120 :         if (frm_hdr->allow_intrabc)
    3183             :         {
    3184             :             int i;
    3185           0 :             int speed = 1;
    3186           0 :             SpeedFeatures *sf = &picture_control_set_ptr->sf;
    3187           0 :             sf->allow_exhaustive_searches = 1;
    3188             : 
    3189           0 :             const int mesh_speed = AOMMIN(speed, MAX_MESH_SPEED);
    3190             :             //if (cpi->twopass.fr_content_type == FC_GRAPHICS_ANIMATION)
    3191             :             //    sf->exhaustive_searches_thresh = (1 << 24);
    3192             :             //else
    3193           0 :             sf->exhaustive_searches_thresh = (1 << 25);
    3194             : 
    3195           0 :             sf->max_exaustive_pct = good_quality_max_mesh_pct[mesh_speed];
    3196           0 :             if (mesh_speed > 0)
    3197           0 :                 sf->exhaustive_searches_thresh = sf->exhaustive_searches_thresh << 1;
    3198             : 
    3199           0 :             for (i = 0; i < MAX_MESH_STEP; ++i) {
    3200           0 :                 sf->mesh_patterns[i].range =
    3201           0 :                     good_quality_mesh_patterns[mesh_speed][i].range;
    3202           0 :                 sf->mesh_patterns[i].interval =
    3203           0 :                     good_quality_mesh_patterns[mesh_speed][i].interval;
    3204             :             }
    3205             : 
    3206           0 :             if (picture_control_set_ptr->slice_type == I_SLICE)
    3207             :             {
    3208           0 :                 for (i = 0; i < MAX_MESH_STEP; ++i) {
    3209           0 :                     sf->mesh_patterns[i].range = intrabc_mesh_patterns[mesh_speed][i].range;
    3210           0 :                     sf->mesh_patterns[i].interval =
    3211           0 :                         intrabc_mesh_patterns[mesh_speed][i].interval;
    3212             :                 }
    3213           0 :                 sf->max_exaustive_pct = intrabc_max_mesh_pct[mesh_speed];
    3214             :             }
    3215             : 
    3216             :             {
    3217             :                 // add to hash table
    3218           0 :                 const int pic_width = picture_control_set_ptr->parent_pcs_ptr->sequence_control_set_ptr->seq_header.max_frame_width;
    3219           0 :                 const int pic_height = picture_control_set_ptr->parent_pcs_ptr->sequence_control_set_ptr->seq_header.max_frame_height;
    3220             :                 uint32_t *block_hash_values[2][2];
    3221             :                 int8_t *is_block_same[2][3];
    3222             :                 int k, j;
    3223             : 
    3224           0 :                 for (k = 0; k < 2; k++) {
    3225           0 :                     for (j = 0; j < 2; j++)
    3226           0 :                         block_hash_values[k][j] = malloc(sizeof(uint32_t) * pic_width * pic_height);
    3227           0 :                     for (j = 0; j < 3; j++)
    3228           0 :                         is_block_same[k][j] = malloc(sizeof(int8_t) * pic_width * pic_height);
    3229             :                 }
    3230             : 
    3231             :                 //picture_control_set_ptr->hash_table.p_lookup_table = NULL;
    3232             :                 //av1_hash_table_create(&picture_control_set_ptr->hash_table);
    3233             : 
    3234             :                 Yv12BufferConfig cpi_source;
    3235           0 :                 link_Eb_to_aom_buffer_desc_8bit(
    3236           0 :                     picture_control_set_ptr->parent_pcs_ptr->enhanced_picture_ptr,
    3237             :                     &cpi_source);
    3238             : 
    3239           0 :                 av1_crc_calculator_init(&picture_control_set_ptr->crc_calculator1, 24, 0x5D6DCB);
    3240           0 :                 av1_crc_calculator_init(&picture_control_set_ptr->crc_calculator2, 24, 0x864CFB);
    3241             : 
    3242           0 :                 av1_generate_block_2x2_hash_value(&cpi_source, block_hash_values[0],
    3243             :                     is_block_same[0], picture_control_set_ptr);
    3244           0 :                 av1_generate_block_hash_value(&cpi_source, 4, block_hash_values[0],
    3245             :                     block_hash_values[1], is_block_same[0],
    3246             :                     is_block_same[1], picture_control_set_ptr);
    3247           0 :                 av1_add_to_hash_map_by_row_with_precal_data(
    3248             :                     &picture_control_set_ptr->hash_table, block_hash_values[1], is_block_same[1][2],
    3249             :                     pic_width, pic_height, 4);
    3250           0 :                 av1_generate_block_hash_value(&cpi_source, 8, block_hash_values[1],
    3251             :                     block_hash_values[0], is_block_same[1],
    3252             :                     is_block_same[0], picture_control_set_ptr);
    3253           0 :                 av1_add_to_hash_map_by_row_with_precal_data(
    3254             :                     &picture_control_set_ptr->hash_table, block_hash_values[0], is_block_same[0][2],
    3255             :                     pic_width, pic_height, 8);
    3256           0 :                 av1_generate_block_hash_value(&cpi_source, 16, block_hash_values[0],
    3257             :                     block_hash_values[1], is_block_same[0],
    3258             :                     is_block_same[1], picture_control_set_ptr);
    3259           0 :                 av1_add_to_hash_map_by_row_with_precal_data(
    3260             :                     &picture_control_set_ptr->hash_table, block_hash_values[1], is_block_same[1][2],
    3261             :                     pic_width, pic_height, 16);
    3262           0 :                 av1_generate_block_hash_value(&cpi_source, 32, block_hash_values[1],
    3263             :                     block_hash_values[0], is_block_same[1],
    3264             :                     is_block_same[0], picture_control_set_ptr);
    3265           0 :                 av1_add_to_hash_map_by_row_with_precal_data(
    3266             :                     &picture_control_set_ptr->hash_table, block_hash_values[0], is_block_same[0][2],
    3267             :                     pic_width, pic_height, 32);
    3268           0 :                 av1_generate_block_hash_value(&cpi_source, 64, block_hash_values[0],
    3269             :                     block_hash_values[1], is_block_same[0],
    3270             :                     is_block_same[1], picture_control_set_ptr);
    3271           0 :                 av1_add_to_hash_map_by_row_with_precal_data(
    3272             :                     &picture_control_set_ptr->hash_table, block_hash_values[1], is_block_same[1][2],
    3273             :                     pic_width, pic_height, 64);
    3274             : 
    3275           0 :                 av1_generate_block_hash_value(&cpi_source, 128, block_hash_values[1],
    3276             :                     block_hash_values[0], is_block_same[1],
    3277             :                     is_block_same[0], picture_control_set_ptr);
    3278           0 :                 av1_add_to_hash_map_by_row_with_precal_data(
    3279             :                     &picture_control_set_ptr->hash_table, block_hash_values[0], is_block_same[0][2],
    3280             :                     pic_width, pic_height, 128);
    3281             : 
    3282           0 :                 for (k = 0; k < 2; k++) {
    3283           0 :                     for (j = 0; j < 2; j++)
    3284           0 :                         free(block_hash_values[k][j]);
    3285           0 :                     for (j = 0; j < 3; j++)
    3286           0 :                         free(is_block_same[k][j]);
    3287             :                 }
    3288             :             }
    3289             : 
    3290           0 :             eb_av1_init3smotion_compensation(&picture_control_set_ptr->ss_cfg, picture_control_set_ptr->parent_pcs_ptr->enhanced_picture_ptr->stride_y);
    3291             :         }
    3292             : 
    3293             :         // Derive MD parameters
    3294         120 :         SetMdSettings( // HT Done
    3295             :             sequence_control_set_ptr,
    3296             :             picture_control_set_ptr);
    3297             : 
    3298             :         // Post the results to the MD processes
    3299         120 :         eb_get_empty_object(
    3300             :             context_ptr->mode_decision_configuration_output_fifo_ptr,
    3301             :             &encDecTasksWrapperPtr);
    3302             : 
    3303         120 :         encDecTasksPtr = (EncDecTasks*)encDecTasksWrapperPtr->object_ptr;
    3304         120 :         encDecTasksPtr->picture_control_set_wrapper_ptr = rateControlResultsPtr->picture_control_set_wrapper_ptr;
    3305         120 :         encDecTasksPtr->input_type = ENCDEC_TASKS_MDC_INPUT;
    3306             : 
    3307             :         // Post the Full Results Object
    3308         120 :         eb_post_full_object(encDecTasksWrapperPtr);
    3309             : 
    3310             :         // Release Rate Control Results
    3311         120 :         eb_release_object(rateControlResultsWrapperPtr);
    3312             :     }
    3313             : 
    3314             :     return EB_NULL;
    3315             : }

Generated by: LCOV version 1.14