FFmpeg
Loading...
Searching...
No Matches
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"
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
30av_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
39av_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 && HAVE_X86ASM
45 if (ff_init_scantable_permutation_x86(idct_permutation,
46 perm_type))
47 return;
48#endif
49
50 switch (perm_type) {
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
73void 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
94static 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
111static 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
126static 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
147void 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
167static 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
183static 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
197static 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}
202static 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
208static 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}
213static 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
219static 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}
223static 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) {
253 c->idct_add = NULL;
254 c->idct = NULL;
255 } else {
259 }
260 c->perm_type = FF_IDCT_PERM_NONE;
261 } else if (avctx->bits_per_raw_sample == 12) {
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#if CONFIG_MPEG4_DECODER
280 } else if (avctx->idct_algo == FF_IDCT_XVID) {
282#endif
283 } else { // accurate/default
287 c->perm_type = FF_IDCT_PERM_NONE;
288 }
289 }
290 }
291
292 c->put_pixels_clamped = ff_put_pixels_clamped_c;
293 c->put_signed_pixels_clamped = put_signed_pixels_clamped_c;
294 c->add_pixels_clamped = ff_add_pixels_clamped_c;
295
296#if ARCH_AARCH64
297 ff_idctdsp_init_aarch64(c, avctx, high_bit_depth);
298#elif ARCH_ARM
299 ff_idctdsp_init_arm(c, avctx, high_bit_depth);
300#elif ARCH_PPC
301 ff_idctdsp_init_ppc(c, avctx, high_bit_depth);
302#elif ARCH_RISCV
303 ff_idctdsp_init_riscv(c, avctx, high_bit_depth);
304#elif ARCH_X86 && HAVE_X86ASM
305 ff_idctdsp_init_x86(c, avctx, high_bit_depth);
306#elif ARCH_MIPS
307 ff_idctdsp_init_mips(c, avctx, high_bit_depth);
308#elif ARCH_LOONGARCH
309 ff_idctdsp_init_loongarch(c, avctx, high_bit_depth);
310#endif
311
312 ff_init_scantable_permutation(c->idct_permutation,
313 c->perm_type);
314}
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
Libavcodec external API header.
#define FF_IDCT_FAAN
Definition avcodec.h:1556
#define FF_IDCT_XVID
Definition avcodec.h:1553
#define FF_IDCT_INT
Definition avcodec.h:1547
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
common internal and external API header
#define av_clip_uint8
Definition common.h:106
#define NULL
Definition coverity.c:32
static int16_t block[64]
Definition dct.c:125
void ff_jref_idct_add(uint8_t *dest, ptrdiff_t line_size, int16_t block[64])
Definition jrevdct.c:1168
void ff_j_rev_dct(int16_t data[64])
void ff_jref_idct_put(uint8_t *dest, ptrdiff_t line_size, int16_t block[64])
Definition jrevdct.c:1162
void ff_j_rev_dct1(int16_t data[64])
void ff_j_rev_dct4(int16_t data[64])
void ff_j_rev_dct2(int16_t data[64])
void ff_faanidct_add(uint8_t *dest, ptrdiff_t line_size, int16_t block[64])
Definition faanidct.c:141
void ff_faanidct(int16_t block[64])
Definition faanidct.c:128
void ff_faanidct_put(uint8_t *dest, ptrdiff_t line_size, int16_t block[64])
Definition faanidct.c:155
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
void ff_idctdsp_init_loongarch(IDCTDSPContext *c, struct AVCodecContext *avctx, unsigned high_bit_depth)
void ff_idctdsp_init_x86(IDCTDSPContext *c, struct AVCodecContext *avctx, unsigned high_bit_depth)
void ff_idctdsp_init_riscv(IDCTDSPContext *c, struct AVCodecContext *avctx, unsigned high_bit_depth)
int ff_init_scantable_permutation_x86(uint8_t *idct_permutation, enum idct_permutation_type perm_type)
idct_permutation_type
Definition idctdsp.h:27
@ FF_IDCT_PERM_LIBMPEG2
Definition idctdsp.h:29
@ FF_IDCT_PERM_NONE
Definition idctdsp.h:28
@ FF_IDCT_PERM_PARTTRANS
Definition idctdsp.h:32
@ FF_IDCT_PERM_TRANSPOSE
Definition idctdsp.h:31
void ff_idctdsp_init_ppc(IDCTDSPContext *c, struct AVCodecContext *avctx, unsigned high_bit_depth)
Definition idctdsp.c:256
void ff_idctdsp_init_mips(IDCTDSPContext *c, struct AVCodecContext *avctx, unsigned high_bit_depth)
av_cold void ff_idctdsp_init_aarch64(IDCTDSPContext *c, AVCodecContext *avctx, unsigned high_bit_depth)
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 *restrict pixels, int line_size)
Definition idctdsp.c:183
static void ff_jref_idct4_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
Definition idctdsp.c:197
av_cold void ff_idctdsp_init(IDCTDSPContext *c, AVCodecContext *avctx)
Definition idctdsp.c:228
static void ff_jref_idct2_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
Definition idctdsp.c:213
av_cold void ff_init_scantable_permutation(uint8_t *idct_permutation, enum idct_permutation_type perm_type)
Definition idctdsp.c:39
static void ff_jref_idct2_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
Definition idctdsp.c:208
av_cold void ff_permute_scantable(uint8_t dst[64], const uint8_t src[64], const uint8_t permutation[64])
Definition idctdsp.c:30
static void add_pixels_clamped4_c(const int16_t *block, uint8_t *restrict pixels, int line_size)
Definition idctdsp.c:167
static void ff_jref_idct1_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
Definition idctdsp.c:219
void ff_add_pixels_clamped_c(const int16_t *block, uint8_t *restrict pixels, ptrdiff_t line_size)
Definition idctdsp.c:147
static void ff_jref_idct1_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
Definition idctdsp.c:223
static void put_pixels_clamped4_c(const int16_t *block, uint8_t *restrict pixels, int line_size)
Definition idctdsp.c:94
static void put_signed_pixels_clamped_c(const int16_t *block, uint8_t *restrict pixels, ptrdiff_t line_size)
Definition idctdsp.c:126
static void put_pixels_clamped2_c(const int16_t *block, uint8_t *restrict pixels, int line_size)
Definition idctdsp.c:111
void ff_put_pixels_clamped_c(const int16_t *block, uint8_t *restrict pixels, ptrdiff_t line_size)
Definition idctdsp.c:73
static void ff_jref_idct4_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
Definition idctdsp.c:202
Macro definitions for various function/variable attributes.
#define av_unused
Definition attributes.h:164
#define av_cold
Definition attributes.h:117
simple idct header.
void ff_simple_idct_int16_8bit(int16_t *block)
void ff_simple_idct_int16_12bit(int16_t *block)
void ff_simple_idct_add_int16_12bit(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
void ff_simple_idct_put_int16_12bit(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
void ff_simple_idct_add_int16_8bit(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
void ff_simple_idct_int16_10bit(int16_t *block)
void ff_simple_idct_put_int16_8bit(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
void ff_simple_idct_add_int16_10bit(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
void ff_simple_idct_put_int16_10bit(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)
main external API structure.
Definition avcodec.h:443
int bits_per_raw_sample
Bits per sample/pixel of internal libavcodec pixel/sample format.
Definition avcodec.h:1572
int idct_algo
IDCT algorithm, see FF_IDCT_* below.
Definition avcodec.h:1545
int lowres
low resolution decoding, 1-> 1/2 size, 2->1/4 size
Definition avcodec.h:1703
#define av_log(a,...)
#define src
Definition vp8dsp.c:248
static double c[64]
av_cold void ff_xvid_idct_init(IDCTDSPContext *c)
Definition xvididct.c:332