From 9721b82d2d9ef1560bd6244d52ec403191cb2fc8 Mon Sep 17 00:00:00 2001 From: rfelker Date: Mon, 29 Mar 2004 04:39:04 +0000 Subject: [PATCH] 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 --- DOCS/man/en/mplayer.1 | 46 +++++++ libmpcodecs/Makefile | 2 +- libmpcodecs/vf.c | 2 + libmpcodecs/vf_phase.c | 283 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 332 insertions(+), 1 deletion(-) create mode 100644 libmpcodecs/vf_phase.c diff --git a/DOCS/man/en/mplayer.1 b/DOCS/man/en/mplayer.1 index 4192d385f2..b7e9e08eb2 100644 --- a/DOCS/man/en/mplayer.1 +++ b/DOCS/man/en/mplayer.1 @@ -3136,6 +3136,52 @@ telecined, inserting this filter before them should make them more reliable. Currently only libmpeg2 exports the needed flags. If used on material that does not set them, the filter does nothing. .TP +.B phase=[t|b|p|a|u|T|B|A|U][:v] +Delay interlaced video by one field time so that the field order +changes. +The intended use is to fix PAL movies that have been captured with the +opposite field order to the film-to-video transfer. +The options are: +.RSs +.IPs t +Capture field order top-first, transfer bottom-first. +Filter will delay the bottom field. +.IPs b +Capture bottom-first, transfer top-first. +Filter will delay the top field. +.IPs p +Capture and transfer with the same field order. +This mode only exists for the documentation of the other options to refer to, +but if you actually select it, the filter will faithfully do nothing ;-) +.IPs a +Capture field order determined automatically by field flags, transfer opposite. +Filter selects among t and b modes on a frame by frame basis using field flags. +If no field information is available, then this works just like u. +.IPs u +Capture unknown or varying, transfer opposite. +Filter selects among t and b on a frame by frame basis by analyzing the +images and selecting the alternative that produces best match between the +fields. +.IPs T +Capture top-first, transfer unknown or varying. +Filter selects among t and p using image analysis. +.IPs B +Capture bottom-first, transfer unknown or varying. +Filter selects among b and p using image analysis. +.IPs A +Capture determined by field flags, transfer unknown or varying. +Filter selects among t, b and p using field flags and image analysis. +If no field information is available, then this works just like U. +This is the default mode. +.IPs U +Both capture and transfer unknown or varying. +Filter selects among t, b and p using image analysis only. +.IPs v +Verbose operation. +Prints the selected mode for each frame and the average squared difference +between fields for t, b, and p alternatives. +.RE +.TP .B telecine[=start] Apply 3:2 'telecine' process to increase framerate by 20%. This most likely will not work correctly with MPlayer, but it can 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 +#include +#include +#include + +#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; tonext, 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 + };