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

📄 timgfilter.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 "TimgFilter.h"
#include "TimgFilters.h"
#include "Tlibmplayer.h"
#include "Tconvert.h"
#include "IffdshowBase.h"
#include "IffdshowDec.h"
#include "IffdshowDecVideo.h"

TimgFilter::TimgFilter(IffdshowBase *Ideci,Tfilters *Iparent):Tfilter(Ideci),parent((TimgFilters*)Iparent),deciV(Ideci)
{
 csp1=csp2=FF_CSP_NULL;
 convert1=convert2=NULL;
 pictRect.x=UINT_MAX;
}
TimgFilter::~TimgFilter()
{
 free();
}
void TimgFilter::checkBorder(TffPict &pict)
{
 if (pict.rectFull!=pict.rectClip && parent->dirtyBorder)
  {
   pict.clearBorder();
   parent->dirtyBorder=0;
  }
}

void TimgFilter::free(void)
{
 own1.clear();if (convert1) delete convert1;convert1=NULL;
 own2.clear();if (convert2) delete convert2;convert2=NULL;
}

void TimgFilter::init(const TffPict &pict,int full,int half)
{
 pictHalf=half;
 Trect newRect=pict.getRect(full,half);
 if (newRect!=pictRect || newRect.sar!=pictRect.sar)
  {
   onSizeChange();
   free();
   pictRect=newRect;
  }
}

bool TimgFilter::is(const TffPictBase &pict,const TfilterSettingsVideo *cfg)
{
 return cfg->is && cfg->show;
}

HRESULT TimgFilter::flush(TfilterQueue::iterator it,TffPict &pict,const TfilterSettingsVideo *cfg0)
{
 return parent->deliverSample(++it,pict);
}

bool TimgFilter::getOutputFmt(TffPictBase &pict,const TfilterSettingsVideo *cfg)
{
 if (!is(pict,cfg)) return false;
 int supcsp1=getSupportedInputColorspaces(cfg);
 if (((pict.csp&FF_CSPS_MASK)&(supcsp1&FF_CSPS_MASK))==0)
  pict.csp=csp_bestMatch(pict.csp,supcsp1&FF_CSPS_MASK)|(supcsp1&FF_CSP_FLAGS_VFLIP);
 int supcsp2=getSupportedOutputColorspaces(cfg);
 if (((pict.csp&FF_CSPS_MASK)&(supcsp2&FF_CSPS_MASK))==0)
  pict.csp=csp_bestMatch(pict.csp,supcsp2&FF_CSPS_MASK)|(supcsp2&FF_CSP_FLAGS_VFLIP);
 return true;
}

