summaryrefslogtreecommitdiffstats
path: root/libmpcodecs
diff options
context:
space:
mode:
authormichael <michael@b3059339-0415-0410-9bf9-f77b7e298cf2>2006-10-16 15:47:32 +0000
committermichael <michael@b3059339-0415-0410-9bf9-f77b7e298cf2>2006-10-16 15:47:32 +0000
commitbc040ace6f8573ac91596a43ce9d23e62bda5f32 (patch)
treedf72740fea5a9210e4846a010088250eee4c2fc1 /libmpcodecs
parent7fd5e0846612b31d80024f315a204fb31fe7df1e (diff)
downloadmpv-bc040ace6f8573ac91596a43ce9d23e62bda5f32.tar.bz2
mpv-bc040ace6f8573ac91596a43ce9d23e62bda5f32.tar.xz
generic equation filter
example: -vf 'geq=(p(X\,Y)+p(mod(Y*2-X*2\,W)\,mod(Y*2+X*2+sin((X-Y)/10/SW+N)*SW*20\,H)))/2' git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@20272 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libmpcodecs')
-rw-r--r--libmpcodecs/Makefile1
-rw-r--r--libmpcodecs/vf.c4
-rw-r--r--libmpcodecs/vf_geq.c217
3 files changed, 222 insertions, 0 deletions
diff --git a/libmpcodecs/Makefile b/libmpcodecs/Makefile
index 6ad6473481..4fd4e5d0e6 100644
--- a/libmpcodecs/Makefile
+++ b/libmpcodecs/Makefile
@@ -188,6 +188,7 @@ VFILTER_LAVC_SRCS += vf_lavc.c \
VFILTER_LAVC_DSPUTIL_SRCS += vf_uspp.c \
vf_fspp.c \
vf_qp.c \
+ vf_geq.c \
vf_spp.c \
vf_mcdeint.c \
diff --git a/libmpcodecs/vf.c b/libmpcodecs/vf.c
index 818aa07ad4..917ce91223 100644
--- a/libmpcodecs/vf.c
+++ b/libmpcodecs/vf.c
@@ -98,6 +98,7 @@ extern vf_info_t vf_info_ass;
extern vf_info_t vf_info_mcdeint;
extern vf_info_t vf_info_yadif;
extern vf_info_t vf_info_blackframe;
+extern vf_info_t vf_info_geq;
// list of available filters:
static vf_info_t* filter_list[]={
@@ -195,6 +196,9 @@ static vf_info_t* filter_list[]={
#endif
&vf_info_yadif,
&vf_info_blackframe,
+#ifdef USE_LIBAVCODEC_DSPUTIL
+ &vf_info_geq,
+#endif
NULL
};
diff --git a/libmpcodecs/vf_geq.c b/libmpcodecs/vf_geq.c
new file mode 100644
index 0000000000..b7ad8dd9a9
--- /dev/null
+++ b/libmpcodecs/vf_geq.c
@@ -0,0 +1,217 @@
+/*
+ Copyright (C) 2006 Michael Niedermayer <michaelni@gmx.at>
+
+ 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <inttypes.h>
+
+#include "config.h"
+
+#include "mp_msg.h"
+#include "cpudetect.h"
+
+#if 1
+double ff_eval(char *s, double *const_value, const char **const_name,
+ double (**func1)(void *, double), const char **func1_name,
+ double (**func2)(void *, double, double), char **func2_name,
+ void *opaque);
+#endif
+
+// Needed to bring in lrintf.
+#define HAVE_AV_CONFIG_H
+
+#include "libavcodec/avcodec.h"
+#include "libavcodec/dsputil.h"
+#include "libavutil/common.h"
+
+/* FIXME: common.h defines printf away when HAVE_AV_CONFIG
+ * is defined, but mp_image.h needs printf.
+ */
+#undef printf
+
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+
+#include "img_format.h"
+#include "mp_image.h"
+#include "vf.h"
+#include "libvo/fastmemcpy.h"
+
+
+struct vf_priv_s {
+ char eq[3][200];
+ int framenum;
+ mp_image_t *mpi;
+};
+
+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 i;
+
+ return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
+}
+
+static void get_image(struct vf_instance_s* vf, mp_image_t *mpi){
+ if(mpi->flags&MP_IMGFLAG_PRESERVE) return; // don't change
+ // ok, we can do pp in-place (or pp disabled):
+ vf->dmpi=vf_get_image(vf->next,mpi->imgfmt,
+ mpi->type, mpi->flags, mpi->w, mpi->h);
+ mpi->planes[0]=vf->dmpi->planes[0];
+ mpi->stride[0]=vf->dmpi->stride[0];
+ mpi->width=vf->dmpi->width;
+ if(mpi->flags&MP_IMGFLAG_PLANAR){
+ mpi->planes[1]=vf->dmpi->planes[1];
+ mpi->planes[2]=vf->dmpi->planes[2];
+ mpi->stride[1]=vf->dmpi->stride[1];
+ mpi->stride[2]=vf->dmpi->stride[2];
+ }
+ mpi->flags|=MP_IMGFLAG_DIRECT;
+}
+
+//FIXME spatial interpolate
+//FIXME keep the last few frames
+static double lum(struct vf_instance_s* vf, double x, double y){
+ mp_image_t *mpi= vf->priv->mpi;
+ x= clip(x, 0, vf->priv->mpi->w-1);
+ y= clip(y, 0, vf->priv->mpi->h-1);
+ return mpi->planes[0][(int)x + (int)y * mpi->stride[0]];
+}
+
+static double cb(struct vf_instance_s* vf, double x, double y){
+ mp_image_t *mpi= vf->priv->mpi;
+ x= clip(x, 0, (vf->priv->mpi->w >> mpi->chroma_x_shift)-1);
+ y= clip(y, 0, (vf->priv->mpi->h >> mpi->chroma_y_shift)-1);
+ return mpi->planes[1][(int)x + (int)y * mpi->stride[1]];
+}
+
+static double cr(struct vf_instance_s* vf, double x, double y){
+ mp_image_t *mpi= vf->priv->mpi;
+ x= clip(x, 0, (vf->priv->mpi->w >> mpi->chroma_x_shift)-1);
+ y= clip(y, 0, (vf->priv->mpi->h >> mpi->chroma_y_shift)-1);
+ return mpi->planes[2][(int)x + (int)y * mpi->stride[2]];
+}
+
+static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){
+ mp_image_t *dmpi;
+ int x,y, plane;
+ static const char *const_names[]={
+ "PI",
+ "E",
+ "X",
+ "Y",
+ "W",
+ "H",
+ "N",
+ "SW",
+ "SH",
+ NULL
+ };
+ static const char *func2_names[]={
+ "lum",
+ "cb",
+ "cr",
+ "p",
+ NULL
+ };
+
+ if(!(mpi->flags&MP_IMGFLAG_DIRECT)){
+ // no DR, so get a new image! hope we'll get DR buffer:
+ vf->dmpi=vf_get_image(vf->next,mpi->imgfmt,
+ MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE|MP_IMGFLAG_PREFER_ALIGNED_STRIDE,
+ mpi->w,mpi->h);
+ }
+
+ dmpi= vf->dmpi;
+ vf->priv->mpi= mpi;
+
+ vf_clone_mpi_attributes(dmpi, mpi);
+
+ for(plane=0; plane<3; plane++){
+ int w= mpi->w >> (plane ? mpi->chroma_x_shift : 0);
+ int h= mpi->h >> (plane ? mpi->chroma_y_shift : 0);
+ uint8_t *dst = dmpi->planes[plane];
+ int dst_stride= dmpi->stride[plane];
+ double (*func2[])(void *, double, double)={
+ lum,
+ cb,
+ cr,
+ plane==0 ? lum : (plane==1 ? cb : cr),
+ NULL
+ };
+ double const_values[]={
+ M_PI,
+ M_E,
+ 0,
+ 0,
+ w,
+ h,
+ vf->priv->framenum,
+ w/(double)mpi->w,
+ h/(double)mpi->h,
+ 0
+ };
+ for(y=0; y<h; y++){
+ const_values[3]=y;
+ for(x=0; x<w; x++){
+ const_values[2]=x;
+ dst[x+y* dst_stride]= ff_eval(vf->priv->eq[plane], const_values, const_names, NULL, NULL, func2, func2_names, vf);
+ }
+ }
+ }
+
+ vf->priv->framenum++;
+
+ return vf_next_put_image(vf,dmpi, pts);
+}
+
+static void uninit(struct vf_instance_s* vf){
+ if(!vf->priv) return;
+
+ av_free(vf->priv);
+ vf->priv=NULL;
+}
+
+//===========================================================================//
+static int open(vf_instance_t *vf, char* args){
+ vf->config=config;
+ vf->put_image=put_image;
+// vf->get_image=get_image;
+ vf->uninit=uninit;
+ vf->priv=av_malloc(sizeof(struct vf_priv_s));
+ memset(vf->priv, 0, sizeof(struct vf_priv_s));
+
+ if (args) sscanf(args, "%199s:%199s:%199s", vf->priv->eq[0], vf->priv->eq[1], vf->priv->eq[2]);
+
+ if(!vf->priv->eq[1][0]) strncpy(vf->priv->eq[1], vf->priv->eq[0], 199);
+ if(!vf->priv->eq[2][0]) strncpy(vf->priv->eq[2], vf->priv->eq[1], 199);
+
+ return 1;
+}
+
+vf_info_t vf_info_geq = {
+ "generic equation filter",
+ "geq",
+ "Michael Niedermayer",
+ "",
+ open,
+ NULL
+};