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

libavfilter/libmpcodecs/vf_kerndeint.c

Go to the documentation of this file.
00001 /*
00002  * Original AVISynth Filter Copyright (C) 2003 Donald A. Graft
00003  *  Adapted to MPlayer by Tobias Diedrich
00004  *
00005  * This file is part of MPlayer.
00006  *
00007  * MPlayer is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2 of the License, or
00010  * (at your option) any later version.
00011  *
00012  * MPlayer is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License along
00018  * with MPlayer; if not, write to the Free Software Foundation, Inc.,
00019  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00020  */
00021 
00022 #include <stdio.h>
00023 #include <stdlib.h>
00024 #include <string.h>
00025 #include <inttypes.h>
00026 #include <math.h>
00027 
00028 #include "mp_msg.h"
00029 #include "img_format.h"
00030 #include "mp_image.h"
00031 #include "vf.h"
00032 #include "libvo/fastmemcpy.h"
00033 
00034 //===========================================================================//
00035 
00036 struct vf_priv_s {
00037     int    frame;
00038     int    map;
00039     int    order;
00040     int    thresh;
00041     int    sharp;
00042     int    twoway;
00043     int    do_deinterlace;
00044 };
00045 
00046 
00047 /***************************************************************************/
00048 
00049 
00050 static int config(struct vf_instance *vf,
00051     int width, int height, int d_width, int d_height,
00052     unsigned int flags, unsigned int outfmt){
00053 
00054     return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
00055 }
00056 
00057 
00058 static void uninit(struct vf_instance *vf)
00059 {
00060     free(vf->priv);
00061 }
00062 
00063 static inline int IsRGB(mp_image_t *mpi)
00064 {
00065     return mpi->imgfmt == IMGFMT_RGB;
00066 }
00067 
00068 static inline int IsYUY2(mp_image_t *mpi)
00069 {
00070     return mpi->imgfmt == IMGFMT_YUY2;
00071 }
00072 
00073 #define PLANAR_Y 0
00074 #define PLANAR_U 1
00075 #define PLANAR_V 2
00076 
00077 static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
00078     int cw= mpi->w >> mpi->chroma_x_shift;
00079     int ch= mpi->h >> mpi->chroma_y_shift;
00080     int W = mpi->w, H = mpi->h;
00081     const unsigned char *prvp, *prvpp, *prvpn, *prvpnn, *prvppp, *prvp4p, *prvp4n;
00082     const unsigned char *srcp_saved;
00083     const unsigned char *srcp, *srcpp, *srcpn, *srcpnn, *srcppp, *srcp3p, *srcp3n, *srcp4p, *srcp4n;
00084     unsigned char *dstp, *dstp_saved;
00085     int src_pitch;
00086     int psrc_pitch;
00087     int dst_pitch;
00088     int x, y, z;
00089     int n = vf->priv->frame++;
00090     int val, hi, lo, w, h;
00091     double valf;
00092     int plane;
00093     int threshold = vf->priv->thresh;
00094     int order = vf->priv->order;
00095     int map = vf->priv->map;
00096     int sharp = vf->priv->sharp;
00097     int twoway = vf->priv->twoway;
00098     mp_image_t *dmpi, *pmpi;
00099 
00100     if(!vf->priv->do_deinterlace)
00101         return vf_next_put_image(vf, mpi, pts);
00102 
00103     dmpi=vf_get_image(vf->next,mpi->imgfmt,
00104         MP_IMGTYPE_IP, MP_IMGFLAG_ACCEPT_STRIDE,
00105         mpi->w,mpi->h);
00106     pmpi=vf_get_image(vf->next,mpi->imgfmt,
00107         MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
00108         mpi->w,mpi->h);
00109     if(!dmpi) return 0;
00110 
00111     for (z=0; z<mpi->num_planes; z++) {
00112         if (z == 0) plane = PLANAR_Y;
00113         else if (z == 1) plane = PLANAR_U;
00114         else plane = PLANAR_V;
00115 
00116         h = plane == PLANAR_Y ? H : ch;
00117         w = plane == PLANAR_Y ? W : cw;
00118 
00119         srcp = srcp_saved = mpi->planes[z];
00120         src_pitch = mpi->stride[z];
00121         psrc_pitch = pmpi->stride[z];
00122         dstp = dstp_saved = dmpi->planes[z];
00123         dst_pitch = dmpi->stride[z];
00124         srcp = srcp_saved + (1-order) * src_pitch;
00125         dstp = dstp_saved + (1-order) * dst_pitch;
00126 
00127         for (y=0; y<h; y+=2) {
00128             fast_memcpy(dstp, srcp, w);
00129             srcp += 2*src_pitch;
00130             dstp += 2*dst_pitch;
00131         }
00132 
00133         // Copy through the lines that will be missed below.
00134         fast_memcpy(dstp_saved + order*dst_pitch, srcp_saved + (1-order)*src_pitch, w);
00135         fast_memcpy(dstp_saved + (2+order)*dst_pitch, srcp_saved + (3-order)*src_pitch, w);
00136         fast_memcpy(dstp_saved + (h-2+order)*dst_pitch, srcp_saved + (h-1-order)*src_pitch, w);
00137         fast_memcpy(dstp_saved + (h-4+order)*dst_pitch, srcp_saved + (h-3-order)*src_pitch, w);
00138         /* For the other field choose adaptively between using the previous field
00139            or the interpolant from the current field. */
00140 
00141         prvp = pmpi->planes[z] + 5*psrc_pitch - (1-order)*psrc_pitch;
00142         prvpp = prvp - psrc_pitch;
00143         prvppp = prvp - 2*psrc_pitch;
00144         prvp4p = prvp - 4*psrc_pitch;
00145         prvpn = prvp + psrc_pitch;
00146         prvpnn = prvp + 2*psrc_pitch;
00147         prvp4n = prvp + 4*psrc_pitch;
00148         srcp = srcp_saved + 5*src_pitch - (1-order)*src_pitch;
00149         srcpp = srcp - src_pitch;
00150         srcppp = srcp - 2*src_pitch;
00151         srcp3p = srcp - 3*src_pitch;
00152         srcp4p = srcp - 4*src_pitch;
00153         srcpn = srcp + src_pitch;
00154         srcpnn = srcp + 2*src_pitch;
00155         srcp3n = srcp + 3*src_pitch;
00156         srcp4n = srcp + 4*src_pitch;
00157         dstp =  dstp_saved  + 5*dst_pitch - (1-order)*dst_pitch;
00158         for (y = 5 - (1-order); y <= h - 5 - (1-order); y+=2)
00159         {
00160             for (x = 0; x < w; x++)
00161             {
00162                 if ((threshold == 0) || (n == 0) ||
00163                     (abs((int)prvp[x] - (int)srcp[x]) > threshold) ||
00164                     (abs((int)prvpp[x] - (int)srcpp[x]) > threshold) ||
00165                     (abs((int)prvpn[x] - (int)srcpn[x]) > threshold))
00166                 {
00167                     if (map == 1)
00168                     {
00169                         int g = x & ~3;
00170                         if (IsRGB(mpi) == 1)
00171                         {
00172                             dstp[g++] = 255;
00173                             dstp[g++] = 255;
00174                             dstp[g++] = 255;
00175                             dstp[g] = 255;
00176                             x = g;
00177                         }
00178                         else if (IsYUY2(mpi) == 1)
00179                         {
00180                             dstp[g++] = 235;
00181                             dstp[g++] = 128;
00182                             dstp[g++] = 235;
00183                             dstp[g] = 128;
00184                             x = g;
00185                         }
00186                         else
00187                         {
00188                             if (plane == PLANAR_Y) dstp[x] = 235;
00189                             else dstp[x] = 128;
00190                         }
00191                     }
00192                     else
00193                     {
00194                         if (IsRGB(mpi))
00195                         {
00196                             hi = 255;
00197                             lo = 0;
00198                         }
00199                         else if (IsYUY2(mpi))
00200                         {
00201                             hi = (x & 1) ? 240 : 235;
00202                             lo = 16;
00203                         }
00204                         else
00205                         {
00206                             hi = (plane == PLANAR_Y) ? 235 : 240;
00207                             lo = 16;
00208                         }
00209 
00210                         if (sharp == 1)
00211                         {
00212                             if (twoway == 1)
00213                                 valf = + 0.526*((int)srcpp[x] + (int)srcpn[x])
00214                                    + 0.170*((int)srcp[x] + (int)prvp[x])
00215                                    - 0.116*((int)srcppp[x] + (int)srcpnn[x] + (int)prvppp[x] + (int)prvpnn[x])
00216                                    - 0.026*((int)srcp3p[x] + (int)srcp3n[x])
00217                                    + 0.031*((int)srcp4p[x] + (int)srcp4n[x] + (int)prvp4p[x] + (int)prvp4n[x]);
00218                             else
00219                                 valf = + 0.526*((int)srcpp[x] + (int)srcpn[x])
00220                                    + 0.170*((int)prvp[x])
00221                                    - 0.116*((int)prvppp[x] + (int)prvpnn[x])
00222                                    - 0.026*((int)srcp3p[x] + (int)srcp3n[x])
00223                                    + 0.031*((int)prvp4p[x] + (int)prvp4p[x]);
00224                             if (valf > hi) valf = hi;
00225                             else if (valf < lo) valf = lo;
00226                             dstp[x] = (int) valf;
00227                         }
00228                         else
00229                         {
00230                             if (twoway == 1)
00231                                 val = (8*((int)srcpp[x] + (int)srcpn[x]) + 2*((int)srcp[x] + (int)prvp[x]) -
00232                                     (int)(srcppp[x]) - (int)(srcpnn[x]) -
00233                                     (int)(prvppp[x]) - (int)(prvpnn[x])) >> 4;
00234                             else
00235                                 val = (8*((int)srcpp[x] + (int)srcpn[x]) + 2*((int)prvp[x]) -
00236                                     (int)(prvppp[x]) - (int)(prvpnn[x])) >> 4;
00237                             if (val > hi) val = hi;
00238                             else if (val < lo) val = lo;
00239                             dstp[x] = (int) val;
00240                         }
00241                     }
00242                 }
00243                 else
00244                 {
00245                     dstp[x] = srcp[x];
00246                 }
00247             }
00248             prvp  += 2*psrc_pitch;
00249             prvpp  += 2*psrc_pitch;
00250             prvppp  += 2*psrc_pitch;
00251             prvpn  += 2*psrc_pitch;
00252             prvpnn  += 2*psrc_pitch;
00253             prvp4p  += 2*psrc_pitch;
00254             prvp4n  += 2*psrc_pitch;
00255             srcp  += 2*src_pitch;
00256             srcpp += 2*src_pitch;
00257             srcppp += 2*src_pitch;
00258             srcp3p += 2*src_pitch;
00259             srcp4p += 2*src_pitch;
00260             srcpn += 2*src_pitch;
00261             srcpnn += 2*src_pitch;
00262             srcp3n += 2*src_pitch;
00263             srcp4n += 2*src_pitch;
00264             dstp  += 2*dst_pitch;
00265         }
00266 
00267         srcp = mpi->planes[z];
00268         dstp = pmpi->planes[z];
00269         for (y=0; y<h; y++) {
00270             fast_memcpy(dstp, srcp, w);
00271             srcp += src_pitch;
00272             dstp += psrc_pitch;
00273         }
00274     }
00275 
00276     return vf_next_put_image(vf,dmpi, pts);
00277 }
00278 
00279 //===========================================================================//
00280 
00281 static int query_format(struct vf_instance *vf, unsigned int fmt){
00282         switch(fmt)
00283     {
00284     case IMGFMT_YV12:
00285     case IMGFMT_RGB:
00286     case IMGFMT_YUY2:
00287         return vf_next_query_format(vf, fmt);
00288     }
00289     return 0;
00290 }
00291 
00292 static int control(struct vf_instance *vf, int request, void* data){
00293     switch (request)
00294     {
00295     case VFCTRL_GET_DEINTERLACE:
00296         *(int*)data = vf->priv->do_deinterlace;
00297         return CONTROL_OK;
00298     case VFCTRL_SET_DEINTERLACE:
00299         vf->priv->do_deinterlace = *(int*)data;
00300         return CONTROL_OK;
00301     }
00302     return vf_next_control (vf, request, data);
00303 }
00304 
00305 static int vf_open(vf_instance_t *vf, char *args){
00306 
00307     vf->control=control;
00308     vf->config=config;
00309     vf->put_image=put_image;
00310         vf->query_format=query_format;
00311         vf->uninit=uninit;
00312     vf->priv=malloc(sizeof(struct vf_priv_s));
00313         memset(vf->priv, 0, sizeof(struct vf_priv_s));
00314 
00315     vf->priv->frame = 0;
00316 
00317     vf->priv->map = 0;
00318     vf->priv->order = 0;
00319     vf->priv->thresh = 10;
00320     vf->priv->sharp = 0;
00321     vf->priv->twoway = 0;
00322     vf->priv->do_deinterlace=1;
00323 
00324         if (args)
00325         {
00326             sscanf(args, "%d:%d:%d:%d:%d",
00327         &vf->priv->thresh, &vf->priv->map,
00328         &vf->priv->order, &vf->priv->sharp,
00329         &vf->priv->twoway);
00330         }
00331     if (vf->priv->order > 1) vf->priv->order = 1;
00332 
00333     return 1;
00334 }
00335 
00336 const vf_info_t vf_info_kerndeint = {
00337     "Kernel Deinterlacer",
00338     "kerndeint",
00339     "Donald Graft",
00340     "",
00341     vf_open,
00342     NULL
00343 };
00344 
00345 //===========================================================================//

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