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 30av_cold void ff_init_scantable(const uint8_t *permutation, ScanTable *st, 31 const uint8_t *src_scantable) 32{ 33 int i, end; 34 35 st->scantable = src_scantable; 36 37 for (i = 0; i < 64; i++) { 38 int j = src_scantable[i]; 39 st->permutated[i] = permutation[j]; 40 } 41 42 end = -1; 43 for (i = 0; i < 64; i++) { 44 int j = st->permutated[i]; 45 if (j > end) 46 end = j; 47 st->raster_end[i] = end; 48 } 49} 50 51av_cold void ff_init_scantable_permutation(uint8_t *idct_permutation, 52 enum idct_permutation_type perm_type) 53{ 54 int i; 55 56#if ARCH_X86 57 if (ff_init_scantable_permutation_x86(idct_permutation, 58 perm_type)) 59 return; 60#endif 61 62 switch (perm_type) { 63 case FF_IDCT_PERM_NONE: 64 for (i = 0; i < 64; i++) 65 idct_permutation[i] = i; 66 break; 67 case FF_IDCT_PERM_LIBMPEG2: 68 for (i = 0; i < 64; i++) 69 idct_permutation[i] = (i & 0x38) | ((i & 6) >> 1) | ((i & 1) << 2); 70 break; 71 case FF_IDCT_PERM_TRANSPOSE: 72 for (i = 0; i < 64; i++) 73 idct_permutation[i] = ((i & 7) << 3) | (i >> 3); 74 break; 75 case FF_IDCT_PERM_PARTTRANS: 76 for (i = 0; i < 64; i++) 77 idct_permutation[i] = (i & 0x24) | ((i & 3) << 3) | ((i >> 3) & 3); 78 break; 79 default: 80 av_log(NULL, AV_LOG_ERROR, 81 "Internal error, IDCT permutation not set\n"); 82 } 83} 84 85void ff_put_pixels_clamped_c(const int16_t *block, uint8_t *av_restrict pixels, 86 ptrdiff_t line_size) 87{ 88 int i; 89 90 /* read the pixels */ 91 for (i = 0; i < 8; i++) { 92 pixels[0] = av_clip_uint8(block[0]); 93 pixels[1] = av_clip_uint8(block[1]); 94 pixels[2] = av_clip_uint8(block[2]); 95 pixels[3] = av_clip_uint8(block[3]); 96 pixels[4] = av_clip_uint8(block[4]); 97 pixels[5] = av_clip_uint8(block[5]); 98 pixels[6] = av_clip_uint8(block[6]); 99 pixels[7] = av_clip_uint8(block[7]); 100 101 pixels += line_size; 102 block += 8; 103 } 104} 105 106static void put_pixels_clamped4_c(const int16_t *block, uint8_t *av_restrict pixels, 107 int line_size) 108{ 109 int i; 110 111 /* read the pixels */ 112 for(i=0;i<4;i++) { 113 pixels[0] = av_clip_uint8(block[0]); 114 pixels[1] = av_clip_uint8(block[1]); 115 pixels[2] = av_clip_uint8(block[2]); 116 pixels[3] = av_clip_uint8(block[3]); 117 118 pixels += line_size; 119 block += 8; 120 } 121} 122 123static void put_pixels_clamped2_c(const int16_t *block, uint8_t *av_restrict pixels, 124 int line_size) 125{ 126 int i; 127 128 /* read the pixels */ 129 for(i=0;i<2;i++) { 130 pixels[0] = av_clip_uint8(block[0]); 131 pixels[1] = av_clip_uint8(block[1]); 132 133 pixels += line_size; 134 block += 8; 135 } 136} 137 138static void put_signed_pixels_clamped_c(const int16_t *block, 139 uint8_t *av_restrict pixels, 140 ptrdiff_t line_size) 141{ 142 int i, j; 143 144 for (i = 0; i < 8; i++) { 145 for (j = 0; j < 8; j++) { 146 if (*block < -128) 147 *pixels = 0; 148 else if (*block > 127) 149 *pixels = 255; 150 else 151 *pixels = (uint8_t) (*block + 128); 152 block++; 153 pixels++; 154 } 155 pixels += (line_size - 8); 156 } 157} 158 159void ff_add_pixels_clamped_c(const int16_t *block, uint8_t *av_restrict pixels, 160 ptrdiff_t line_size) 161{ 162 int i; 163 164 /* read the pixels */ 165 for (i = 0; i < 8; i++) { 166 pixels[0] = av_clip_uint8(pixels[0] + block[0]); 167 pixels[1] = av_clip_uint8(pixels[1] + block[1]); 168 pixels[2] = av_clip_uint8(pixels[2] + block[2]); 169 pixels[3] = av_clip_uint8(pixels[3] + block[3]); 170 pixels[4] = av_clip_uint8(pixels[4] + block[4]); 171 pixels[5] = av_clip_uint8(pixels[5] + block[5]); 172 pixels[6] = av_clip_uint8(pixels[6] + block[6]); 173 pixels[7] = av_clip_uint8(pixels[7] + block[7]); 174 pixels += line_size; 175 block += 8; 176 } 177} 178 179static void add_pixels_clamped4_c(const int16_t *block, uint8_t *av_restrict pixels, 180 int line_size) 181{ 182 int i; 183 184 /* read the pixels */ 185 for(i=0;i<4;i++) { 186 pixels[0] = av_clip_uint8(pixels[0] + block[0]); 187 pixels[1] = av_clip_uint8(pixels[1] + block[1]); 188 pixels[2] = av_clip_uint8(pixels[2] + block[2]); 189 pixels[3] = av_clip_uint8(pixels[3] + block[3]); 190 pixels += line_size; 191 block += 8; 192 } 193} 194 195static void add_pixels_clamped2_c(const int16_t *block, uint8_t *av_restrict pixels, 196 int line_size) 197{ 198 int i; 199 200 /* read the pixels */ 201 for(i=0;i<2;i++) { 202 pixels[0] = av_clip_uint8(pixels[0] + block[0]); 203 pixels[1] = av_clip_uint8(pixels[1] + block[1]); 204 pixels += line_size; 205 block += 8; 206 } 207} 208 209static void ff_jref_idct4_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block) 210{ 211 ff_j_rev_dct4 (block); 212 put_pixels_clamped4_c(block, dest, line_size); 213} 214static void ff_jref_idct4_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block) 215{ 216 ff_j_rev_dct4 (block); 217 add_pixels_clamped4_c(block, dest, line_size); 218} 219 220static void ff_jref_idct2_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block) 221{ 222 ff_j_rev_dct2 (block); 223 put_pixels_clamped2_c(block, dest, line_size); 224} 225static void ff_jref_idct2_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block) 226{ 227 ff_j_rev_dct2 (block); 228 add_pixels_clamped2_c(block, dest, line_size); 229} 230 231static void ff_jref_idct1_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block) 232{ 233 dest[0] = av_clip_uint8((block[0] + 4)>>3); 234} 235static void ff_jref_idct1_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block) 236{ 237 dest[0] = av_clip_uint8(dest[0] + ((block[0] + 4)>>3)); 238} 239 240av_cold void ff_idctdsp_init(IDCTDSPContext *c, AVCodecContext *avctx) 241{ 242 av_unused const unsigned high_bit_depth = avctx->bits_per_raw_sample > 8; 243 244 if (avctx->lowres==1) { 245 c->idct_put = ff_jref_idct4_put; 246 c->idct_add = ff_jref_idct4_add; 247 c->idct = ff_j_rev_dct4; 248 c->perm_type = FF_IDCT_PERM_NONE; 249 } else if (avctx->lowres==2) { 250 c->idct_put = ff_jref_idct2_put; 251 c->idct_add = ff_jref_idct2_add; 252 c->idct = ff_j_rev_dct2; 253 c->perm_type = FF_IDCT_PERM_NONE; 254 } else if (avctx->lowres==3) { 255 c->idct_put = ff_jref_idct1_put; 256 c->idct_add = ff_jref_idct1_add; 257 c->idct = ff_j_rev_dct1; 258 c->perm_type = FF_IDCT_PERM_NONE; 259 } else { 260 if (avctx->bits_per_raw_sample == 10 || avctx->bits_per_raw_sample == 9) { 261 /* 10-bit MPEG-4 Simple Studio Profile requires a higher precision IDCT 262 However, it only uses idct_put */ 263 if (c->mpeg4_studio_profile) { 264 c->idct_put = ff_simple_idct_put_int32_10bit; 265 c->idct_add = NULL; 266 c->idct = NULL; 267 } else { 268 c->idct_put = ff_simple_idct_put_int16_10bit; 269 c->idct_add = ff_simple_idct_add_int16_10bit; 270 c->idct = ff_simple_idct_int16_10bit; 271 } 272 c->perm_type = FF_IDCT_PERM_NONE; 273 } else if (avctx->bits_per_raw_sample == 12) { 274 c->idct_put = ff_simple_idct_put_int16_12bit; 275 c->idct_add = ff_simple_idct_add_int16_12bit; 276 c->idct = ff_simple_idct_int16_12bit; 277 c->perm_type = FF_IDCT_PERM_NONE; 278 } else { 279 if (avctx->idct_algo == FF_IDCT_INT) { 280 c->idct_put = ff_jref_idct_put; 281 c->idct_add = ff_jref_idct_add; 282 c->idct = ff_j_rev_dct; 283 c->perm_type = FF_IDCT_PERM_LIBMPEG2; 284#if CONFIG_FAANIDCT 285 } else if (avctx->idct_algo == FF_IDCT_FAAN) { 286 c->idct_put = ff_faanidct_put; 287 c->idct_add = ff_faanidct_add; 288 c->idct = ff_faanidct; 289 c->perm_type = FF_IDCT_PERM_NONE; 290#endif /* CONFIG_FAANIDCT */ 291 } else { // accurate/default 292 c->idct_put = ff_simple_idct_put_int16_8bit; 293 c->idct_add = ff_simple_idct_add_int16_8bit; 294 c->idct = ff_simple_idct_int16_8bit; 295 c->perm_type = FF_IDCT_PERM_NONE; 296 } 297 } 298 } 299 300 c->put_pixels_clamped = ff_put_pixels_clamped_c; 301 c->put_signed_pixels_clamped = put_signed_pixels_clamped_c; 302 c->add_pixels_clamped = ff_add_pixels_clamped_c; 303 304 if (CONFIG_MPEG4_DECODER && avctx->idct_algo == FF_IDCT_XVID) 305 ff_xvid_idct_init(c, avctx); 306 307#if ARCH_AARCH64 308 ff_idctdsp_init_aarch64(c, avctx, high_bit_depth); 309#elif ARCH_ALPHA 310 ff_idctdsp_init_alpha(c, avctx, high_bit_depth); 311#elif ARCH_ARM 312 ff_idctdsp_init_arm(c, avctx, high_bit_depth); 313#elif ARCH_PPC 314 ff_idctdsp_init_ppc(c, avctx, high_bit_depth); 315#elif ARCH_X86 316 ff_idctdsp_init_x86(c, avctx, high_bit_depth); 317#elif ARCH_MIPS 318 ff_idctdsp_init_mips(c, avctx, high_bit_depth); 319#elif ARCH_LOONGARCH 320 ff_idctdsp_init_loongarch(c, avctx, high_bit_depth); 321#endif 322 323 ff_init_scantable_permutation(c->idct_permutation, 324 c->perm_type); 325} 326