Yet another inverse telecine filter by Zoltan Hidvegi <mplayer@hzoli.2y.net>. Also heavily MMX centric.

git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@11601 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
alex 2003-12-08 22:57:47 +00:00
parent d5188eb90a
commit a5c024156d
5 changed files with 1706 additions and 1 deletions

View File

@ -2917,6 +2917,80 @@ during 30 fps progressive sequences or stills, it will output more
than 24 fps, meaning you'll have trouble if you use it with mencoder
\-ofps 23.976.
.TP
.B filmdint[=options]
Inverse telecine filter, similar to the pullup filter above.
It is designed to handle any pulldown pattern, including mixed soft and
hard telecine and limited support for movies that are slowed down or sped
up from their original framerate for TV.
Only the luma plane is used to find the frame breaks.
If a field has no match, it is deinterlaced with simple linear
approximation.
If the source is MPEG-2, libmpeg2 must be used for decoding (not
ffmpeg2!), and this must be the first filter to allow access to the
field-flags set by the MPEG-2 decoder.
Depending on the source mpeg, you may be fine ignoring this advice, as
long as you do not see lots of "Bottom-first field" warnings.
With no options it does normal inverse telecine, and should be used
together with mencoder \-fps 29.97 \-ofps 23.976.
When this filter is used with mplayer, it will result in an uneven
framerate during playback, but it is still generally better than using
pp=lb or no deinterlacing at all.
Multiple options can be specified separated by /.
.RSs
.IPs crop=w:h:x:y
Just like the crop filter, but faster, and works on mixed hard and soft
telecined content as well as when y is not a multiple of 4.
If x or y would require cropping fractional pixels from the chroma
planes, the crop area is extended.
This usually means that x and y must be even.
.IPs io=ifps:ofps
For each ifps input frames the filter will output ofps frames.
The ratio of ifps/ofps should match the \-fps/\-ofps ratio.
This could be used to filter movies that are broadcast on TV at a frame
rate different from their original frame rate.
.IPs luma_only=n
If n is nonzero, the chroma plane is copied unchanged.
This is useful for YV12 sampled TV, which discards one of the chroma
fields.
.IPs mmx2=n
On x86, if n=1, use MMX2 optimized functions, if n=2, use 3DNow!
optimized functions, othewise, use plain C.
If this option is not specified, MMX2 and 3DNow! are auto-detected, use
this option to override auto-detection.
.IPs fast=n
The larger n will speed up the filter at the expense of accuracy.
The default value is n=3.
If n is odd, a frame immediately following a frame marked with the
REPEAT_FIRST_FIELD mpeg flag is assumed to be progressive, thus filter
will not spend any time on soft-telecined MPEG-2 content.
This is the only effect of this flag if MMX2 or 3DNow! is available.
Without MMX2 and 3DNow, if n=0 or 1, the same calculations will be used
as with MMX2.
If n=2 or 3, the number of luma levels used to find the frame breaks is
reduced from 256 to 128, which results in a faster filter without losing
much accuracy.
If n=4 or 5, a faster, but much less accurate metrics will be used to
find the frame breaks, which is more likely to misdetect high vertical
detail as interlaced content.
.IPs verbose=n
If n is nonzero, print the detailed metrics for each frame.
Useful for debugging.
.IPs dint_thres=n
Deinterlace threshold.
Used during de-interlacing of unmatched frames.
Larger value means less deinterlacing, use n=256 to completely turn off
deinterlacing.
Default is n=8.
.IPs comb_thres=n
Threshold for comparing a top and bottom fields.
Defaults to 128.
.IPs diff_thres=n
Threshold to detect temporal change of a field.
Default is 128.
.IPs sad_thres=n
Sum of Absolute Difference threshold, default is 64.
.RE
.TP
.B softpulldown
This filter works only correct with MEncoder and acts on the MPEG2 flags
used for soft 3:2 pulldown (soft telecine).

View File

@ -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_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_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
VFILTER_SRCS=vf.c vf_vo.c vf_crop.c vf_expand.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 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
ifeq ($(HAVE_FFPOSTPROCESS),yes)
VFILTER_SRCS += vf_pp.c
endif

186
libmpcodecs/cmmx.h Normal file
View File

