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