changeset 7369:b34b005ab4f8

drop-deinterlace (dint) filter by Andriy N. Gritsenko <andrej@lucky.net>
author arpi
date Tue, 10 Sep 2002 23:18:31 +0000
parents a894e99c1e51
children 8e07aeda7344
files libmpcodecs/Makefile libmpcodecs/vf.c libmpcodecs/vf_dint.c
diffstat 3 files changed, 198 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/libmpcodecs/Makefile	Tue Sep 10 22:18:32 2002 +0000
+++ b/libmpcodecs/Makefile	Tue Sep 10 23:18:31 2002 +0000
@@ -6,7 +6,7 @@
 
 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
 
--- a/libmpcodecs/vf.c	Tue Sep 10 22:18:32 2002 +0000
+++ b/libmpcodecs/vf.c	Tue Sep 10 23:18:31 2002 +0000
@@ -40,6 +40,7 @@
 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 @@
     &vf_info_yvu9,
     &vf_info_eq,
     &vf_info_halfpack,
+    &vf_info_dint,
     NULL
 };
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libmpcodecs/vf_dint.c	Tue Sep 10 23:18:31 2002 +0000
@@ -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
+};