@ -0,0 +1,186 @@
/*
* x86 MMX and MMX2 packed byte operations in portable C.
* Extra instructions: pdiffub, pcmpzb, psumbw, pcmpgtub
* Author: Zoltan Hidvegi
*/
#ifndef __CMMX_H
#define __CMMX_H
typedef unsigned long cmmx_t;
#define ONE_BYTES (~(cmmx_t)0 / 255)
#define SIGN_BITS (ONE_BYTES << 7)
#define LOWBW_MASK (~(cmmx_t)0 / 257)
static inline cmmx_t
paddb(cmmx_t a, cmmx_t b)
{
return ((a & ~SIGN_BITS) + (b & ~SIGN_BITS)) ^ ((a^b) & SIGN_BITS);
}
static inline cmmx_t
psubb(cmmx_t a, cmmx_t b)
{
return ((a | SIGN_BITS) - (b & ~SIGN_BITS)) ^ (~(a^b) & SIGN_BITS);
}
static inline cmmx_t
paddusb(cmmx_t a, cmmx_t b)
{
cmmx_t s = (a & ~SIGN_BITS) + (b & ~SIGN_BITS);
cmmx_t abs = (a | b) & SIGN_BITS;
cmmx_t c = abs & (s | (a & b));
return s | abs | (abs - (c >> 7));
}
static inline cmmx_t
paddusb_s(cmmx_t a, cmmx_t b)
{
cmmx_t sum = a+b;
cmmx_t ov = sum & SIGN_BITS;
return sum + (sum ^ (ov - (ov>>7)));
}
static inline cmmx_t
psubusb(cmmx_t a, cmmx_t b)
{
cmmx_t s = (a | SIGN_BITS) - (b & ~SIGN_BITS);
cmmx_t anb = a & ~b;
cmmx_t c = (anb | (s & ~(a^b))) & SIGN_BITS;
return s & ((c & anb) | (c - (c >> 7)));
}
static inline cmmx_t
psubusb_s(cmmx_t a, cmmx_t b)
{
cmmx_t d = (a|SIGN_BITS) - b;
cmmx_t m = d & SIGN_BITS;
return d & (m - (m>>7));
}
static inline cmmx_t
pcmpgtub(cmmx_t b, cmmx_t a)
{
cmmx_t s = (a | SIGN_BITS) - (b & ~SIGN_BITS);
cmmx_t ret = ((~a & b) | (~s & ~(a ^ b))) & SIGN_BITS;
return ret | (ret - (ret >> 7));
}
static inline cmmx_t
pdiffub(cmmx_t a, cmmx_t b)
{
cmmx_t xs = (~a ^ b) & SIGN_BITS;
cmmx_t s = ((a | SIGN_BITS) - (b & ~SIGN_BITS)) ^ xs;
cmmx_t gt = ((~a & b) | (s & xs)) & SIGN_BITS;
cmmx_t gt7 = gt >> 7;
return (s ^ gt ^ (gt - gt7)) + gt7;
}
static inline cmmx_t
pdiffub_s(cmmx_t a, cmmx_t b)
{
cmmx_t d = (a|SIGN_BITS) - b;
cmmx_t g = (~d & SIGN_BITS) >> 7;
return (d ^ (SIGN_BITS-g)) + g;
}
static inline cmmx_t
pmaxub(cmmx_t a, cmmx_t b)
{
return psubusb(a,b) + b;
}
static inline cmmx_t
pminub(cmmx_t a, cmmx_t b)
{
return paddusb(a,~b) - ~b;
}
static inline cmmx_t
pminub_s(cmmx_t a, cmmx_t b)
{
cmmx_t d = (a|SIGN_BITS) - b;
cmmx_t m = ~SIGN_BITS + ((d&SIGN_BITS)>>7);
return ((d&m) + b) & ~SIGN_BITS;
}
static inline cmmx_t
pavgb(cmmx_t a, cmmx_t b)
{
cmmx_t ao = a & ONE_BYTES;
cmmx_t bo = b & ONE_BYTES;
return ((a^ao)>>1) + ((b^bo)>>1) + (ao|bo);
}
static inline cmmx_t
pavgb_s(cmmx_t a, cmmx_t b)
{
return ((a+b+ONE_BYTES)>>1) & ~SIGN_BITS;
}
static inline cmmx_t
p31avgb(cmmx_t a, cmmx_t b)
{
cmmx_t ao = a & (3*ONE_BYTES);
cmmx_t bo = b & (3*ONE_BYTES);
return 3*((a^ao)>>2) + ((b^bo)>>2) +
(((3*ao+bo+2*ONE_BYTES)>>2) & (3*ONE_BYTES));
}
static inline cmmx_t
p31avgb_s(cmmx_t a, cmmx_t b)
{
cmmx_t avg = ((a+b)>>1) & ~SIGN_BITS;
return pavgb_s(avg, a);
}
static inline unsigned long
psumbw(cmmx_t a)
{
cmmx_t t = (a & LOWBW_MASK) + ((a>>8) & LOWBW_MASK);
unsigned long ret =
(unsigned long)t + (unsigned long)(t >> (4*sizeof(cmmx_t)));
if (sizeof(cmmx_t) > 4)
ret += ret >> 16;
return ret & 0xffff;
}
static inline unsigned long
psumbw_s(cmmx_t a)
{
unsigned long ret =
(unsigned long)a + (unsigned long)(a >> (4*sizeof(cmmx_t)));
if (sizeof(cmmx_t) <= 4)
return (ret & 0xff) + ((ret>>8) & 0xff);
ret = (ret & 0xff00ff) + ((ret>>8) & 0xff00ff);
ret += ret >> 16;
return ret & 0xffff;
}
static inline unsigned long
psadbw(cmmx_t a, cmmx_t b)
{
return psumbw(pdiffub(a,b));
}
static inline unsigned long
psadbw_s(cmmx_t a, cmmx_t b)
{
return psumbw_s(pdiffub_s(a,b));
}
static inline cmmx_t
pcmpzb(cmmx_t a)
{
cmmx_t ret = (((a | SIGN_BITS) - ONE_BYTES) | a) & SIGN_BITS;
return ~(ret | (ret - (ret >> 7)));
}
static inline cmmx_t
pcmpeqb(cmmx_t a, cmmx_t b)
{
return pcmpzb(a ^ b);
}
#endif

View File

@ -75,6 +75,7 @@ extern vf_info_t vf_info_dsize;
extern vf_info_t vf_info_decimate;
extern vf_info_t vf_info_softpulldown;
extern vf_info_t vf_info_pullup;
extern vf_info_t vf_info_filmdint;
extern vf_info_t vf_info_framestep;
extern vf_info_t vf_info_tile;
extern vf_info_t vf_info_delogo;
@ -143,6 +144,7 @@ static vf_info_t* filter_list[]={
&vf_info_decimate,
&vf_info_softpulldown,
&vf_info_pullup,
&vf_info_filmdint,
&vf_info_framestep,
&vf_info_tile,
&vf_info_delogo,

1443
libmpcodecs/vf_filmdint.c Normal file

File diff suppressed because it is too large Load Diff