vf_ow.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2007 Michael Niedermayer <michaelni@gmx.at>
3  *
4  * This file is part of MPlayer.
5  *
6  * MPlayer is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * MPlayer 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
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with MPlayer; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20 
21 /**
22  * @todo try to change to int
23  * @todo try lifting based implementation
24  * @todo optimize optimize optimize
25  * @todo hard tresholding
26  * @todo use QP to decide filter strength
27  * @todo wavelet normalization / least squares optimal signal vs. noise thresholds
28  */
29 
30 #include <stdio.h>
31 #include <string.h>
32 #include <inttypes.h>
33 #include <math.h>
34 
35 #include "mp_msg.h"
36 #include "img_format.h"
37 #include "mp_image.h"
38 #include "vf.h"
39 
40 //===========================================================================//
41 static const uint8_t __attribute__((aligned(8))) dither[8][8]={
42 { 0, 48, 12, 60, 3, 51, 15, 63, },
43 { 32, 16, 44, 28, 35, 19, 47, 31, },
44 { 8, 56, 4, 52, 11, 59, 7, 55, },
45 { 40, 24, 36, 20, 43, 27, 39, 23, },
46 { 2, 50, 14, 62, 1, 49, 13, 61, },
47 { 34, 18, 46, 30, 33, 17, 45, 29, },
48 { 10, 58, 6, 54, 9, 57, 5, 53, },
49 { 42, 26, 38, 22, 41, 25, 37, 21, },
50 };
51 //FIXME the above is duplicated in many filters
52 
53 struct vf_priv_s {
54  float strength[2];
55  float delta;
56  int mode;
57  int depth;
58  float *plane[16][4];
59  int stride;
60 };
61 
62 #define S 1.41421356237 //sqrt(2)
63 
64 static const double coeff[2][5]={
65  {
66  0.6029490182363579 *S,
67  0.2668641184428723 *S,
68  -0.07822326652898785 *S,
69  -0.01686411844287495 *S,
70  0.02674875741080976 *S
71  },{
72  1.115087052456994 /S,
73  -0.5912717631142470 /S,
74  -0.05754352622849957 /S,
75  0.09127176311424948 /S
76  }
77 };
78 
79 static const double icoeff[2][5]={
80  {
81  1.115087052456994 /S,
82  0.5912717631142470 /S,
83  -0.05754352622849957 /S,
84  -0.09127176311424948 /S
85  },{
86  0.6029490182363579 *S,
87  -0.2668641184428723 *S,
88  -0.07822326652898785 *S,
89  0.01686411844287495 *S,
90  0.02674875741080976 *S
91  }
92 };
93 #undef S
94 
95 static inline int mirror(int x, int w){
96  while((unsigned)x > (unsigned)w){
97  x=-x;
98  if(x<0) x+= 2*w;
99  }
100  return x;
101 }
102 
103 static inline void decompose(float *dstL, float *dstH, float *src, int stride, int w){
104  int x, i;
105  for(x=0; x<w; x++){
106  double sumL= src[x*stride] * coeff[0][0];
107  double sumH= src[x*stride] * coeff[1][0];
108  for(i=1; i<=4; i++){
109  double s= (src[mirror(x-i, w-1)*stride] + src[mirror(x+i, w-1)*stride]);
110 
111  sumL+= coeff[0][i]*s;
112  sumH+= coeff[1][i]*s;
113  }
114  dstL[x*stride]= sumL;
115  dstH[x*stride]= sumH;
116  }
117 }
118 
119 static inline void compose(float *dst, float *srcL, float *srcH, int stride, int w){
120  int x, i;
121  for(x=0; x<w; x++){
122  double sumL= srcL[x*stride] * icoeff[0][0];
123  double sumH= srcH[x*stride] * icoeff[1][0];
124  for(i=1; i<=4; i++){
125  int x0= mirror(x-i, w-1)*stride;
126  int x1= mirror(x+i, w-1)*stride;
127 
128  sumL+= icoeff[0][i]*(srcL[x0] + srcL[x1]);
129  sumH+= icoeff[1][i]*(srcH[x0] + srcH[x1]);
130  }
131  dst[x*stride]= (sumL + sumH)*0.5;
132  }
133 }
134 
135 static inline void decompose2D(float *dstL, float *dstH, float *src, int xstride, int ystride, int step, int w, int h){
136  int y, x;
137  for(y=0; y<h; y++)
138  for(x=0; x<step; x++)
139  decompose(dstL + ystride*y + xstride*x, dstH + ystride*y + xstride*x, src + ystride*y + xstride*x, step*xstride, (w-x+step-1)/step);
140 }
141 
142 static inline void compose2D(float *dst, float *srcL, float *srcH, int xstride, int ystride, int step, int w, int h){
143  int y, x;
144  for(y=0; y<h; y++)
145  for(x=0; x<step; x++)
146  compose(dst + ystride*y + xstride*x, srcL + ystride*y + xstride*x, srcH + ystride*y + xstride*x, step*xstride, (w-x+step-1)/step);
147 }
148 
149 static void decompose2D2(float *dst[4], float *src, float *temp[2], int stride, int step, int w, int h){
150  decompose2D(temp[0], temp[1], src , 1, stride, step , w, h);
151  decompose2D( dst[0], dst[1], temp[0], stride, 1, step , h, w);
152  decompose2D( dst[2], dst[3], temp[1], stride, 1, step , h, w);
153 }
154 
155 static void compose2D2(float *dst, float *src[4], float *temp[2], int stride, int step, int w, int h){
156  compose2D(temp[0], src[0], src[1], stride, 1, step , h, w);
157  compose2D(temp[1], src[2], src[3], stride, 1, step , h, w);
158  compose2D(dst , temp[0], temp[1], 1, stride, step , w, h);
159 }
160 
161 static void filter(struct vf_priv_s *p, uint8_t *dst, uint8_t *src, int dst_stride, int src_stride, int width, int height, int is_luma){
162  int x,y, i, j;
163 // double sum=0;
164  double s= p->strength[!is_luma];
165  int depth= p->depth;
166 
167  while(1<<depth > width || 1<<depth > height)
168  depth--;
169 
170  for(y=0; y<height; y++)
171  for(x=0; x<width; x++)
172  p->plane[0][0][x + y*p->stride]= src[x + y*src_stride];
173 
174  for(i=0; i<depth; i++){
175  decompose2D2(p->plane[i+1], p->plane[i][0], p->plane[0]+1,p->stride, 1<<i, width, height);
176  }
177  for(i=0; i<depth; i++){
178  for(j=1; j<4; j++){
179  for(y=0; y<height; y++){
180  for(x=0; x<width; x++){
181  double v= p->plane[i+1][j][x + y*p->stride];
182  if (v> s) v-=s;
183  else if(v<-s) v+=s;
184  else v =0;
185  p->plane[i+1][j][x + y*p->stride]= v;
186  }
187  }
188  }
189  }
190  for(i=depth-1; i>=0; i--){
191  compose2D2(p->plane[i][0], p->plane[i+1], p->plane[0]+1, p->stride, 1<<i, width, height);
192  }
193 
194  for(y=0; y<height; y++)
195  for(x=0; x<width; x++){
196  i= p->plane[0][0][x + y*p->stride] + dither[x&7][y&7]*(1.0/64) + 1.0/128; //yes the rounding is insane but optimal :)
197 // double e= i - src[x + y*src_stride];
198 // sum += e*e;
199  if((unsigned)i > 255U) i= ~(i>>31);
200  dst[x + y*dst_stride]= i;
201  }
202 
203 // printf("%f\n", sum/height/width);
204 }
205 
206 static int config(struct vf_instance *vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){
207  int h= (height+15)&(~15);
208  int i,j;
209 
210  vf->priv->stride= (width+15)&(~15);
211  for(j=0; j<4; j++){
212  for(i=0; i<=vf->priv->depth; i++)
213  vf->priv->plane[i][j]= malloc(vf->priv->stride*h*sizeof(vf->priv->plane[0][0][0]));
214  }
215 
216  return ff_vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
217 }
218 
219 static void get_image(struct vf_instance *vf, mp_image_t *mpi){
220  if(mpi->flags&MP_IMGFLAG_PRESERVE) return; // don't change
221  // ok, we can do pp in-place (or pp disabled):
222  vf->dmpi=ff_vf_get_image(vf->next,mpi->imgfmt,
223  mpi->type, mpi->flags | MP_IMGFLAG_READABLE, mpi->width, mpi->height);
224  mpi->planes[0]=vf->dmpi->planes[0];
225  mpi->stride[0]=vf->dmpi->stride[0];
226  mpi->width=vf->dmpi->width;
227  if(mpi->flags&MP_IMGFLAG_PLANAR){
228  mpi->planes[1]=vf->dmpi->planes[1];
229  mpi->planes[2]=vf->dmpi->planes[2];
230  mpi->stride[1]=vf->dmpi->stride[1];
231  mpi->stride[2]=vf->dmpi->stride[2];
232  }
233  mpi->flags|=MP_IMGFLAG_DIRECT;
234 }
235 
236 static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
237  mp_image_t *dmpi;
238 
239  if(!(mpi->flags&MP_IMGFLAG_DIRECT)){
240  // no DR, so get a new image! hope we'll get DR buffer:
241  dmpi=ff_vf_get_image(vf->next,mpi->imgfmt,
244  mpi->width,mpi->height);
245  ff_vf_clone_mpi_attributes(dmpi, mpi);
246  }else{
247  dmpi=vf->dmpi;
248  }
249 
250  filter(vf->priv, dmpi->planes[0], mpi->planes[0], dmpi->stride[0], mpi->stride[0], mpi->w, mpi->h, 1);
251  filter(vf->priv, dmpi->planes[1], mpi->planes[1], dmpi->stride[1], mpi->stride[1], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, 0);
252  filter(vf->priv, dmpi->planes[2], mpi->planes[2], dmpi->stride[2], mpi->stride[2], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, 0);
253 
254  return ff_vf_next_put_image(vf,dmpi, pts);
255 }
256 
257 static void uninit(struct vf_instance *vf){
258  int i,j;
259  if(!vf->priv) return;
260 
261  for(j=0; j<4; j++){
262  for(i=0; i<16; i++){
263  free(vf->priv->plane[i][j]);
264  vf->priv->plane[i][j]= NULL;
265  }
266  }
267 
268  free(vf->priv);
269  vf->priv=NULL;
270 }
271 
272 //===========================================================================//
273 static int query_format(struct vf_instance *vf, unsigned int fmt){
274  switch(fmt){
275  case IMGFMT_YVU9:
276  case IMGFMT_IF09:
277  case IMGFMT_YV12:
278  case IMGFMT_I420:
279  case IMGFMT_IYUV:
280  case IMGFMT_CLPL:
281  case IMGFMT_Y800:
282  case IMGFMT_Y8:
283  case IMGFMT_444P:
284  case IMGFMT_422P:
285  case IMGFMT_411P:
286  return ff_vf_next_query_format(vf,fmt);
287  }
288  return 0;
289 }
290 
291 
292 static int vf_open(vf_instance_t *vf, char *args){
293  vf->config=config;
294  vf->put_image=put_image;
295  vf->get_image=get_image;
297  vf->uninit=uninit;
298  vf->priv=malloc(sizeof(struct vf_priv_s));
299  memset(vf->priv, 0, sizeof(struct vf_priv_s));
300 
301  vf->priv->depth= 8;
302  vf->priv->strength[0]= 1.0;
303  vf->priv->strength[1]= 1.0;
304  vf->priv->delta= 1.0;
305 
306  if (args) sscanf(args, "%d:%f:%f:%d:%f", &vf->priv->depth,
307  &vf->priv->strength[0],
308  &vf->priv->strength[1],
309  &vf->priv->mode,
310  &vf->priv->delta);
311 
312  return 1;
313 }
314 
316  "overcomplete wavelet denoiser",
317  "ow",
318  "Michael Niedermayer",
319  "",
320  vf_open,
321  NULL
322 };
unsigned int imgfmt
Definition: mp_image.h:130
static void compose(float *dst, float *srcL, float *srcH, int stride, int w)
Definition: vf_ow.c:119
float v
const char * s
Definition: avisynth_c.h:668
void(* get_image)(struct vf_instance *vf, mp_image_t *mpi)
Definition: vf.h:66
const char * fmt
Definition: avisynth_c.h:669
int stride
Definition: vf_ow.c:59
float delta
Definition: vf_ow.c:55
mp_image_t * ff_vf_get_image(vf_instance_t *vf, unsigned int outfmt, int mp_imgtype, int mp_imgflag, int w, int h)
Definition: vf_mp.c:380
x1
Definition: genspecsines3.m:7
#define MP_IMGFLAG_PRESERVE
Definition: mp_image.h:46
#define IMGFMT_YVU9
Definition: img_format.h:117
#define IMGFMT_YV12
Definition: img_format.h:119
void(* uninit)(struct vf_instance *vf)
Definition: vf.h:74
#define MP_IMGFLAG_READABLE
Definition: mp_image.h:55
#define IMGFMT_Y8
Definition: img_format.h:124
output residual component w
static void decompose(float *dstL, float *dstH, float *src, int stride, int w)
Definition: vf_ow.c:103
int ff_vf_next_config(struct vf_instance *vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt)
Definition: vf_mp.c:584
int width
Definition: mp_image.h:131
int(* put_image)(struct vf_instance *vf, mp_image_t *mpi, double pts)
Definition: vf.h:68
uint8_t
#define IMGFMT_CLPL
Definition: img_format.h:122
Definition: vf.h:31
unsigned char * planes[MP_MAX_PLANES]
Definition: mp_image.h:133
int stride[MP_MAX_PLANES]
Definition: mp_image.h:134
static int mirror(int x, int w)
Definition: vf_ow.c:95
int width
Definition: vf_fil.c:32
#define IMGFMT_IF09
Definition: img_format.h:118
float strength[2]
Definition: vf_ow.c:54
static int vf_open(vf_instance_t *vf, char *args)
Definition: vf_ow.c:292
static void uninit(struct vf_instance *vf)
Definition: vf_ow.c:257
int mode
Definition: vf_ilpack.c:38
Discrete Time axis x
#define U(x)
int16_t * temp
Definition: vf_fspp.c:99
#define MP_IMGTYPE_TEMP
Definition: mp_image.h:104
int(* query_format)(struct vf_instance *vf, unsigned int fmt)
Definition: vf.h:64
#define IMGFMT_IYUV
Definition: img_format.h:121
static void decompose2D2(float *dst[4], float *src, float *temp[2], int stride, int step, int w, int h)
Definition: vf_ow.c:149
uint8_t * src
Definition: vf_fspp.c:98
#define MP_IMGFLAG_PREFER_ALIGNED_STRIDE
Definition: mp_image.h:61
static void compose2D2(float *dst, float *src[4], float *temp[2], int stride, int step, int w, int h)
Definition: vf_ow.c:155
static void compose2D(float *dst, float *srcL, float *srcH, int xstride, int ystride, int step, int w, int h)
Definition: vf_ow.c:142
int chroma_y_shift
Definition: mp_image.h:145
void ff_vf_clone_mpi_attributes(mp_image_t *dst, mp_image_t *src)
Definition: vf_mp.c:293
static void filter(struct vf_priv_s *p, uint8_t *dst, uint8_t *src, int dst_stride, int src_stride, int width, int height, int is_luma)
Definition: vf_ow.c:161
struct vf_instance * next
Definition: vf.h:84
NULL
Definition: eval.c:55
static int config(struct vf_instance *vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt)
Definition: vf_ow.c:206
static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
Definition: vf_ow.c:236
synthesis window for stochastic i
#define IMGFMT_Y800
Definition: img_format.h:123
#define IMGFMT_422P
Definition: img_format.h:131
int w
Definition: mp_image.h:132
int(* config)(struct vf_instance *vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt)
Definition: vf.h:59
static int flags
Definition: cpu.c:23
int height
Definition: mp_image.h:131
unsigned char type
Definition: mp_image.h:127
#define IMGFMT_444P
Definition: img_format.h:130
const vf_info_t ff_vf_info_ow
Definition: vf_ow.c:315
int32_t coeff[1<< SUB_PIXEL_BITS][4]
static const uint8_t __attribute__((aligned(8)))
Definition: vf_ow.c:41
#define MP_IMGFLAG_PLANAR
Definition: mp_image.h:76
static void decompose2D(float *dstL, float *dstH, float *src, int xstride, int ystride, int step, int w, int h)
Definition: vf_ow.c:135
static void get_image(struct vf_instance *vf, mp_image_t *mpi)
Definition: vf_ow.c:219
function y
Definition: D.m:1
float * plane[16][4]
Definition: vf_ow.c:58
int ff_vf_next_put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
Definition: vf_mp.c:539
else dst[i][x+y *dst_stride[i]]
Definition: vf_mcdeint.c:160
int chroma_x_shift
Definition: mp_image.h:144
static const double icoeff[2][5]
Definition: vf_ow.c:79
#define MP_IMGFLAG_ACCEPT_STRIDE
Definition: mp_image.h:63
struct vf_priv_s * priv
Definition: vf.h:86
#define MP_IMGFLAG_DIRECT
Definition: mp_image.h:91
#define IMGFMT_I420
Definition: img_format.h:120
int h
Definition: mp_image.h:132
int depth
Definition: vf_ow.c:57
int ff_vf_next_query_format(struct vf_instance *vf, unsigned int fmt)
Definition: vf_mp.c:371
Definition: vf.h:56
unsigned int flags
Definition: mp_image.h:126
int height
Definition: vf_fil.c:31
#define IMGFMT_411P
Definition: img_format.h:132
mp_image_t * dmpi
Definition: vf.h:85
static int query_format(struct vf_instance *vf, unsigned int fmt)
Definition: vf_ow.c:273
MUSIC TECHNOLOGY GROUP UNIVERSITAT POMPEU FABRA Free Non Commercial Binary License Agreement UNIVERSITAT POMPEU OR INDICATING ACCEPTANCE BY SELECTING THE ACCEPT BUTTON ON ANY DOWNLOAD OR INSTALL YOU ACCEPT THE TERMS OF THE LICENSE SUMMARY TABLE Software MELODIA Melody Extraction vamp plug in Licensor Music Technology Group Universitat Pompeu Plaça de la Spain Permitted purposes Non commercial internal research and validation and educational purposes only All commercial uses in a production either internal or are prohibited by this license and require an additional commercial exploitation license TERMS AND CONDITIONS SOFTWARE Software means the software programs identified herein in binary any other machine readable any updates or error corrections provided by and any user programming guides and other documentation provided to you by UPF under this Agreement LICENSE Subject to the terms and conditions of this UPF grants you a royalty free
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But a word about which is also called distortion Distortion can be quantified by almost any quality measurement one chooses the sum of squared differences is used but more complex methods that consider psychovisual effects can be used as well It makes no difference in this discussion First step
#define S
Definition: vf_ow.c:62