⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 timgfilterkerneldeint.cpp

📁 从FFMPEG转换而来的H264解码程序,VC下编译..
💻 CPP
字号:
/*
 * Copyright (c) 2004-2006 Milan Cutka
 * based on KernelDeint Plugin for Avisynth by Donald A. Graft
 *
 * 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
 */

#include "stdafx.h"
#include "TimgFilterKernelDeint.h"
#include "TdeinterlaceSettings.h"
#include "Tdll.h"
/*
TimgFilterKernelDeint::TimgFilterKernelDeint(IffdshowBase *Ideci,Tfilters *Iparent):TimgFilter(Ideci,Iparent)
{
 prvbuf=NULL;prvbuflen=NULL;
 n=0;
}
TimgFilterKernelDeint::~TimgFilterKernelDeint()
{
 done();
}
void TimgFilterKernelDeint::onSizeChange(void)
{
 done();
}
void TimgFilterKernelDeint::done(void)
{
 if (prvbuf) aligned_free(prvbuf);prvbuf=NULL;prvbuflen=0;
 n=0;
}
HRESULT TimgFilterKernelDeint::process(TfilterQueue::iterator it,TffPict &pict,const TfilterSettingsVideo *cfg0)
{
 const TdeinterlaceSettings *cfg=(const TdeinterlaceSettings*)cfg0;
 init(pict,cfg->full,cfg->half);
 const unsigned char *src[4];
 bool cspChanged=getCur(FF_CSP_420P|FF_CSP_YUY2|FF_CSP_RGB32,pict,cfg->full,src);
 unsigned char *dst[4];
 cspChanged|=getNext(csp1,pict,cfg->full,dst);
 if (cspChanged)
  done();

 if (!prvbuf)
  prv.alloc(dx1[0],dy1[0],csp1,0,prvbuf,prvbuflen);

 int order=cfg->swapfields?1:0;
 for (unsigned int z=0;z<pict.cspInfo.numPlanes;z++)
  {
   unsigned int plane=z;
   const unsigned char *srcp,*srcp_saved;
   srcp=srcp_saved=src[z];

   int src_pitch = stride1[plane];
   unsigned char *dstp,*dstp_saved;
   dstp=dstp_saved=dst[plane];
   int dst_pitch = stride2[plane];

   int w = dx1[plane]*pict.cspInfo.Bpp;
   int h = dy1[plane];
   srcp = srcp_saved  + (1-order) * src_pitch;
   dstp = dstp_saved  + (1-order) * dst_pitch;
   for (int y=0;y<h;y+=2)
    {
     memcpy(dstp, srcp, w);
     srcp += 2*src_pitch;
     dstp += 2*dst_pitch;
    }
   // Copy through the lines that will be missed below.
   memcpy(dstp_saved + order*dst_pitch, srcp_saved + (1-order)*src_pitch, w);
   memcpy(dstp_saved + (2+order)*dst_pitch, srcp_saved + (3-order)*src_pitch, w);
   memcpy(dstp_saved + (h-2+order)*dst_pitch, srcp_saved + (h-1-order)*src_pitch, w);
   memcpy(dstp_saved + (h-4+order)*dst_pitch, srcp_saved + (h-3-order)*src_pitch, w);
   // For the other field choose adaptively between using the previous field or the interpolant from the current field.
   unsigned char *prvp = prv.data[plane] + 5*prv.stride[plane] - (1-order)*prv.stride[plane];
   unsigned char *prvpp = prvp - prv.stride[plane];
   unsigned char *prvppp = prvp - 2*prv.stride[plane];
   unsigned char *prvp4p = prvp - 4*prv.stride[plane];
   unsigned char *prvpn = prvp + prv.stride[plane];
   unsigned char *prvpnn = prvp + 2*prv.stride[plane];
   unsigned char *prvp4n = prvp + 4*prv.stride[plane];
   srcp = srcp_saved + 5*src_pitch - (1-order)*src_pitch;
   const unsigned char *srcpp = srcp - src_pitch;
   const unsigned char *srcppp = srcp - 2*src_pitch;
   const unsigned char *srcp3p = srcp - 3*src_pitch;
   const unsigned char *srcp4p = srcp - 4*src_pitch;
   const unsigned char *srcpn = srcp + src_pitch;
   const unsigned char *srcpnn = srcp + 2*src_pitch;
   const unsigned char *srcp3n = srcp + 3*src_pitch;
   const unsigned char *srcp4n = srcp + 4*src_pitch;
   dstp =  dstp_saved  + 5*dst_pitch - (1-order)*dst_pitch;
   for (int y = 5 - (1-order); y <= h - 5 - (1-order); y+=2)
    {
     for (int x = 0; x < w; x++)
      {
       if ((cfg->kernelThreshold == 0) || (n == 0) ||
           (abs((int)prvp[x] - (int)srcp[x]) > cfg->kernelThreshold) ||
           (abs((int)prvpp[x] - (int)srcpp[x]) > cfg->kernelThreshold) ||
           (abs((int)prvpn[x] - (int)srcpn[x]) > cfg->kernelThreshold))
        {
         if (cfg->kernelMap)
          {
           int g = x & ~3;
           if (csp1==FF_CSP_RGB32)
            {
             dstp[g++] = 255;
             dstp[g++] = 255;
             dstp[g++] = 255;
             dstp[g] = 255;
             x = g;
            }
           else if (csp1==FF_CSP_YUY2)
            {
             dstp[g++] = 235;
             dstp[g++] = 128;
             dstp[g++] = 235;
             dstp[g] = 128;
             x = g;
            }
           else
            {
             if (plane == 0) dstp[x] = 235;
             else dstp[x] = 128;
            }
          }
         else
          {
           int hi,lo;
           if (csp1==FF_CSP_RGB32)
            {
             hi = 255;
             lo = 0;
            }
           else if (csp_isYUVplanar(csp1))
            {
             hi = (plane == 0) ? 235 : 240;
             lo = 16;
            }
           else if (csp1==FF_CSP_YUY2)
            {
             hi = (x & 1) ? 240 : 235;
             lo = 16;
            }
           else
            {
             hi=255;
             lo=0;
            }
           if (cfg->kernelSharp)
            {
             double valf;
             if (cfg->kernelTwoway)
              valf = + 0.526*((int)srcpp[x] + (int)srcpn[x])
                 + 0.170*((int)srcp[x] + (int)prvp[x])
                 - 0.116*((int)srcppp[x] + (int)srcpnn[x] + (int)prvppp[x] + (int)prvpnn[x])
                 - 0.026*((int)srcp3p[x] + (int)srcp3n[x])
                 + 0.031*((int)srcp4p[x] + (int)srcp4n[x] + (int)prvp4p[x] + (int)prvp4n[x]);
             else
              valf = + 0.526*((int)srcpp[x] + (int)srcpn[x])
                 + 0.170*((int)prvp[x])
                 - 0.116*((int)prvppp[x] + (int)prvpnn[x])
                 - 0.026*((int)srcp3p[x] + (int)srcp3n[x])
                 + 0.031*((int)prvp4p[x] + (int)prvp4p[x]);
             if (valf > hi) valf = hi;
             else if (valf < lo) valf = lo;
             dstp[x] = (unsigned char) valf;
            }
           else
            {
             int val;
             if (cfg->kernelTwoway)
              val = (8*((int)srcpp[x] + (int)srcpn[x]) + 2*((int)srcp[x] + (int)prvp[x]) -
                      (int)(srcppp[x]) - (int)(srcpnn[x]) -
                      (int)(prvppp[x]) - (int)(prvpnn[x])) >> 4;
             else
              val = (8*((int)srcpp[x] + (int)srcpn[x]) + 2*((int)prvp[x]) -
                      (int)(prvppp[x]) - (int)(prvpnn[x])) >> 4;
             if (val > hi) val = hi;
             else if (val < lo) val = lo;
             dstp[x] = (unsigned char) val;
            }
          }
        }
       else
        dstp[x] = srcp[x];
      }
     prvp  += 2*prv.stride[plane];
     prvpp  += 2*prv.stride[plane];
     prvppp  += 2*prv.stride[plane];
     prvpn  += 2*prv.stride[plane];
     prvpnn  += 2*prv.stride[plane];
     prvp4p  += 2*prv.stride[plane];
     prvp4n  += 2*prv.stride[plane];
     srcp  += 2*src_pitch;
     srcpp += 2*src_pitch;
     srcppp += 2*src_pitch;
     srcp3p += 2*src_pitch;
     srcp4p += 2*src_pitch;
     srcpn += 2*src_pitch;
     srcpnn += 2*src_pitch;
     srcp3n += 2*src_pitch;
     srcp4n += 2*src_pitch;
     dstp  += 2*dst_pitch;
    }
   TffPict::copy(prv.data[plane],prv.stride[plane],src[plane],stride1[plane],w,dy1[plane]);
  }
 n++;
 pict.fieldtype=FIELD_TYPE::PROGRESSIVE_FRAME;
 return parent->deliverSample(++it,pict);
}
void TimgFilterKernelDeint::onSeek(void)
{
 done();
}
*/
//====================================================================================
#include "KernelDeint/ff_kernelDeint.h"
const char_t* TimgFilterKernelDeint2::dllname=_l("ff_kernelDeint.dll");

