summaryrefslogtreecommitdiffstats
path: root/libmpcodecs
diff options
context:
space:
mode:
authorrfelker <rfelker@b3059339-0415-0410-9bf9-f77b7e298cf2>2004-03-29 04:39:04 +0000
committerrfelker <rfelker@b3059339-0415-0410-9bf9-f77b7e298cf2>2004-03-29 04:39:04 +0000
commit9721b82d2d9ef1560bd6244d52ec403191cb2fc8 (patch)
tree17e9c1c1fc337bb9da243090296e8781d229f102 /libmpcodecs
parentd37c2fad12e84a00e201d7da3350f6403c513984 (diff)
downloadmpv-9721b82d2d9ef1560bd6244d52ec403191cb2fc8.tar.bz2
mpv-9721b82d2d9ef1560bd6244d52ec403191cb2fc8.tar.xz
vf_phase filter by Ville Saari (114263 at foo dot bar dot org)
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@12082 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libmpcodecs')
-rw-r--r--libmpcodecs/Makefile2
-rw-r--r--libmpcodecs/vf.c2
-rw-r--r--libmpcodecs/vf_phase.c283
3 files changed, 286 insertions, 1 deletions
diff --git a/libmpcodecs/Makefile b/libmpcodecs/Makefile
index 29e25c9efd..748dcbfc52 100644
--- a/libmpcodecs/Makefile
+++ b/libmpcodecs/Makefile
@@ -14,7 +14,7 @@ VIDEO_SRCS_NAT=vd_null.c vd_cinepak.c vd_raw.c vd_hmblck.c vd_fli.c vd_qtrle.c v
VIDEO_SRCS_OPT=vd_realvid.c vd_ffmpeg.c vd_dshow.c vd_dmo.c vd_vfw.c vd_vfwex.c vd_odivx.c vd_divx4.c vd_zrmjpeg.c vd_xanim.c vd_xvid.c vd_xvid4.c vd_libdv.c vd_qtvideo.c vd_theora.c
VIDEO_SRCS=dec_video.c vd.c $(VIDEO_SRCS_NAT) $(VIDEO_SRCS_LIB) $(VIDEO_SRCS_OPT)
-VFILTER_SRCS=vf.c vf_vo.c vf_crop.c vf_expand.c vf_scale.c vf_format.c vf_noformat.c vf_yuy2.c vf_flip.c vf_rgb2bgr.c vf_rotate.c vf_mirror.c vf_palette.c vf_lavc.c vf_dvbscale.c vf_cropdetect.c vf_test.c vf_noise.c vf_yvu9.c vf_rectangle.c vf_lavcdeint.c vf_eq.c vf_eq2.c vf_halfpack.c vf_dint.c vf_1bpp.c vf_bmovl.c vf_2xsai.c vf_unsharp.c vf_swapuv.c vf_il.c vf_boxblur.c vf_sab.c vf_smartblur.c vf_perspective.c vf_down3dright.c vf_field.c vf_denoise3d.c vf_hqdn3d.c vf_detc.c vf_telecine.c vf_tfields.c vf_ivtc.c vf_ilpack.c vf_dsize.c vf_decimate.c vf_softpulldown.c vf_tinterlace.c vf_pullup.c pullup.c vf_framestep.c vf_tile.c vf_delogo.c vf_fil.c vf_hue.c vf_spp.c vf_yuvcsp.c vf_filmdint.c vf_kerndeint.c vf_rgbtest.c vf_qp.c
+VFILTER_SRCS=vf.c vf_vo.c vf_crop.c vf_expand.c vf_scale.c vf_format.c vf_noformat.c vf_yuy2.c vf_flip.c vf_rgb2bgr.c vf_rotate.c vf_mirror.c vf_palette.c vf_lavc.c vf_dvbscale.c vf_cropdetect.c vf_test.c vf_noise.c vf_yvu9.c vf_rectangle.c vf_lavcdeint.c vf_eq.c vf_eq2.c vf_halfpack.c vf_dint.c vf_1bpp.c vf_bmovl.c vf_2xsai.c vf_unsharp.c vf_swapuv.c vf_il.c vf_boxblur.c vf_sab.c vf_smartblur.c vf_perspective.c vf_down3dright.c vf_field.c vf_denoise3d.c vf_hqdn3d.c vf_detc.c vf_telecine.c vf_tfields.c vf_ivtc.c vf_ilpack.c vf_dsize.c vf_decimate.c vf_softpulldown.c vf_tinterlace.c vf_pullup.c pullup.c vf_framestep.c vf_tile.c vf_delogo.c vf_fil.c vf_hue.c vf_spp.c vf_yuvcsp.c vf_filmdint.c vf_kerndeint.c vf_rgbtest.c vf_qp.c vf_phase.c
ifeq ($(HAVE_FFPOSTPROCESS),yes)
VFILTER_SRCS += vf_pp.c
endif
diff --git a/libmpcodecs/vf.c b/libmpcodecs/vf.c
index ede20446b4..042dcc1705 100644
--- a/libmpcodecs/vf.c
+++ b/libmpcodecs/vf.c
@@ -87,6 +87,7 @@ extern vf_info_t vf_info_yuvcsp;
extern vf_info_t vf_info_kerndeint;
extern vf_info_t vf_info_rgbtest;
extern vf_info_t vf_info_qp;
+extern vf_info_t vf_info_phase;
// list of available filters:
static vf_info_t* filter_list[]={
@@ -167,6 +168,7 @@ static vf_info_t* filter_list[]={
#ifdef USE_LIBAVCODEC
&vf_info_qp,
#endif
+ &vf_info_phase,
NULL
};
diff --git a/libmpcodecs/vf_phase.c b/libmpcodecs/vf_phase.c
new file mode 100644
index 0000000000..67ad902153
--- /dev/null
+++ b/libmpcodecs/vf_phase.c
@@ -0,0 +1,283 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+
+#include "../config.h"
+#include "../mp_msg.h"
+
+#include "img_format.h"
+#include "mp_image.h"
+#include "vf.h"
+
+#include "../libvo/fastmemcpy.h"
+
+enum mode { PROGRESSIVE, TOP_FIRST, BOTTOM_FIRST,
+ TOP_FIRST_ANALYZE, BOTTOM_FIRST_ANALYZE,
+ ANALYZE, FULL_ANALYZE, AUTO, AUTO_ANALYZE };
+
+#define fixed_mode(p) ((p)<=BOTTOM_FIRST)
+
+struct vf_priv_s
+ {
+ enum mode mode;
+ int verbose;
+ unsigned char *buf[3];
+ };
+
+/*
+ * Copy fields from either current or buffered previous frame to the
+ * output and store the current frame unmodified to the buffer.
+ */
+
+static void do_plane(unsigned char *to, unsigned char *from,
+ int w, int h, int ts, int fs,
+ unsigned char **bufp, enum mode mode)
+ {
+ unsigned char *buf, *end;
+ int top;
+
+ if(!*bufp)
+ {
+ mode=PROGRESSIVE;
+ if(!(*bufp=malloc(h*w))) return;
+ }
+
+ for(end=to+h*ts, buf=*bufp, top=1; to<end; from+=fs, to+=ts, buf+=w, top^=1)
+ {
+ memcpy(to, mode==(top?BOTTOM_FIRST:TOP_FIRST)?buf:from, w);
+ memcpy(buf, from, w);
+ }
+ }
+
+/*
+ * This macro interpolates the value of both fields at a point halfway
+ * between lines and takes the squared difference. In field resolution
+ * the point is a quarter pixel below a line in one field and a quarter
+ * pixel above a line in other.
+ *
+ * (the result is actually multiplied by 25)
+ */
+
+#define diff(a, as, b, bs) (t=(*a-b[bs]<<2)+a[as<<1]-b[-bs], t*t)
+
+/*
+ * Find which field combination has the smallest average squared difference
+ * between the fields.
+ */
+
+static enum mode analyze_plane(unsigned char *old, unsigned char *new,
+ int w, int h, int os, int ns, enum mode mode,
+ int verbose, int fields)
+ {
+ double bdiff, pdiff, tdiff, scale;
+ int bdif, tdif, pdif;
+ int top, t;
+ unsigned char *end, *rend;
+
+ if(mode==AUTO)
+ mode=fields&MP_IMGFIELD_ORDERED?fields&MP_IMGFIELD_TOP_FIRST?
+ TOP_FIRST:BOTTOM_FIRST:PROGRESSIVE;
+ else if(mode==AUTO_ANALYZE)
+ mode=fields&MP_IMGFIELD_ORDERED?fields&MP_IMGFIELD_TOP_FIRST?
+ TOP_FIRST_ANALYZE:BOTTOM_FIRST_ANALYZE:FULL_ANALYZE;
+
+ if(fixed_mode(mode))
+ bdiff=pdiff=tdiff=65536.0;
+ else
+ {
+ bdiff=pdiff=tdiff=0.0;
+
+ for(end=new+(h-2)*ns, new+=ns, old+=os, top=0;
+ new<end; new+=ns-w, old+=os-w, top^=1)
+ {
+ pdif=tdif=bdif=0;
+
+ switch(mode)
+ {
+ case TOP_FIRST_ANALYZE:
+ if(top)
+ for(rend=new+w; new<rend; new++, old++)
+ pdif+=diff(new, ns, new, ns),
+ tdif+=diff(new, ns, old, os);
+ else
+ for(rend=new+w; new<rend; new++, old++)
+ pdif+=diff(new, ns, new, ns),
+ tdif+=diff(old, os, new, ns);
+ break;
+
+ case BOTTOM_FIRST_ANALYZE:
+ if(top)
+ for(rend=new+w; new<rend; new++, old++)
+ pdif+=diff(new, ns, new, ns),
+ bdif+=diff(old, os, new, ns);
+ else
+ for(rend=new+w; new<rend; new++, old++)
+ pdif+=diff(new, ns, new, ns),
+ bdif+=diff(new, ns, old, os);
+ break;
+
+ case ANALYZE:
+ if(top)
+ for(rend=new+w; new<rend; new++, old++)
+ tdif+=diff(new, ns, old, os),
+ bdif+=diff(old, os, new, ns);
+ else
+ for(rend=new+w; new<rend; new++, old++)
+ bdif+=diff(new, ns, old, os),
+ tdif+=diff(old, os, new, ns);
+ break;
+
+ default: /* FULL_ANALYZE */
+ if(top)
+ for(rend=new+w; new<rend; new++, old++)
+ pdif+=diff(new, ns, new, ns),
+ tdif+=diff(new, ns, old, os),
+ bdif+=diff(old, os, new, ns);
+ else
+ for(rend=new+w; new<rend; new++, old++)
+ pdif+=diff(new, ns, new, ns),
+ bdif+=diff(new, ns, old, os),
+ tdif+=diff(old, os, new, ns);
+ }
+
+ pdiff+=(double)pdif;
+ tdiff+=(double)tdif;
+ bdiff+=(double)bdif;
+ }
+
+ scale=1.0/(w*(h-3))/25.0;
+ pdiff*=scale;
+ tdiff*=scale;
+ bdiff*=scale;
+
+ if(mode==TOP_FIRST_ANALYZE)
+ bdiff=65536.0;
+ else if(mode==BOTTOM_FIRST_ANALYZE)
+ tdiff=65536.0;
+ else if(mode==ANALYZE)
+ pdiff=65536.0;
+
+ if(bdiff<pdiff && bdiff<tdiff)
+ mode=BOTTOM_FIRST;
+ else if(tdiff<pdiff && tdiff<bdiff)
+ mode=TOP_FIRST;
+ else
+ mode=PROGRESSIVE;
+ }
+
+ if(verbose)
+ {
+ printf("%c", mode==BOTTOM_FIRST?'b':mode==TOP_FIRST?'t':'p');
+ if(tdiff==65536.0) printf(" N/A "); else printf(" %8.2f", tdiff);
+ if(bdiff==65536.0) printf(" N/A "); else printf(" %8.2f", bdiff);
+ if(pdiff==65536.0) printf(" N/A "); else printf(" %8.2f", pdiff);
+ printf(" \n");
+ }
+
+ return mode;
+ }
+
+static int put_image(struct vf_instance_s* vf, mp_image_t *mpi)
+ {
+ mp_image_t *dmpi;
+ int w;
+ enum mode mode;
+
+ if(!(dmpi=vf_get_image(vf->next, mpi->imgfmt,
+ MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
+ mpi->w, mpi->h)))
+ return 0;
+
+ w=dmpi->w;
+ if(!(dmpi->flags&MP_IMGFLAG_PLANAR))
+ w*=dmpi->bpp/8;
+
+ mode=vf->priv->mode;
+
+ if(!vf->priv->buf[0])
+ mode=PROGRESSIVE;
+ else
+ mode=analyze_plane(vf->priv->buf[0], mpi->planes[0],
+ w, dmpi->h, w, mpi->stride[0], mode,
+ vf->priv->verbose, mpi->fields);
+
+ do_plane(dmpi->planes[0], mpi->planes[0],
+ w, dmpi->h,
+ dmpi->stride[0], mpi->stride[0],
+ &vf->priv->buf[0], mode);
+
+ if(dmpi->flags&MP_IMGFLAG_PLANAR)
+ {
+ do_plane(dmpi->planes[1], mpi->planes[1],
+ dmpi->chroma_width, dmpi->chroma_height,
+ dmpi->stride[1], mpi->stride[1],
+ &vf->priv->buf[1], mode);
+ do_plane(dmpi->planes[2], mpi->planes[2],
+ dmpi->chroma_width, dmpi->chroma_height,
+ dmpi->stride[2], mpi->stride[2],
+ &vf->priv->buf[2], mode);
+ }
+
+ return vf_next_put_image(vf, dmpi);
+ }
+
+static void uninit(struct vf_instance_s* vf)
+ {
+ free(vf->priv->buf[0]);
+ free(vf->priv->buf[1]);
+ free(vf->priv->buf[2]);
+ free(vf->priv);
+ }
+
+static int open(vf_instance_t *vf, char* args)
+ {
+ vf->put_image = put_image;
+ vf->uninit = uninit;
+ vf->default_reqs = VFCAP_ACCEPT_STRIDE;
+
+ if(!(vf->priv = calloc(1, sizeof(struct vf_priv_s))))
+ {
+ uninit(vf);
+ return 0;
+ }
+
+ vf->priv->mode=AUTO_ANALYZE;
+ vf->priv->verbose=0;
+
+ while(args && *args)
+ {
+ switch(*args)
+ {
+ case 't': vf->priv->mode=TOP_FIRST; break;
+ case 'a': vf->priv->mode=AUTO; break;
+ case 'b': vf->priv->mode=BOTTOM_FIRST; break;
+ case 'u': vf->priv->mode=ANALYZE; break;
+ case 'T': vf->priv->mode=TOP_FIRST_ANALYZE; break;
+ case 'A': vf->priv->mode=AUTO_ANALYZE; break;
+ case 'B': vf->priv->mode=BOTTOM_FIRST_ANALYZE; break;
+ case 'U': vf->priv->mode=FULL_ANALYZE; break;
+ case 'p': vf->priv->mode=PROGRESSIVE; break;
+ case 'v': vf->priv->verbose=1; break;
+ case ':': break;
+
+ default:
+ uninit(vf);
+ return 0; /* bad args */
+ }
+
+ if(args=strchr(args, ':')) args++;
+ }
+
+ return 1;
+ }
+
+vf_info_t vf_info_phase =
+ {
+ "phase shift fields",
+ "phase",
+ "Ville Saari",
+ "",
+ open,
+ NULL
+ };