vf_spp.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2003 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  * This implementation is based on an algorithm described in
23  * "Aria Nosratinia Embedded Post-Processing for
24  * Enhancement of Compressed Images (1999)"
25  * (http://citeseer.nj.nec.com/nosratinia99embedded.html)
26  */
27 
28 
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <inttypes.h>
33 #include <math.h>
34 
35 #include "config.h"
36 
37 #include "mp_msg.h"
38 #include "cpudetect.h"
39 
40 #include "libavutil/common.h"
41 #include "libavutil/internal.h"
42 #include "libavutil/intreadwrite.h"
43 #include "libavcodec/avcodec.h"
44 #include "libavcodec/dsputil.h"
45 
46 #undef fprintf
47 #undef free
48 #undef malloc
49 
50 #include "img_format.h"
51 #include "mp_image.h"
52 #include "vf.h"
53 #include "av_helpers.h"
54 #include "libvo/fastmemcpy.h"
55 
56 #define XMIN(a,b) ((a) < (b) ? (a) : (b))
57 
58 //===========================================================================//
59 static const uint8_t __attribute__((aligned(8))) dither[8][8]={
60 { 0, 48, 12, 60, 3, 51, 15, 63, },
61 { 32, 16, 44, 28, 35, 19, 47, 31, },
62 { 8, 56, 4, 52, 11, 59, 7, 55, },
63 { 40, 24, 36, 20, 43, 27, 39, 23, },
64 { 2, 50, 14, 62, 1, 49, 13, 61, },
65 { 34, 18, 46, 30, 33, 17, 45, 29, },
66 { 10, 58, 6, 54, 9, 57, 5, 53, },
67 { 42, 26, 38, 22, 41, 25, 37, 21, },
68 };
69 
70 static const uint8_t offset[127][2]= {
71 {0,0},
72 {0,0}, {4,4},
73 {0,0}, {2,2}, {6,4}, {4,6},
74 {0,0}, {5,1}, {2,2}, {7,3}, {4,4}, {1,5}, {6,6}, {3,7},
75 
76 {0,0}, {4,0}, {1,1}, {5,1}, {3,2}, {7,2}, {2,3}, {6,3},
77 {0,4}, {4,4}, {1,5}, {5,5}, {3,6}, {7,6}, {2,7}, {6,7},
78 
79 {0,0}, {0,2}, {0,4}, {0,6}, {1,1}, {1,3}, {1,5}, {1,7},
80 {2,0}, {2,2}, {2,4}, {2,6}, {3,1}, {3,3}, {3,5}, {3,7},
81 {4,0}, {4,2}, {4,4}, {4,6}, {5,1}, {5,3}, {5,5}, {5,7},
82 {6,0}, {6,2}, {6,4}, {6,6}, {7,1}, {7,3}, {7,5}, {7,7},
83 
84 {0,0}, {4,4}, {0,4}, {4,0}, {2,2}, {6,6}, {2,6}, {6,2},
85 {0,2}, {4,6}, {0,6}, {4,2}, {2,0}, {6,4}, {2,4}, {6,0},
86 {1,1}, {5,5}, {1,5}, {5,1}, {3,3}, {7,7}, {3,7}, {7,3},
87 {1,3}, {5,7}, {1,7}, {5,3}, {3,1}, {7,5}, {3,5}, {7,1},
88 {0,1}, {4,5}, {0,5}, {4,1}, {2,3}, {6,7}, {2,7}, {6,3},
89 {0,3}, {4,7}, {0,7}, {4,3}, {2,1}, {6,5}, {2,5}, {6,1},
90 {1,0}, {5,4}, {1,4}, {5,0}, {3,2}, {7,6}, {3,6}, {7,2},
91 {1,2}, {5,6}, {1,6}, {5,2}, {3,0}, {7,4}, {3,4}, {7,0},
92 };
93 
94 struct vf_priv_s {
95  int log2_count;
96  int qp;
97  int mode;
98  int mpeg2;
99  int temp_stride;
100  uint8_t *src;
101  int16_t *temp;
104  char *non_b_qp;
105 };
106 
107 #define SHIFT 22
108 
109 static void hardthresh_c(int16_t dst[64], int16_t src[64], int qp, uint8_t *permutation){
110  int i;
111  int bias= 0; //FIXME
112  unsigned int threshold1, threshold2;
113 
114  threshold1= qp*((1<<4) - bias) - 1;
115  threshold2= (threshold1<<1);
116 
117  memset(dst, 0, 64*sizeof(int16_t));
118  dst[0]= (src[0] + 4)>>3;
119 
120  for(i=1; i<64; i++){
121  int level= src[i];
122  if(((unsigned)(level+threshold1))>threshold2){
123  const int j= permutation[i];
124  dst[j]= (level + 4)>>3;
125  }
126  }
127 }
128 
129 static void softthresh_c(int16_t dst[64], int16_t src[64], int qp, uint8_t *permutation){
130  int i;
131  int bias= 0; //FIXME
132  unsigned int threshold1, threshold2;
133 
134  threshold1= qp*((1<<4) - bias) - 1;
135  threshold2= (threshold1<<1);
136 
137  memset(dst, 0, 64*sizeof(int16_t));
138  dst[0]= (src[0] + 4)>>3;
139 
140  for(i=1; i<64; i++){
141  int level= src[i];
142  if(((unsigned)(level+threshold1))>threshold2){
143  const int j= permutation[i];
144  if(level>0)
145  dst[j]= (level - threshold1 + 4)>>3;
146  else
147  dst[j]= (level + threshold1 + 4)>>3;
148  }
149  }
150 }
151 
152 #if HAVE_MMX
153 static void hardthresh_mmx(int16_t dst[64], int16_t src[64], int qp, uint8_t *permutation){
154  int bias= 0; //FIXME
155  unsigned int threshold1;
156 
157  threshold1= qp*((1<<4) - bias) - 1;
158 
159  __asm__ volatile(
160 #define REQUANT_CORE(dst0, dst1, dst2, dst3, src0, src1, src2, src3) \
161  "movq " #src0 ", %%mm0 \n\t"\
162  "movq " #src1 ", %%mm1 \n\t"\
163  "movq " #src2 ", %%mm2 \n\t"\
164  "movq " #src3 ", %%mm3 \n\t"\
165  "psubw %%mm4, %%mm0 \n\t"\
166  "psubw %%mm4, %%mm1 \n\t"\
167  "psubw %%mm4, %%mm2 \n\t"\
168  "psubw %%mm4, %%mm3 \n\t"\
169  "paddusw %%mm5, %%mm0 \n\t"\
170  "paddusw %%mm5, %%mm1 \n\t"\
171  "paddusw %%mm5, %%mm2 \n\t"\
172  "paddusw %%mm5, %%mm3 \n\t"\
173  "paddw %%mm6, %%mm0 \n\t"\
174  "paddw %%mm6, %%mm1 \n\t"\
175  "paddw %%mm6, %%mm2 \n\t"\
176  "paddw %%mm6, %%mm3 \n\t"\
177  "psubusw %%mm6, %%mm0 \n\t"\
178  "psubusw %%mm6, %%mm1 \n\t"\
179  "psubusw %%mm6, %%mm2 \n\t"\
180  "psubusw %%mm6, %%mm3 \n\t"\
181  "psraw $3, %%mm0 \n\t"\
182  "psraw $3, %%mm1 \n\t"\
183  "psraw $3, %%mm2 \n\t"\
184  "psraw $3, %%mm3 \n\t"\
185 \
186  "movq %%mm0, %%mm7 \n\t"\
187  "punpcklwd %%mm2, %%mm0 \n\t" /*A*/\
188  "punpckhwd %%mm2, %%mm7 \n\t" /*C*/\
189  "movq %%mm1, %%mm2 \n\t"\
190  "punpcklwd %%mm3, %%mm1 \n\t" /*B*/\
191  "punpckhwd %%mm3, %%mm2 \n\t" /*D*/\
192  "movq %%mm0, %%mm3 \n\t"\
193  "punpcklwd %%mm1, %%mm0 \n\t" /*A*/\
194  "punpckhwd %%mm7, %%mm3 \n\t" /*C*/\
195  "punpcklwd %%mm2, %%mm7 \n\t" /*B*/\
196  "punpckhwd %%mm2, %%mm1 \n\t" /*D*/\
197 \
198  "movq %%mm0, " #dst0 " \n\t"\
199  "movq %%mm7, " #dst1 " \n\t"\
200  "movq %%mm3, " #dst2 " \n\t"\
201  "movq %%mm1, " #dst3 " \n\t"
202 
203  "movd %2, %%mm4 \n\t"
204  "movd %3, %%mm5 \n\t"
205  "movd %4, %%mm6 \n\t"
206  "packssdw %%mm4, %%mm4 \n\t"
207  "packssdw %%mm5, %%mm5 \n\t"
208  "packssdw %%mm6, %%mm6 \n\t"
209  "packssdw %%mm4, %%mm4 \n\t"
210  "packssdw %%mm5, %%mm5 \n\t"
211  "packssdw %%mm6, %%mm6 \n\t"
212  REQUANT_CORE( (%1), 8(%1), 16(%1), 24(%1), (%0), 8(%0), 64(%0), 72(%0))
213  REQUANT_CORE(32(%1), 40(%1), 48(%1), 56(%1),16(%0),24(%0), 48(%0), 56(%0))
214  REQUANT_CORE(64(%1), 72(%1), 80(%1), 88(%1),32(%0),40(%0), 96(%0),104(%0))
215  REQUANT_CORE(96(%1),104(%1),112(%1),120(%1),80(%0),88(%0),112(%0),120(%0))
216  : : "r" (src), "r" (dst), "g" (threshold1+1), "g" (threshold1+5), "g" (threshold1-4) //FIXME maybe more accurate then needed?
217  );
218  dst[0]= (src[0] + 4)>>3;
219 }
220 
221 static void softthresh_mmx(int16_t dst[64], int16_t src[64], int qp, uint8_t *permutation){
222  int bias= 0; //FIXME
223  unsigned int threshold1;
224 
225  threshold1= qp*((1<<4) - bias) - 1;
226 
227  __asm__ volatile(
228 #undef REQUANT_CORE
229 #define REQUANT_CORE(dst0, dst1, dst2, dst3, src0, src1, src2, src3) \
230  "movq " #src0 ", %%mm0 \n\t"\
231  "movq " #src1 ", %%mm1 \n\t"\
232  "pxor %%mm6, %%mm6 \n\t"\
233  "pxor %%mm7, %%mm7 \n\t"\
234  "pcmpgtw %%mm0, %%mm6 \n\t"\
235  "pcmpgtw %%mm1, %%mm7 \n\t"\
236  "pxor %%mm6, %%mm0 \n\t"\
237  "pxor %%mm7, %%mm1 \n\t"\
238  "psubusw %%mm4, %%mm0 \n\t"\
239  "psubusw %%mm4, %%mm1 \n\t"\
240  "pxor %%mm6, %%mm0 \n\t"\
241  "pxor %%mm7, %%mm1 \n\t"\
242  "movq " #src2 ", %%mm2 \n\t"\
243  "movq " #src3 ", %%mm3 \n\t"\
244  "pxor %%mm6, %%mm6 \n\t"\
245  "pxor %%mm7, %%mm7 \n\t"\
246  "pcmpgtw %%mm2, %%mm6 \n\t"\
247  "pcmpgtw %%mm3, %%mm7 \n\t"\
248  "pxor %%mm6, %%mm2 \n\t"\
249  "pxor %%mm7, %%mm3 \n\t"\
250  "psubusw %%mm4, %%mm2 \n\t"\
251  "psubusw %%mm4, %%mm3 \n\t"\
252  "pxor %%mm6, %%mm2 \n\t"\
253  "pxor %%mm7, %%mm3 \n\t"\
254 \
255  "paddsw %%mm5, %%mm0 \n\t"\
256  "paddsw %%mm5, %%mm1 \n\t"\
257  "paddsw %%mm5, %%mm2 \n\t"\
258  "paddsw %%mm5, %%mm3 \n\t"\
259  "psraw $3, %%mm0 \n\t"\
260  "psraw $3, %%mm1 \n\t"\
261  "psraw $3, %%mm2 \n\t"\
262  "psraw $3, %%mm3 \n\t"\
263 \
264  "movq %%mm0, %%mm7 \n\t"\
265  "punpcklwd %%mm2, %%mm0 \n\t" /*A*/\
266  "punpckhwd %%mm2, %%mm7 \n\t" /*C*/\
267  "movq %%mm1, %%mm2 \n\t"\
268  "punpcklwd %%mm3, %%mm1 \n\t" /*B*/\
269  "punpckhwd %%mm3, %%mm2 \n\t" /*D*/\
270  "movq %%mm0, %%mm3 \n\t"\
271  "punpcklwd %%mm1, %%mm0 \n\t" /*A*/\
272  "punpckhwd %%mm7, %%mm3 \n\t" /*C*/\
273  "punpcklwd %%mm2, %%mm7 \n\t" /*B*/\
274  "punpckhwd %%mm2, %%mm1 \n\t" /*D*/\
275 \
276  "movq %%mm0, " #dst0 " \n\t"\
277  "movq %%mm7, " #dst1 " \n\t"\
278  "movq %%mm3, " #dst2 " \n\t"\
279  "movq %%mm1, " #dst3 " \n\t"
280 
281  "movd %2, %%mm4 \n\t"
282  "movd %3, %%mm5 \n\t"
283  "packssdw %%mm4, %%mm4 \n\t"
284  "packssdw %%mm5, %%mm5 \n\t"
285  "packssdw %%mm4, %%mm4 \n\t"
286  "packssdw %%mm5, %%mm5 \n\t"
287  REQUANT_CORE( (%1), 8(%1), 16(%1), 24(%1), (%0), 8(%0), 64(%0), 72(%0))
288  REQUANT_CORE(32(%1), 40(%1), 48(%1), 56(%1),16(%0),24(%0), 48(%0), 56(%0))
289  REQUANT_CORE(64(%1), 72(%1), 80(%1), 88(%1),32(%0),40(%0), 96(%0),104(%0))
290  REQUANT_CORE(96(%1),104(%1),112(%1),120(%1),80(%0),88(%0),112(%0),120(%0))
291  : : "r" (src), "r" (dst), "g" (threshold1), "rm" (4) //FIXME maybe more accurate then needed?
292  );
293 
294  dst[0]= (src[0] + 4)>>3;
295 }
296 #endif
297 
298 static inline void add_block(int16_t *dst, int stride, int16_t block[64]){
299  int y;
300 
301  for(y=0; y<8; y++){
302  *(uint32_t*)&dst[0 + y*stride]+= *(uint32_t*)&block[0 + y*8];
303  *(uint32_t*)&dst[2 + y*stride]+= *(uint32_t*)&block[2 + y*8];
304  *(uint32_t*)&dst[4 + y*stride]+= *(uint32_t*)&block[4 + y*8];
305  *(uint32_t*)&dst[6 + y*stride]+= *(uint32_t*)&block[6 + y*8];
306  }
307 }
308 
309 static void store_slice_c(uint8_t *dst, int16_t *src, int dst_stride, int src_stride, int width, int height, int log2_scale){
310  int y, x;
311 
312 #define STORE(pos) \
313  temp= ((src[x + y*src_stride + pos]<<log2_scale) + d[pos])>>6;\
314  if(temp & 0x100) temp= ~(temp>>31);\
315  dst[x + y*dst_stride + pos]= temp;
316 
317  for(y=0; y<height; y++){
318  const uint8_t *d= dither[y];
319  for(x=0; x<width; x+=8){
320  int temp;
321  STORE(0);
322  STORE(1);
323  STORE(2);
324  STORE(3);
325  STORE(4);
326  STORE(5);
327  STORE(6);
328  STORE(7);
329  }
330  }
331 }
332 
333 #if HAVE_MMX
334 static void store_slice_mmx(uint8_t *dst, int16_t *src, int dst_stride, int src_stride, int width, int height, int log2_scale){
335  int y;
336 
337  for(y=0; y<height; y++){
338  uint8_t *dst1= dst;
339  int16_t *src1= src;
340  __asm__ volatile(
341  "movq (%3), %%mm3 \n\t"
342  "movq (%3), %%mm4 \n\t"
343  "movd %4, %%mm2 \n\t"
344  "pxor %%mm0, %%mm0 \n\t"
345  "punpcklbw %%mm0, %%mm3 \n\t"
346  "punpckhbw %%mm0, %%mm4 \n\t"
347  "psraw %%mm2, %%mm3 \n\t"
348  "psraw %%mm2, %%mm4 \n\t"
349  "movd %5, %%mm2 \n\t"
350  "1: \n\t"
351  "movq (%0), %%mm0 \n\t"
352  "movq 8(%0), %%mm1 \n\t"
353  "paddw %%mm3, %%mm0 \n\t"
354  "paddw %%mm4, %%mm1 \n\t"
355  "psraw %%mm2, %%mm0 \n\t"
356  "psraw %%mm2, %%mm1 \n\t"
357  "packuswb %%mm1, %%mm0 \n\t"
358  "movq %%mm0, (%1) \n\t"
359  "add $16, %0 \n\t"
360  "add $8, %1 \n\t"
361  "cmp %2, %1 \n\t"
362  " jb 1b \n\t"
363  : "+r" (src1), "+r"(dst1)
364  : "r"(dst + width), "r"(dither[y]), "g"(log2_scale), "g"(6-log2_scale)
365  );
366  src += src_stride;
367  dst += dst_stride;
368  }
369 // if(width != mmxw)
370 // store_slice_c(dst + mmxw, src + mmxw, dst_stride, src_stride, width - mmxw, log2_scale);
371 }
372 #endif
373 
374 static void (*store_slice)(uint8_t *dst, int16_t *src, int dst_stride, int src_stride, int width, int height, int log2_scale)= store_slice_c;
375 
376 static void (*requantize)(int16_t dst[64], int16_t src[64], int qp, uint8_t *permutation)= hardthresh_c;
377 
378 static void filter(struct vf_priv_s *p, uint8_t *dst, uint8_t *src, int dst_stride, int src_stride, int width, int height, uint8_t *qp_store, int qp_stride, int is_luma){
379  int x, y, i;
380  const int count= 1<<p->log2_count;
381  const int stride= is_luma ? p->temp_stride : ((width+16+15)&(~15));
382  uint64_t __attribute__((aligned(16))) block_align[32];
383  int16_t *block = (int16_t *)block_align;
384  int16_t *block2= (int16_t *)(block_align+16);
385 
386  if (!src || !dst) return; // HACK avoid crash for Y8 colourspace
387  for(y=0; y<height; y++){
388  int index= 8 + 8*stride + y*stride;
389  fast_memcpy(p->src + index, src + y*src_stride, width);
390  for(x=0; x<8; x++){
391  p->src[index - x - 1]= p->src[index + x ];
392  p->src[index + width + x ]= p->src[index + width - x - 1];
393  }
394  }
395  for(y=0; y<8; y++){
396  fast_memcpy(p->src + ( 7-y)*stride, p->src + ( y+8)*stride, stride);
397  fast_memcpy(p->src + (height+8+y)*stride, p->src + (height-y+7)*stride, stride);
398  }
399  //FIXME (try edge emu)
400 
401  for(y=0; y<height+8; y+=8){
402  memset(p->temp + (8+y)*stride, 0, 8*stride*sizeof(int16_t));
403  for(x=0; x<width+8; x+=8){
404  const int qps= 3 + is_luma;
405  int qp;
406 
407  if(p->qp)
408  qp= p->qp;
409  else{
410  qp= qp_store[ (XMIN(x, width-1)>>qps) + (XMIN(y, height-1)>>qps) * qp_stride];
411  qp = FFMAX(1, norm_qscale(qp, p->mpeg2));
412  }
413  for(i=0; i<count; i++){
414  const int x1= x + offset[i+count-1][0];
415  const int y1= y + offset[i+count-1][1];
416  const int index= x1 + y1*stride;
417  p->dsp.get_pixels(block, p->src + index, stride);
418  p->dsp.fdct(block);
419  requantize(block2, block, qp, p->dsp.idct_permutation);
420  p->dsp.idct(block2);
421  add_block(p->temp + index, stride, block2);
422  }
423  }
424  if(y)
425  store_slice(dst + (y-8)*dst_stride, p->temp + 8 + y*stride, dst_stride, stride, width, XMIN(8, height+8-y), 6-p->log2_count);
426  }
427 #if 0
428  for(y=0; y<height; y++){
429  for(x=0; x<width; x++){
430  if((((x>>6) ^ (y>>6)) & 1) == 0)
431  dst[x + y*dst_stride]= p->src[8 + 8*stride + x + y*stride];
432  if((x&63) == 0 || (y&63)==0)
433  dst[x + y*dst_stride] += 128;
434  }
435  }
436 #endif
437  //FIXME reorder for better caching
438 }
439 
440 static int config(struct vf_instance *vf,
441  int width, int height, int d_width, int d_height,
442  unsigned int flags, unsigned int outfmt){
443  int h= (height+16+15)&(~15);
444 
445  vf->priv->temp_stride= (width+16+15)&(~15);
446  vf->priv->temp= malloc(vf->priv->temp_stride*h*sizeof(int16_t));
447  vf->priv->src = malloc(vf->priv->temp_stride*h*sizeof(uint8_t));
448 
449  return ff_vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
450 }
451 
452 static void get_image(struct vf_instance *vf, mp_image_t *mpi){
453  if(mpi->flags&MP_IMGFLAG_PRESERVE) return; // don't change
454  // ok, we can do pp in-place (or pp disabled):
455  vf->dmpi=ff_vf_get_image(vf->next,mpi->imgfmt,
456  mpi->type, mpi->flags | MP_IMGFLAG_READABLE, mpi->width, mpi->height);
457  mpi->planes[0]=vf->dmpi->planes[0];
458  mpi->stride[0]=vf->dmpi->stride[0];
459  mpi->width=vf->dmpi->width;
460  if(mpi->flags&MP_IMGFLAG_PLANAR){
461  mpi->planes[1]=vf->dmpi->planes[1];
462  mpi->planes[2]=vf->dmpi->planes[2];
463  mpi->stride[1]=vf->dmpi->stride[1];
464  mpi->stride[2]=vf->dmpi->stride[2];
465  }
466  mpi->flags|=MP_IMGFLAG_DIRECT;
467 }
468 
469 static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
470  mp_image_t *dmpi;
471 
472  if(!(mpi->flags&MP_IMGFLAG_DIRECT)){
473  // no DR, so get a new image! hope we'll get DR buffer:
474  dmpi=ff_vf_get_image(vf->next,mpi->imgfmt,
477  mpi->width,mpi->height);
478  ff_vf_clone_mpi_attributes(dmpi, mpi);
479  }else{
480  dmpi=vf->dmpi;
481  }
482 
483  vf->priv->mpeg2= mpi->qscale_type;
484  if(mpi->pict_type != 3 && mpi->qscale && !vf->priv->qp){
485  int w = mpi->qstride;
486  int h = (mpi->h + 15) >> 4;
487  if (!w) {
488  w = (mpi->w + 15) >> 4;
489  h = 1;
490  }
491  if(!vf->priv->non_b_qp)
492  vf->priv->non_b_qp= malloc(w*h);
493  fast_memcpy(vf->priv->non_b_qp, mpi->qscale, w*h);
494  }
495  if(vf->priv->log2_count || !(mpi->flags&MP_IMGFLAG_DIRECT)){
496  char *qp_tab= vf->priv->non_b_qp;
497  if((vf->priv->mode&4) || !qp_tab)
498  qp_tab= mpi->qscale;
499 
500  if(qp_tab || vf->priv->qp){
501  filter(vf->priv, dmpi->planes[0], mpi->planes[0], dmpi->stride[0], mpi->stride[0], mpi->w, mpi->h, qp_tab, mpi->qstride, 1);
502  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, qp_tab, mpi->qstride, 0);
503  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, qp_tab, mpi->qstride, 0);
504  }else{
505  memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h, dmpi->stride[0], mpi->stride[0]);
506  memcpy_pic(dmpi->planes[1], mpi->planes[1], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, dmpi->stride[1], mpi->stride[1]);
507  memcpy_pic(dmpi->planes[2], mpi->planes[2], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, dmpi->stride[2], mpi->stride[2]);
508  }
509  }
510 
511 #if HAVE_MMX
512  if(ff_gCpuCaps.hasMMX) __asm__ volatile ("emms\n\t");
513 #endif
514 #if HAVE_MMX2
515  if(ff_gCpuCaps.hasMMX2) __asm__ volatile ("sfence\n\t");
516 #endif
517 
518  return ff_vf_next_put_image(vf,dmpi, pts);
519 }
520 
521 static void uninit(struct vf_instance *vf){
522  if(!vf->priv) return;
523 
524  free(vf->priv->temp);
525  vf->priv->temp= NULL;
526  free(vf->priv->src);
527  vf->priv->src= NULL;
528  free(vf->priv->avctx);
529  vf->priv->avctx= NULL;
530  free(vf->priv->non_b_qp);
531  vf->priv->non_b_qp= NULL;
532 
533  free(vf->priv);
534  vf->priv=NULL;
535 }
536 
537 //===========================================================================//
538 static int query_format(struct vf_instance *vf, unsigned int fmt){
539  switch(fmt){
540  case IMGFMT_YVU9:
541  case IMGFMT_IF09:
542  case IMGFMT_YV12:
543  case IMGFMT_I420:
544  case IMGFMT_IYUV:
545  case IMGFMT_CLPL:
546  case IMGFMT_Y800:
547  case IMGFMT_Y8:
548  case IMGFMT_444P:
549  case IMGFMT_422P:
550  case IMGFMT_411P:
551  return ff_vf_next_query_format(vf,fmt);
552  }
553  return 0;
554 }
555 
556 static int control(struct vf_instance *vf, int request, void* data){
557  switch(request){
559  return 6;
560  case VFCTRL_SET_PP_LEVEL:
561  vf->priv->log2_count= *((unsigned int*)data);
562  return CONTROL_TRUE;
563  }
564  return ff_vf_next_control(vf,request,data);
565 }
566 
567 static int vf_open(vf_instance_t *vf, char *args){
568 
569  int log2c=-1;
570 
571  vf->config=config;
572  vf->put_image=put_image;
573  vf->get_image=get_image;
575  vf->uninit=uninit;
576  vf->control= control;
577  vf->priv=malloc(sizeof(struct vf_priv_s));
578  memset(vf->priv, 0, sizeof(struct vf_priv_s));
579 
580  ff_init_avcodec();
581 
583  ff_dsputil_init(&vf->priv->dsp, vf->priv->avctx);
584 
585  vf->priv->log2_count= 3;
586 
587  if (args) sscanf(args, "%d:%d:%d", &log2c, &vf->priv->qp, &vf->priv->mode);
588 
589  if( log2c >=0 && log2c <=6 )
590  vf->priv->log2_count = log2c;
591 
592  if(vf->priv->qp < 0)
593  vf->priv->qp = 0;
594 
595  switch(vf->priv->mode&3){
596  default:
597  case 0: requantize= hardthresh_c; break;
598  case 1: requantize= softthresh_c; break;
599  }
600 
601 #if HAVE_MMX
602  if(ff_gCpuCaps.hasMMX){
603  store_slice= store_slice_mmx;
604  switch(vf->priv->mode&3){
605  case 0: requantize= hardthresh_mmx; break;
606  case 1: requantize= softthresh_mmx; break;
607  }
608  }
609 #endif
610 
611  return 1;
612 }
613 
615  "simple postprocess",
616  "spp",
617  "Michael Niedermayer",
618  "",
619  vf_open,
620  NULL
621 };
unsigned int imgfmt
Definition: mp_image.h:130
static int vf_open(vf_instance_t *vf, char *args)
Definition: vf_spp.c:567
av_cold void ff_dsputil_init(DSPContext *c, AVCodecContext *avctx)
Definition: dsputil.c:2675
void(* get_image)(struct vf_instance *vf, mp_image_t *mpi)
Definition: vf.h:66
static void add_block(int16_t *dst, int stride, int16_t block[64])
Definition: vf_spp.c:298
int qscale_type
Definition: mp_image.h:139
char * qscale
Definition: mp_image.h:135
const char * fmt
Definition: avisynth_c.h:669
#define VFCTRL_SET_PP_LEVEL
Definition: vf.h:99
int stride
Definition: vf_ow.c:59
int(* control)(struct vf_instance *vf, int request, void *data)
Definition: vf.h:62
static void get_image(struct vf_instance *vf, mp_image_t *mpi)
Definition: vf_spp.c:452
y1
Definition: lab5.m:33
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
static int query_format(struct vf_instance *vf, unsigned int fmt)
Definition: vf_spp.c:538
x1
Definition: genspecsines3.m:7
#define MP_IMGFLAG_PRESERVE
Definition: mp_image.h:46
#define IMGFMT_YVU9
Definition: img_format.h:117
int temp_stride
Definition: vf_fspp.c:94
#define IMGFMT_YV12
Definition: img_format.h:119
#define CONTROL_TRUE
Definition: mpc_info.h:37
void(* fdct)(int16_t *block)
Definition: dsputil.h:218
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
float level
Definition: vf_dint.c:33
void(* get_pixels)(int16_t *block, const uint8_t *pixels, int line_size)
Definition: dsputil.h:129
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
set threshold d
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
int mpeg2
Definition: vf_fspp.c:96
#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
int pict_type
Definition: mp_image.h:137
uint8_t idct_permutation[64]
idct input permutation.
Definition: dsputil.h:249
AVCodecContext * avctx
Definition: vf_spp.c:102
int width
Definition: vf_fil.c:32
#define IMGFMT_IF09
Definition: img_format.h:118
int qstride
Definition: mp_image.h:136
int mode
Definition: vf_ilpack.c:38
#define XMIN(a, b)
Definition: vf_spp.c:56
Discrete Time axis x
int hasMMX2
Definition: cpudetect.h:34
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
int qp_stride
Definition: vf_qp.c:43
int qp
Definition: vf_fspp.c:95
Spectrum Plot time data
int ff_vf_next_control(struct vf_instance *vf, int request, void *data)
Definition: vf_mp.c:613
#define IMGFMT_IYUV
Definition: img_format.h:121
static const uint8_t offset[127][2]
Definition: vf_spp.c:70
#define FFMAX(a, b)
Definition: common.h:56
external API header
uint8_t * src
Definition: vf_fspp.c:98
common internal API header
#define MP_IMGFLAG_PREFER_ALIGNED_STRIDE
Definition: mp_image.h:61
AVCodecContext * avcodec_alloc_context3(const AVCodec *codec)
Allocate an AVCodecContext and set its fields to default values.
static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
Definition: vf_spp.c:469
void ff_init_avcodec(void)
Definition: vf_mp.c:287
int chroma_y_shift
Definition: mp_image.h:145
int hasMMX
Definition: cpudetect.h:33
static void hardthresh_c(int16_t dst[64], int16_t src[64], int qp, uint8_t *permutation)
Definition: vf_spp.c:109
void ff_vf_clone_mpi_attributes(mp_image_t *dst, mp_image_t *src)
Definition: vf_mp.c:293
#define VFCTRL_QUERY_MAX_PP_LEVEL
Definition: vf.h:98
struct vf_instance * next
Definition: vf.h:84
const vf_info_t ff_vf_info_spp
Definition: vf_spp.c:614
NULL
Definition: eval.c:55
static void(* requantize)(int16_t dst[64], int16_t src[64], int qp, uint8_t *permutation)
Definition: vf_spp.c:376
typedef void(RENAME(mix_any_func_type))
main external API structure.
static const uint8_t __attribute__((aligned(8)))
Definition: vf_spp.c:59
#define STORE(pos)
#define memcpy_pic(d, s, b, h, ds, ss)
Definition: fastmemcpy.h:62
static int control(struct vf_instance *vf, int request, void *data)
Definition: vf_spp.c:556
int index
Definition: gxfenc.c:89
synthesis window for stochastic i
static void uninit(struct vf_instance *vf)
Definition: vf_spp.c:521
#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 void store_slice_c(uint8_t *dst, int16_t *src, int dst_stride, int src_stride, int width, int height, int log2_scale)
Definition: vf_spp.c:309
static int flags
Definition: cpu.c:23
void(* idct)(int16_t *block)
Definition: dsputil.h:222
int height
Definition: mp_image.h:131
unsigned char type
Definition: mp_image.h:127
#define IMGFMT_444P
Definition: img_format.h:130
common internal and external API header
static void(* store_slice)(uint8_t *dst, int16_t *src, int dst_stride, int src_stride, int width, int height, int log2_scale)
Definition: vf_spp.c:374
#define MP_IMGFLAG_PLANAR
Definition: mp_image.h:76
void * fast_memcpy(void *to, const void *from, size_t len)
DSPContext dsp
Definition: vf_spp.c:103
function y
Definition: D.m:1
int ff_vf_next_put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
Definition: vf_mp.c:539
DSP utils.
int log2_count
Definition: vf_fspp.c:93
char * non_b_qp
Definition: vf_fspp.c:101
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_spp.c:440
else dst[i][x+y *dst_stride[i]]
Definition: vf_mcdeint.c:160
int chroma_x_shift
Definition: mp_image.h:144
CpuCaps ff_gCpuCaps
Definition: vf_mp.c:193
#define MP_IMGFLAG_ACCEPT_STRIDE
Definition: mp_image.h:63
struct vf_priv_s * priv
Definition: vf.h:86
static void filter(struct vf_priv_s *p, uint8_t *dst, uint8_t *src, int dst_stride, int src_stride, int width, int height, uint8_t *qp_store, int qp_stride, int is_luma)
Definition: vf_spp.c:378
void INT64 INT64 count
Definition: avisynth_c.h:594
#define MP_IMGFLAG_DIRECT
Definition: mp_image.h:91
static int norm_qscale(int qscale, int type)
Definition: vf.h:154
#define IMGFMT_I420
Definition: img_format.h:120
int h
Definition: mp_image.h:132
static void softthresh_c(int16_t dst[64], int16_t src[64], int qp, uint8_t *permutation)
Definition: vf_spp.c:129
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
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
DSPContext.
Definition: dsputil.h:127