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