mirror of
https://github.com/mpv-player/mpv
synced 2025-02-20 23:07:02 +00:00
drop-deinterlace (dint) filter by Andriy N. Gritsenko <andrej@lucky.net>
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@7370 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
c7944423a3
commit
7f6484b29e
@ -6,7 +6,7 @@ LIBNAME2 = libmpencoders.a
|
||||
|
||||
AUDIO_SRCS=dec_audio.c ad.c ad_liba52.c ad_acm.c ad_alaw.c ad_dk3adpcm.c ad_dshow.c ad_dvdpcm.c ad_ffmpeg.c ad_hwac3.c ad_imaadpcm.c ad_mp3lib.c ad_msadpcm.c ad_pcm.c ad_roqaudio.c ad_msgsm.c ad_faad.c ad_libvorbis.c ad_libmad.c ad_realaud.c ad_libdv.c
|
||||
VIDEO_SRCS=dec_video.c vd.c vd_null.c vd_realvid.c vd_cinepak.c vd_qtrpza.c vd_ffmpeg.c vd_dshow.c vd_vfw.c vd_vfwex.c vd_odivx.c vd_divx4.c vd_raw.c vd_xanim.c vd_msvidc.c vd_fli.c vd_qtrle.c vd_qtsmc.c vd_roqvideo.c vd_cyuv.c vd_nuv.c vd_libmpeg2.c vd_msrle.c vd_huffyuv.c vd_mpegpes.c vd_svq1.c vd_xvid.c vd_libdv.c vd_lcl.c vd_mtga.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_halfpack.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_halfpack.c vf_dint.c
|
||||
ENCODER_SRCS=ve.c ve_divx4.c ve_lavc.c ve_vfw.c ve_rawrgb.c ve_libdv.c
|
||||
NATIVE_SRCS=native/RTjpegN.c native/cinepak.c native/cyuv.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/svq1.c
|
||||
|
||||
|
@ -40,6 +40,7 @@ extern vf_info_t vf_info_yvu9;
|
||||
extern vf_info_t vf_info_lavcdeint;
|
||||
extern vf_info_t vf_info_eq;
|
||||
extern vf_info_t vf_info_halfpack;
|
||||
extern vf_info_t vf_info_dint;
|
||||
|
||||
char** vo_plugin_args=(char**) NULL;
|
||||
|
||||
@ -73,6 +74,7 @@ static vf_info_t* filter_list[]={
|
||||
&vf_info_yvu9,
|
||||
&vf_info_eq,
|
||||
&vf_info_halfpack,
|
||||
&vf_info_dint,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
195
libmpcodecs/vf_dint.c
Normal file
195
libmpcodecs/vf_dint.c
Normal file
@ -0,0 +1,195 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "../config.h"
|
||||
#include "../mp_msg.h"
|
||||
#include "../libvo/fastmemcpy.h"
|
||||
|
||||
#include "mp_image.h"
|
||||
#include "img_format.h"
|
||||
#include "vf.h"
|
||||
|
||||
struct vf_priv_s {
|
||||
float sense; // first parameter
|
||||
float level; // second parameter
|
||||
unsigned int imgfmt;
|
||||
char diff;
|
||||
uint32_t max;
|
||||
// int dfr;
|
||||
// int rdfr;
|
||||
int was_dint;
|
||||
mp_image_t *pmpi; // previous mpi
|
||||
};
|
||||
|
||||
#define MAXROWSIZE 1200
|
||||
|
||||
static int config (struct vf_instance_s* vf,
|
||||
int width, int height, int d_width, int d_height,
|
||||
unsigned int flags, unsigned int outfmt)
|
||||
{
|
||||
int rowsize;
|
||||
|
||||
vf->priv->pmpi = vf_get_image (vf->next, outfmt, MP_IMGTYPE_TEMP,
|
||||
0, width, height);
|
||||
if (!(vf->priv->pmpi->flags & MP_IMGFLAG_PLANAR) &&
|
||||
outfmt != IMGFMT_RGB32 && outfmt != IMGFMT_BGR32 &&
|
||||
outfmt != IMGFMT_RGB24 && outfmt != IMGFMT_BGR24 &&
|
||||
outfmt != IMGFMT_RGB16 && outfmt != IMGFMT_BGR16)
|
||||
{
|
||||
mp_msg (MSGT_VFILTER, MSGL_WARN, "Drop-interlaced filter doesn't support this outfmt :(\n");
|
||||
return 0;
|
||||
}
|
||||
vf->priv->imgfmt = outfmt;
|
||||
// recalculate internal values
|
||||
rowsize = vf->priv->pmpi->width;
|
||||
if (rowsize > MAXROWSIZE) rowsize = MAXROWSIZE;
|
||||
vf->priv->max = vf->priv->level * vf->priv->pmpi->height * rowsize / 2;
|
||||
if (vf->priv->pmpi->flags & MP_IMGFLAG_PLANAR) // planar YUV
|
||||
vf->priv->diff = vf->priv->sense * 256;
|
||||
else
|
||||
vf->priv->diff = vf->priv->sense * (1 << (vf->priv->pmpi->bpp/3));
|
||||
if (vf->priv->diff < 0) vf->priv->diff = 0;
|
||||
if (!(vf->priv->pmpi->flags & MP_IMGFLAG_PLANAR) &&
|
||||
vf->priv->pmpi->bpp < 24 && vf->priv->diff > 31)
|
||||
vf->priv->diff = 31;
|
||||
mp_msg (MSGT_VFILTER, MSGL_INFO, "Drop-interlaced: %dx%d diff %d / level %u\n",
|
||||
vf->priv->pmpi->width, vf->priv->pmpi->height,
|
||||
(int)vf->priv->diff, (unsigned int)vf->priv->max);
|
||||
// vf->priv->rdfr = vf->priv->dfr = 0;
|
||||
vf->priv->was_dint = 0;
|
||||
return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
|
||||
}
|
||||
|
||||
static int put_image (struct vf_instance_s* vf, mp_image_t *mpi)
|
||||
{
|
||||
char rrow0[MAXROWSIZE];
|
||||
char rrow1[MAXROWSIZE];
|
||||
char rrow2[MAXROWSIZE];
|
||||
char *row0 = rrow0, *row1 = rrow1, *row2 = rrow2/*, *row3 = rrow3*/;
|
||||
int rowsize = mpi->width;
|
||||
uint32_t nok = 0, max = vf->priv->max;
|
||||
int diff = vf->priv->diff;
|
||||
int i, j;
|
||||
register int n1, n2;
|
||||
unsigned char *cur0, *prv0;
|
||||
register unsigned char *cur, *prv;
|
||||
|
||||
// check if nothing to do
|
||||
if (mpi->imgfmt == vf->priv->imgfmt)
|
||||
{
|
||||
cur0 = mpi->planes[0] + mpi->stride[0];
|
||||
prv0 = mpi->planes[0];
|
||||
for (j = 1; j < mpi->height && nok <= max; j++)
|
||||
{
|
||||
cur = cur0;
|
||||
prv = prv0;
|
||||
// analyse row (row0)
|
||||
if (mpi->flags & MP_IMGFLAG_PLANAR) // planar YUV - check luminance
|
||||
for (i = 0; i < rowsize; i++)
|
||||
{
|
||||
if (cur[0] - prv[0] > diff)
|
||||
row0[i] = 1;
|
||||
else if (cur[0] - prv[0] < -diff)
|
||||
row0[i] = -1;
|
||||
else
|
||||
row0[i] = 0;
|
||||
cur++;
|
||||
prv++;
|
||||
// check if row0 is 1 but row1 is 0, and row2 is 1 or row2 is 0
|
||||
// but row3 is 1 so it's interlaced ptr (nok++)
|
||||
if (j > 2 && row0[i] > 0 && (row1[i] < 0 || (!row1[i] && row2[i] < 0)) &&
|
||||
(++nok) > max)
|
||||
break;
|
||||
}
|
||||
else if (mpi->bpp < 24) // RGB/BGR 16 - check all colors
|
||||
for (i = 0; i < rowsize; i++)
|
||||
{
|
||||
n1 = cur[0] + (cur[1]<<8);
|
||||
n2 = prv[0] + (prv[1]<<8);
|
||||
if ((n1&0x1f) - (n2&0x1f) > diff ||
|
||||
((n1>>5)&0x3f) - ((n2>>5)&0x3f) > diff ||
|
||||
((n1>>11)&0x1f) - ((n2>>11)&0x1f) > diff)
|
||||
row0[i] = 1;
|
||||
else if ((n1&0x1f) - (n2&0x1f) < -diff ||
|
||||
((n1>>5)&0x3f) - ((n2>>5)&0x3f) < -diff ||
|
||||
((n1>>11)&0x1f) - ((n2>>11)&0x1f) < -diff)
|
||||
row0[i] = -1;
|
||||
else
|
||||
row0[i] = 0;
|
||||
cur += 2;
|
||||
prv += 2;
|
||||
// check if row0 is 1 but row1 is 0, and row2 is 1 or row2 is 0
|
||||
// but row3 is 1 so it's interlaced ptr (nok++)
|
||||
if (j > 2 && row0[i] > 0 && (row1[i] < 0 || (!row1[i] && row2[i] < 0)) &&
|
||||
(++nok) > max)
|
||||
break;
|
||||
}
|
||||
else // RGB/BGR 24/32
|
||||
for (i = 0; i < rowsize; i++)
|
||||
{
|
||||
if (cur[0] - prv[0] > diff ||
|
||||
cur[1] - prv[1] > diff ||
|
||||
cur[2] - prv[2] > diff)
|
||||
row0[i] = 1;
|
||||
else if (prv[0] - cur[0] > diff ||
|
||||
prv[1] - cur[1] > diff ||
|
||||
prv[2] - cur[2] > diff)
|
||||
row0[i] = -1;
|
||||
else
|
||||
row0[i] = 0;
|
||||
cur += mpi->bpp/8;
|
||||
prv += mpi->bpp/8;
|
||||
// check if row0 is 1 but row1 is 0, and row2 is 1 or row2 is 0
|
||||
// but row3 is 1 so it's interlaced ptr (nok++)
|
||||
if (j > 2 && row0[i] > 0 && (row1[i] < 0 || (!row1[i] && row2[i] < 0)) &&
|
||||
(++nok) > max)
|
||||
break;
|
||||
}
|
||||
cur0 += mpi->stride[0];
|
||||
prv0 += mpi->stride[0];
|
||||
// rotate rows
|
||||
cur = row2;
|
||||
row2 = row1;
|
||||
row1 = row0;
|
||||
row0 = cur;
|
||||
}
|
||||
}
|
||||
// check if number of interlaced is above of max
|
||||
if (nok > max)
|
||||
{
|
||||
// vf->priv->dfr++;
|
||||
if (vf->priv->was_dint < 1) // can skip at most one frame!
|
||||
{
|
||||
vf->priv->was_dint++;
|
||||
// vf->priv->rdfr++;
|
||||
// mp_msg (MSGT_VFILTER, MSGL_INFO, "DI:%d/%d ", vf->priv->rdfr, vf->priv->dfr);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
vf->priv->was_dint = 0;
|
||||
// mp_msg (MSGT_VFILTER, MSGL_INFO, "DI:%d/%d ", vf->priv->rdfr, vf->priv->dfr);
|
||||
return vf_next_put_image (vf, mpi);
|
||||
}
|
||||
|
||||
static int open (vf_instance_t *vf, char* args){
|
||||
vf->config = config;
|
||||
vf->put_image = put_image;
|
||||
// vf->default_reqs=VFCAP_ACCEPT_STRIDE;
|
||||
vf->priv = malloc (sizeof(struct vf_priv_s));
|
||||
vf->priv->sense = 0.01;
|
||||
vf->priv->level = 0.15;
|
||||
vf->priv->pmpi = NULL;
|
||||
if (args)
|
||||
sscanf (args, "%f:%f", &vf->priv->sense, &vf->priv->level);
|
||||
return 1;
|
||||
}
|
||||
|
||||
vf_info_t vf_info_dint = {
|
||||
"drop interlaced frames",
|
||||
"dint",
|
||||
"A.G.",
|
||||
"",
|
||||
open
|
||||
};
|
Loading…
Reference in New Issue
Block a user