Mercurial > mplayer.hg
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", |