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

libavfilter/libmpcodecs/vf_dint.c

Go to the documentation of this file.
00001 /*
00002  * This file is part of MPlayer.
00003  *
00004  * MPlayer is free software; you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License as published by
00006  * the Free Software Foundation; either version 2 of the License, or
00007  * (at your option) any later version.
00008  *
00009  * MPlayer is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License along
00015  * with MPlayer; if not, write to the Free Software Foundation, Inc.,
00016  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00017  */
00018 
00019 #include <stdio.h>
00020 #include <stdlib.h>
00021 #include <string.h>
00022 #include <inttypes.h>
00023 
00024 #include "config.h"
00025 #include "mp_msg.h"
00026 
00027 #include "mp_image.h"
00028 #include "img_format.h"
00029 #include "vf.h"
00030 
00031 struct vf_priv_s {
00032   float sense; // first parameter
00033   float level; // second parameter
00034   unsigned int imgfmt;
00035   int diff;
00036   uint32_t max;
00037 //  int dfr;
00038 //  int rdfr;
00039   int was_dint;
00040   mp_image_t *pmpi; // previous mpi
00041 };
00042 
00043 #define MAXROWSIZE 1200
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 {
00049     int rowsize;
00050 
00051     vf->priv->pmpi = vf_get_image (vf->next, outfmt, MP_IMGTYPE_TEMP,
00052                                    0, width, height);
00053     if (!(vf->priv->pmpi->flags & MP_IMGFLAG_PLANAR) &&
00054         outfmt != IMGFMT_RGB32 && outfmt != IMGFMT_BGR32 &&
00055         outfmt != IMGFMT_RGB24 && outfmt != IMGFMT_BGR24 &&
00056         outfmt != IMGFMT_RGB16 && outfmt != IMGFMT_BGR16)
00057     {
00058       mp_msg (MSGT_VFILTER, MSGL_WARN, "Drop-interlaced filter doesn't support this outfmt :(\n");
00059       return 0;
00060     }
00061     vf->priv->imgfmt = outfmt;
00062     // recalculate internal values
00063     rowsize = vf->priv->pmpi->width;
00064     if (rowsize > MAXROWSIZE) rowsize = MAXROWSIZE;
00065     vf->priv->max = vf->priv->level * vf->priv->pmpi->height * rowsize / 2;
00066     if (vf->priv->pmpi->flags & MP_IMGFLAG_PLANAR) // planar YUV
00067       vf->priv->diff = vf->priv->sense * 256;
00068     else
00069       vf->priv->diff = vf->priv->sense * (1 << (vf->priv->pmpi->bpp/3));
00070     if (vf->priv->diff < 0) vf->priv->diff = 0;
00071     if (!(vf->priv->pmpi->flags & MP_IMGFLAG_PLANAR) &&
00072         vf->priv->pmpi->bpp < 24 && vf->priv->diff > 31)
00073       vf->priv->diff = 31;
00074     mp_msg (MSGT_VFILTER, MSGL_INFO, "Drop-interlaced: %dx%d diff %d / level %u\n",
00075            vf->priv->pmpi->width, vf->priv->pmpi->height,
00076            vf->priv->diff, (unsigned int)vf->priv->max);
00077 //    vf->priv->rdfr = vf->priv->dfr = 0;
00078     vf->priv->was_dint = 0;
00079     return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
00080 }
00081 
00082 static int put_image (struct vf_instance *vf, mp_image_t *mpi, double pts)
00083 {
00084     int8_t rrow0[MAXROWSIZE];
00085     int8_t rrow1[MAXROWSIZE];
00086     int8_t rrow2[MAXROWSIZE];
00087     int8_t *row0 = rrow0, *row1 = rrow1, *row2 = rrow2/*, *row3 = rrow3*/;
00088     int rowsize = mpi->width;
00089     uint32_t nok = 0, max = vf->priv->max;
00090     int diff = vf->priv->diff;
00091     int i, j;
00092     register int n1, n2;
00093     unsigned char *cur0, *prv0;
00094     register unsigned char *cur, *prv;
00095 
00096     if (rowsize > MAXROWSIZE) rowsize = MAXROWSIZE;
00097     // check if nothing to do
00098     if (mpi->imgfmt == vf->priv->imgfmt)
00099     {
00100       cur0 = mpi->planes[0] + mpi->stride[0];
00101       prv0 = mpi->planes[0];
00102       for (j = 1; j < mpi->height && nok <= max; j++)
00103       {
00104         cur = cur0;
00105         prv = prv0;
00106         // analyse row (row0)
00107         if (mpi->flags & MP_IMGFLAG_PLANAR) // planar YUV - check luminance
00108           for (i = 0; i < rowsize; i++)
00109           {
00110             if (cur[0] - prv[0] > diff)
00111               row0[i] = 1;
00112             else if (cur[0] - prv[0] < -diff)
00113               row0[i] = -1;
00114             else
00115               row0[i] = 0;
00116             cur++;
00117             prv++;
00118             // check if row0 is 1 but row1 is 0, and row2 is 1 or row2 is 0
00119             // but row3 is 1 so it's interlaced ptr (nok++)
00120             if (j > 2 && row0[i] > 0 && (row1[i] < 0 || (!row1[i] && row2[i] < 0)) &&
00121                 (++nok) > max)
00122               break;
00123           }
00124         else if (mpi->bpp < 24) // RGB/BGR 16 - check all colors
00125           for (i = 0; i < rowsize; i++)
00126           {
00127             n1 = cur[0] + (cur[1]<<8);
00128             n2 = prv[0] + (prv[1]<<8);
00129             if ((n1&0x1f) - (n2&0x1f) > diff ||
00130                 ((n1>>5)&0x3f) - ((n2>>5)&0x3f) > diff ||
00131                 ((n1>>11)&0x1f) - ((n2>>11)&0x1f) > diff)
00132               row0[i] = 1;
00133             else if ((n1&0x1f) - (n2&0x1f) < -diff ||
00134                      ((n1>>5)&0x3f) - ((n2>>5)&0x3f) < -diff ||
00135                      ((n1>>11)&0x1f) - ((n2>>11)&0x1f) < -diff)
00136               row0[i] = -1;
00137             else
00138               row0[i] = 0;
00139             cur += 2;
00140             prv += 2;
00141             // check if row0 is 1 but row1 is 0, and row2 is 1 or row2 is 0
00142             // but row3 is 1 so it's interlaced ptr (nok++)
00143             if (j > 2 && row0[i] > 0 && (row1[i] < 0 || (!row1[i] && row2[i] < 0)) &&
00144                 (++nok) > max)
00145               break;
00146           }
00147         else // RGB/BGR 24/32
00148           for (i = 0; i < rowsize; i++)
00149           {
00150             if (cur[0] - prv[0] > diff ||
00151                 cur[1] - prv[1] > diff ||
00152                 cur[2] - prv[2] > diff)
00153               row0[i] = 1;
00154             else if (prv[0] - cur[0] > diff ||
00155                      prv[1] - cur[1] > diff ||
00156                      prv[2] - cur[2] > diff)
00157               row0[i] = -1;
00158             else
00159               row0[i] = 0;
00160             cur += mpi->bpp/8;
00161             prv += mpi->bpp/8;
00162             // check if row0 is 1 but row1 is 0, and row2 is 1 or row2 is 0
00163             // but row3 is 1 so it's interlaced ptr (nok++)
00164             if (j > 2 && row0[i] > 0 && (row1[i] < 0 || (!row1[i] && row2[i] < 0)) &&
00165                 (++nok) > max)
00166               break;
00167           }
00168         cur0 += mpi->stride[0];
00169         prv0 += mpi->stride[0];
00170         // rotate rows
00171         cur = row2;
00172         row2 = row1;
00173         row1 = row0;
00174         row0 = cur;
00175       }
00176     }
00177     // check if number of interlaced is above of max
00178     if (nok > max)
00179     {
00180 //    vf->priv->dfr++;
00181       if (vf->priv->was_dint < 1) // can skip at most one frame!
00182       {
00183         vf->priv->was_dint++;
00184 //      vf->priv->rdfr++;
00185 //      mp_msg (MSGT_VFILTER, MSGL_INFO, "DI:%d/%d ", vf->priv->rdfr, vf->priv->dfr);
00186         return 0;
00187       }
00188     }
00189     vf->priv->was_dint = 0;
00190 //    mp_msg (MSGT_VFILTER, MSGL_INFO, "DI:%d/%d ", vf->priv->rdfr, vf->priv->dfr);
00191     return vf_next_put_image (vf, mpi, pts);
00192 }
00193 
00194 static int vf_open(vf_instance_t *vf, char *args){
00195     vf->config = config;
00196     vf->put_image = put_image;
00197 //  vf->default_reqs=VFCAP_ACCEPT_STRIDE;
00198     vf->priv = malloc (sizeof(struct vf_priv_s));
00199     vf->priv->sense = 0.1;
00200     vf->priv->level = 0.15;
00201     vf->priv->pmpi = NULL;
00202     if (args)
00203       sscanf (args, "%f:%f", &vf->priv->sense, &vf->priv->level);
00204     return 1;
00205 }
00206 
00207 const vf_info_t vf_info_dint = {
00208     "drop interlaced frames",
00209     "dint",
00210     "A.G.",
00211     "",
00212     vf_open,
00213     NULL
00214 };
Generated on Fri Feb 1 2013 14:34:48 for FFmpeg by doxygen 1.7.1