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

📄 timgfilteroffset.cpp

📁 从FFMPEG转换而来的H264解码程序,VC下编译..
💻 CPP
字号:
/*
 * Copyright (c) 2002-2006 Milan Cutka
 *
 * 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 "TimgFilterOffset.h"
#include "ToffsetSettings.h"
#include "TsampleFormat.h"

//================================= TimgFilterOffset =================================
TimgFilterOffset::TimgFilterOffset(IffdshowBase *Ideci,Tfilters *Iparent):TimgFilter(Ideci,Iparent)
{
 Y_X=Y_Y=U_X=U_Y=V_X=V_Y=-1000;
}
void TimgFilterOffset::onSizeChange(void)
{
 Y_X=Y_Y=U_X=U_Y=V_X=V_Y=-1000;
}
void TimgFilterOffset::offset(int c,const unsigned char *src,stride_t srcStride,unsigned char *dst,stride_t dstStride,unsigned int dx,unsigned int dy,int offsetX,int offsetY)
{
 unsigned int x1,x2;
 if (offsetX>0)
  {
   x1=offsetX;x2=0;
  }
 else
  {
   offsetX=abs(offsetX);
   x1=0;x2=offsetX;
  }
 unsigned int y1,y2;
 if (offsetY>0)
  {
   y1=offsetY;y2=0;
  }
 else
  {
   offsetY=abs(offsetY);
   y1=0;y2=offsetY;
  }
 for (unsigned char *dstCx=dst+(x2?dx-offsetX:0),*dstCXend=dstCx+dy*dstStride;dstCx<dstCXend;dstCx+=dstStride)
  memset(dstCx,c,offsetX);
 for (unsigned char *dstCy=dst+(y1?dy-offsetY:0)*dstStride,*dstCYend=dstCy+offsetY*dstStride;dstCy<dstCYend;dstCy+=dstStride)
  memset(dstCy,c,dx);
 src+=y1*srcStride;dst+=y2*dstStride;
 for (unsigned int y=0;y<dy-offsetY;src+=srcStride,dst+=dstStride,y++)
  memcpy(dst+x1,src+x2,dx-offsetX);
}
bool TimgFilterOffset::is(const TffPictBase &pict,const TfilterSettingsVideo *cfg0)
{
 const ToffsetSettings *cfg=(const ToffsetSettings*)cfg0;
 return super::is(pict,cfg) && (cfg->Y_X || cfg->Y_Y || cfg->U_X || cfg->U_Y || cfg->V_X || cfg->V_Y);
}
HRESULT TimgFilterOffset::process(TfilterQueue::iterator it,TffPict &pict,const TfilterSettingsVideo *cfg0)
{
 if (is(pict,cfg0))
  {
   const ToffsetSettings *cfg=(const ToffsetSettings*)cfg0;
   init(pict,cfg->full,cfg->half);
   if (cfg->Y_X || cfg->Y_Y)
    {
     const unsigned char *srcY;
     getCur(FF_CSPS_MASK_YUV_PLANAR,pict,cfg->full,&srcY,NULL,NULL,NULL);
     unsigned char *dstY;
     getNext(csp1,pict,cfg->full,&dstY,NULL,NULL,NULL);
     if (cfg->Y_X!=Y_X || cfg->Y_Y!=Y_Y)
      {
       Y_X=cfg->Y_X;Y_Y=cfg->Y_Y;
       pict.clear(cfg->full,0);
      }
     offset(0,srcY,stride1[0],dstY,stride2[0],dx1[0],dy1[0],cfg->Y_X,-cfg->Y_Y);
    }
   if (cfg->U_X || cfg->U_Y)
    {
     const unsigned char *srcU;
     getCur(FF_CSPS_MASK_YUV_PLANAR,pict,cfg->full,NULL,&srcU,NULL,NULL);
     unsigned char *dstU;
     getNext(csp1,pict,cfg->full,NULL,&dstU,NULL,NULL);
     if (cfg->U_X!=U_X || cfg->U_Y!=U_Y)
      {
       U_X=cfg->U_X;U_Y=cfg->U_Y;
       pict.clear(cfg->full,1);
      }
     offset(128,srcU,stride1[1],dstU,stride2[1],dx1[1],dy1[1],cfg->U_X>>pict.cspInfo.shiftX[1],-cfg->U_Y>>pict.cspInfo.shiftY[1]);
    }
   if (cfg->V_X || cfg->V_Y)
    {
     const unsigned char *srcV;
     getCur(FF_CSPS_MASK_YUV_PLANAR,pict,cfg->full,NULL,NULL,&srcV,NULL);
     unsigned char *dstV;
     getNext(csp1,pict,cfg->full,NULL,NULL,&dstV,NULL);
     if (cfg->V_X!=V_X || cfg->V_Y!=V_Y)
      {
       V_X=cfg->V_X;V_Y=cfg->V_Y;
       pict.clear(cfg->full,2);
      }
     offset(128,srcV,stride1[2],dstV,stride2[2],dx1[2],dy1[2],cfg->V_X>>pict.cspInfo.shiftX[2],-cfg->V_Y>>pict.cspInfo.shiftY[2]);
    }
  }
 return parent->deliverSample(++it,pict);
}

//================================== TimgFilterFlip ==================================
TimgFilterFlip::TimgFilterFlip(IffdshowBase *Ideci,Tfilters *Iparent):TimgFilter(Ideci,Iparent)
{
}
bool TimgFilterFlip::is(const TffPictBase &pict,const TfilterSettingsVideo *cfg0)
{
 const ToffsetSettings *cfg=(const ToffsetSettings*)cfg0;
 return super::is(pict,cfg) && cfg->flip;
}
HRESULT TimgFilterFlip::process(TfilterQueue::iterator it,TffPict &pict,const TfilterSettingsVideo *cfg0)
{
 if (is(pict,cfg0))
  {
   const ToffsetSettings *cfg=(const ToffsetSettings*)cfg0;
   init(pict,cfg->full,cfg->half);
   unsigned char *ptr[4];
   getCurNext(pict.csp,pict,cfg->full,COPYMODE_DEF,ptr);
   for (unsigned int i=0;i<pict.cspInfo.numPlanes;i++)
    {
     unsigned char *src=ptr[i],*dst=ptr[i]+stride2[i]*(dy2[i]-1);
     unsigned int dx=dx2[i]*pict.cspInfo.Bpp,dy=dy2[i]/2;
     void *tmp=_alloca(dx);
     for (unsigned int y=0;y<dy;y++,src+=stride2[i],dst-=stride2[i])
      {
       memcpy(tmp,src,dx);
       memcpy(src,dst,dx);
       memcpy(dst,tmp,dx);
      }
    }
  }
 return parent->deliverSample(++it,pict);
}

//================================== TimgFilterMirror ==================================
TimgFilterMirror::TimgFilterMirror(IffdshowBase *Ideci,Tfilters *Iparent):
 TimgFilter(Ideci,Iparent),
 mirrorFc(NULL)
{
}
bool TimgFilterMirror::is(const TffPictBase &pict,const TfilterSettingsVideo *cfg0)
{
 const ToffsetSettings *cfg=(const ToffsetSettings*)cfg0;
 return super::is(pict,cfg) && cfg->mirror;
}
template<class pixel_t> void TimgFilterMirror::mirror(int i,unsigned int dx,unsigned char *line)
{
 pixel_t *src=(pixel_t*)line;
 pixel_t *dst=(pixel_t*)line+(dx2[i]-1);
 for (unsigned int x=0;x<dx;x++,src++,dst--)
  std::swap(*src,*dst);
}
HRESULT TimgFilterMirror::process(TfilterQueue::iterator it,TffPict &pict,const TfilterSettingsVideo *cfg0)
{
 if (is(pict,cfg0))
  {
   const ToffsetSettings *cfg=(const ToffsetSettings*)cfg0;
   init(pict,cfg->full,cfg->half);
   unsigned char *ptr[4];
   bool cspChanged=getCurNext(pict.csp,pict,cfg->full,COPYMODE_DEF,ptr);
   if (cspChanged)
    switch (pict.cspInfo.Bpp)
     {
      case 1:mirrorFc=&TimgFilterMirror::mirror<int8_t>;break;
      case 2:mirrorFc=&TimgFilterMirror::mirror<int16_t>;
      case 3:mirrorFc=&TimgFilterMirror::mirror<int24_t>;break;
      case 4:mirrorFc=&TimgFilterMirror::mirror<int32_t>;break;
      default:mirrorFc=NULL;break;
     }
   if (csp_isYUVpacked(pict.csp))
    {
     unsigned char *src=ptr[0],*dst=ptr[0]+(dx2[0]-1)*2;
     int dx=dx2[0];
     if (pict.cspInfo.packedLumaOffset==0 && pict.cspInfo.packedChromaOffset==1)
      for (unsigned int y=0;y<dy2[0];y++,src+=stride2[0],dst+=stride2[0])
       for (int x=0;x<dx;x+=4)
        {
         std::swap(src[x  ],dst[-x+2]);
         std::swap(src[x+3],dst[-x+1]);
         std::swap(src[x+2],dst[-x  ]);
         std::swap(src[x+1],dst[-x+3]);
        }
     else
      for (unsigned int y=0;y<dy2[0];y++,src+=stride2[0],dst+=stride2[0])
       for (int x=0;x<dx;x+=4)
        {
         std::swap(src[x  ],dst[-x+2]);
         std::swap(src[x+3],dst[-x+1]);
         std::swap(src[x+2],dst[-x  ]);
         std::swap(src[x+1],dst[-x+3]);
        }
    }
   else
    if (mirrorFc)
     for (unsigned int i=0;i<pict.cspInfo.numPlanes;i++)
      {
       unsigned int dx=dx2[i]/2;
       for (unsigned int y=0;y<dy2[i];y++,ptr[i]+=stride2[i])
        (this->*mirrorFc)(i,dx,ptr[i]);
      }
  }
 return parent->deliverSample(++it,pict);
}

⌨️ 快捷键说明

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