Mercurial > mplayer.hg
view libmpcodecs/vf_dint.c @ 31939:6ccc2a358030
Fix --disable-ass-internal to actually have an effect.
Further cleanup of this "mess" welcome.
author | reimar |
---|---|
date | Thu, 26 Aug 2010 19:24:18 +0000 |
parents | a972c1a4a012 |
children | 7af3e6f901fd |
line wrap: on
line source
/* * This file is part of MPlayer. * * MPlayer 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. * * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <inttypes.h> #include "config.h" #include "mp_msg.h" #include "mp_image.h" #include "img_format.h" #include "vf.h" struct vf_priv_s { float sense; // first parameter float level; // second parameter unsigned int imgfmt; char diff; uint32_t max; // int dfr; // int rdfr; int was_dint; mp_image_t *pmpi; // previous mpi }; #define MAXROWSIZE 1200 static int config (struct vf_instance *vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt) { int rowsize; vf->priv->pmpi = vf_get_image (vf->next, outfmt, MP_IMGTYPE_TEMP, 0, width, height); if (!(vf->priv->pmpi->flags & MP_IMGFLAG_PLANAR) && outfmt != IMGFMT_RGB32 && outfmt != IMGFMT_BGR32 && outfmt != IMGFMT_RGB24 && outfmt != IMGFMT_BGR24 && outfmt != IMGFMT_RGB16 && outfmt != IMGFMT_BGR16) { mp_msg (MSGT_VFILTER, MSGL_WARN, "Drop-interlaced filter doesn't support this outfmt :(\n"); return 0; } vf->priv->imgfmt = outfmt; // recalculate internal values rowsize = vf->priv->pmpi->width; if (rowsize > MAXROWSIZE) rowsize = MAXROWSIZE; vf->priv->max = vf->priv->level * vf->priv->pmpi->height * rowsize / 2; if (vf->priv->pmpi->flags & MP_IMGFLAG_PLANAR) // planar YUV vf->priv->diff = vf->priv->sense * 256; else vf->priv->diff = vf->priv->sense * (1 << (vf->priv->pmpi->bpp/3)); if (vf->priv->diff < 0) vf->priv->diff = 0; if (!(vf->priv->pmpi->flags & MP_IMGFLAG_PLANAR) && vf->priv->pmpi->bpp < 24 && vf->priv->diff > 31) vf->priv->diff = 31; mp_msg (MSGT_VFILTER, MSGL_INFO, "Drop-interlaced: %dx%d diff %d / level %u\n", vf->priv->pmpi->width, vf->priv->pmpi->height, (int)vf->priv->diff, (unsigned int)vf->priv->max); // vf->priv->rdfr = vf->priv->dfr = 0; vf->priv->was_dint = 0; return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); } static int put_image (struct vf_instance *vf, mp_image_t *mpi, double pts) { char rrow0[MAXROWSIZE]; char rrow1[MAXROWSIZE]; char rrow2[MAXROWSIZE]; char *row0 = rrow0, *row1 = rrow1, *row2 = rrow2/*, *row3 = rrow3*/; int rowsize = mpi->width; uint32_t nok = 0, max = vf->priv->max; int diff = vf->priv->diff; int i, j; register int n1, n2; unsigned char *cur0, *prv0; register unsigned char *cur, *prv; if (rowsize > MAXROWSIZE) rowsize = MAXROWSIZE; // check if nothing to do if (mpi->imgfmt == vf->priv->imgfmt) { cur0 = mpi->planes[0] + mpi->stride[0]; prv0 = mpi->planes[0]; for (j = 1; j < mpi->height && nok <= max; j++) { cur = cur0; prv = prv0; // analyse row (row0) if (mpi->flags & MP_IMGFLAG_PLANAR) // planar YUV - check luminance for (i = 0; i < rowsize; i++) { if (cur[0] - prv[0] > diff) row0[i] = 1; else if (cur[0] - prv[0] < -diff) row0[i] = -1; else row0[i] = 0; cur++; prv++; // check if row0 is 1 but row1 is 0, and row2 is 1 or row2 is 0 // but row3 is 1 so it's interlaced ptr (nok++) if (j > 2 && row0[i] > 0 && (row1[i] < 0 || (!row1[i] && row2[i] < 0)) && (++nok) > max) break; } else if (mpi->bpp < 24) // RGB/BGR 16 - check all colors for (i = 0; i < rowsize; i++) { n1 = cur[0] + (cur[1]<<8); n2 = prv[0] + (prv[1]<<8); if ((n1&0x1f) - (n2&0x1f) > diff || ((n1>>5)&0x3f) - ((n2>>5)&0x3f) > diff || ((n1>>11)&0x1f) - ((n2>>11)&0x1f) > diff) row0[i] = 1; else if ((n1&0x1f) - (n2&0x1f) < -diff || ((n1>>5)&0x3f) - ((n2>>5)&0x3f) < -diff || ((n1>>11)&0x1f) - ((n2>>11)&0x1f) < -diff) row0[i] = -1; else row0[i] = 0; cur += 2; prv += 2; // check if row0 is 1 but row1 is 0, and row2 is 1 or row2 is 0 // but row3 is 1 so it's interlaced ptr (nok++) if (j > 2 && row0[i] > 0 && (row1[i] < 0 || (!row1[i] && row2[i] < 0)) && (++nok) > max) break; } else // RGB/BGR 24/32 for (i = 0; i < rowsize; i++) { if (cur[0] - prv[0] > diff || cur[1] - prv[1] > diff || cur[2] - prv[2] > diff) row0[i] = 1; else if (prv[0] - cur[0] > diff || prv[1] - cur[1] > diff || prv[2] - cur[2] > diff) row0[i] = -1; else row0[i] = 0; cur += mpi->bpp/8; prv += mpi->bpp/8; // check if row0 is 1 but row1 is 0, and row2 is 1 or row2 is 0 // but row3 is 1 so it's interlaced ptr (nok++) if (j > 2 && row0[i] > 0 && (row1[i] < 0 || (!row1[i] && row2[i] < 0)) && (++nok) > max) break; } cur0 += mpi->stride[0]; prv0 += mpi->stride[0]; // rotate rows cur = row2; row2 = row1; row1 = row0; row0 = cur; } } // check if number of interlaced is above of max if (nok > max) { // vf->priv->dfr++; if (vf->priv->was_dint < 1) // can skip at most one frame! { vf->priv->was_dint++; // vf->priv->rdfr++; // mp_msg (MSGT_VFILTER, MSGL_INFO, "DI:%d/%d ", vf->priv->rdfr, vf->priv->dfr); return 0; } } vf->priv->was_dint = 0; // mp_msg (MSGT_VFILTER, MSGL_INFO, "DI:%d/%d ", vf->priv->rdfr, vf->priv->dfr); return vf_next_put_image (vf, mpi, pts); } static int vf_open(vf_instance_t *vf, char *args){ vf->config = config; vf->put_image = put_image; // vf->default_reqs=VFCAP_ACCEPT_STRIDE; vf->priv = malloc (sizeof(struct vf_priv_s)); vf->priv->sense = 0.1; vf->priv->level = 0.15; vf->priv->pmpi = NULL; if (args) sscanf (args, "%f:%f", &vf->priv->sense, &vf->priv->level); return 1; } const vf_info_t vf_info_dint = { "drop interlaced frames", "dint", "A.G.", "", vf_open, NULL };