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_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 
51 av_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;
68  for (i = 0; i < 64; i++)
69  idct_permutation[i] = (i & 0x38) | ((i & 6) >> 1) | ((i & 1) << 2);
70  break;
72  for (i = 0; i < 64; i++)
73  idct_permutation[i] = ((i & 7) << 3) | (i >> 3);
74  break;
76  for (i = 0; i < 64; i++)
77  idct_permutation[i] = (i & 0x24) | ((i & 3) << 3) | ((i >> 3) & 3);
78  break;
79  default:
81  "Internal error, IDCT permutation not set\n");
82  }
83 }
84 
85 void 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 
106 static 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 
123 static 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 
138 static 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 
159 void 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 
179 static 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 
195 static 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 
209 static void ff_jref_idct4_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
210 {
212  put_pixels_clamped4_c(block, dest, line_size);
213 }
214 static void ff_jref_idct4_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
215 {
217  add_pixels_clamped4_c(block, dest, line_size);
218 }
219 
220 static void ff_jref_idct2_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
221 {
223  put_pixels_clamped2_c(block, dest, line_size);
224 }
225 static void ff_jref_idct2_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
226 {
228  add_pixels_clamped2_c(block, dest, line_size);
229 }
230 
231 static 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 }
235 static 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 
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;
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;
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;
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 }
ff_simple_idct_put_int16_10bit
void ff_simple_idct_put_int16_10bit(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
add_pixels_clamped2_c
static void add_pixels_clamped2_c(const int16_t *block, uint8_t *av_restrict pixels, int line_size)
Definition: idctdsp.c:195
ff_jref_idct1_put
static void ff_jref_idct1_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
Definition: idctdsp.c:231
ff_xvid_idct_init
av_cold void ff_xvid_idct_init(IDCTDSPContext *c, AVCodecContext *avctx)
Definition: xvididct.c:333
put_pixels_clamped2_c
static void put_pixels_clamped2_c(const int16_t *block, uint8_t *av_restrict pixels, int line_size)
Definition: idctdsp.c:123
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:225
av_unused
#define av_unused
Definition: attributes.h:131
ff_jref_idct4_add
static void ff_jref_idct4_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
Definition: idctdsp.c:214
ff_put_pixels_clamped_c
void ff_put_pixels_clamped_c(const int16_t *block, uint8_t *av_restrict pixels, ptrdiff_t line_size)
Definition: idctdsp.c:85
ff_idctdsp_init_x86
void ff_idctdsp_init_x86(IDCTDSPContext *c, AVCodecContext *avctx, unsigned high_bit_depth)
Definition: idctdsp_init.c:61
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:240
ff_simple_idct_int16_10bit
void ff_simple_idct_int16_10bit(int16_t *block)
FF_IDCT_XVID
#define FF_IDCT_XVID
Definition: avcodec.h:1428
ff_jref_idct2_put
static void ff_jref_idct2_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
Definition: idctdsp.c:220
FF_IDCT_INT
#define FF_IDCT_INT
Definition: avcodec.h:1422
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
av_cold
#define av_cold
Definition: attributes.h:90
dct.h
put_pixels_clamped4_c
static void put_pixels_clamped4_c(const int16_t *block, uint8_t *av_restrict pixels, int line_size)
Definition: idctdsp.c:106
ff_faanidct_add
void ff_faanidct_add(uint8_t *dest, ptrdiff_t line_size, int16_t block[64])
Definition: faanidct.c:140
ff_faanidct
void ff_faanidct(int16_t block[64])
Definition: faanidct.c:127
AVCodecContext::bits_per_raw_sample
int bits_per_raw_sample
Bits per sample/pixel of internal libavcodec pixel/sample format.
Definition: avcodec.h:1451
ff_simple_idct_put_int16_8bit
void ff_simple_idct_put_int16_8bit(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
ScanTable::scantable
const uint8_t * scantable
Definition: idctdsp.h:32
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
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)
ff_idctdsp_init_mips
void ff_idctdsp_init_mips(IDCTDSPContext *c, AVCodecContext *avctx, unsigned high_bit_depth)
Definition: idctdsp_init_mips.c:27
ff_jref_idct_put
void ff_jref_idct_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
Definition: jrevdct.c:1162
put_signed_pixels_clamped_c
static void put_signed_pixels_clamped_c(const int16_t *block, uint8_t *av_restrict pixels, ptrdiff_t line_size)
Definition: idctdsp.c:138
ff_jref_idct4_put
static void ff_jref_idct4_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
Definition: idctdsp.c:209
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:154
AVCodecContext::lowres
int lowres
low resolution decoding, 1-> 1/2 size, 2->1/4 size
Definition: avcodec.h:1458
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:255
FF_IDCT_PERM_NONE
@ FF_IDCT_PERM_NONE
Definition: idctdsp.h:38
ff_jref_idct1_add
static void ff_jref_idct1_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
Definition: idctdsp.c:235
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:269
ff_init_scantable
av_cold void ff_init_scantable(const uint8_t *permutation, ScanTable *st, const uint8_t *src_scantable)
Definition: idctdsp.c:30
common.h
ff_idctdsp_init_loongarch
void ff_idctdsp_init_loongarch(IDCTDSPContext *c, AVCodecContext *avctx, unsigned high_bit_depth)
Definition: idctdsp_init_loongarch.c:26
AVCodecContext::idct_algo
int idct_algo
IDCT algorithm, see FF_IDCT_* below.
Definition: avcodec.h:1420
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:41
FF_IDCT_FAAN
#define FF_IDCT_FAAN
Definition: avcodec.h:1431
IDCTDSPContext
Definition: idctdsp.h:53
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:398
ff_add_pixels_clamped_c
void ff_add_pixels_clamped_c(const int16_t *block, uint8_t *av_restrict pixels, ptrdiff_t line_size)
Definition: idctdsp.c:159
FF_IDCT_PERM_PARTTRANS
@ FF_IDCT_PERM_PARTTRANS
Definition: idctdsp.h:42
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:101
idct_permutation_type
idct_permutation_type
Definition: idctdsp.h:37
ff_init_scantable_permutation
av_cold void ff_init_scantable_permutation(uint8_t *idct_permutation, enum idct_permutation_type perm_type)
Definition: idctdsp.c:51
ScanTable
Scantable.
Definition: idctdsp.h:31
ScanTable::permutated
uint8_t permutated[64]
Definition: idctdsp.h:33
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
add_pixels_clamped4_c
static void add_pixels_clamped4_c(const int16_t *block, uint8_t *av_restrict pixels, int line_size)
Definition: idctdsp.c:179
ff_idctdsp_init_alpha
av_cold void ff_idctdsp_init_alpha(IDCTDSPContext *c, AVCodecContext *avctx, unsigned high_bit_depth)
Definition: idctdsp_alpha.c:108
FF_IDCT_PERM_LIBMPEG2
@ FF_IDCT_PERM_LIBMPEG2
Definition: idctdsp.h:39
ScanTable::raster_end
uint8_t raster_end[64]
Definition: idctdsp.h:34