idctdsp.c (10303B)
1 /* 2 * This file is part of FFmpeg. 3 * 4 * FFmpeg is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * FFmpeg is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with FFmpeg; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18 19 #include "config.h" 20 #include "config_components.h" 21 #include "libavutil/attributes.h" 22 #include "libavutil/common.h" 23 #include "avcodec.h" 24 #include "dct.h" 25 #include "faanidct.h" 26 #include "idctdsp.h" 27 #include "simple_idct.h" 28 #include "xvididct.h" 29 30 av_cold void ff_permute_scantable(uint8_t dst[64], const uint8_t src[64], 31 const uint8_t permutation[64]) 32 { 33 for (int i = 0; i < 64; i++) { 34 int j = src[i]; 35 dst[i] = permutation[j]; 36 } 37 } 38 39 av_cold void ff_init_scantable_permutation(uint8_t *idct_permutation, 40 enum idct_permutation_type perm_type) 41 { 42 int i; 43 44 #if ARCH_X86 45 if (ff_init_scantable_permutation_x86(idct_permutation, 46 perm_type)) 47 return; 48 #endif 49 50 switch (perm_type) { 51 case FF_IDCT_PERM_NONE: 52 for (i = 0; i < 64; i++) 53 idct_permutation[i] = i; 54 break; 55 case FF_IDCT_PERM_LIBMPEG2: 56 for (i = 0; i < 64; i++) 57 idct_permutation[i] = (i & 0x38) | ((i & 6) >> 1) | ((i & 1) << 2); 58 break; 59 case FF_IDCT_PERM_TRANSPOSE: 60 for (i = 0; i < 64; i++) 61 idct_permutation[i] = ((i & 7) << 3) | (i >> 3); 62 break; 63 case FF_IDCT_PERM_PARTTRANS: 64 for (i = 0; i < 64; i++) 65 idct_permutation[i] = (i & 0x24) | ((i & 3) << 3) | ((i >> 3) & 3); 66 break; 67 default: 68 av_log(NULL, AV_LOG_ERROR, 69 "Internal error, IDCT permutation not set\n"); 70 } 71 } 72 73 void ff_put_pixels_clamped_c(const int16_t *block, uint8_t *restrict pixels, 74 ptrdiff_t line_size) 75 { 76 int i; 77 78 /* read the pixels */ 79 for (i = 0; i < 8; i++) { 80 pixels[0] = av_clip_uint8(block[0]); 81 pixels[1] = av_clip_uint8(block[1]); 82 pixels[2] = av_clip_uint8(block[2]); 83 pixels[3] = av_clip_uint8(block[3]); 84 pixels[4] = av_clip_uint8(block[4]); 85 pixels[5] = av_clip_uint8(block[5]); 86 pixels[6] = av_clip_uint8(block[6]); 87 pixels[7] = av_clip_uint8(block[7]); 88 89 pixels += line_size; 90 block += 8; 91 } 92 } 93 94 static void put_pixels_clamped4_c(const int16_t *block, uint8_t *restrict pixels, 95 int line_size) 96 { 97 int i; 98 99 /* read the pixels */ 100 for(i=0;i<4;i++) { 101 pixels[0] = av_clip_uint8(block[0]); 102 pixels[1] = av_clip_uint8(block[1]); 103 pixels[2] = av_clip_uint8(block[2]); 104 pixels[3] = av_clip_uint8(block[3]); 105 106 pixels += line_size; 107 block += 8; 108 } 109 } 110 111 static void put_pixels_clamped2_c(const int16_t *block, uint8_t *restrict pixels, 112 int line_size) 113 { 114 int i; 115 116 /* read the pixels */ 117 for(i=0;i<2;i++) { 118 pixels[0] = av_clip_uint8(block[0]); 119 pixels[1] = av_clip_uint8(block[1]); 120 121 pixels += line_size; 122 block += 8; 123 } 124 } 125 126 static void put_signed_pixels_clamped_c(const int16_t *block, 127 uint8_t *restrict pixels, 128 ptrdiff_t line_size) 129 { 130 int i, j; 131 132 for (i = 0; i < 8; i++) { 133 for (j = 0; j < 8; j++) { 134 if (*block < -128) 135 *pixels = 0; 136 else if (*block > 127) 137 *pixels = 255; 138 else 139 *pixels = (uint8_t) (*block + 128); 140 block++; 141 pixels++; 142 } 143 pixels += (line_size - 8); 144 } 145 } 146 147 void ff_add_pixels_clamped_c(const int16_t *block, uint8_t *restrict pixels, 148 ptrdiff_t line_size) 149 { 150 int i; 151 152 /* read the pixels */ 153 for (i = 0; i < 8; i++) { 154 pixels[0] = av_clip_uint8(pixels[0] + block[0]); 155 pixels[1] = av_clip_uint8(pixels[1] + block[1]); 156 pixels[2] = av_clip_uint8(pixels[2] + block[2]); 157 pixels[3] = av_clip_uint8(pixels[3] + block[3]); 158 pixels[4] = av_clip_uint8(pixels[4] + block[4]); 159 pixels[5] = av_clip_uint8(pixels[5] + block[5]); 160 pixels[6] = av_clip_uint8(pixels[6] + block[6]); 161 pixels[7] = av_clip_uint8(pixels[7] + block[7]); 162 pixels += line_size; 163 block += 8; 164 } 165 } 166 167 static void add_pixels_clamped4_c(const int16_t *block, uint8_t *restrict pixels, 168 int line_size) 169 { 170 int i; 171 172 /* read the pixels */ 173 for(i=0;i<4;i++) { 174 pixels[0] = av_clip_uint8(pixels[0] + block[0]); 175 pixels[1] = av_clip_uint8(pixels[1] + block[1]); 176 pixels[2] = av_clip_uint8(pixels[2] + block[2]); 177 pixels[3] = av_clip_uint8(pixels[3] + block[3]); 178 pixels += line_size; 179 block += 8; 180 } 181 } 182 183 static void add_pixels_clamped2_c(const int16_t *block, uint8_t *restrict pixels, 184 int line_size) 185 { 186 int i; 187 188 /* read the pixels */ 189 for(i=0;i<2;i++) { 190 pixels[0] = av_clip_uint8(pixels[0] + block[0]); 191 pixels[1] = av_clip_uint8(pixels[1] + block[1]); 192 pixels += line_size; 193 block += 8; 194 } 195 } 196 197 static void ff_jref_idct4_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block) 198 { 199 ff_j_rev_dct4 (block); 200 put_pixels_clamped4_c(block, dest, line_size); 201 } 202 static void ff_jref_idct4_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block) 203 { 204 ff_j_rev_dct4 (block); 205 add_pixels_clamped4_c(block, dest, line_size); 206 } 207 208 static void ff_jref_idct2_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block) 209 { 210 ff_j_rev_dct2 (block); 211 put_pixels_clamped2_c(block, dest, line_size); 212 } 213 static void ff_jref_idct2_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block) 214 { 215 ff_j_rev_dct2 (block); 216 add_pixels_clamped2_c(block, dest, line_size); 217 } 218 219 static void ff_jref_idct1_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block) 220 { 221 dest[0] = av_clip_uint8((block[0] + 4)>>3); 222 } 223 static void ff_jref_idct1_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block) 224 { 225 dest[0] = av_clip_uint8(dest[0] + ((block[0] + 4)>>3)); 226 } 227 228 av_cold void ff_idctdsp_init(IDCTDSPContext *c, AVCodecContext *avctx) 229 { 230 av_unused const unsigned high_bit_depth = avctx->bits_per_raw_sample > 8; 231 232 if (avctx->lowres==1) { 233 c->idct_put = ff_jref_idct4_put; 234 c->idct_add = ff_jref_idct4_add; 235 c->idct = ff_j_rev_dct4; 236 c->perm_type = FF_IDCT_PERM_NONE; 237 } else if (avctx->lowres==2) { 238 c->idct_put = ff_jref_idct2_put; 239 c->idct_add = ff_jref_idct2_add; 240 c->idct = ff_j_rev_dct2; 241 c->perm_type = FF_IDCT_PERM_NONE; 242 } else if (avctx->lowres==3) { 243 c->idct_put = ff_jref_idct1_put; 244 c->idct_add = ff_jref_idct1_add; 245 c->idct = ff_j_rev_dct1; 246 c->perm_type = FF_IDCT_PERM_NONE; 247 } else { 248 if (avctx->bits_per_raw_sample == 10 || avctx->bits_per_raw_sample == 9) { 249 /* 10-bit MPEG-4 Simple Studio Profile requires a higher precision IDCT 250 However, it only uses idct_put */ 251 if (c->mpeg4_studio_profile) { 252 c->idct_put = ff_simple_idct_put_int32_10bit; 253 c->idct_add = NULL; 254 c->idct = NULL; 255 } else { 256 c->idct_put = ff_simple_idct_put_int16_10bit; 257 c->idct_add = ff_simple_idct_add_int16_10bit; 258 c->idct = ff_simple_idct_int16_10bit; 259 } 260 c->perm_type = FF_IDCT_PERM_NONE; 261 } else if (avctx->bits_per_raw_sample == 12) { 262 c->idct_put = ff_simple_idct_put_int16_12bit; 263 c->idct_add = ff_simple_idct_add_int16_12bit; 264 c->idct = ff_simple_idct_int16_12bit; 265 c->perm_type = FF_IDCT_PERM_NONE; 266 } else { 267 if (avctx->idct_algo == FF_IDCT_INT) { 268 c->idct_put = ff_jref_idct_put; 269 c->idct_add = ff_jref_idct_add; 270 c->idct = ff_j_rev_dct; 271 c->perm_type = FF_IDCT_PERM_LIBMPEG2; 272 #if CONFIG_FAANIDCT 273 } else if (avctx->idct_algo == FF_IDCT_FAAN) { 274 c->idct_put = ff_faanidct_put; 275 c->idct_add = ff_faanidct_add; 276 c->idct = ff_faanidct; 277 c->perm_type = FF_IDCT_PERM_NONE; 278 #endif /* CONFIG_FAANIDCT */ 279 } else { // accurate/default 280 c->idct_put = ff_simple_idct_put_int16_8bit; 281 c->idct_add = ff_simple_idct_add_int16_8bit; 282 c->idct = ff_simple_idct_int16_8bit; 283 c->perm_type = FF_IDCT_PERM_NONE; 284 } 285 } 286 } 287 288 c->put_pixels_clamped = ff_put_pixels_clamped_c; 289 c->put_signed_pixels_clamped = put_signed_pixels_clamped_c; 290 c->add_pixels_clamped = ff_add_pixels_clamped_c; 291 292 if (CONFIG_MPEG4_DECODER && avctx->idct_algo == FF_IDCT_XVID) 293 ff_xvid_idct_init(c, avctx); 294 295 #if ARCH_AARCH64 296 ff_idctdsp_init_aarch64(c, avctx, high_bit_depth); 297 #elif ARCH_ARM 298 ff_idctdsp_init_arm(c, avctx, high_bit_depth); 299 #elif ARCH_PPC 300 ff_idctdsp_init_ppc(c, avctx, high_bit_depth); 301 #elif ARCH_RISCV 302 ff_idctdsp_init_riscv(c, avctx, high_bit_depth); 303 #elif ARCH_X86 304 ff_idctdsp_init_x86(c, avctx, high_bit_depth); 305 #elif ARCH_MIPS 306 ff_idctdsp_init_mips(c, avctx, high_bit_depth); 307 #elif ARCH_LOONGARCH 308 ff_idctdsp_init_loongarch(c, avctx, high_bit_depth); 309 #endif 310 311 ff_init_scantable_permutation(c->idct_permutation, 312 c->perm_type); 313 }