TimgFilterKernelDeint2::TimgFilterKernelDeint2(IffdshowBase *Ideci,Tfilters *Iparent,bool Ibob):TimgFilter(Ideci,Iparent),bob(Ibob)
{
 kernel=NULL;oldcfg.cfgId=-1;
 dll=new Tdll(dllname,parent->config);
 dll->loadFunction(createI,"createI");
}
TimgFilterKernelDeint2::~TimgFilterKernelDeint2()
{
 done();
 delete dll;
}

bool TimgFilterKernelDeint2::is(const TffPictBase &pict,const TfilterSettingsVideo *cfg)
{
 return dll->ok && super::is(pict,cfg);
}

void TimgFilterKernelDeint2::onSizeChange(void)
{
 done();
}
void TimgFilterKernelDeint2::done(void)
{
 if (kernel) kernel->destroy();kernel=NULL;
}

HRESULT TimgFilterKernelDeint2::process(TfilterQueue::iterator it,TffPict &pict,const TfilterSettingsVideo *cfg0)
{
 if (dll->ok)
  {
   const TdeinterlaceSettings *cfg=(const TdeinterlaceSettings*)cfg0;
   if (!cfg->equal(oldcfg))
    {
     oldcfg=*cfg;
     done();
    }
   init(pict,cfg->full,cfg->half);
   const unsigned char *src[4];
   bool cspChanged=getCur(FF_CSP_420P|FF_CSP_YUY2,pict,cfg->full,src);
   unsigned char *dst[4];
   if (cfg->kernelMap)
    cspChanged|=getCurNext(csp1,pict,cfg->full,COPYMODE_DEF,dst);
   else
    cspChanged|=getNext(csp1,pict,cfg->full,dst);
   int order=pict.fieldtype&FIELD_TYPE::INT_BFF?0:1;if (cfg->swapfields) order=1-order;

   if (cspChanged)
    done();

   if (!kernel)
    kernel=createI(csp1&FF_CSP_420P,dx1[0],dy1[0],dx1[0]*pict.cspInfo.Bpp,order,cfg->kernelThreshold,!!cfg->kernelSharp,!!cfg->kernelTwoway,!!cfg->kernelLinked,!!cfg->kernelMap,bob,parent->config->cpu_flags,TffPict::copy);
   else if (oldOrder != order)
    kernel->setOrder(order);

   oldOrder=order;

   pict.fieldtype=FIELD_TYPE::PROGRESSIVE_FRAME;
   if (bob)
    {
     kernel->getFrame(src,stride1,dst,stride2,0);
     TffPict pict0=pict;
     REFERENCE_TIME rtDur=pict.rtStop-pict.rtStart;
     pict0.rtStop=pict.rtStart+rtDur/2;

     parent->deliverSample(++it,pict0);
     --it;
     getNext(csp1,pict,cfg->full,dst);
     pict.rtStart=pict.rtStart+rtDur/2;
    }
   kernel->getFrame(src,stride1,dst,stride2,bob?1:0);
  }

 if (pict.rectClip != pict.rectFull)
  parent->dirtyBorder=1;

 return parent->deliverSample(++it,pict);
}

void TimgFilterKernelDeint2::onSeek(void)
{
 done();
}

⌨️ 快捷键说明

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