FFmpeg
diracdsp.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2009 David Conrad
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include "config.h"
22 #include "libavutil/attributes.h"
23 #include "libavutil/common.h"
24 #include "diracdsp.h"
25 
26 #define FILTER(src, stride) \
27  ((21*((src)[ 0*stride] + (src)[1*stride]) \
28  -7*((src)[-1*stride] + (src)[2*stride]) \
29  +3*((src)[-2*stride] + (src)[3*stride]) \
30  -1*((src)[-3*stride] + (src)[4*stride]) + 16) >> 5)
31 
32 static void dirac_hpel_filter(uint8_t *dsth, uint8_t *dstv, uint8_t *dstc,
33  const uint8_t *src, ptrdiff_t stride, int width, int height)
34 {
35  int x, y;
36 
37  for (y = 0; y < height; y++) {
38  for (x = -3; x < width+5; x++)
39  dstv[x] = av_clip_uint8(FILTER(src+x, stride));
40 
41  for (x = 0; x < width; x++)
42  dstc[x] = av_clip_uint8(FILTER(dstv+x, 1));
43 
44  for (x = 0; x < width; x++)
45  dsth[x] = av_clip_uint8(FILTER(src+x, 1));
46 
47  src += stride;
48  dsth += stride;
49  dstv += stride;
50  dstc += stride;
51  }
52 }
53 
54 #define PIXOP_BILINEAR(PFX, OP, WIDTH) \
55  static void ff_ ## PFX ## _dirac_pixels ## WIDTH ## _bilinear_c(uint8_t *dst, const uint8_t *src[5], ptrdiff_t stride, int h) \
56  { \
57  int x; \
58  const uint8_t *s0 = src[0]; \
59  const uint8_t *s1 = src[1]; \
60  const uint8_t *s2 = src[2]; \
61  const uint8_t *s3 = src[3]; \
62  const uint8_t *w = src[4]; \
63  \
64  while (h--) { \
65  for (x = 0; x < WIDTH; x++) { \
66  OP(dst[x], (s0[x]*w[0] + s1[x]*w[1] + s2[x]*w[2] + s3[x]*w[3] + 8) >> 4); \
67  } \
68  \
69  dst += stride; \
70  s0 += stride; \
71  s1 += stride; \
72  s2 += stride; \
73  s3 += stride; \
74  } \
75  }
76 
77 #define OP_PUT(dst, val) (dst) = (val)
78 #define OP_AVG(dst, val) (dst) = (((dst) + (val) + 1)>>1)
79 
80 PIXOP_BILINEAR(put, OP_PUT, 8)
81 PIXOP_BILINEAR(put, OP_PUT, 16)
82 PIXOP_BILINEAR(put, OP_PUT, 32)
86 
87 #define op_scale1(x) block[x] = av_clip_uint8( (block[x]*weight + (1<<(log2_denom-1))) >> log2_denom)
88 #define op_scale2(x) dst[x] = av_clip_uint8( (src[x]*weights + dst[x]*weightd + (1<<(log2_denom-1))) >> log2_denom)
89 
90 #define DIRAC_WEIGHT(W) \
91  static void weight_dirac_pixels ## W ## _c(uint8_t *block, ptrdiff_t stride, \
92  int log2_denom, int weight, int h) \
93  { \
94  int x; \
95  while (h--) { \
96  for (x = 0; x < W; x++) { \
97  op_scale1(x); \
98  op_scale1(x+1); \
99  } \
100  block += stride; \
101  } \
102  } \
103  static void biweight_dirac_pixels ## W ## _c(uint8_t *dst, const uint8_t *src, \
104  ptrdiff_t stride, int log2_denom, \
105  int weightd, int weights, int h) { \
106  int x; \
107  while (h--) { \
108  for (x = 0; x < W; x++) { \
109  op_scale2(x); \
110  op_scale2(x+1); \
111  } \
112  dst += stride; \
113  src += stride; \
114  } \
115  }
116 
117 DIRAC_WEIGHT(8)
118 DIRAC_WEIGHT(16)
119 DIRAC_WEIGHT(32)
120 
121 #define ADD_OBMC(xblen) \
122  static void add_obmc ## xblen ## _c(uint16_t *dst, const uint8_t *src, ptrdiff_t stride, \
123  const uint8_t *obmc_weight, int yblen) \
124  { \
125  int x; \
126  while (yblen--) { \
127  for (x = 0; x < xblen; x += 2) { \
128  dst[x ] += src[x ] * obmc_weight[x ]; \
129  dst[x+1] += src[x+1] * obmc_weight[x+1]; \
130  } \
131  dst += stride; \
132  src += stride; \
133  obmc_weight += 32; \
134  } \
135  }
136 
137 ADD_OBMC(8)
138 ADD_OBMC(16)
139 ADD_OBMC(32)
140 
141 static void put_signed_rect_clamped_8bit_c(uint8_t *dst, ptrdiff_t dst_stride,
142  const uint8_t *_src, ptrdiff_t src_stride,
143  int width, int height)
144 {
145  int x, y;
146  const int16_t *src = (const int16_t *)_src;
147  for (y = 0; y < height; y++) {
148  for (x = 0; x < width; x+=4) {
149  dst[x ] = av_clip_uint8(src[x ] + 128);
150  dst[x+1] = av_clip_uint8(src[x+1] + 128);
151  dst[x+2] = av_clip_uint8(src[x+2] + 128);
152  dst[x+3] = av_clip_uint8(src[x+3] + 128);
153  }
154  dst += dst_stride;
155  src += src_stride >> 1;
156  }
157 }
158 
159 #define PUT_SIGNED_RECT_CLAMPED(PX) \
160 static void put_signed_rect_clamped_ ## PX ## bit_c(uint8_t *_dst, ptrdiff_t dst_stride, \
161  const uint8_t *_src, ptrdiff_t src_stride, \
162  int width, int height) \
163 { \
164  int x, y; \
165  uint16_t *dst = (uint16_t *)_dst; \
166  const int32_t *src = (const int32_t *)_src; \
167  for (y = 0; y < height; y++) { \
168  for (x = 0; x < width; x+=4) { \
169  dst[x ] = av_clip_uintp2(src[x ] + (1U << (PX - 1)), PX); \
170  dst[x+1] = av_clip_uintp2(src[x+1] + (1U << (PX - 1)), PX); \
171  dst[x+2] = av_clip_uintp2(src[x+2] + (1U << (PX - 1)), PX); \
172  dst[x+3] = av_clip_uintp2(src[x+3] + (1U << (PX - 1)), PX); \
173  } \
174  dst += dst_stride >> 1; \
175  src += src_stride >> 2; \
176  } \
177 }
178 
181 
182 static void add_rect_clamped_c(uint8_t *dst, const uint16_t *src, ptrdiff_t stride,
183  const int16_t *idwt, ptrdiff_t idwt_stride,
184  int width, int height)
185 {
186  int x, y;
187 
188  for (y = 0; y < height; y++) {
189  for (x = 0; x < width; x+=2) {
190  dst[x ] = av_clip_uint8(((src[x ]+32)>>6) + idwt[x ]);
191  dst[x+1] = av_clip_uint8(((src[x+1]+32)>>6) + idwt[x+1]);
192  }
193  dst += stride;
194  src += stride;
195  idwt += idwt_stride;
196  }
197 }
198 
199 #define DEQUANT_SUBBAND(PX) \
200 static void dequant_subband_ ## PX ## _c(uint8_t *src, uint8_t *dst, ptrdiff_t stride, \
201  const int qf, const int qs, int tot_v, int tot_h) \
202 { \
203  int i, y; \
204  for (y = 0; y < tot_v; y++) { \
205  PX c, *src_r = (PX *)src, *dst_r = (PX *)dst; \
206  for (i = 0; i < tot_h; i++) { \
207  c = *src_r++; \
208  if (c < 0) c = -((-(unsigned)c*qf + qs) >> 2); \
209  else if(c > 0) c = (( (unsigned)c*qf + qs) >> 2); \
210  *dst_r++ = c; \
211  } \
212  src += tot_h << (sizeof(PX) >> 1); \
213  dst += stride; \
214  } \
215 }
216 
217 DEQUANT_SUBBAND(int16_t)
219 
220 #define PIXFUNC(PFX, WIDTH) \
221  c->PFX ## _dirac_pixels_tab[WIDTH>>4][0] = ff_ ## PFX ## _dirac_pixels ## WIDTH ## _c; \
222  c->PFX ## _dirac_pixels_tab[WIDTH>>4][1] = ff_ ## PFX ## _dirac_pixels ## WIDTH ## _l2_c; \
223  c->PFX ## _dirac_pixels_tab[WIDTH>>4][2] = ff_ ## PFX ## _dirac_pixels ## WIDTH ## _l4_c; \
224  c->PFX ## _dirac_pixels_tab[WIDTH>>4][3] = ff_ ## PFX ## _dirac_pixels ## WIDTH ## _bilinear_c
225 
227 {
228  c->dirac_hpel_filter = dirac_hpel_filter;
229  c->add_rect_clamped = add_rect_clamped_c;
230  c->put_signed_rect_clamped[0] = put_signed_rect_clamped_8bit_c;
231  c->put_signed_rect_clamped[1] = put_signed_rect_clamped_10bit_c;
232  c->put_signed_rect_clamped[2] = put_signed_rect_clamped_12bit_c;
233 
234  c->add_dirac_obmc[0] = add_obmc8_c;
235  c->add_dirac_obmc[1] = add_obmc16_c;
236  c->add_dirac_obmc[2] = add_obmc32_c;
237 
238  c->weight_dirac_pixels_tab[0] = weight_dirac_pixels8_c;
239  c->weight_dirac_pixels_tab[1] = weight_dirac_pixels16_c;
240  c->weight_dirac_pixels_tab[2] = weight_dirac_pixels32_c;
241  c->biweight_dirac_pixels_tab[0] = biweight_dirac_pixels8_c;
242  c->biweight_dirac_pixels_tab[1] = biweight_dirac_pixels16_c;
243  c->biweight_dirac_pixels_tab[2] = biweight_dirac_pixels32_c;
244 
245  c->dequant_subband[0] = c->dequant_subband[2] = dequant_subband_int16_t_c;
246  c->dequant_subband[1] = c->dequant_subband[3] = dequant_subband_int32_t_c;
247 
248  PIXFUNC(put, 8);
249  PIXFUNC(put, 16);
250  PIXFUNC(put, 32);
251  PIXFUNC(avg, 8);
252  PIXFUNC(avg, 16);
253  PIXFUNC(avg, 32);
254 
255 #if ARCH_X86 && HAVE_X86ASM
257 #endif
258 }
dirac_hpel_filter
static void dirac_hpel_filter(uint8_t *dsth, uint8_t *dstv, uint8_t *dstc, const uint8_t *src, ptrdiff_t stride, int width, int height)
Definition: diracdsp.c:32
ff_diracdsp_init
av_cold void ff_diracdsp_init(DiracDSPContext *c)
Definition: diracdsp.c:226
av_cold
#define av_cold
Definition: attributes.h:119
PIXOP_BILINEAR
#define PIXOP_BILINEAR(PFX, OP, WIDTH)
Definition: diracdsp.c:54
_src
uint8_t ptrdiff_t const uint8_t * _src
Definition: dsp.h:56
OP_AVG
#define OP_AVG(dst, val)
Definition: diracdsp.c:78
DIRAC_WEIGHT
#define DIRAC_WEIGHT(W)
Definition: diracdsp.c:90
FILTER
#define FILTER(src, stride)
Definition: diracdsp.c:26
diracdsp.h
PUT_SIGNED_RECT_CLAMPED
#define PUT_SIGNED_RECT_CLAMPED(PX)
Definition: diracdsp.c:159
attributes.h
put_signed_rect_clamped_8bit_c
static void put_signed_rect_clamped_8bit_c(uint8_t *dst, ptrdiff_t dst_stride, const uint8_t *_src, ptrdiff_t src_stride, int width, int height)
Definition: diracdsp.c:141
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
height
#define height
Definition: dsp.h:89
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
avg
#define avg(a, b, c, d)
Definition: colorspacedsp_template.c:28
OP_PUT
#define OP_PUT(dst, val)
Definition: diracdsp.c:77
DiracDSPContext
Definition: diracdsp.h:31
common.h
DEQUANT_SUBBAND
#define DEQUANT_SUBBAND(PX)
Definition: diracdsp.c:199
ADD_OBMC
#define ADD_OBMC(xblen)
Definition: diracdsp.c:121
ff_diracdsp_init_x86
void ff_diracdsp_init_x86(DiracDSPContext *c)
Definition: diracdsp_init.c:91
av_clip_uint8
#define av_clip_uint8
Definition: common.h:106
int32_t
int32_t
Definition: audioconvert.c:56
PIXFUNC
#define PIXFUNC(PFX, WIDTH)
Definition: diracdsp.c:220
stride
#define stride
Definition: h264pred_template.c:536
width
#define width
Definition: dsp.h:89
src
#define src
Definition: vp8dsp.c:248
add_rect_clamped_c
static void add_rect_clamped_c(uint8_t *dst, const uint16_t *src, ptrdiff_t stride, const int16_t *idwt, ptrdiff_t idwt_stride, int width, int height)
Definition: diracdsp.c:182