bool TimgFilter::getCur(int csp,TffPict &pict,int full,const unsigned char **src[4])
{
 int wasAdj=pict.csp&FF_CSP_FLAGS_YUV_ADJ;
 csp_yuv_adj_to_plane(pict.csp,&pict.cspInfo,pict.rectFull.dy,pict.data,pict.stride);csp_yuv_order(pict.csp,pict.data,pict.stride);
 if (((csp&FF_CSPS_MASK)&(pict.csp&FF_CSPS_MASK))==0 || ((csp&FF_CSP_FLAGS_YUV_ADJ) && !wasAdj))
  {
   if (!convert1) convert1=new Tconvert(deci,pict.rectFull.dx,pict.rectFull.dy);
   pict.convertCSP(csp_bestMatch(pict.csp,csp&FF_CSPS_MASK)|(csp&(FF_CSP_FLAGS_VFLIP|FF_CSP_FLAGS_YUV_ADJ|FF_CSP_FLAGS_YUV_ORDER)),own1,convert1);
   pict.setRO(false);
  }
 bool cspChanged=csp1!=pict.csp;
 csp1=pict.csp;
 const Trect &r=pictRect; //full?pict.rectFull:pict.rectClip;
 for (unsigned int i=0;i<pict.cspInfo.numPlanes;i++)
  {
   if (src[i])
    *src[i]=pict.data[i]+(full?0:pict.diff[i])+(pictHalf?r.x*pict.cspInfo.Bpp>>pict.cspInfo.shiftX[i]:0);
   stride1[i]=pict.stride[i];
   dx1[i]=r.dx>>pict.cspInfo.shiftX[i];
   dy1[i]=r.dy>>pict.cspInfo.shiftY[i];
  }
 return cspChanged;
}
bool TimgFilter::getNext(int csp,TffPict &pict,int full,unsigned char **dst[4],const Trect *rect2)
{
 if (rect2) pict.rectFull=pict.rectClip=*rect2;
 const Trect &r=pictRect;//full?pict.rectFull:pict.rectClip;
 TffPict pictN;
 if (((csp&FF_CSPS_MASK)&(pict.csp&FF_CSPS_MASK))==0)
  {
   pict.convertCSP(csp_bestMatch(pict.csp,csp&FF_CSPS_MASK)|(csp&FF_CSP_FLAGS_YUV_ADJ),own2);
   pict.setRO(false);
   pictN=pict;
  }
 else
  {
   pictN=pict;
   pictN.convertCSP(pict.csp|(csp&FF_CSP_FLAGS_YUV_ADJ),own2);
  }
 bool copyBorder=!rect2 && !full && pict.rectClip!=pict.rectFull;
 for (unsigned int i=0;i<pict.cspInfo.numPlanes;i++)
  {
   if (dst[i])
    {
     if (copyBorder)
      pictN.copyBorder(pict,i);
     if (pictHalf && !rect2)
      TffPict::copy(pictN.data[i]+(full?0:pictN.diff[i]),pictN.stride[i],pict.data[i]+(full?0:pict.diff[i]),pict.stride[i],(pictRect.dx>>pictN.cspInfo.shiftX[i])*pict.cspInfo.Bpp,pictRect.dy>>pictN.cspInfo.shiftY[i]);
     pict.diff[i]=pictN.diff[i];
     pict.ro[i]=false;
     pict.data[i]=pictN.data[i];
     pict.stride[i]=pictN.stride[i];
     *dst[i]=pict.data[i]+(full?0:pict.diff[i]);
     if (pictHalf && !rect2)
      *dst[i]+=(pictRect.x>>pict.cspInfo.shiftX[i])*pict.cspInfo.Bpp;
    }
   stride2[i]=pict.stride[i];
   dx2[i]=r.dx>>pict.cspInfo.shiftX[i];
   dy2[i]=r.dy>>pict.cspInfo.shiftY[i];
  }
 bool cspChanged=csp2!=pict.csp;
 csp2=pictN.csp;
 return cspChanged;
}
bool TimgFilter::getNext(int csp,TffPict &pict,const Trect &clipRect,unsigned char **dst[4],const Trect *rect2)
{
 bool cspChanged=getNext(csp,pict,true,dst,rect2);
 pict.rectClip=clipRect;
 pict.calcDiff();
 for (unsigned int i=0;i<pict.cspInfo.numPlanes;i++)
  if (dst[i])
   *dst[i]+=pict.diff[i];
 if (cspChanged)
  pict.clearBorder();
 return cspChanged;
}
bool TimgFilter::getCurNext(int csp,TffPict &pict,int full,int copy,unsigned char **dst[4])
{
 csp_yuv_adj_to_plane(pict.csp,&pict.cspInfo,pict.rectFull.dy,pict.data,pict.stride);csp_yuv_order(pict.csp,pict.data,pict.stride);
 TffPict pictN;
 if (((csp&FF_CSPS_MASK)&(pict.csp&FF_CSPS_MASK))==0)
  {
   if (!convert2) convert2=new Tconvert(deci,pict.rectFull.dx,pict.rectFull.dy);
   pict.convertCSP((csp_bestMatch(pict.csp,csp&FF_CSPS_MASK)&~FF_CSP_FLAGS_VFLIP)|(csp&FF_CSP_FLAGS_YUV_ADJ),own2,convert2);
   pict.setRO(false);
   pictN=pict;
  }
 else
  {
   pictN=pict;
   pictN.convertCSP(pict.csp|(csp&FF_CSP_FLAGS_YUV_ADJ),own2);
  }
 const Trect r=pictRect;//=full?pict.rectFull:pict.rectClip;
 if (copy==COPYMODE_DEF) copy=full?COPYMODE_FULL:COPYMODE_CLIP;
 bool copyBorder=!full && pict.rectClip!=pict.rectFull;
 for (unsigned int i=0;i<pictN.cspInfo.numPlanes;i++)
  if (dst[i])
   {
    dx1[i]=dx2[i]=r.dx>>pict.cspInfo.shiftX[i];
    dy1[i]=dy2[i]=r.dy>>pict.cspInfo.shiftY[i];
    if (pict.ro[i])
     {
      pict.ro[i]=false;
      switch (copy)
       {
        case COPYMODE_CLIP:
         if (copyBorder) pictN.copyBorder(pict,i);
         TffPict::copy(pictN.data[i]+pictN.diff[i],pictN.stride[i],pict.data[i]+pict.diff[i],pict.stride[i],(pict.rectClip.dx>>pict.cspInfo.shiftX[i])*pict.cspInfo.Bpp,pict.rectClip.dy>>pict.cspInfo.shiftY[i]);
         break;
        case COPYMODE_FULL:
         TffPict::copy(pictN.data[i],pictN.stride[i],pict.data[i],pict.stride[i],(pict.rectFull.dx>>pict.cspInfo.shiftX[i])*pict.cspInfo.Bpp,pict.rectFull.dy>>pict.cspInfo.shiftY[i]);
         break;
        case COPYMODE_NO:
         if (pictHalf)
          TffPict::copy(pictN.data[i],pictN.stride[i],pict.data[i],pict.stride[i],(pictRect.dx>>pict.cspInfo.shiftX[i])*pict.cspInfo.Bpp,pictRect.dy>>pict.cspInfo.shiftY[i]);
       }
      pict.data[i]=pictN.data[i];
      pict.stride[i]=pictN.stride[i];
      pict.diff[i]=pictN.diff[i];
     }
    stride2[i]=pict.stride[i];
    *dst[i]=pict.data[i]+(full?0:pict.diff[i])+(pictHalf?r.x*pict.cspInfo.Bpp>>pict.cspInfo.shiftX[i]:0);
   }
 bool cspChanged=csp2!=pict.csp;
 csp2=pictN.csp;
 if (full) checkBorder(pict);
 return cspChanged;
}

bool TimgFilter::screenToPict(CPoint &pt)
{
 GetCursorPos(&pt);
 int wx,wy;
 if (SUCCEEDED(deciV->getVideoWindowPos(&wx,&wy,NULL,NULL)))
  {
   pt-=CPoint(wx,wy);
   CRect dst;
   if (SUCCEEDED(deciV->getVideoDestRect(&dst)))
    {
     pt-=CPoint(dst.TopLeft());
     pt.scale(dx2[0],dst.Width(),dy2[0],dst.Height());
     if (isIn(pt.x,0L,long(dx2[0]-1)) && isIn(pt.y,0L,long(dy2[0]-1)))
      return true;
    }
  }
 return false;
}

⌨️ 快捷键说明

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