changeset 6859:ed26b2d781e9

new filter to use libavcodec's deinterlacer patch by Joe Rabinoff <rabinoff@fas.harvard.edu> (TODO: DOCS, DR1)
author arpi
date Wed, 31 Jul 2002 19:50:42 +0000
parents 21186a5514b4
children e575f4ee82f1
files libmpcodecs/Makefile libmpcodecs/vf.c libmpcodecs/vf_lavcdeint.c
diffstat 3 files changed, 223 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/libmpcodecs/Makefile	Wed Jul 31 19:40:33 2002 +0000
+++ b/libmpcodecs/Makefile	Wed Jul 31 19:50:42 2002 +0000
@@ -6,7 +6,7 @@
 
 AUDIO_SRCS=dec_audio.c ad.c ad_a52.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_mp3.c ad_msadpcm.c ad_pcm.c ad_roqaudio.c ad_msgsm.c ad_faad.c ad_vorbis.c ad_libmad.c ad_real.c
 VIDEO_SRCS=dec_video.c vd.c vd_null.c vd_real.c vd_cinepak.c vd_qtrpza.c vd_ffmpeg.c vd_dshow.c vd_vfw.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_zlib.c vd_mpegpes.c vd_svq1.c vd_xvid.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
+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
 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	Wed Jul 31 19:40:33 2002 +0000
+++ b/libmpcodecs/vf.c	Wed Jul 31 19:50:42 2002 +0000
@@ -35,6 +35,7 @@
 extern vf_info_t vf_info_test;
 extern vf_info_t vf_info_noise;
 extern vf_info_t vf_info_yvu9;
+extern vf_info_t vf_info_lavcdeint;
 
 char** vo_plugin_args=(char**) NULL;
 
@@ -59,6 +60,7 @@
     &vf_info_palette,
 #ifdef USE_LIBAVCODEC
     &vf_info_lavc,
+    &vf_info_lavcdeint,
 #endif
     &vf_info_dvbscale,
     &vf_info_cropdetect,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libmpcodecs/vf_lavcdeint.c	Wed Jul 31 19:50:42 2002 +0000
