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 
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 {
209  ff_j_rev_dct4 (block);
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 {
214  ff_j_rev_dct4 (block);
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 {
220  ff_j_rev_dct2 (block);
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 {
225  ff_j_rev_dct2 (block);
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) {
245  c->idct = ff_j_rev_dct4;
247  } else if (avctx->lowres==2) {
250  c->idct = ff_j_rev_dct2;
252  } else if (avctx->lowres==3) {
255  c->idct = ff_j_rev_dct1;
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) {
263  c->idct_add = NULL;
264  c->idct = NULL;
265  } else {
269  }
271  } else if (avctx->bits_per_raw_sample == 12) {
276  } else {
277  if (avctx->idct_algo == FF_IDCT_INT) {
280  c->idct = ff_j_rev_dct;
282 #if CONFIG_FAANIDCT
283  } else if (avctx->idct_algo == FF_IDCT_FAAN) {
286  c->idct = ff_faanidct;
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 */
295  }
296  }
297  }
298 
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 
320  c->perm_type);
321 }
void ff_idctdsp_init_x86(IDCTDSPContext *c, AVCodecContext *avctx, unsigned high_bit_depth)
Definition: idctdsp_init.c:61
int ff_init_scantable_permutation_x86(uint8_t *idct_permutation, enum idct_permutation_type perm_type)
Definition: idctdsp_init.c:42
idct_permutation_type
Definition: idctdsp.h:37
#define NULL
Definition: coverity.c:32
static void put_pixels_clamped4_c(const int16_t *block, uint8_t *av_restrict pixels, int line_size)
Definition: idctdsp.c:104
void ff_j_rev_dct4(int16_t *data)
void(* put_pixels_clamped)(const int16_t *block, uint8_t *av_restrict pixels, ptrdiff_t line_size)
Definition: idctdsp.h:55
void ff_faanidct_put(uint8_t *dest, ptrdiff_t line_size, int16_t block[64])
Definition: faanidct.c:154
Scantable.
Definition: idctdsp.h:31
void ff_simple_idct_int16_8bit(int16_t *block)
uint8_t raster_end[64]
Definition: idctdsp.h:34
uint8_t permutated[64]
Definition: idctdsp.h:33
int bits_per_raw_sample
Bits per sample/pixel of internal libavcodec pixel/sample format.
Definition: avcodec.h:2799
Macro definitions for various function/variable attributes.
static void add_pixels_clamped4_c(const int16_t *block, uint8_t *av_restrict pixels, int line_size)
Definition: idctdsp.c:177
av_cold void ff_idctdsp_init_ppc(IDCTDSPContext *c, AVCodecContext *avctx, unsigned high_bit_depth)
Definition: idctdsp.c:255
The exact code depends on how similar the blocks are and how related they are to the block
uint8_t
#define av_cold
Definition: attributes.h:82
#define FF_IDCT_INT
Definition: avcodec.h:2773
void ff_faanidct(int16_t block[64])
Definition: faanidct.c:127
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
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
static void ff_jref_idct2_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
Definition: idctdsp.c:223
static void put_signed_pixels_clamped_c(const int16_t *block, uint8_t *av_restrict pixels, ptrdiff_t line_size)
Definition: idctdsp.c:136
void ff_simple_idct_int16_12bit(int16_t *block)
const uint8_t * scantable
Definition: idctdsp.h:32
int lowres
low resolution decoding, 1-> 1/2 size, 2->1/4 size
Definition: avcodec.h:2807
int mpeg4_studio_profile
Definition: idctdsp.h:99
#define av_log(a,...)
void ff_jref_idct_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
Definition: jrevdct.c:1160
void ff_add_pixels_clamped_c(const int16_t *block, uint8_t *av_restrict pixels, ptrdiff_t line_size)
Definition: idctdsp.c:157
av_cold void ff_xvid_idct_init(IDCTDSPContext *c, AVCodecContext *avctx)
Definition: xvididct.c:333
#define FF_IDCT_XVID
Definition: avcodec.h:2779
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
void ff_simple_idct_add_int16_10bit(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
void ff_jref_idct_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
Definition: jrevdct.c:1166
void ff_idctdsp_init_mips(IDCTDSPContext *c, AVCodecContext *avctx, unsigned high_bit_depth)
void(* put_signed_pixels_clamped)(const int16_t *block, uint8_t *av_restrict pixels, ptrdiff_t line_size)
Definition: idctdsp.h:58
void ff_faanidct_add(uint8_t *dest, ptrdiff_t line_size, int16_t block[64])
Definition: faanidct.c:140
static void ff_jref_idct1_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
Definition: idctdsp.c:233
av_cold void ff_init_scantable_permutation(uint8_t *idct_permutation, enum idct_permutation_type perm_type)
Definition: idctdsp.c:50
av_cold void ff_idctdsp_init_alpha(IDCTDSPContext *c, AVCodecContext *avctx, unsigned high_bit_depth)
int idct_algo
IDCT algorithm, see FF_IDCT_* below.
Definition: avcodec.h:2771
void(* idct_add)(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
block -> idct -> add dest -> clip to unsigned 8 bit -> dest.
Definition: idctdsp.h:79
uint8_t idct_permutation[64]
IDCT input permutation.
Definition: idctdsp.h:96
static void put_pixels_clamped2_c(const int16_t *block, uint8_t *av_restrict pixels, int line_size)
Definition: idctdsp.c:121
void(* idct_put)(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
block -> idct -> clip to unsigned 8 bit -> dest.
Definition: idctdsp.h:72
void ff_simple_idct_put_int16_10bit(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
void ff_put_pixels_clamped_c(const int16_t *block, uint8_t *av_restrict pixels, ptrdiff_t line_size)
Definition: idctdsp.c:83
void ff_j_rev_dct1(int16_t *data)
void ff_j_rev_dct(int16_t *data)
void ff_simple_idct_add_int16_12bit(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
Libavcodec external API header.
main external API structure.
Definition: avcodec.h:1568
static void ff_jref_idct4_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
Definition: idctdsp.c:207
av_cold void ff_idctdsp_init_arm(IDCTDSPContext *c, AVCodecContext *avctx, unsigned high_bit_depth)
static void add_pixels_clamped2_c(const int16_t *block, uint8_t *av_restrict pixels, int line_size)
Definition: idctdsp.c:193
av_cold void ff_idctdsp_init_aarch64(IDCTDSPContext *c, AVCodecContext *avctx, unsigned high_bit_depth)
void ff_simple_idct_int16_10bit(int16_t *block)
void ff_j_rev_dct2(int16_t *data)
static void ff_jref_idct4_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
Definition: idctdsp.c:212
common internal and external API header
#define FF_IDCT_FAAN
Definition: avcodec.h:2782
av_cold void ff_init_scantable(uint8_t *permutation, ScanTable *st, const uint8_t *src_scantable)
Definition: idctdsp.c:29
int pixels
Definition: avisynth_c.h:390
av_cold void ff_idctdsp_init(IDCTDSPContext *c, AVCodecContext *avctx)
Definition: idctdsp.c:238
simple idct header.
void ff_simple_idct_add_int16_8bit(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
void ff_simple_idct_put_int32_10bit(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
void ff_simple_idct_put_int16_8bit(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
static void ff_jref_idct2_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
Definition: idctdsp.c:218
void(* idct)(int16_t *block)
Definition: idctdsp.h:65
static void ff_jref_idct1_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
Definition: idctdsp.c:229
void ff_simple_idct_put_int16_12bit(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
enum idct_permutation_type perm_type
Definition: idctdsp.h:97
void(* add_pixels_clamped)(const int16_t *block, uint8_t *av_restrict pixels, ptrdiff_t line_size)
Definition: idctdsp.h:61