vf_delogo.c

来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 283 行

C
283
字号
/*  Copyright (C) 2002 Jindrich Makovicka <makovick@gmail.com>  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*//* A very simple tv station logo remover */#include <uclib.h>#include <uclib.h>#include <uclib.h>#include <inttypes.h>#include <math.h>#include "config.h"#include "mp_msg.h"#include "cpudetect.h"#ifdef HAVE_MALLOC_H#include <uclib.h>#endif#include "img_format.h"#include "mp_image.h"#include "vf.h"#include "libvo/fastmemcpy.h"#include "m_option.h"#include "m_struct.h"//===========================================================================//static struct vf_priv_s {    unsigned int outfmt;    int xoff, yoff, lw, lh, band, show;} const vf_priv_dflt = {    0,    0, 0, 0, 0, 0, 0};#define MIN(a,b) (((a) < (b)) ? (a) : (b))#define MAX(a,b) (((a) > (b)) ? (a) : (b))static void delogo(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int width, int height,		   int logo_x, int logo_y, int logo_w, int logo_h, int band, int show, int direct) {    int y, x;    int interp, dist;    uint8_t *xdst, *xsrc;        uint8_t *topleft, *botleft, *topright;    int xclipl, xclipr, yclipt, yclipb;    int logo_x1, logo_x2, logo_y1, logo_y2;        xclipl = MAX(-logo_x, 0);    xclipr = MAX(logo_x+logo_w-width, 0);    yclipt = MAX(-logo_y, 0);    yclipb = MAX(logo_y+logo_h-height, 0);    logo_x1 = logo_x + xclipl;    logo_x2 = logo_x + logo_w - xclipr;    logo_y1 = logo_y + yclipt;    logo_y2 = logo_y + logo_h - yclipb;    topleft = src+logo_y1*srcStride+logo_x1;    topright = src+logo_y1*srcStride+logo_x2-1;    botleft = src+(logo_y2-1)*srcStride+logo_x1;    if (!direct) memcpy_pic(dst, src, width, height, dstStride, srcStride);    dst += (logo_y1+1)*dstStride;    src += (logo_y1+1)*srcStride;        for(y = logo_y1+1; y < logo_y2-1; y++)    {	for (x = logo_x1+1, xdst = dst+logo_x1+1, xsrc = src+logo_x1+1; x < logo_x2-1; x++, xdst++, xsrc++) {	    interp = ((topleft[srcStride*(y-logo_y-yclipt)]		       + topleft[srcStride*(y-logo_y-1-yclipt)]		       + topleft[srcStride*(y-logo_y+1-yclipt)])*(logo_w-(x-logo_x))/logo_w		      + (topright[srcStride*(y-logo_y-yclipt)]			 + topright[srcStride*(y-logo_y-1-yclipt)]			 + topright[srcStride*(y-logo_y+1-yclipt)])*(x-logo_x)/logo_w		      + (topleft[x-logo_x-xclipl]			 + topleft[x-logo_x-1-xclipl]			 + topleft[x-logo_x+1-xclipl])*(logo_h-(y-logo_y))/logo_h		      + (botleft[x-logo_x-xclipl]			 + botleft[x-logo_x-1-xclipl]			 + botleft[x-logo_x+1-xclipl])*(y-logo_y)/logo_h		)/6;/*		interp = (topleft[srcStride*(y-logo_y)]*(logo_w-(x-logo_x))/logo_w			  + topright[srcStride*(y-logo_y)]*(x-logo_x)/logo_w			  + topleft[x-logo_x]*(logo_h-(y-logo_y))/logo_h			  + botleft[x-logo_x]*(y-logo_y)/logo_h			  )/2;*/	    if (y >= logo_y+band && y < logo_y+logo_h-band && x >= logo_x+band && x < logo_x+logo_w-band) {		    *xdst = interp;	    } else {		dist = 0;		if (x < logo_x+band) dist = MAX(dist, logo_x-x+band);		else if (x >= logo_x+logo_w-band) dist = MAX(dist, x-(logo_x+logo_w-1-band));		if (y < logo_y+band) dist = MAX(dist, logo_y-y+band);		else if (y >= logo_y+logo_h-band) dist = MAX(dist, y-(logo_y+logo_h-1-band));		*xdst = (*xsrc*dist + interp*(band-dist))/band;		if (show && (dist == band-1)) *xdst = 0;	    }	}	dst+= dstStride;	src+= srcStride;    }}static int config(struct vf_instance_s* vf,		  int width, int height, int d_width, int d_height,		  unsigned int flags, unsigned int outfmt){    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    if(mpi->imgfmt!=vf->priv->outfmt) return; // colorspace differ    // 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;}static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){    mp_image_t *dmpi;    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,vf->priv->outfmt,			      MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,			      mpi->w,mpi->h);    }    dmpi= vf->dmpi;    delogo(dmpi->planes[0], mpi->planes[0], dmpi->stride[0], mpi->stride[0], mpi->w, mpi->h,	   vf->priv->xoff, vf->priv->yoff, vf->priv->lw, vf->priv->lh, vf->priv->band, vf->priv->show,	   mpi->flags&MP_IMGFLAG_DIRECT);    delogo(dmpi->planes[1], mpi->planes[1], dmpi->stride[1], mpi->stride[1], mpi->w/2, mpi->h/2,	   vf->priv->xoff/2, vf->priv->yoff/2, vf->priv->lw/2, vf->priv->lh/2, vf->priv->band/2, vf->priv->show,	   mpi->flags&MP_IMGFLAG_DIRECT);    delogo(dmpi->planes[2], mpi->planes[2], dmpi->stride[2], mpi->stride[2], mpi->w/2, mpi->h/2,	   vf->priv->xoff/2, vf->priv->yoff/2, vf->priv->lw/2, vf->priv->lh/2, vf->priv->band/2, vf->priv->show,	   mpi->flags&MP_IMGFLAG_DIRECT);    vf_clone_mpi_attributes(dmpi, mpi);    return vf_next_put_image(vf,dmpi, pts);}static void uninit(struct vf_instance_s* vf){    if(!vf->priv) return;    free(vf->priv);    vf->priv=NULL;}//===========================================================================//static int query_format(struct vf_instance_s* vf, unsigned int fmt){    switch(fmt)    {    case IMGFMT_YV12:    case IMGFMT_I420:    case IMGFMT_IYUV:	return vf_next_query_format(vf,vf->priv->outfmt);    }    return 0;}static unsigned int fmt_list[]={    IMGFMT_YV12,    IMGFMT_I420,    IMGFMT_IYUV,    0};static int open(vf_instance_t *vf, char* args){    int res;        vf->config=config;    vf->put_image=put_image;    vf->get_image=get_image;    vf->query_format=query_format;    vf->uninit=uninit;    if (!vf->priv)    {        vf->priv=malloc(sizeof(struct vf_priv_s));	memset(vf->priv, 0, sizeof(struct vf_priv_s));    }    if (args) res = sscanf(args, "%d:%d:%d:%d:%d",			   &vf->priv->xoff, &vf->priv->yoff,			   &vf->priv->lw, &vf->priv->lh,			   &vf->priv->band);    if (args && (res != 5)) {	uninit(vf);	return 0; // bad syntax    }    mp_msg(MSGT_VFILTER, MSGL_V, "delogo: %d x %d, %d x %d, band = %d\n",	   vf->priv->xoff, vf->priv->yoff,	   vf->priv->lw, vf->priv->lh,	   vf->priv->band);    vf->priv->show = 0;    if (vf->priv->band < 0) {	vf->priv->band = 4;	vf->priv->show = 1;    }        vf->priv->lw += vf->priv->band*2;    vf->priv->lh += vf->priv->band*2;    vf->priv->xoff -= vf->priv->band;    vf->priv->yoff -= vf->priv->band;    // check csp:    vf->priv->outfmt=vf_match_csp(&vf->next,fmt_list,IMGFMT_YV12);    if(!vf->priv->outfmt)    {	uninit(vf);        return 0; // no csp match :(    }    return 1;}#define ST_OFF(f) M_ST_OFF(struct vf_priv_s,f)static m_option_t vf_opts_fields[] = {    { "x", ST_OFF(xoff), CONF_TYPE_INT, 0, 0, 0, NULL },    { "y", ST_OFF(yoff), CONF_TYPE_INT, 0, 0, 0, NULL },    { "w", ST_OFF(lw), CONF_TYPE_INT, 0, 0, 0, NULL },    { "h", ST_OFF(lh), CONF_TYPE_INT, 0, 0, 0, NULL },    { "t", ST_OFF(band), CONF_TYPE_INT, 0, 0, 0, NULL },    { "band", ST_OFF(band), CONF_TYPE_INT, 0, 0, 0, NULL }, // alias    { NULL, NULL, 0, 0, 0, 0, NULL }};static m_struct_t vf_opts = {    "delogo",    sizeof(struct vf_priv_s),    &vf_priv_dflt,    vf_opts_fields};vf_info_t vf_info_delogo = {    "simple logo remover",    "delogo",    "Jindrich Makovicka, Alex Beregszaszi",    "",    open,    &vf_opts};//===========================================================================//

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?