00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <stdio.h>
00020 #include <stdlib.h>
00021 #include <string.h>
00022 #include <limits.h>
00023
00024 #include "config.h"
00025 #include "mp_msg.h"
00026
00027 #include "img_format.h"
00028 #include "mp_image.h"
00029 #include "vf.h"
00030
00031 #include "libvo/fastmemcpy.h"
00032
00033 enum mode { PROGRESSIVE, TOP_FIRST, BOTTOM_FIRST,
00034 TOP_FIRST_ANALYZE, BOTTOM_FIRST_ANALYZE,
00035 ANALYZE, FULL_ANALYZE, AUTO, AUTO_ANALYZE };
00036
00037 #define fixed_mode(p) ((p)<=BOTTOM_FIRST)
00038
00039 struct vf_priv_s
00040 {
00041 enum mode mode;
00042 int verbose;
00043 unsigned char *buf[3];
00044 };
00045
00046
00047
00048
00049
00050
00051 static void do_plane(unsigned char *to, unsigned char *from,
00052 int w, int h, int ts, int fs,
00053 unsigned char **bufp, enum mode mode)
00054 {
00055 unsigned char *buf, *end;
00056 int top;
00057
00058 if(!*bufp)
00059 {
00060 mode=PROGRESSIVE;
00061 if(!(*bufp=malloc(h*w))) return;
00062 }
00063
00064 for(end=to+h*ts, buf=*bufp, top=1; to<end; from+=fs, to+=ts, buf+=w, top^=1)
00065 {
00066 fast_memcpy(to, mode==(top?BOTTOM_FIRST:TOP_FIRST)?buf:from, w);
00067 fast_memcpy(buf, from, w);
00068 }
00069 }
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 #define diff(a, as, b, bs) (t=((*a-b[bs])<<2)+a[as<<1]-b[-bs], t*t)
00081
00082
00083
00084
00085
00086
00087 static enum mode analyze_plane(unsigned char *old, unsigned char *new,
00088 int w, int h, int os, int ns, enum mode mode,
00089 int verbose, int fields)
00090 {
00091 double bdiff, pdiff, tdiff, scale;
00092 int bdif, tdif, pdif;
00093 int top, t;
00094 unsigned char *end, *rend;
00095
00096 if(mode==AUTO)
00097 mode=fields&MP_IMGFIELD_ORDERED?fields&MP_IMGFIELD_TOP_FIRST?
00098 TOP_FIRST:BOTTOM_FIRST:PROGRESSIVE;
00099 else if(mode==AUTO_ANALYZE)
00100 mode=fields&MP_IMGFIELD_ORDERED?fields&MP_IMGFIELD_TOP_FIRST?
00101 TOP_FIRST_ANALYZE:BOTTOM_FIRST_ANALYZE:FULL_ANALYZE;
00102
00103 if(fixed_mode(mode))
00104 bdiff=pdiff=tdiff=65536.0;
00105 else
00106 {
00107 bdiff=pdiff=tdiff=0.0;
00108
00109 for(end=new+(h-2)*ns, new+=ns, old+=os, top=0;
00110 new<end; new+=ns-w, old+=os-w, top^=1)
00111 {
00112 pdif=tdif=bdif=0;
00113
00114 switch(mode)
00115 {
00116 case TOP_FIRST_ANALYZE:
00117 if(top)
00118 for(rend=new+w; new<rend; new++, old++)
00119 pdif+=diff(new, ns, new, ns),
00120 tdif+=diff(new, ns, old, os);
00121 else
00122 for(rend=new+w; new<rend; new++, old++)
00123 pdif+=diff(new, ns, new, ns),
00124 tdif+=diff(old, os, new, ns);
00125 break;
00126
00127 case BOTTOM_FIRST_ANALYZE:
00128 if(top)
00129 for(rend=new+w; new<rend; new++, old++)
00130 pdif+=diff(new, ns, new, ns),
00131 bdif+=diff(old, os, new, ns);
00132 else
00133 for(rend=new+w; new<rend; new++, old++)
00134 pdif+=diff(new, ns, new, ns),
00135 bdif+=diff(new, ns, old, os);
00136 break;
00137
00138 case ANALYZE:
00139 if(top)
00140 for(rend=new+w; new<rend; new++, old++)
00141 tdif+=diff(new, ns, old, os),
00142 bdif+=diff(old, os, new, ns);
00143 else
00144 for(rend=new+w; new<rend; new++, old++)
00145 bdif+=diff(new, ns, old, os),
00146 tdif+=diff(old, os, new, ns);
00147 break;
00148
00149 default:
00150 if(top)
00151 for(rend=new+w; new<rend; new++, old++)
00152 pdif+=diff(new, ns, new, ns),
00153 tdif+=diff(new, ns, old, os),
00154 bdif+=diff(old, os, new, ns);
00155 else
00156 for(rend=new+w; new<rend; new++, old++)
00157 pdif+=diff(new, ns, new, ns),
00158 bdif+=diff(new, ns, old, os),
00159 tdif+=diff(old, os, new, ns);
00160 }
00161
00162 pdiff+=(double)pdif;
00163 tdiff+=(double)tdif;
00164 bdiff+=(double)bdif;
00165 }
00166
00167 scale=1.0/(w*(h-3))/25.0;
00168 pdiff*=scale;
00169 tdiff*=scale;
00170 bdiff*=scale;
00171
00172 if(mode==TOP_FIRST_ANALYZE)
00173 bdiff=65536.0;
00174 else if(mode==BOTTOM_FIRST_ANALYZE)
00175 tdiff=65536.0;
00176 else if(mode==ANALYZE)
00177 pdiff=65536.0;
00178
00179 if(bdiff<pdiff && bdiff<tdiff)
00180 mode=BOTTOM_FIRST;
00181 else if(tdiff<pdiff && tdiff<bdiff)
00182 mode=TOP_FIRST;
00183 else
00184 mode=PROGRESSIVE;
00185 }
00186
00187 if( mp_msg_test(MSGT_VFILTER,MSGL_V) )
00188 {
00189 mp_msg(MSGT_VFILTER, MSGL_INFO, "%c", mode==BOTTOM_FIRST?'b':mode==TOP_FIRST?'t':'p');
00190 if(tdiff==65536.0) mp_msg(MSGT_VFILTER, MSGL_INFO," N/A "); else mp_msg(MSGT_VFILTER, MSGL_INFO," %8.2f", tdiff);
00191 if(bdiff==65536.0) mp_msg(MSGT_VFILTER, MSGL_INFO," N/A "); else mp_msg(MSGT_VFILTER, MSGL_INFO," %8.2f", bdiff);
00192 if(pdiff==65536.0) mp_msg(MSGT_VFILTER, MSGL_INFO," N/A "); else mp_msg(MSGT_VFILTER, MSGL_INFO," %8.2f", pdiff);
00193 mp_msg(MSGT_VFILTER, MSGL_INFO," \n");
00194 }
00195
00196 return mode;
00197 }
00198
00199 static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
00200 {
00201 mp_image_t *dmpi;
00202 int w;
00203 enum mode mode;
00204
00205 if(!(dmpi=vf_get_image(vf->next, mpi->imgfmt,
00206 MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
00207 mpi->w, mpi->h)))
00208 return 0;
00209
00210 w=dmpi->w;
00211 if(!(dmpi->flags&MP_IMGFLAG_PLANAR))
00212 w*=dmpi->bpp/8;
00213
00214 mode=vf->priv->mode;
00215
00216 if(!vf->priv->buf[0])
00217 mode=PROGRESSIVE;
00218 else
00219 mode=analyze_plane(vf->priv->buf[0], mpi->planes[0],
00220 w, dmpi->h, w, mpi->stride[0], mode,
00221 vf->priv->verbose, mpi->fields);
00222
00223 do_plane(dmpi->planes[0], mpi->planes[0],
00224 w, dmpi->h,
00225 dmpi->stride[0], mpi->stride[0],
00226 &vf->priv->buf[0], mode);
00227
00228 if(dmpi->flags&MP_IMGFLAG_PLANAR)
00229 {
00230 do_plane(dmpi->planes[1], mpi->planes[1],
00231 dmpi->chroma_width, dmpi->chroma_height,
00232 dmpi->stride[1], mpi->stride[1],
00233 &vf->priv->buf[1], mode);
00234 do_plane(dmpi->planes[2], mpi->planes[2],
00235 dmpi->chroma_width, dmpi->chroma_height,
00236 dmpi->stride[2], mpi->stride[2],
00237 &vf->priv->buf[2], mode);
00238 }
00239
00240 return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
00241 }
00242
00243 static void uninit(struct vf_instance *vf)
00244 {
00245 free(vf->priv->buf[0]);
00246 free(vf->priv->buf[1]);
00247 free(vf->priv->buf[2]);
00248 free(vf->priv);
00249 }
00250
00251 static int vf_open(vf_instance_t *vf, char *args)
00252 {
00253 vf->put_image = put_image;
00254 vf->uninit = uninit;
00255 vf->default_reqs = VFCAP_ACCEPT_STRIDE;
00256
00257 if(!(vf->priv = calloc(1, sizeof(struct vf_priv_s))))
00258 {
00259 uninit(vf);
00260 return 0;
00261 }
00262
00263 vf->priv->mode=AUTO_ANALYZE;
00264 vf->priv->verbose=0;
00265
00266 while(args && *args)
00267 {
00268 switch(*args)
00269 {
00270 case 't': vf->priv->mode=TOP_FIRST; break;
00271 case 'a': vf->priv->mode=AUTO; break;
00272 case 'b': vf->priv->mode=BOTTOM_FIRST; break;
00273 case 'u': vf->priv->mode=ANALYZE; break;
00274 case 'T': vf->priv->mode=TOP_FIRST_ANALYZE; break;
00275 case 'A': vf->priv->mode=AUTO_ANALYZE; break;
00276 case 'B': vf->priv->mode=BOTTOM_FIRST_ANALYZE; break;
00277 case 'U': vf->priv->mode=FULL_ANALYZE; break;
00278 case 'p': vf->priv->mode=PROGRESSIVE; break;
00279 case 'v': vf->priv->verbose=1; break;
00280 case ':': break;
00281
00282 default:
00283 uninit(vf);
00284 return 0;
00285 }
00286
00287 if( (args=strchr(args, ':')) ) args++;
00288 }
00289
00290 return 1;
00291 }
00292
00293 const vf_info_t vf_info_phase =
00294 {
00295 "phase shift fields",
00296 "phase",
00297 "Ville Saari",
00298 "",
00299 vf_open,
00300 NULL
00301 };