FFmpeg
idctdsp.c
Go to the documentation of this file.
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;
56  for (i = 0; i < 64; i++)
57  idct_permutation[i] = (i & 0x38) | ((i & 6) >> 1) | ((i & 1) << 2);
58  break;
60  for (i = 0; i < 64; i++)
61  idct_permutation[i] = ((i & 7) << 3) | (i >> 3);
62  break;
64  for (i = 0; i < 64; i++)
65  idct_permutation[i] = (i & 0x24) | ((i & 3) << 3) | ((i >> 3) & 3);
66  break;
67  default:
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 {
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 {
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 {
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 {
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 
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;
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;
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;
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 }
add_pixels_clamped2_c
static void add_pixels_clamped2_c(const int16_t *block, uint8_t *restrict pixels, int line_size)
Definition: idctdsp.c:183
ff_simple_idct_put_int16_10bit
void ff_simple_idct_put_int16_10bit(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
ff_jref_idct1_put
static void ff_jref_idct1_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
Definition: idctdsp.c:219
ff_xvid_idct_init
av_cold void ff_xvid_idct_init(IDCTDSPContext *c, AVCodecContext *avctx)
Definition: xvididct.c:333
ff_init_scantable_permutation_x86
int ff_init_scantable_permutation_x86(uint8_t *idct_permutation, enum idct_permutation_type perm_type)
Definition: idctdsp_init.c:42
ff_idctdsp_init_arm
av_cold void ff_idctdsp_init_arm(IDCTDSPContext *c, AVCodecContext *avctx, unsigned high_bit_depth)
Definition: idctdsp_init_arm.c:66
ff_jref_idct2_add
static void ff_jref_idct2_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
Definition: idctdsp.c:213
av_unused
#define av_unused
Definition: attributes.h:131
put_signed_pixels_clamped_c
static void put_signed_pixels_clamped_c(const int16_t *block, uint8_t *restrict pixels, ptrdiff_t line_size)
Definition: idctdsp.c:126
ff_jref_idct4_add
static void ff_jref_idct4_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
Definition: idctdsp.c:202
add_pixels_clamped4_c
static void add_pixels_clamped4_c(const int16_t *block, uint8_t *restrict pixels, int line_size)
Definition: idctdsp.c:167
ff_simple_idct_add_int16_12bit
void ff_simple_idct_add_int16_12bit(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
ff_idctdsp_init_aarch64
av_cold void ff_idctdsp_init_aarch64(IDCTDSPContext *c, AVCodecContext *avctx, unsigned high_bit_depth)
Definition: idctdsp_init_aarch64.c:34
ff_idctdsp_init
av_cold void ff_idctdsp_init(IDCTDSPContext *c, AVCodecContext *avctx)
Definition: idctdsp.c:228
ff_simple_idct_int16_10bit
void ff_simple_idct_int16_10bit(int16_t *block)
FF_IDCT_XVID
#define FF_IDCT_XVID
Definition: avcodec.h:1566
ff_permute_scantable
av_cold void ff_permute_scantable(uint8_t dst[64], const uint8_t src[64], const uint8_t permutation[64])
Definition: idctdsp.c:30
ff_jref_idct2_put
static void ff_jref_idct2_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
Definition: idctdsp.c:208
ff_idctdsp_init_riscv
void ff_idctdsp_init_riscv(IDCTDSPContext *c, struct AVCodecContext *avctx, unsigned high_bit_depth)
Definition: idctdsp_init.c:36
FF_IDCT_INT
#define FF_IDCT_INT
Definition: avcodec.h:1560
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:209
av_cold
#define av_cold
Definition: attributes.h:90
dct.h
ff_faanidct_add
void ff_faanidct_add(uint8_t *dest, ptrdiff_t line_size, int16_t block[64])
Definition: faanidct.c:141
ff_faanidct
void ff_faanidct(int16_t block[64])
Definition: faanidct.c:128
AVCodecContext::bits_per_raw_sample
int bits_per_raw_sample
Bits per sample/pixel of internal libavcodec pixel/sample format.
Definition: avcodec.h:1585
ff_simple_idct_put_int16_8bit
void ff_simple_idct_put_int16_8bit(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
simple_idct.h
ff_simple_idct_put_int16_12bit
void ff_simple_idct_put_int16_12bit(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
xvididct.h
ff_idctdsp_init_x86
void ff_idctdsp_init_x86(IDCTDSPContext *c, struct AVCodecContext *avctx, unsigned high_bit_depth)
Definition: idctdsp_init.c:63
NULL
#define NULL
Definition: coverity.c:32
ff_simple_idct_add_int16_8bit
void ff_simple_idct_add_int16_8bit(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
ff_simple_idct_put_int32_10bit
void ff_simple_idct_put_int32_10bit(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
put_pixels_clamped4_c
static void put_pixels_clamped4_c(const int16_t *block, uint8_t *restrict pixels, int line_size)
Definition: idctdsp.c:94
ff_jref_idct_put
void ff_jref_idct_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
Definition: jrevdct.c:1162
ff_jref_idct4_put
static void ff_jref_idct4_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
Definition: idctdsp.c:197
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
ff_faanidct_put
void ff_faanidct_put(uint8_t *dest, ptrdiff_t line_size, int16_t block[64])
Definition: faanidct.c:155
ff_idctdsp_init_mips
void ff_idctdsp_init_mips(IDCTDSPContext *c, struct AVCodecContext *avctx, unsigned high_bit_depth)
Definition: idctdsp_init_mips.c:27
AVCodecContext::lowres
int lowres
low resolution decoding, 1-> 1/2 size, 2->1/4 size
Definition: avcodec.h:1865
ff_j_rev_dct1
void ff_j_rev_dct1(int16_t *data)
ff_idctdsp_init_ppc
av_cold void ff_idctdsp_init_ppc(IDCTDSPContext *c, AVCodecContext *avctx, unsigned high_bit_depth)
Definition: idctdsp.c:256
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:83
FF_IDCT_PERM_NONE
@ FF_IDCT_PERM_NONE
Definition: idctdsp.h:28
ff_jref_idct1_add
static void ff_jref_idct1_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
Definition: idctdsp.c:223
attributes.h
faanidct.h
ff_j_rev_dct2
void ff_j_rev_dct2(int16_t *data)
ff_simple_idct_int16_8bit
void ff_simple_idct_int16_8bit(int16_t *block)
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
ff_add_pixels_clamped_c
void ff_add_pixels_clamped_c(const int16_t *block, uint8_t *restrict pixels, ptrdiff_t line_size)
Definition: idctdsp.c:147
common.h
AVCodecContext::idct_algo
int idct_algo
IDCT algorithm, see FF_IDCT_* below.
Definition: avcodec.h:1558
idctdsp.h
avcodec.h
ff_j_rev_dct
void ff_j_rev_dct(int16_t *data)
FF_IDCT_PERM_TRANSPOSE
@ FF_IDCT_PERM_TRANSPOSE
Definition: idctdsp.h:31
FF_IDCT_FAAN
#define FF_IDCT_FAAN
Definition: avcodec.h:1569
IDCTDSPContext
Definition: idctdsp.h:43
ff_jref_idct_add
void ff_jref_idct_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
Definition: jrevdct.c:1168
AVCodecContext
main external API structure.
Definition: avcodec.h:451
FF_IDCT_PERM_PARTTRANS
@ FF_IDCT_PERM_PARTTRANS
Definition: idctdsp.h:32
ff_simple_idct_int16_12bit
void ff_simple_idct_int16_12bit(int16_t *block)
ff_simple_idct_add_int16_10bit
void ff_simple_idct_add_int16_10bit(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
av_clip_uint8
#define av_clip_uint8
Definition: common.h:106
idct_permutation_type
idct_permutation_type
Definition: idctdsp.h:27
ff_put_pixels_clamped_c
void ff_put_pixels_clamped_c(const int16_t *block, uint8_t *restrict pixels, ptrdiff_t line_size)
Definition: idctdsp.c:73
ff_init_scantable_permutation
av_cold void ff_init_scantable_permutation(uint8_t *idct_permutation, enum idct_permutation_type perm_type)
Definition: idctdsp.c:39
put_pixels_clamped2_c
static void put_pixels_clamped2_c(const int16_t *block, uint8_t *restrict pixels, int line_size)
Definition: idctdsp.c:111
ff_j_rev_dct4
void ff_j_rev_dct4(int16_t *data)
block
The exact code depends on how similar the blocks are and how related they are to the block
Definition: filter_design.txt:207
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
src
#define src
Definition: vp8dsp.c:248
FF_IDCT_PERM_LIBMPEG2
@ FF_IDCT_PERM_LIBMPEG2
Definition: idctdsp.h:29
ff_idctdsp_init_loongarch
void ff_idctdsp_init_loongarch(IDCTDSPContext *c, struct AVCodecContext *avctx, unsigned high_bit_depth)
Definition: idctdsp_init_loongarch.c:26