1 #ifndef STRATEGIES_PICTURE_H_ 2 #define STRATEGIES_PICTURE_H_ 3 /***************************************************************************** 4 * This file is part of Kvazaar HEVC encoder. 5 * 6 * Copyright (c) 2021, Tampere University, ITU/ISO/IEC, project contributors 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without modification, 10 * are permitted provided that the following conditions are met: 11 * 12 * * Redistributions of source code must retain the above copyright notice, this 13 * list of conditions and the following disclaimer. 14 * 15 * * Redistributions in binary form must reproduce the above copyright notice, this 16 * list of conditions and the following disclaimer in the documentation and/or 17 * other materials provided with the distribution. 18 * 19 * * Neither the name of the Tampere University or ITU/ISO/IEC nor the names of its 20 * contributors may be used to endorse or promote products derived from 21 * this software without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 27 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 * INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND ON 30 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 * INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS 33 ****************************************************************************/ 34 35 /** 36 * \ingroup Optimization 37 * \file 38 * Interface for distortion metric functions. 39 */ 40 41 #include "global.h" // IWYU pragma: keep 42 #include "inter.h" 43 #include "kvazaar.h" 44 #include "encoderstate.h" 45 #include "strategies/optimized_sad_func_ptr_t.h" 46 47 48 typedef kvz_pixel (*pred_buffer)[32 * 32]; 49 50 // Function macro for defining hadamard calculating functions 51 // for fixed size blocks. They calculate hadamard for integer 52 // multiples of 8x8 with the 8x8 hadamard function. 53 #define SATD_NxN(suffix, n) \ 54 /* Declare the function in advance, hopefully reducing the probability that the 55 * macro expands to something unexpected and silently breaks things. */ \ 56 static cost_pixel_nxn_func satd_ ## n ## x ## n ## _ ## suffix;\ 57 static unsigned satd_ ## n ## x ## n ## _ ## suffix ( \ 58 const kvz_pixel * const block1, \ 59 const kvz_pixel * const block2) \ 60 { \ 61 unsigned sum = 0; \ 62 for (unsigned y = 0; y < (n); y += 8) { \ 63 unsigned row = y * (n); \ 64 for (unsigned x = 0; x < (n); x += 8) { \ 65 sum += satd_8x8_subblock_ ## suffix(&block1[row + x], (n), &block2[row + x], (n)); \ 66 } \ 67 } \ 68 return sum >> (KVZ_BIT_DEPTH - 8); \ 69 } 70 71 72 // Function macro for defining hadamard calculating functions for dynamic size 73 // blocks. They calculate hadamard for integer multiples of 8x8 with the 8x8 74 // hadamard function. 75 #define SATD_ANY_SIZE(suffix) \ 76 static cost_pixel_any_size_func satd_any_size_ ## suffix; \ 77 static unsigned satd_any_size_ ## suffix ( \ 78 int width, int height, \ 79 const kvz_pixel *block1, int stride1, \ 80 const kvz_pixel *block2, int stride2) \ 81 { \ 82 unsigned sum = 0; \ 83 if (width % 8 != 0) { \ 84 /* Process the first column using 4x4 blocks. */ \ 85 for (int y = 0; y < height; y += 4) { \ 86 sum += kvz_satd_4x4_subblock_ ## suffix(&block1[y * stride1], stride1, \ 87 &block2[y * stride2], stride2); \ 88 } \ 89 block1 += 4; \ 90 block2 += 4; \ 91 width -= 4; \ 92 } \ 93 if (height % 8 != 0) { \ 94 /* Process the first row using 4x4 blocks. */ \ 95 for (int x = 0; x < width; x += 4) { \ 96 sum += kvz_satd_4x4_subblock_ ## suffix(&block1[x], stride1, \ 97 &block2[x], stride2); \ 98 } \ 99 block1 += 4 * stride1; \ 100 block2 += 4 * stride2; \ 101 height -= 4; \ 102 } \ 103 /* The rest can now be processed with 8x8 blocks. */ \ 104 for (int y = 0; y < height; y += 8) { \ 105 const kvz_pixel *row1 = &block1[y * stride1]; \ 106 const kvz_pixel *row2 = &block2[y * stride2]; \ 107 for (int x = 0; x < width; x += 8) { \ 108 sum += satd_8x8_subblock_ ## suffix(&row1[x], stride1, \ 109 &row2[x], stride2); \ 110 } \ 111 } \ 112 return sum >> (KVZ_BIT_DEPTH - 8); \ 113 } 114 115 typedef unsigned(reg_sad_func)(const kvz_pixel *const data1, const kvz_pixel *const data2, 116 const int width, const int height, 117 const unsigned stride1, const unsigned stride2); 118 typedef unsigned (cost_pixel_nxn_func)(const kvz_pixel *block1, const kvz_pixel *block2); 119 typedef unsigned (cost_pixel_any_size_func)( 120 int width, int height, 121 const kvz_pixel *block1, int stride1, 122 const kvz_pixel *block2, int stride2 123 ); 124 typedef void (cost_pixel_nxn_multi_func)(const pred_buffer preds, const kvz_pixel *orig, unsigned num_modes, unsigned *costs_out); 125 typedef void (cost_pixel_any_size_multi_func)(int width, int height, const kvz_pixel **preds, const int stride, const kvz_pixel *orig, const int orig_stride, unsigned num_modes, unsigned *costs_out, int8_t *valid); 126 127 typedef unsigned (pixels_calc_ssd_func)(const kvz_pixel *const ref, const kvz_pixel *const rec, const int ref_stride, const int rec_stride, const int width); 128 typedef optimized_sad_func_ptr_t (get_optimized_sad_func)(int32_t); 129 typedef uint32_t (ver_sad_func)(const kvz_pixel *pic_data, const kvz_pixel *ref_data, 130 int32_t block_width, int32_t block_height, 131 uint32_t pic_stride); 132 typedef uint32_t (hor_sad_func)(const kvz_pixel *pic_data, const kvz_pixel *ref_data, 133 int32_t width, int32_t height, uint32_t pic_stride, 134 uint32_t ref_stride, uint32_t left, uint32_t right); 135 136 typedef void (inter_recon_bipred_func)(const int hi_prec_luma_rec0, 137 const int hi_prec_luma_rec1, 138 const int hi_prec_chroma_rec0, 139 const int hi_prec_chroma_rec1, 140 int height, 141 int width, 142 int ypos, 143 int xpos, 144 const hi_prec_buf_t*high_precision_rec0, 145 const hi_prec_buf_t*high_precision_rec1, 146 lcu_t* lcu, 147 kvz_pixel temp_lcu_y[LCU_WIDTH*LCU_WIDTH], 148 kvz_pixel temp_lcu_u[LCU_WIDTH_C*LCU_WIDTH_C], 149 kvz_pixel temp_lcu_v[LCU_WIDTH_C*LCU_WIDTH_C], 150 bool predict_luma, 151 bool predict_chroma); 152 153 typedef double (pixel_var_func)(const kvz_pixel *buf, const uint32_t len); 154 155 // Declare function pointers. 156 extern reg_sad_func * kvz_reg_sad; 157 158 extern cost_pixel_nxn_func * kvz_sad_4x4; 159 extern cost_pixel_nxn_func * kvz_sad_8x8; 160 extern cost_pixel_nxn_func * kvz_sad_16x16; 161 extern cost_pixel_nxn_func * kvz_sad_32x32; 162 extern cost_pixel_nxn_func * kvz_sad_64x64; 163 164 extern cost_pixel_nxn_func * kvz_satd_4x4; 165 extern cost_pixel_nxn_func * kvz_satd_8x8; 166 extern cost_pixel_nxn_func * kvz_satd_16x16; 167 extern cost_pixel_nxn_func * kvz_satd_32x32; 168 extern cost_pixel_nxn_func * kvz_satd_64x64; 169 extern cost_pixel_any_size_func *kvz_satd_any_size; 170 171 extern cost_pixel_nxn_multi_func * kvz_sad_4x4_dual; 172 extern cost_pixel_nxn_multi_func * kvz_sad_8x8_dual; 173 extern cost_pixel_nxn_multi_func * kvz_sad_16x16_dual; 174 extern cost_pixel_nxn_multi_func * kvz_sad_32x32_dual; 175 extern cost_pixel_nxn_multi_func * kvz_sad_64x64_dual; 176 177 extern cost_pixel_nxn_multi_func * kvz_satd_4x4_dual; 178 extern cost_pixel_nxn_multi_func * kvz_satd_8x8_dual; 179 extern cost_pixel_nxn_multi_func * kvz_satd_16x16_dual; 180 extern cost_pixel_nxn_multi_func * kvz_satd_32x32_dual; 181 extern cost_pixel_nxn_multi_func * kvz_satd_64x64_dual; 182 183 extern cost_pixel_any_size_multi_func *kvz_satd_any_size_quad; 184 185 extern pixels_calc_ssd_func *kvz_pixels_calc_ssd; 186 187 extern inter_recon_bipred_func * kvz_inter_recon_bipred_blend; 188 189 extern get_optimized_sad_func *kvz_get_optimized_sad; 190 extern ver_sad_func *kvz_ver_sad; 191 extern hor_sad_func *kvz_hor_sad; 192 193 extern pixel_var_func *kvz_pixel_var; 194 195 int kvz_strategy_register_picture(void* opaque, uint8_t bitdepth); 196 cost_pixel_nxn_func * kvz_pixels_get_satd_func(unsigned n); 197 cost_pixel_nxn_func * kvz_pixels_get_sad_func(unsigned n); 198 cost_pixel_nxn_multi_func * kvz_pixels_get_satd_dual_func(unsigned n); 199 cost_pixel_nxn_multi_func * kvz_pixels_get_sad_dual_func(unsigned n); 200 201 #define STRATEGIES_PICTURE_EXPORTS \ 202 {"reg_sad", (void**) &kvz_reg_sad}, \ 203 {"sad_4x4", (void**) &kvz_sad_4x4}, \ 204 {"sad_8x8", (void**) &kvz_sad_8x8}, \ 205 {"sad_16x16", (void**) &kvz_sad_16x16}, \ 206 {"sad_32x32", (void**) &kvz_sad_32x32}, \ 207 {"sad_64x64", (void**) &kvz_sad_64x64}, \ 208 {"satd_4x4", (void**) &kvz_satd_4x4}, \ 209 {"satd_8x8", (void**) &kvz_satd_8x8}, \ 210 {"satd_16x16", (void**) &kvz_satd_16x16}, \ 211 {"satd_32x32", (void**) &kvz_satd_32x32}, \ 212 {"satd_64x64", (void**) &kvz_satd_64x64}, \ 213 {"satd_any_size", (void**) &kvz_satd_any_size}, \ 214 {"sad_4x4_dual", (void**) &kvz_sad_4x4_dual}, \ 215 {"sad_8x8_dual", (void**) &kvz_sad_8x8_dual}, \ 216 {"sad_16x16_dual", (void**) &kvz_sad_16x16_dual}, \ 217 {"sad_32x32_dual", (void**) &kvz_sad_32x32_dual}, \ 218 {"sad_64x64_dual", (void**) &kvz_sad_64x64_dual}, \ 219 {"satd_4x4_dual", (void**) &kvz_satd_4x4_dual}, \ 220 {"satd_8x8_dual", (void**) &kvz_satd_8x8_dual}, \ 221 {"satd_16x16_dual", (void**) &kvz_satd_16x16_dual}, \ 222 {"satd_32x32_dual", (void**) &kvz_satd_32x32_dual}, \ 223 {"satd_64x64_dual", (void**) &kvz_satd_64x64_dual}, \ 224 {"satd_any_size_quad", (void**) &kvz_satd_any_size_quad}, \ 225 {"pixels_calc_ssd", (void**) &kvz_pixels_calc_ssd}, \ 226 {"inter_recon_bipred", (void**) &kvz_inter_recon_bipred_blend}, \ 227 {"get_optimized_sad", (void**) &kvz_get_optimized_sad}, \ 228 {"ver_sad", (void**) &kvz_ver_sad}, \ 229 {"hor_sad", (void**) &kvz_hor_sad}, \ 230 {"pixel_var", (void**) &kvz_pixel_var}, \ 231 232 233 234 #endif //STRATEGIES_PICTURE_H_ 235