comparison libmpcodecs/vf_decimate.c @ 32702:7af3e6f901fd

Convert some tabs to whitespace to allow using MPlayer filter sourcecode in FFmpeg.
author cehoyos
date Fri, 14 Jan 2011 22:10:21 +0000
parents a972c1a4a012
children 064be070d8c8
comparison
equal deleted inserted replaced
32701:02bc7c860503 32702:7af3e6f901fd
30 30
31 #include "libvo/fastmemcpy.h" 31 #include "libvo/fastmemcpy.h"
32 32
33 33
34 struct vf_priv_s { 34 struct vf_priv_s {
35 int hi, lo; 35 int hi, lo;
36 float frac; 36 float frac;
37 int max, last, cnt; 37 int max, last, cnt;
38 }; 38 };
39 39
40 #if HAVE_MMX && HAVE_EBX_AVAILABLE 40 #if HAVE_MMX && HAVE_EBX_AVAILABLE
41 static int diff_MMX(unsigned char *old, unsigned char *new, int os, int ns) 41 static int diff_MMX(unsigned char *old, unsigned char *new, int os, int ns)
42 { 42 {
43 volatile short out[4]; 43 volatile short out[4];
44 __asm__ ( 44 __asm__ (
45 "movl $8, %%ecx \n\t" 45 "movl $8, %%ecx \n\t"
46 "pxor %%mm4, %%mm4 \n\t" 46 "pxor %%mm4, %%mm4 \n\t"
47 "pxor %%mm7, %%mm7 \n\t" 47 "pxor %%mm7, %%mm7 \n\t"
48 48
49 ASMALIGN(4) 49 ASMALIGN(4)
50 "1: \n\t" 50 "1: \n\t"
51 51
52 "movq (%%"REG_S"), %%mm0 \n\t" 52 "movq (%%"REG_S"), %%mm0 \n\t"
53 "movq (%%"REG_S"), %%mm2 \n\t" 53 "movq (%%"REG_S"), %%mm2 \n\t"
54 "add %%"REG_a", %%"REG_S" \n\t" 54 "add %%"REG_a", %%"REG_S" \n\t"
55 "movq (%%"REG_D"), %%mm1 \n\t" 55 "movq (%%"REG_D"), %%mm1 \n\t"
56 "add %%"REG_b", %%"REG_D" \n\t" 56 "add %%"REG_b", %%"REG_D" \n\t"
57 "psubusb %%mm1, %%mm2 \n\t" 57 "psubusb %%mm1, %%mm2 \n\t"
58 "psubusb %%mm0, %%mm1 \n\t" 58 "psubusb %%mm0, %%mm1 \n\t"
59 "movq %%mm2, %%mm0 \n\t" 59 "movq %%mm2, %%mm0 \n\t"
60 "movq %%mm1, %%mm3 \n\t" 60 "movq %%mm1, %%mm3 \n\t"
61 "punpcklbw %%mm7, %%mm0 \n\t" 61 "punpcklbw %%mm7, %%mm0 \n\t"
62 "punpcklbw %%mm7, %%mm1 \n\t" 62 "punpcklbw %%mm7, %%mm1 \n\t"
63 "punpckhbw %%mm7, %%mm2 \n\t" 63 "punpckhbw %%mm7, %%mm2 \n\t"
64 "punpckhbw %%mm7, %%mm3 \n\t" 64 "punpckhbw %%mm7, %%mm3 \n\t"
65 "paddw %%mm0, %%mm4 \n\t" 65 "paddw %%mm0, %%mm4 \n\t"
66 "paddw %%mm1, %%mm4 \n\t" 66 "paddw %%mm1, %%mm4 \n\t"
67 "paddw %%mm2, %%mm4 \n\t" 67 "paddw %%mm2, %%mm4 \n\t"
68 "paddw %%mm3, %%mm4 \n\t" 68 "paddw %%mm3, %%mm4 \n\t"
69 69
70 "decl %%ecx \n\t" 70 "decl %%ecx \n\t"
71 "jnz 1b \n\t" 71 "jnz 1b \n\t"
72 "movq %%mm4, (%%"REG_d") \n\t" 72 "movq %%mm4, (%%"REG_d") \n\t"
73 "emms \n\t" 73 "emms \n\t"
74 : 74 :
75 : "S" (old), "D" (new), "a" ((long)os), "b" ((long)ns), "d" (out) 75 : "S" (old), "D" (new), "a" ((long)os), "b" ((long)ns), "d" (out)
76 : "%ecx", "memory" 76 : "%ecx", "memory"
77 ); 77 );
78 return out[0]+out[1]+out[2]+out[3]; 78 return out[0]+out[1]+out[2]+out[3];
79 } 79 }
80 #endif 80 #endif
81 81
82 static int diff_C(unsigned char *old, unsigned char *new, int os, int ns) 82 static int diff_C(unsigned char *old, unsigned char *new, int os, int ns)
83 { 83 {
84 int x, y, d=0; 84 int x, y, d=0;
85 for (y = 8; y; y--) { 85 for (y = 8; y; y--) {
86 for (x = 8; x; x--) { 86 for (x = 8; x; x--) {
87 d += abs(new[x] - old[x]); 87 d += abs(new[x] - old[x]);
88 } 88 }
89 new += ns; 89 new += ns;
90 old += os; 90 old += os;
91 } 91 }
92 return d; 92 return d;
93 } 93 }
94 94
95 static int (*diff)(unsigned char *, unsigned char *, int, int); 95 static int (*diff)(unsigned char *, unsigned char *, int, int);
96 96
97 static int diff_to_drop_plane(int hi, int lo, float frac, unsigned char *old, unsigned char *new, int w, int h, int os, int ns) 97 static int diff_to_drop_plane(int hi, int lo, float frac, unsigned char *old, unsigned char *new, int w, int h, int os, int ns)
98 { 98 {
99 int x, y; 99 int x, y;
100 int d, c=0; 100 int d, c=0;
101 int t = (w/16)*(h/16)*frac; 101 int t = (w/16)*(h/16)*frac;
102 for (y = 0; y < h-7; y += 4) { 102 for (y = 0; y < h-7; y += 4) {
103 for (x = 8; x < w-7; x += 4) { 103 for (x = 8; x < w-7; x += 4) {
104 d = diff(old+x+y*os, new+x+y*ns, os, ns); 104 d = diff(old+x+y*os, new+x+y*ns, os, ns);
105 if (d > hi) return 0; 105 if (d > hi) return 0;
106 if (d > lo) { 106 if (d > lo) {
107 c++; 107 c++;
108 if (c > t) return 0; 108 if (c > t) return 0;
109 } 109 }
110 } 110 }
111 } 111 }
112 return 1; 112 return 1;
113 } 113 }
114 114
115 static int diff_to_drop(int hi, int lo, float frac, mp_image_t *old, mp_image_t *new) 115 static int diff_to_drop(int hi, int lo, float frac, mp_image_t *old, mp_image_t *new)
116 { 116 {
117 if (new->flags & MP_IMGFLAG_PLANAR) { 117 if (new->flags & MP_IMGFLAG_PLANAR) {
118 return diff_to_drop_plane(hi,lo,frac, old->planes[0], new->planes[0], 118 return diff_to_drop_plane(hi,lo,frac, old->planes[0], new->planes[0],
119 new->w, new->h, old->stride[0], new->stride[0]) 119 new->w, new->h, old->stride[0], new->stride[0])
120 && diff_to_drop_plane(hi,lo,frac, old->planes[1], new->planes[1], 120 && diff_to_drop_plane(hi,lo,frac, old->planes[1], new->planes[1],
121 new->chroma_width, new->chroma_height, 121 new->chroma_width, new->chroma_height,
122 old->stride[1], new->stride[1]) 122 old->stride[1], new->stride[1])
123 && diff_to_drop_plane(hi,lo,frac, old->planes[2], new->planes[2], 123 && diff_to_drop_plane(hi,lo,frac, old->planes[2], new->planes[2],
124 new->chroma_width, new->chroma_height, 124 new->chroma_width, new->chroma_height,
125 old->stride[2], new->stride[2]); 125 old->stride[2], new->stride[2]);
126 } 126 }
127 return diff_to_drop_plane(hi,lo,frac, old->planes[0], new->planes[0], 127 return diff_to_drop_plane(hi,lo,frac, old->planes[0], new->planes[0],
128 new->w*(new->bpp/8), new->h, old->stride[0], new->stride[0]); 128 new->w*(new->bpp/8), new->h, old->stride[0], new->stride[0]);
129 } 129 }
130 130
131 static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts) 131 static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
132 { 132 {
133 mp_image_t *dmpi; 133 mp_image_t *dmpi;
134 134
135 dmpi = vf_get_image(vf->next, mpi->imgfmt, 135 dmpi = vf_get_image(vf->next, mpi->imgfmt,
136 MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE | 136 MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE |
137 MP_IMGFLAG_PRESERVE | MP_IMGFLAG_READABLE, 137 MP_IMGFLAG_PRESERVE | MP_IMGFLAG_READABLE,
138 mpi->width, mpi->height); 138 mpi->width, mpi->height);
139 dmpi->qscale = mpi->qscale; 139 dmpi->qscale = mpi->qscale;
140 dmpi->qstride = mpi->qstride; 140 dmpi->qstride = mpi->qstride;
141 dmpi->qscale_type = mpi->qscale_type; 141 dmpi->qscale_type = mpi->qscale_type;
142 142
143 if (diff_to_drop(vf->priv->hi, vf->priv->lo, vf->priv->frac, dmpi, mpi)) { 143 if (diff_to_drop(vf->priv->hi, vf->priv->lo, vf->priv->frac, dmpi, mpi)) {
144 if (vf->priv->max == 0) 144 if (vf->priv->max == 0)
145 return 0; 145 return 0;
146 else if ((vf->priv->max > 0) && (vf->priv->cnt++ < vf->priv->max)) 146 else if ((vf->priv->max > 0) && (vf->priv->cnt++ < vf->priv->max))
147 return 0; 147 return 0;
148 else if ((vf->priv->max < 0) && (vf->priv->last+1 >= -vf->priv->max)) 148 else if ((vf->priv->max < 0) && (vf->priv->last+1 >= -vf->priv->max))
149 return vf->priv->last=0; 149 return vf->priv->last=0;
150 } 150 }
151 vf->priv->last++; 151 vf->priv->last++;
152 vf->priv->cnt=0; 152 vf->priv->cnt=0;
153 153
154 memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h, 154 memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h,
155 dmpi->stride[0], mpi->stride[0]); 155 dmpi->stride[0], mpi->stride[0]);
156 if (mpi->flags & MP_IMGFLAG_PLANAR) { 156 if (mpi->flags & MP_IMGFLAG_PLANAR) {
157 memcpy_pic(dmpi->planes[1], mpi->planes[1], 157 memcpy_pic(dmpi->planes[1], mpi->planes[1],
158 mpi->chroma_width, mpi->chroma_height, 158 mpi->chroma_width, mpi->chroma_height,
159 dmpi->stride[1], mpi->stride[1]); 159 dmpi->stride[1], mpi->stride[1]);
160 memcpy_pic(dmpi->planes[2], mpi->planes[2], 160 memcpy_pic(dmpi->planes[2], mpi->planes[2],
161 mpi->chroma_width, mpi->chroma_height, 161 mpi->chroma_width, mpi->chroma_height,
162 dmpi->stride[2], mpi->stride[2]); 162 dmpi->stride[2], mpi->stride[2]);
163 } 163 }
164 return vf_next_put_image(vf, dmpi, pts); 164 return vf_next_put_image(vf, dmpi, pts);
165 } 165 }
166 166
167 static void uninit(struct vf_instance *vf) 167 static void uninit(struct vf_instance *vf)
168 { 168 {
169 free(vf->priv); 169 free(vf->priv);
170 } 170 }
171 171
172 static int vf_open(vf_instance_t *vf, char *args) 172 static int vf_open(vf_instance_t *vf, char *args)
173 { 173 {
174 struct vf_priv_s *p; 174 struct vf_priv_s *p;
175 vf->put_image = put_image; 175 vf->put_image = put_image;
176 vf->uninit = uninit; 176 vf->uninit = uninit;
177 vf->default_reqs = VFCAP_ACCEPT_STRIDE; 177 vf->default_reqs = VFCAP_ACCEPT_STRIDE;
178 vf->priv = p = calloc(1, sizeof(struct vf_priv_s)); 178 vf->priv = p = calloc(1, sizeof(struct vf_priv_s));
179 p->max = 0; 179 p->max = 0;
180 p->hi = 64*12; 180 p->hi = 64*12;
181 p->lo = 64*5; 181 p->lo = 64*5;
182 p->frac = 0.33; 182 p->frac = 0.33;
183 if (args) sscanf(args, "%d:%d:%d:%f", &p->max, &p->hi, &p->lo, &p->frac); 183 if (args) sscanf(args, "%d:%d:%d:%f", &p->max, &p->hi, &p->lo, &p->frac);
184 diff = diff_C; 184 diff = diff_C;
185 #if HAVE_MMX && HAVE_EBX_AVAILABLE 185 #if HAVE_MMX && HAVE_EBX_AVAILABLE
186 if(gCpuCaps.hasMMX) diff = diff_MMX; 186 if(gCpuCaps.hasMMX) diff = diff_MMX;
187 #endif 187 #endif
188 return 1; 188 return 1;
189 } 189 }
190 190
191 const vf_info_t vf_info_decimate = { 191 const vf_info_t vf_info_decimate = {
192 "near-duplicate frame remover", 192 "near-duplicate frame remover",
193 "decimate", 193 "decimate",