9 #include "img_format.h"
13 #include "libvo/fastmemcpy.h"
15 enum mode
{ PROGRESSIVE
, TOP_FIRST
, BOTTOM_FIRST
,
16 TOP_FIRST_ANALYZE
, BOTTOM_FIRST_ANALYZE
,
17 ANALYZE
, FULL_ANALYZE
, AUTO
, AUTO_ANALYZE
};
19 #define fixed_mode(p) ((p)<=BOTTOM_FIRST)
25 unsigned char *buf
[3];
29 * Copy fields from either current or buffered previous frame to the
30 * output and store the current frame unmodified to the buffer.
33 static void do_plane(unsigned char *to
, unsigned char *from
,
34 int w
, int h
, int ts
, int fs
,
35 unsigned char **bufp
, enum mode mode
)
37 unsigned char *buf
, *end
;
43 if(!(*bufp
=malloc(h
*w
))) return;
46 for(end
=to
+h
*ts
, buf
=*bufp
, top
=1; to
<end
; from
+=fs
, to
+=ts
, buf
+=w
, top
^=1)
48 fast_memcpy(to
, mode
==(top
?BOTTOM_FIRST
:TOP_FIRST
)?buf
:from
, w
);
49 fast_memcpy(buf
, from
, w
);
54 * This macro interpolates the value of both fields at a point halfway
55 * between lines and takes the squared difference. In field resolution
56 * the point is a quarter pixel below a line in one field and a quarter
57 * pixel above a line in other.
59 * (the result is actually multiplied by 25)
62 #define diff(a, as, b, bs) (t=((*a-b[bs])<<2)+a[as<<1]-b[-bs], t*t)
65 * Find which field combination has the smallest average squared difference
69 static enum mode
analyze_plane(unsigned char *old
, unsigned char *new,
70 int w
, int h
, int os
, int ns
, enum mode mode
,
71 int verbose
, int fields
)
73 double bdiff
, pdiff
, tdiff
, scale
;
76 unsigned char *end
, *rend
;
79 mode
=fields
&MP_IMGFIELD_ORDERED
?fields
&MP_IMGFIELD_TOP_FIRST
?
80 TOP_FIRST
:BOTTOM_FIRST
:PROGRESSIVE
;
81 else if(mode
==AUTO_ANALYZE
)
82 mode
=fields
&MP_IMGFIELD_ORDERED
?fields
&MP_IMGFIELD_TOP_FIRST
?
83 TOP_FIRST_ANALYZE
:BOTTOM_FIRST_ANALYZE
:FULL_ANALYZE
;
86 bdiff
=pdiff
=tdiff
=65536.0;
89 bdiff
=pdiff
=tdiff
=0.0;
91 for(end
=new+(h
-2)*ns
, new+=ns
, old
+=os
, top
=0;
92 new<end
; new+=ns
-w
, old
+=os
-w
, top
^=1)
98 case TOP_FIRST_ANALYZE
:
100 for(rend
=new+w
; new<rend
; new++, old
++)
101 pdif
+=diff(new, ns
, new, ns
),
102 tdif
+=diff(new, ns
, old
, os
);
104 for(rend
=new+w
; new<rend
; new++, old
++)
105 pdif
+=diff(new, ns
, new, ns
),
106 tdif
+=diff(old
, os
, new, ns
);
109 case BOTTOM_FIRST_ANALYZE
:
111 for(rend
=new+w
; new<rend
; new++, old
++)
112 pdif
+=diff(new, ns
, new, ns
),
113 bdif
+=diff(old
, os
, new, ns
);
115 for(rend
=new+w
; new<rend
; new++, old
++)
116 pdif
+=diff(new, ns
, new, ns
),
117 bdif
+=diff(new, ns
, old
, os
);
122 for(rend
=new+w
; new<rend
; new++, old
++)
123 tdif
+=diff(new, ns
, old
, os
),
124 bdif
+=diff(old
, os
, new, ns
);
126 for(rend
=new+w
; new<rend
; new++, old
++)
127 bdif
+=diff(new, ns
, old
, os
),
128 tdif
+=diff(old
, os
, new, ns
);
131 default: /* FULL_ANALYZE */
133 for(rend
=new+w
; new<rend
; new++, old
++)
134 pdif
+=diff(new, ns
, new, ns
),
135 tdif
+=diff(new, ns
, old
, os
),
136 bdif
+=diff(old
, os
, new, ns
);
138 for(rend
=new+w
; new<rend
; new++, old
++)
139 pdif
+=diff(new, ns
, new, ns
),
140 bdif
+=diff(new, ns
, old
, os
),
141 tdif
+=diff(old
, os
, new, ns
);
149 scale
=1.0/(w
*(h
-3))/25.0;
154 if(mode
==TOP_FIRST_ANALYZE
)
156 else if(mode
==BOTTOM_FIRST_ANALYZE
)
158 else if(mode
==ANALYZE
)
161 if(bdiff
<pdiff
&& bdiff
<tdiff
)
163 else if(tdiff
<pdiff
&& tdiff
<bdiff
)
169 if( mp_msg_test(MSGT_VFILTER
,MSGL_V
) )
171 mp_msg(MSGT_VFILTER
, MSGL_INFO
, "%c", mode
==BOTTOM_FIRST
?'b':mode
==TOP_FIRST
?'t':'p');
172 if(tdiff
==65536.0) mp_msg(MSGT_VFILTER
, MSGL_INFO
," N/A "); else mp_msg(MSGT_VFILTER
, MSGL_INFO
," %8.2f", tdiff
);
173 if(bdiff
==65536.0) mp_msg(MSGT_VFILTER
, MSGL_INFO
," N/A "); else mp_msg(MSGT_VFILTER
, MSGL_INFO
," %8.2f", bdiff
);
174 if(pdiff
==65536.0) mp_msg(MSGT_VFILTER
, MSGL_INFO
," N/A "); else mp_msg(MSGT_VFILTER
, MSGL_INFO
," %8.2f", pdiff
);
175 mp_msg(MSGT_VFILTER
, MSGL_INFO
," \n");
181 static int put_image(struct vf_instance
* vf
, mp_image_t
*mpi
, double pts
)
187 if(!(dmpi
=vf_get_image(vf
->next
, mpi
->imgfmt
,
188 MP_IMGTYPE_TEMP
, MP_IMGFLAG_ACCEPT_STRIDE
,
193 if(!(dmpi
->flags
&MP_IMGFLAG_PLANAR
))
198 if(!vf
->priv
->buf
[0])
201 mode
=analyze_plane(vf
->priv
->buf
[0], mpi
->planes
[0],
202 w
, dmpi
->h
, w
, mpi
->stride
[0], mode
,
203 vf
->priv
->verbose
, mpi
->fields
);
205 do_plane(dmpi
->planes
[0], mpi
->planes
[0],
207 dmpi
->stride
[0], mpi
->stride
[0],
208 &vf
->priv
->buf
[0], mode
);
210 if(dmpi
->flags
&MP_IMGFLAG_PLANAR
)
212 do_plane(dmpi
->planes
[1], mpi
->planes
[1],
213 dmpi
->chroma_width
, dmpi
->chroma_height
,
214 dmpi
->stride
[1], mpi
->stride
[1],
215 &vf
->priv
->buf
[1], mode
);
216 do_plane(dmpi
->planes
[2], mpi
->planes
[2],
217 dmpi
->chroma_width
, dmpi
->chroma_height
,
218 dmpi
->stride
[2], mpi
->stride
[2],
219 &vf
->priv
->buf
[2], mode
);
222 return vf_next_put_image(vf
, dmpi
, MP_NOPTS_VALUE
);
225 static void uninit(struct vf_instance
* vf
)
227 free(vf
->priv
->buf
[0]);
228 free(vf
->priv
->buf
[1]);
229 free(vf
->priv
->buf
[2]);
233 static int open(vf_instance_t
*vf
, char* args
)
235 vf
->put_image
= put_image
;
237 vf
->default_reqs
= VFCAP_ACCEPT_STRIDE
;
239 if(!(vf
->priv
= calloc(1, sizeof(struct vf_priv_s
))))
245 vf
->priv
->mode
=AUTO_ANALYZE
;
252 case 't': vf
->priv
->mode
=TOP_FIRST
; break;
253 case 'a': vf
->priv
->mode
=AUTO
; break;
254 case 'b': vf
->priv
->mode
=BOTTOM_FIRST
; break;
255 case 'u': vf
->priv
->mode
=ANALYZE
; break;
256 case 'T': vf
->priv
->mode
=TOP_FIRST_ANALYZE
; break;
257 case 'A': vf
->priv
->mode
=AUTO_ANALYZE
; break;
258 case 'B': vf
->priv
->mode
=BOTTOM_FIRST_ANALYZE
; break;
259 case 'U': vf
->priv
->mode
=FULL_ANALYZE
; break;
260 case 'p': vf
->priv
->mode
=PROGRESSIVE
; break;
261 case 'v': vf
->priv
->verbose
=1; break;
266 return 0; /* bad args */
269 if( (args
=strchr(args
, ':')) ) args
++;
275 const vf_info_t vf_info_phase
=
277 "phase shift fields",