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 "libavutil/attributes.h"
21 #include "libavutil/common.h"
22 #include "avcodec.h"
23 #include "dct.h"
24 #include "faanidct.h"
25 #include "idctdsp.h"
26 #include "simple_idct.h"
27 #include "xvididct.h"
28 
29 av_cold void ff_init_scantable(uint8_t *permutation, ScanTable *st,
30  const uint8_t *src_scantable)
31 {
32  int i, end;
33 
34  st->scantable = src_scantable;
35 
36  for (i = 0; i < 64; i++) {
37  int j = src_scantable[i];
38  st->permutated[i] = permutation[j];
39  }
40 
41  end = -1;
42  for (i = 0; i < 64; i++) {
43  int j = st->permutated[i];
44  if (j > end)
45  end = j;
46  st->raster_end[i] = end;
47  }
48 }
49 
50 av_cold void ff_init_scantable_permutation(uint8_t *idct_permutation,
51  enum idct_permutation_type perm_type)
52 {
53  int i;
54 
55  if (ARCH_X86)
56  if (ff_init_scantable_permutation_x86(idct_permutation,
57  perm_type))
58  return;
59 
60  switch (perm_type) {
61  case FF_IDCT_PERM_NONE:
62  for (i = 0; i < 64; i++)
63  idct_permutation[i] = i;
64  break;
66  for (i = 0; i < 64; i++)
67  idct_permutation[i] = (i & 0x38) | ((i & 6) >> 1) | ((i & 1) << 2);
68  break;
70  for (i = 0; i < 64; i++)
71  idct_permutation[i] = ((i & 7) << 3) | (i >> 3);
72  break;
74  for (i = 0; i < 64; i++)
75  idct_permutation[i] = (i & 0x24) | ((i & 3) << 3) | ((i >> 3) & 3);
76  break;
77  default:
79  "Internal error, IDCT permutation not set\n");
80  }
81 }
82 
83 void ff_put_pixels_clamped_c(const int16_t *block, uint8_t *av_restrict pixels,
84  ptrdiff_t line_size)
85 {
86  int i;
87 
88  /* read the pixels */
89  for (i = 0; i < 8; i++) {
90  pixels[0] = av_clip_uint8(block[0]);
91  pixels[1] = av_clip_uint8(block[1]);
92  pixels[2] = av_clip_uint8(block[2]);
93  pixels[3] = av_clip_uint8(block[3]);
94  pixels[4] = av_clip_uint8(block[4]);
95  pixels[5] = av_clip_uint8(block[5]);
96  pixels[6] = av_clip_uint8(block[6]);
97  pixels[7] = av_clip_uint8(block[7]);
98 
99  pixels += line_size;
100  block += 8;
101  }
102 }
103 
104 static void put_pixels_clamped4_c(const int16_t *block, uint8_t *av_restrict pixels,
105  int line_size)
106 {
107  int i;
108 
109  /* read the pixels */
110  for(i=0;i<4;i++) {
111  pixels[0] = av_clip_uint8(block[0]);
112  pixels[1] = av_clip_uint8(block[1]);
113  pixels[2] = av_clip_uint8(block[2]);
114  pixels[3] = av_clip_uint8(block[3]);
115 
116  pixels += line_size;
117  block += 8;
118  }
119 }
120 
121 static void put_pixels_clamped2_c(const int16_t *block, uint8_t *av_restrict pixels,
122  int line_size)
123 {
124  int i;
125 
126  /* read the pixels */
127  for(i=0;i<2;i++) {
128  pixels[0] = av_clip_uint8(block[0]);
129  pixels[1] = av_clip_uint8(block[1]);
130 
131  pixels += line_size;
132  block += 8;
133  }
134 }
135 
136 static void put_signed_pixels_clamped_c(const int16_t *block,
137  uint8_t *av_restrict pixels,
138  ptrdiff_t line_size)
139 {
140  int i, j;
141 
142  for (i = 0; i < 8; i++) {
143  for (j = 0; j < 8; j++) {
144  if (*block < -128)
145  *pixels = 0;
146  else if (*block > 127)
147  *pixels = 255;
148  else
149  *pixels = (uint8_t) (*block + 128);
150  block++;
151  pixels++;
152  }
153  pixels += (line_size - 8);
154  }
155 }
156 
157 void ff_add_pixels_clamped_c(const int16_t *block, uint8_t *av_restrict pixels,
158  ptrdiff_t line_size)
159 {
160  int i;
161 
162  /* read the pixels */
163  for (i = 0; i < 8; i++) {
164  pixels[0] = av_clip_uint8(pixels[0] + block[0]);
165  pixels[1] = av_clip_uint8(pixels[1] + block[1]);
166  pixels[2] = av_clip_uint8(pixels[2] + block[2]);
167  pixels[3] = av_clip_uint8(pixels[3] + block[3]);
168  pixels[4] = av_clip_uint8(pixels[4] + block[4]);
169  pixels[5] = av_clip_uint8(pixels[5] + block[5]);
170  pixels[6] = av_clip_uint8(pixels[6] + block[6]);
171  pixels[7] = av_clip_uint8(pixels[7] + block[7]);
172  pixels += line_size;
173  block += 8;
174  }
175 }
176 
177 static void add_pixels_clamped4_c(const int16_t *block, uint8_t *av_restrict pixels,
178  int line_size)
179 {
180  int i;
181 
182  /* read the pixels */
183  for(i=0;i<4;i++) {
184  pixels[0] = av_clip_uint8(pixels[0] + block[0]);
185  pixels[1] = av_clip_uint8(pixels[1] + block[1]);
186  pixels[2] = av_clip_uint8(pixels[2] + block[2]);
187  pixels[3] = av_clip_uint8(pixels[3] + block[3]);
188  pixels += line_size;
189  block += 8;
190  }
191 }
192 
193 static void add_pixels_clamped2_c(const int16_t *block, uint8_t *av_restrict pixels,
194  int line_size)
195 {
196  int i;
197 
198  /* read the pixels */
199  for(i=0;i<2;i++) {
200  pixels[0] = av_clip_uint8(pixels[0] + block[0]);
201  pixels[1] = av_clip_uint8(pixels[1] + block[1]);
202  pixels += line_size;
203  block += 8;
204  }
205 }
206 
207 static void ff_jref_idct4_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
208 {
210  put_pixels_clamped4_c(block, dest, line_size);
211 }
212 static void ff_jref_idct4_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
213 {
215  add_pixels_clamped4_c(block, dest, line_size);
216 }
217 
218 static void ff_jref_idct2_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
219 {
221  put_pixels_clamped2_c(block, dest, line_size);
222 }
223 static void ff_jref_idct2_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
224 {
226  add_pixels_clamped2_c(block, dest, line_size);
227 }
228 
229 static void ff_jref_idct1_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
230 {
231  dest[0] = av_clip_uint8((block[0] + 4)>>3);
232 }
233 static void ff_jref_idct1_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
234 {
235  dest[0] = av_clip_uint8(dest[0] + ((block[0] + 4)>>3));
236 }
237 
239 {
240  const unsigned high_bit_depth = avctx->bits_per_raw_sample > 8;
241 
242  if (avctx->lowres==1) {
243  c->idct_put = ff_jref_idct4_put;
244  c->idct_add = ff_jref_idct4_add;
245  c->idct = ff_j_rev_dct4;
246  c->perm_type = FF_IDCT_PERM_NONE;
247  } else if (avctx->lowres==2) {
248  c->idct_put = ff_jref_idct2_put;
249  c->idct_add = ff_jref_idct2_add;
250  c->idct = ff_j_rev_dct2;
251  c->perm_type = FF_IDCT_PERM_NONE;
252  } else if (avctx->lowres==3) {
253  c->idct_put = ff_jref_idct1_put;
254  c->idct_add = ff_jref_idct1_add;
255  c->idct = ff_j_rev_dct1;
256  c->perm_type = FF_IDCT_PERM_NONE;
257  } else {
258  if (avctx->bits_per_raw_sample == 10 || avctx->bits_per_raw_sample == 9) {
259  /* 10-bit MPEG-4 Simple Studio Profile requires a higher precision IDCT
260  However, it only uses idct_put */
261  if (c->mpeg4_studio_profile) {
262  c->idct_put = ff_simple_idct_put_int32_10bit;
263  c->idct_add = NULL;
264  c->idct = NULL;
265  } else {
266  c->idct_put = ff_simple_idct_put_int16_10bit;
267  c->idct_add = ff_simple_idct_add_int16_10bit;
269  }
270  c->perm_type = FF_IDCT_PERM_NONE;
271  } else if (avctx->bits_per_raw_sample == 12) {
272  c->idct_put = ff_simple_idct_put_int16_12bit;
273  c->idct_add = ff_simple_idct_add_int16_12bit;
275  c->perm_type = FF_IDCT_PERM_NONE;
276  } else {
277  if (avctx->idct_algo == FF_IDCT_INT) {
278  c->idct_put = ff_jref_idct_put;
279  c->idct_add = ff_jref_idct_add;
280  c->idct = ff_j_rev_dct;
281  c->perm_type = FF_IDCT_PERM_LIBMPEG2;
282 #if CONFIG_FAANIDCT
283  } else if (avctx->idct_algo == FF_IDCT_FAAN) {
284  c->idct_put = ff_faanidct_put;
285  c->idct_add = ff_faanidct_add;
286  c->idct = ff_faanidct;
287  c->perm_type = FF_IDCT_PERM_NONE;
288 #endif /* CONFIG_FAANIDCT */
289  } else { // accurate/default
290  /* Be sure FF_IDCT_NONE will select this one, since it uses FF_IDCT_PERM_NONE */
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 
319  ff_init_scantable_permutation(c->idct_permutation,
320  c->perm_type);
321 }
ff_jref_idct1_put
static void ff_jref_idct1_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
Definition: idctdsp.c:229
ff_init_scantable
av_cold void ff_init_scantable(uint8_t *permutation, ScanTable *st, const uint8_t *src_scantable)
Definition: idctdsp.c:29
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:1401
ff_jref_idct2_add
static void ff_jref_idct2_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
Definition: idctdsp.c:223
FF_IDCT_INT
#define FF_IDCT_INT
Definition: avcodec.h:1395
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:177
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:1421
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:157
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:136
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:1160
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:1428
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:121
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:233
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:83
ff_init_scantable_permutation
av_cold void ff_init_scantable_permutation(uint8_t *idct_permutation, enum idct_permutation_type perm_type)
Definition: idctdsp.c:50
ff_simple_idct_int16_8bit
void ff_simple_idct_int16_8bit(int16_t *block)
i
int i
Definition: input.c:406
common.h
ff_idctdsp_init
av_cold void ff_idctdsp_init(IDCTDSPContext *c, AVCodecContext *avctx)
Definition: idctdsp.c:238
AVCodecContext::idct_algo
int idct_algo
IDCT algorithm, see FF_IDCT_* below.
Definition: avcodec.h:1393
ff_jref_idct4_put
static void ff_jref_idct4_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
Definition: idctdsp.c:207
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:1404
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:218
ff_jref_idct_add
void ff_jref_idct_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
Definition: jrevdct.c:1166
AVCodecContext
main external API structure.
Definition: avcodec.h:379
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:102
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:193
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:28
ff_jref_idct4_add
static void ff_jref_idct4_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
Definition: idctdsp.c:212
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:104
ScanTable::raster_end
uint8_t raster_end[64]
Definition: idctdsp.h:34