mirror of
https://github.com/mpv-player/mpv
synced 2025-03-25 04:38:01 +00:00
'tinterlace' filter (partial inverse of tfields) by Not Zed <notzed@ximian.com> (with minor fixes for current cvs by me)
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@10572 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
7aa3b58b98
commit
1e87b4bbaa
@ -2742,6 +2742,26 @@ Both fps options are essential!
|
||||
The optional start parameter tells the filter where in the telecine
|
||||
pattern to start (0-3).
|
||||
.TP
|
||||
.B "tinterlace[=mode]"
|
||||
Temporal field interlacing -- merge pairs of frames into an interlaced
|
||||
frame, halving the framerate. Even frames are moved into the upper
|
||||
field, odd frames to the lower field. This can be used to fully reverse
|
||||
the effect of the tfields filter (in mode 0). Available modes are:
|
||||
.PD 0
|
||||
.RSs
|
||||
.IPs 0
|
||||
odd frames into upper field, even to lower, generating a full-height
|
||||
frame at half the framerate
|
||||
.IPs 1
|
||||
only output odd frames, even frames are dropped, height unchanged
|
||||
.IPs 2
|
||||
only output even frames, odd frames are dropped, height unchanged
|
||||
.IPs 3
|
||||
expand each frame to full height, but pad alternate lines with black,
|
||||
framerate unchanged
|
||||
.RE
|
||||
.PD 1
|
||||
.TP
|
||||
.B "tfields[=mode]"
|
||||
Temporal field separation -- split fields into frames, doubling the
|
||||
output framerate.
|
||||
|
@ -14,7 +14,7 @@ VIDEO_SRCS_NAT=vd_null.c vd_cinepak.c vd_qtrpza.c vd_raw.c vd_hmblck.c vd_msvidc
|
||||
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_xanim.c vd_xvid.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_pp.c vf_scale.c vf_format.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
|
||||
VFILTER_SRCS=vf.c vf_vo.c vf_crop.c vf_expand.c vf_pp.c vf_scale.c vf_format.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
|
||||
ENCODER_SRCS=ve.c ve_divx4.c ve_lavc.c ve_vfw.c ve_rawrgb.c ve_libdv.c ve_xvid.c ve_qtvideo.c ve_nuv.c
|
||||
|
||||
NATIVE_SRCS=native/RTjpegN.c native/cinepak.c native/fli.c native/minilzo.c native/msvidc.c native/nuppelvideo.c native/qtrle.c native/qtrpza.c native/qtsmc.c native/roqav.c native/xa_gsm.c native/decode144.c native/decode288.c
|
||||
|
@ -64,6 +64,7 @@ extern vf_info_t vf_info_denoise3d;
|
||||
extern vf_info_t vf_info_hqdn3d;
|
||||
extern vf_info_t vf_info_detc;
|
||||
extern vf_info_t vf_info_telecine;
|
||||
extern vf_info_t vf_info_tinterlace;
|
||||
extern vf_info_t vf_info_tfields;
|
||||
extern vf_info_t vf_info_ivtc;
|
||||
extern vf_info_t vf_info_ilpack;
|
||||
@ -123,6 +124,7 @@ static vf_info_t* filter_list[]={
|
||||
&vf_info_hqdn3d,
|
||||
&vf_info_detc,
|
||||
&vf_info_telecine,
|
||||
&vf_info_tinterlace,
|
||||
&vf_info_tfields,
|
||||
&vf_info_ivtc,
|
||||
&vf_info_ilpack,
|
||||
|
181
libmpcodecs/vf_tinterlace.c
Normal file
181
libmpcodecs/vf_tinterlace.c
Normal file
@ -0,0 +1,181 @@
|
||||
/*
|
||||
Copyright (C) 2003 Michael Zucchi <notzed@ximian.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../config.h"
|
||||
#include "../mp_msg.h"
|
||||
|
||||
#include "img_format.h"
|
||||
#include "mp_image.h"
|
||||
#include "vf.h"
|
||||
|
||||
#include "../libvo/fastmemcpy.h"
|
||||
|
||||
struct vf_priv_s {
|
||||
int mode;
|
||||
int frame;
|
||||
mp_image_t *dmpi;
|
||||
};
|
||||
|
||||
static int put_image(struct vf_instance_s* vf, mp_image_t *mpi)
|
||||
{
|
||||
int ret = 0;
|
||||
mp_image_t *dmpi;
|
||||
|
||||
switch (vf->priv->mode) {
|
||||
case 0:
|
||||
dmpi = vf->priv->dmpi;
|
||||
if (dmpi == NULL) {
|
||||
dmpi = vf_get_image(vf->next, mpi->imgfmt,
|
||||
MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE |
|
||||
MP_IMGFLAG_PRESERVE | MP_IMGFLAG_READABLE,
|
||||
mpi->width, mpi->height*2);
|
||||
|
||||
vf->priv->dmpi = dmpi;
|
||||
|
||||
memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h,
|
||||
dmpi->stride[0]*2, mpi->stride[0]);
|
||||
if (mpi->flags & MP_IMGFLAG_PLANAR) {
|
||||
memcpy_pic(dmpi->planes[1], mpi->planes[1],
|
||||
mpi->chroma_width, mpi->chroma_height,
|
||||
dmpi->stride[1]*2, mpi->stride[1]);
|
||||
memcpy_pic(dmpi->planes[2], mpi->planes[2],
|
||||
mpi->chroma_width, mpi->chroma_height,
|
||||
dmpi->stride[2]*2, mpi->stride[2]);
|
||||
}
|
||||
} else {
|
||||
vf->priv->dmpi = NULL;
|
||||
|
||||
memcpy_pic(dmpi->planes[0]+dmpi->stride[0], mpi->planes[0], mpi->w, mpi->h,
|
||||
dmpi->stride[0]*2, mpi->stride[0]);
|
||||
if (mpi->flags & MP_IMGFLAG_PLANAR) {
|
||||
memcpy_pic(dmpi->planes[1]+dmpi->stride[1], mpi->planes[1],
|
||||
mpi->chroma_width, mpi->chroma_height,
|
||||
dmpi->stride[1]*2, mpi->stride[1]);
|
||||
memcpy_pic(dmpi->planes[2]+dmpi->stride[2], mpi->planes[2],
|
||||
mpi->chroma_width, mpi->chroma_height,
|
||||
dmpi->stride[2]*2, mpi->stride[2]);
|
||||
}
|
||||
ret = vf_next_put_image(vf, dmpi);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (vf->priv->frame & 1)
|
||||
ret = vf_next_put_image(vf, mpi);
|
||||
break;
|
||||
case 2:
|
||||
if ((vf->priv->frame & 1) == 0)
|
||||
ret = vf_next_put_image(vf, mpi);
|
||||
break;
|
||||
case 3:
|
||||
dmpi = vf_get_image(vf->next, mpi->imgfmt,
|
||||
MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
|
||||
mpi->width, mpi->height*2);
|
||||
/* fixme, just clear alternate lines */
|
||||
vf_mpi_clear(dmpi, 0, 0, dmpi->w, dmpi->h);
|
||||
if ((vf->priv->frame & 1) == 0) {
|
||||
memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h,
|
||||
dmpi->stride[0]*2, mpi->stride[0]);
|
||||
if (mpi->flags & MP_IMGFLAG_PLANAR) {
|
||||
memcpy_pic(dmpi->planes[1], mpi->planes[1],
|
||||
mpi->chroma_width, mpi->chroma_height,
|
||||
dmpi->stride[1]*2, mpi->stride[1]);
|
||||
memcpy_pic(dmpi->planes[2], mpi->planes[2],
|
||||
mpi->chroma_width, mpi->chroma_height,
|
||||
dmpi->stride[2]*2, mpi->stride[2]);
|
||||
}
|
||||
} else {
|
||||
memcpy_pic(dmpi->planes[0]+dmpi->stride[0], mpi->planes[0], mpi->w, mpi->h,
|
||||
dmpi->stride[0]*2, mpi->stride[0]);
|
||||
if (mpi->flags & MP_IMGFLAG_PLANAR) {
|
||||
memcpy_pic(dmpi->planes[1]+dmpi->stride[1], mpi->planes[1],
|
||||
mpi->chroma_width, mpi->chroma_height,
|
||||
dmpi->stride[1]*2, mpi->stride[1]);
|
||||
memcpy_pic(dmpi->planes[2]+dmpi->stride[2], mpi->planes[2],
|
||||
mpi->chroma_width, mpi->chroma_height,
|
||||
dmpi->stride[2]*2, mpi->stride[2]);
|
||||
}
|
||||
}
|
||||
ret = vf_next_put_image(vf, dmpi);
|
||||
break;
|
||||
}
|
||||
|
||||
vf->priv->frame++;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int query_format(struct vf_instance_s* vf, unsigned int fmt)
|
||||
{
|
||||
/* FIXME - figure out which other formats work */
|
||||
switch (fmt) {
|
||||
case IMGFMT_YV12:
|
||||
case IMGFMT_IYUV:
|
||||
case IMGFMT_I420:
|
||||
return vf_next_query_format(vf, fmt);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int config(struct vf_instance_s* vf,
|
||||
int width, int height, int d_width, int d_height,
|
||||
unsigned int flags, unsigned int outfmt)
|
||||
{
|
||||
switch (vf->priv->mode) {
|
||||
case 0:
|
||||
case 3:
|
||||
return vf_next_config(vf,width,height*2,d_width,d_height*2,flags,outfmt);
|
||||
case 1: /* odd frames */
|
||||
case 2: /* even frames */
|
||||
return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void uninit(struct vf_instance_s* vf)
|
||||
{
|
||||
free(vf->priv);
|
||||
}
|
||||
|
||||
static int open(vf_instance_t *vf, char* args)
|
||||
{
|
||||
struct vf_priv_s *p;
|
||||
vf->config = config;
|
||||
vf->put_image = put_image;
|
||||
vf->query_format = query_format;
|
||||
vf->uninit = uninit;
|
||||
vf->default_reqs = VFCAP_ACCEPT_STRIDE;
|
||||
vf->priv = p = calloc(1, sizeof(struct vf_priv_s));
|
||||
vf->priv->mode = 0;
|
||||
if (args)
|
||||
sscanf(args, "%d", &vf->priv->mode);
|
||||
vf->priv->frame = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
vf_info_t vf_info_tinterlace = {
|
||||
"temporal field interlacing",
|
||||
"tinterlace",
|
||||
"Michael Zucchi",
|
||||
"",
|
||||
open,
|
||||
NULL
|
||||
};
|
Loading…
Reference in New Issue
Block a user