9 #include "img_format.h"
13 #include "libvo/fastmemcpy.h"
22 #if HAVE_MMX && HAVE_EBX_AVAILABLE
23 static int diff_MMX(unsigned char *old
, unsigned char *new, int os
, int ns
)
25 volatile short out
[4];
28 "pxor %%mm4, %%mm4 \n\t"
29 "pxor %%mm7, %%mm7 \n\t"
34 "movq (%%"REG_S
"), %%mm0 \n\t"
35 "movq (%%"REG_S
"), %%mm2 \n\t"
36 "add %%"REG_a
", %%"REG_S
" \n\t"
37 "movq (%%"REG_D
"), %%mm1 \n\t"
38 "add %%"REG_b
", %%"REG_D
" \n\t"
39 "psubusb %%mm1, %%mm2 \n\t"
40 "psubusb %%mm0, %%mm1 \n\t"
41 "movq %%mm2, %%mm0 \n\t"
42 "movq %%mm1, %%mm3 \n\t"
43 "punpcklbw %%mm7, %%mm0 \n\t"
44 "punpcklbw %%mm7, %%mm1 \n\t"
45 "punpckhbw %%mm7, %%mm2 \n\t"
46 "punpckhbw %%mm7, %%mm3 \n\t"
47 "paddw %%mm0, %%mm4 \n\t"
48 "paddw %%mm1, %%mm4 \n\t"
49 "paddw %%mm2, %%mm4 \n\t"
50 "paddw %%mm3, %%mm4 \n\t"
54 "movq %%mm4, (%%"REG_d
") \n\t"
57 : "S" (old
), "D" (new), "a" ((long)os
), "b" ((long)ns
), "d" (out
)
60 return out
[0]+out
[1]+out
[2]+out
[3];
64 static int diff_C(unsigned char *old
, unsigned char *new, int os
, int ns
)
69 d
+= abs(new[x
] - old
[x
]);
77 static int (*diff
)(unsigned char *, unsigned char *, int, int);
79 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
)
83 int t
= (w
/16)*(h
/16)*frac
;
84 for (y
= 0; y
< h
-7; y
+= 4) {
85 for (x
= 8; x
< w
-7; x
+= 4) {
86 d
= diff(old
+x
+y
*os
, new+x
+y
*ns
, os
, ns
);
97 static int diff_to_drop(int hi
, int lo
, float frac
, mp_image_t
*old
, mp_image_t
*new)
99 if (new->flags
& MP_IMGFLAG_PLANAR
) {
100 return diff_to_drop_plane(hi
,lo
,frac
, old
->planes
[0], new->planes
[0],
101 new->w
, new->h
, old
->stride
[0], new->stride
[0])
102 && diff_to_drop_plane(hi
,lo
,frac
, old
->planes
[1], new->planes
[1],
103 new->chroma_width
, new->chroma_height
,
104 old
->stride
[1], new->stride
[1])
105 && diff_to_drop_plane(hi
,lo
,frac
, old
->planes
[2], new->planes
[2],
106 new->chroma_width
, new->chroma_height
,
107 old
->stride
[2], new->stride
[2]);
109 return diff_to_drop_plane(hi
,lo
,frac
, old
->planes
[0], new->planes
[0],
110 new->w
*(new->bpp
/8), new->h
, old
->stride
[0], new->stride
[0]);
113 static int put_image(struct vf_instance_s
* vf
, mp_image_t
*mpi
, double pts
)
117 dmpi
= vf_get_image(vf
->next
, mpi
->imgfmt
,
118 MP_IMGTYPE_STATIC
, MP_IMGFLAG_ACCEPT_STRIDE
|
119 MP_IMGFLAG_PRESERVE
| MP_IMGFLAG_READABLE
,
120 mpi
->width
, mpi
->height
);
121 dmpi
->qscale
= mpi
->qscale
;
122 dmpi
->qstride
= mpi
->qstride
;
123 dmpi
->qscale_type
= mpi
->qscale_type
;
125 if (diff_to_drop(vf
->priv
->hi
, vf
->priv
->lo
, vf
->priv
->frac
, dmpi
, mpi
)) {
126 if (vf
->priv
->max
== 0)
128 else if ((vf
->priv
->max
> 0) && (vf
->priv
->cnt
++ < vf
->priv
->max
))
130 else if ((vf
->priv
->max
< 0) && (vf
->priv
->last
+1 >= -vf
->priv
->max
))
131 return vf
->priv
->last
=0;
136 memcpy_pic(dmpi
->planes
[0], mpi
->planes
[0], mpi
->w
, mpi
->h
,
137 dmpi
->stride
[0], mpi
->stride
[0]);
138 if (mpi
->flags
& MP_IMGFLAG_PLANAR
) {
139 memcpy_pic(dmpi
->planes
[1], mpi
->planes
[1],
140 mpi
->chroma_width
, mpi
->chroma_height
,
141 dmpi
->stride
[1], mpi
->stride
[1]);
142 memcpy_pic(dmpi
->planes
[2], mpi
->planes
[2],
143 mpi
->chroma_width
, mpi
->chroma_height
,
144 dmpi
->stride
[2], mpi
->stride
[2]);
146 return vf_next_put_image(vf
, dmpi
, pts
);
149 static void uninit(struct vf_instance_s
* vf
)
154 static int open(vf_instance_t
*vf
, char* args
)
157 vf
->put_image
= put_image
;
159 vf
->default_reqs
= VFCAP_ACCEPT_STRIDE
;
160 vf
->priv
= p
= calloc(1, sizeof(struct vf_priv_s
));
165 if (args
) sscanf(args
, "%d:%d:%d:%f", &p
->max
, &p
->hi
, &p
->lo
, &p
->frac
);
167 #if HAVE_MMX && HAVE_EBX_AVAILABLE
168 if(gCpuCaps
.hasMMX
) diff
= diff_MMX
;
173 const vf_info_t vf_info_decimate
= {
174 "near-duplicate frame remover",