• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • Examples
  • File List
  • Globals

libavfilter/libmpcodecs/vf_geq.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2006 Michael Niedermayer <michaelni@gmx.at>
00003  *
00004  * This file is part of MPlayer.
00005  *
00006  * MPlayer is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * MPlayer is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License along
00017  * with MPlayer; if not, write to the Free Software Foundation, Inc.,
00018  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00019  */
00020 
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023 #include <string.h>
00024 #include <math.h>
00025 #include <inttypes.h>
00026 
00027 #include "config.h"
00028 
00029 #include "mp_msg.h"
00030 #include "cpudetect.h"
00031 
00032 #include "img_format.h"
00033 #include "mp_image.h"
00034 #include "vf.h"
00035 
00036 #include "libavcodec/avcodec.h"
00037 #include "libavutil/eval.h"
00038 
00039 struct vf_priv_s {
00040     AVExpr * e[3];
00041     int framenum;
00042     mp_image_t *mpi;
00043 };
00044 
00045 static int config(struct vf_instance *vf,
00046         int width, int height, int d_width, int d_height,
00047         unsigned int flags, unsigned int outfmt){
00048     return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
00049 }
00050 
00051 static inline double getpix(struct vf_instance *vf, double x, double y, int plane){
00052     int xi, yi;
00053     mp_image_t *mpi= vf->priv->mpi;
00054     int stride= mpi->stride[plane];
00055     uint8_t *src=  mpi->planes[plane];
00056     xi=x= FFMIN(FFMAX(x, 0), (mpi->w >> (plane ? mpi->chroma_x_shift : 0))-1);
00057     yi=y= FFMIN(FFMAX(y, 0), (mpi->h >> (plane ? mpi->chroma_y_shift : 0))-1);
00058 
00059     x-=xi;
00060     y-=yi;
00061 
00062     return
00063      (1-y)*((1-x)*src[xi +  yi    * stride] + x*src[xi + 1 +  yi    * stride])
00064     +   y *((1-x)*src[xi + (yi+1) * stride] + x*src[xi + 1 + (yi+1) * stride]);
00065 }
00066 
00067 //FIXME cubic interpolate
00068 //FIXME keep the last few frames
00069 static double lum(void *vf, double x, double y){
00070     return getpix(vf, x, y, 0);
00071 }
00072 
00073 static double cb(void *vf, double x, double y){
00074     return getpix(vf, x, y, 1);
00075 }
00076 
00077 static double cr(void *vf, double x, double y){
00078     return getpix(vf, x, y, 2);
00079 }
00080 
00081 static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
00082     mp_image_t *dmpi;
00083     int x,y, plane;
00084 
00085     if(!(mpi->flags&MP_IMGFLAG_DIRECT)){
00086         // no DR, so get a new image! hope we'll get DR buffer:
00087         vf->dmpi=vf_get_image(vf->next,mpi->imgfmt, MP_IMGTYPE_TEMP,
00088                               MP_IMGFLAG_ACCEPT_STRIDE|MP_IMGFLAG_PREFER_ALIGNED_STRIDE,
00089                               mpi->w,mpi->h);
00090     }
00091 
00092     dmpi= vf->dmpi;
00093     vf->priv->mpi= mpi;
00094 
00095     vf_clone_mpi_attributes(dmpi, mpi);
00096 
00097     for(plane=0; plane<3; plane++){
00098         int w= mpi->w >> (plane ? mpi->chroma_x_shift : 0);
00099         int h= mpi->h >> (plane ? mpi->chroma_y_shift : 0);
00100         uint8_t *dst  = dmpi->planes[plane];
00101         int dst_stride= dmpi->stride[plane];
00102         double const_values[]={
00103             M_PI,
00104             M_E,
00105             0,
00106             0,
00107             w,
00108             h,
00109             vf->priv->framenum,
00110             w/(double)mpi->w,
00111             h/(double)mpi->h,
00112             0
00113         };
00114         if (!vf->priv->e[plane]) continue;
00115         for(y=0; y<h; y++){
00116             const_values[3]=y;
00117             for(x=0; x<w; x++){
00118                 const_values[2]=x;
00119                 dst[x + y * dst_stride] = av_expr_eval(vf->priv->e[plane],
00120                                                        const_values, vf);
00121             }
00122         }
00123     }
00124 
00125     vf->priv->framenum++;
00126 
00127     return vf_next_put_image(vf,dmpi, pts);
00128 }
00129 
00130 static void uninit(struct vf_instance *vf){
00131     av_free(vf->priv);
00132     vf->priv=NULL;
00133 }
00134 
00135 //===========================================================================//
00136 static int vf_open(vf_instance_t *vf, char *args){
00137     char eq[3][2000] = { { 0 }, { 0 }, { 0 } };
00138     int plane, res;
00139 
00140     vf->config=config;
00141     vf->put_image=put_image;
00142 //    vf->get_image=get_image;
00143     vf->uninit=uninit;
00144     vf->priv=av_malloc(sizeof(struct vf_priv_s));
00145     memset(vf->priv, 0, sizeof(struct vf_priv_s));
00146 
00147     if (args) sscanf(args, "%1999[^:]:%1999[^:]:%1999[^:]", eq[0], eq[1], eq[2]);
00148 
00149     if (!eq[1][0]) strncpy(eq[1], eq[0], sizeof(eq[0])-1);
00150     if (!eq[2][0]) strncpy(eq[2], eq[1], sizeof(eq[0])-1);
00151 
00152     for(plane=0; plane<3; plane++){
00153         static const char *const_names[]={
00154             "PI",
00155             "E",
00156             "X",
00157             "Y",
00158             "W",
00159             "H",
00160             "N",
00161             "SW",
00162             "SH",
00163             NULL
00164         };
00165         static const char *func2_names[]={
00166             "lum",
00167             "cb",
00168             "cr",
00169             "p",
00170             NULL
00171         };
00172         double (*func2[])(void *, double, double)={
00173             lum,
00174             cb,
00175             cr,
00176             plane==0 ? lum : (plane==1 ? cb : cr),
00177             NULL
00178         };
00179         res = av_expr_parse(&vf->priv->e[plane], eq[plane], const_names, NULL, NULL, func2_names, func2, 0, NULL);
00180 
00181         if (res < 0) {
00182             mp_msg(MSGT_VFILTER, MSGL_ERR, "geq: error loading equation `%s'\n", eq[plane]);
00183             return 0;
00184         }
00185     }
00186 
00187     return 1;
00188 }
00189 
00190 const vf_info_t vf_info_geq = {
00191     "generic equation filter",
00192     "geq",
00193     "Michael Niedermayer",
00194     "",
00195     vf_open,
00196     NULL
00197 };

Generated on Fri Feb 22 2013 07:24:30 for FFmpeg by  doxygen 1.7.1