vf_divtc.c

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

C
705
字号
	    imgop(copyop, tmpi, mpi, 0);	    imgop(deghost_plane, tmpi, dmpi, p->deghost);	    imgop(copyop, dmpi, mpi, 0);	    return vf_next_put_image(vf, tmpi, MP_NOPTS_VALUE);	    }      }   imgop(copyop, dmpi, mpi, 0);   return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);   }static int analyze(struct vf_priv_s *p)   {   int *buf=0, *bp, bufsize=0, n, b, f, i, j, m, s;   unsigned int *cbuf=0, *cp;   char *pbuf;   char lbuf[256];   int sum[5];   double d;   /* read the file */   n=15;   while(fgets(lbuf, 256, p->file))      {      if(n>=bufsize-19)	 {	 bufsize=bufsize?bufsize*2:30000;	 if((bp=realloc(buf, bufsize*sizeof *buf))) buf=bp;	 if((cp=realloc(cbuf, bufsize*sizeof *cbuf))) cbuf=cp;	 if(!bp || !cp)	    {	    mp_msg(MSGT_VFILTER, MSGL_FATAL, "%s: Not enough memory.\n",		   vf_info_divtc.name);	    free(buf);	    free(cbuf);	    return 0;	    }	 }      sscanf(lbuf, "%x %d", cbuf+n, buf+n);      n++;      }   if(!n)      {      mp_msg(MSGT_VFILTER, MSGL_FATAL, "%s: Empty 2-pass log file.\n",	     vf_info_divtc.name);      free(buf);      free(cbuf);      return 0;      }   /* generate some dummy data past the beginning and end of the array */   buf+=15, cbuf+=15;   n-=15;   memcpy(buf-15, buf, 15*sizeof *buf);   memset(cbuf-15, 0, 15*sizeof *cbuf);   while(n%5)      buf[n]=buf[n-5], cbuf[n]=0, n++;   memcpy(buf+n, buf+n-15, 15*sizeof *buf);   memset(cbuf+n, 0, 15*sizeof *cbuf);   p->csdata=cbuf;   p->fcount=n;   /* array with one slot for each slice of 5 frames */   p->bdata=pbuf=malloc(p->bcount=b=(n/5));   memset(pbuf, 255, b);   /* resolve the automatic mode */   if(p->deghost<0)      {      int deghost=-p->deghost;      double s0=0.0, s1=0.0;      for(f=0; f<n; f+=5)	 {	 p->deghost=0; match(p, buf+f, -1, -1, &d); s0+=d;	 p->deghost=1; match(p, buf+f, -1, -1, &d); s1+=d;	 }      p->deghost=s1>s0?deghost:0;      mp_msg(MSGT_VFILTER, MSGL_INFO,	     "%s: Deghosting %-3s (relative pattern strength %+.2fdB).\n",	     vf_info_divtc.name,	     p->deghost?"ON":"OFF",	     10.0*log10(s1/s0));      }   /* analyze the data */   for(f=0; f<5; f++)      for(sum[f]=0, n=-15; n<20; n+=5)	 sum[f]+=buf[n+f];   for(f=0; f<b; f++)      {      m=match(p, sum, -1, -1, &d);      if(d>=p->threshold)	 pbuf[f]=m;      if(f<b-1)	 for(n=0; n<5; n++)	    sum[n]=sum[n]-buf[5*(f-3)+n]+buf[5*(f+4)+n];      }   /* fill in the gaps */   /* the beginning */   for(f=0; f<b && pbuf[f]==-1; f++);   if(f==b)      {      free(buf-15);      mp_msg(MSGT_VFILTER, MSGL_FATAL, "%s: No telecine pattern found!\n",	     vf_info_divtc.name);      return 0;      }   for(n=0; n<f; pbuf[n++]=pbuf[f]);   /* the end */   for(f=b-1; pbuf[f]==-1; f--);   for(n=f+1; n<b; pbuf[n++]=pbuf[f]);   /* the rest */   for(f=0;;)      {      while(f<b && pbuf[f]!=-1) f++;      if(f==b) break;      for(n=f; pbuf[n]==-1; n++);      if(pbuf[f-1]==pbuf[n])	 {	 /* just a gap */	 while(f<n) pbuf[f++]=pbuf[n];	 }      else	 {	 /* phase change, reanalyze the original data in the gap with zero	    threshold for only the two phases that appear at the ends */	 for(i=0; i<5; i++)	    for(sum[i]=0, j=5*f-15; j<5*f; j+=5)	       sum[i]+=buf[i+j];	 for(i=f; i<n; i++)	    {	    pbuf[i]=match(p, sum, pbuf[f-1], pbuf[n], 0);	    for(j=0; j<5; j++)	       sum[j]=sum[j]-buf[5*(i-3)+j]+buf[5*(i+4)+j];	    }	 /* estimate the transition point by dividing the gap	    in the same proportion as the number of matches of each kind */	 for(i=f, m=f; i<n; i++)	    if(pbuf[i]==pbuf[f-1]) m++;	 /* find the transition of the right direction nearest to the	    estimated point */	 if(m>f && m<n)	    {	    for(j=m; j>f; j--)	       if(pbuf[j-1]==pbuf[f-1] && pbuf[j]==pbuf[n]) break;	    for(s=m; s<n; s++)	       if(pbuf[s-1]==pbuf[f-1] && pbuf[s]==pbuf[n]) break;	    m=(s-m<m-j)?s:j;	    }	 /* and rewrite the data to allow only this one transition */	 for(i=f; i<m; i++)	    pbuf[i]=pbuf[f-1];	 for(; i<n; i++)	    pbuf[i]=pbuf[n];	 f=n;	 }      }   free(buf-15);   return 1;   }static int query_format(struct vf_instance_s* vf, unsigned int fmt)   {   switch(fmt)      {      case IMGFMT_444P: case IMGFMT_IYUV: case IMGFMT_RGB24:      case IMGFMT_422P: case IMGFMT_UYVY: case IMGFMT_BGR24:      case IMGFMT_411P: case IMGFMT_YUY2: case IMGFMT_IF09:      case IMGFMT_YV12: case IMGFMT_I420: case IMGFMT_YVU9:      case IMGFMT_IUYV: case IMGFMT_Y800: case IMGFMT_Y8:	 return vf_next_query_format(vf,fmt);      }   return 0;   }static void uninit(struct vf_instance_s* vf)   {   if(vf->priv)      {      if(vf->priv->file) fclose(vf->priv->file);      if(vf->priv->csdata) free(vf->priv->csdata-15);      free(vf->priv->bdata);      free(vf->priv->history);      free(vf->priv);      }   }static int vf_open(vf_instance_t *vf, char* args)   {   struct vf_priv_s *p;   char *filename="framediff.log", *ap, *q, *a;   if(args && !(args=strdup(args)))      {   nomem:      mp_msg(MSGT_VFILTER, MSGL_FATAL,	     "%s: Not enough memory.\n", vf->info->name);   fail:      uninit(vf);      free(args);      return 0;      }   vf->put_image=put_image;   vf->uninit=uninit;   vf->query_format=query_format;   vf->default_reqs=VFCAP_ACCEPT_STRIDE;   if(!(vf->priv=p=calloc(1, sizeof(struct vf_priv_s))))      goto nomem;   p->phase=5;   p->threshold=0.5;   p->window=30;   if((ap=args))      while(*ap)	 {	 q=ap;	 if((ap=strchr(q, ':'))) *ap++=0; else ap=q+strlen(q);	 if((a=strchr(q, '='))) *a++=0; else a=q+strlen(q);	 switch(*q)	    {	    case 0:                              break;	    case 'f': filename=a;                break;	    case 't': p->threshold=atof(a);      break;	    case 'w': p->window=5*(atoi(a)+4)/5; break;	    case 'd': p->deghost=atoi(a);        break;	    case 'p':	       if(q[1]=='h') p->phase=atoi(a);	       else p->pass=atoi(a);	       break;	    case 'h':	       mp_msg(MSGT_VFILTER, MSGL_INFO,		      "\n%s options:\n\n"		      "pass=1|2         - Use 2-pass mode.\n"		      "file=filename    - Set the 2-pass log file name "		      "(default %s).\n"		      "threshold=value  - Set the pattern recognition "		      "sensitivity (default %g).\n"		      "deghost=value    - Select deghosting threshold "		      "(default %d).\n"		      "window=numframes - Set the statistics window "		      "for 1-pass mode (default %d).\n"		      "phase=0|1|2|3|4  - Set the initial phase "		      "for 1-pass mode (default %d).\n\n"		      "The option names can be abbreviated to the shortest "		      "unique prefix.\n\n",		      vf->info->name, filename, p->threshold, p->deghost,		      p->window, p->phase%5);	       break;	    default:	       mp_msg(MSGT_VFILTER, MSGL_FATAL,		      "%s: Unknown argument %s.\n", vf->info->name, q);	       goto fail;	    }	 }   switch(p->pass)      {      case 1:	 if(!(p->file=fopen(filename, "w")))	    {	    mp_msg(MSGT_VFILTER, MSGL_FATAL,		   "%s: Can't create file %s.\n", vf->info->name, filename);	    goto fail;	    }	 break;      case 2:	 if(!(p->file=fopen(filename, "r")))	    {	    mp_msg(MSGT_VFILTER, MSGL_FATAL,		   "%s: Can't open file %s.\n", vf->info->name, filename);	    goto fail;	    }	 if(!analyze(p))	    goto fail;	 fclose(p->file);	 p->file=0;	 break;      }   if(p->window<5) p->window=5;   if(!(p->history=calloc(sizeof *p->history, p->window)))      goto nomem;   diff=#ifdef HAVE_MMX      gCpuCaps.hasMMX?diff_MMX:#endif      diff_C;   free(args);   return 1;   }vf_info_t vf_info_divtc =   {   "inverse telecine for deinterlaced video",   "divtc",   "Ville Saari",   "",   vf_open,   NULL   };

⌨️ 快捷键说明

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