@@ -0,0 +1,220 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include "../config.h"
+#include "../mp_msg.h"
+#include "../help_mp.h"
+
+#ifdef USE_LIBAVCODEC
+
+#include "img_format.h"
+#include "mp_image.h"
+#include "vf.h"
+
+//#include "../libvo/fastmemcpy.h"
+
+#ifdef USE_LIBAVCODEC_SO
+#include <libffmpeg/avcodec.h>
+#else
+#include "libavcodec/avcodec.h"
+#endif
+
+extern int avcodec_inited;
+
+struct vf_priv_s 
+{
+  AVPicture pic;
+  UINT8     *outbuf;
+  int       outbuf_size;
+  int       width, height;
+  int       pix_fmt;
+};
+
+#define lavc_venc_context (vf->priv->context)
+
+
+/* Support for avcodec's built-in deinterlacer.
+ * Based on vf_lavc.c
+ */
+
+//===========================================================================//
+
+
+/* Convert mplayer's IMGFMT_* to avcodec's PIX_FMT_* for the supported
+ * IMGFMT's, and return -1 if the deinterlacer doesn't support
+ * that format (-1 because 0 is a valid PIX_FMT).
+ */
+/* The deinterlacer supports planer 4:2:0, 4:2:2, and 4:4:4 YUV */
+static int
+imgfmt_to_pixfmt (int imgfmt)
+{
+  switch(imgfmt)
+    {
+      /* I hope I got all the supported formats */
+
+      /* 4:2:0 */
+    case IMGFMT_YV12:
+    case IMGFMT_I420:
+    case IMGFMT_IYUV:
+      return PIX_FMT_YUV420P;
+      break;
+
+      /* 4:2:2 */
+    case IMGFMT_UYVY:
+    case IMGFMT_UYNV:
+    case IMGFMT_Y422:
+    case IMGFMT_YUY2:
+    case IMGFMT_YUNV:
+    case IMGFMT_YVYU:
+    case IMGFMT_Y42T:
+    case IMGFMT_V422:
+    case IMGFMT_V655:
+      return PIX_FMT_YUV422P;
+      break;
+
+      /* Are there any _planar_ YUV 4:4:4 formats? */
+
+    default:
+      return -1;
+    }
+}
+
+
+static int 
+config (struct vf_instance_s* vf,
+        int width, int height, int d_width, int d_height,
+        unsigned int flags, unsigned int outfmt)
+{
+  struct vf_priv_s *priv = vf->priv;
+
+  priv->pix_fmt = imgfmt_to_pixfmt(outfmt);
+  if(priv->pix_fmt == -1)
+    return 0;
+  
+  /* The deinterlacer will fail if this is false */
+  if ((width & 1) != 0 || (height & 3) != 0)
+    return 0;
+
+  /* If we get here, the deinterlacer is guaranteed not to fail */
+
+  priv->width  = width;
+  priv->height = height;
+
+    
+  if(priv->outbuf) 
+    av_free(priv->outbuf);
+
+  priv->outbuf_size = 
+    avpicture_get_size(priv->pix_fmt, priv->width, priv->height);
+
+  priv->outbuf = av_malloc(priv->outbuf_size); 
+  avpicture_fill(&priv->pic, priv->outbuf, priv->pix_fmt, 
+		 priv->width, priv->height);
+  
+  return vf_next_config(vf,
+			width, height,
+			d_width, d_height,
+			flags, outfmt);
+}
+
+
+static void
+uninit (struct vf_instance_s *vf)
+{
+  if(vf->priv->outbuf)
+    av_free(vf->priv->outbuf);
+}
+
+
+static void 
+put_image (struct vf_instance_s* vf, mp_image_t *mpi)
+{
+  struct vf_priv_s *priv = vf->priv;
+  mp_image_t* dmpi;
+  AVPicture lavc_picture;
+  
+  lavc_picture.data[0]     = mpi->planes[0];
+  lavc_picture.data[1]     = mpi->planes[1];
+  lavc_picture.data[2]     = mpi->planes[2];
+  lavc_picture.linesize[0] = mpi->stride[0];
+  lavc_picture.linesize[1] = mpi->stride[1];
+  lavc_picture.linesize[2] = mpi->stride[2];
+  
+
+  dmpi = vf_get_image(vf->next, mpi->imgfmt,
+		      MP_IMGTYPE_EXPORT, 0,
+		      mpi->w, mpi->h);
+
+  
+  if (avpicture_deinterlace(&priv->pic, &lavc_picture, 
+			    priv->pix_fmt, priv->width, priv->height) < 0)
+    {
+      /* This should not happen -- see config() */
+      return;
+    }
+
+  
+  dmpi->planes[0] = priv->pic.data[0];
+  dmpi->planes[1] = priv->pic.data[1];
+  dmpi->planes[2] = priv->pic.data[2];
+  dmpi->stride[0] = priv->pic.linesize[0];
+  dmpi->stride[1] = priv->pic.linesize[1];
+  dmpi->stride[2] = priv->pic.linesize[2];
+  
+  vf_next_put_image(vf, dmpi);
+}
+
+
+static int 
+query_format (struct vf_instance_s* vf, unsigned int fmt)
+{
+  if(imgfmt_to_pixfmt(fmt) == -1)
+    return 0;
+
+  return vf_next_query_format(vf,fmt);
+}
+
+
+static int 
+open (vf_instance_t *vf, char* args)
+{
+  /* We don't have any args */
+  (void) args;
+
+  vf->config       = config;
+  vf->put_image    = put_image;
+  vf->query_format = query_format;
+  vf->uninit       = uninit;
+  vf->priv         = malloc(sizeof(struct vf_priv_s));
+  memset(vf->priv,0,sizeof(struct vf_priv_s));
+
+  /* This may not technically be necessary just for a deinterlace,
+   * but it seems like a good idea.
+   */
+  if(!avcodec_inited)
+    {
+      avcodec_init();
+      avcodec_register_all();
+      avcodec_inited=1;
+    }
+
+  return 1;
+}
+
+
+vf_info_t vf_info_lavcdeint = {
+    "libavcodec's deinterlacing filter",
+    "lavcdeint",
+    "Joe Rabinoff",
+    "libavcodec's internal deinterlacer, in case you don't like "
+      "the builtin ones (invoked with -pp or -npp)",
+    open
+};
+
+
+//===========================================================================//
+
+#endif /* USE_LIBAVCODEC */
+