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

📄 tffproc.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 "IffdshowBase.h"
#include "TffDecoderVideo.h"
#include "TffProc.h"
#include "TffPict.h"
#include "TpresetSettings.h"
#include "Tconvert.h"
#include "ffdshow_constants.h"
#include "ffImgfmt.h"
#include "TpresetSettingsVideo.h"
#include "TimgFilterOutput.h"
#include "ToutputVideoSettings.h"

class TimgFiltersProc :public TimgFilters
{
private:
 TimgFilterOutputConvert outputConvert;ToutputVideoConvertSettings outputConvertCfg;
protected:
 virtual void makeQueue(const Tpreset *cfg,TfilterQueue &queue)
  {
   TimgFilters::makeQueue(cfg,queue);
   queue.add(&outputConvert,&outputConvertCfg);
  }
public:
 TimgFiltersProc(IffdshowBase *Ideci,IprocVideoSink *Isink):TimgFilters(Ideci,Isink),outputConvert(Ideci,this)
  {
  }
 HRESULT processConvert(TffPict &pict,const TpresetVideo *cfg,int outcsp)
  {
   outputConvertCfg.csp=outcsp;
   return TimgFilters::process(pict,cfg);
  }
};

class TffdshowDecVideoProc :public TffdshowDecVideo
{
private:
 IprocVideoSink *procVideoSink;
protected:
 TimgFilters* createImgFilters(void)
  {
   return new TimgFiltersProc(this,procVideoSink);
  }
public:
 TffdshowDecVideoProc(HRESULT *phr,IprocVideoSink* iprocVideoSink):
  TffdshowDecVideo(CLSID_FFDSHOWVFW,NAME("TffdshowDecVideoProc"),CLSID_TFFDSHOWPAGEPROC,IDS_FFDSHOWVIDEOPROC,IDI_FFDSHOW,NULL,phr,IDFF_FILTERMODE_VIDEO|IDFF_FILTERMODE_PROC,MERIT_DO_NOT_USE,new TintStrColl),
  procVideoSink(iprocVideoSink)
  {
   AddRef();
  }
 void release(void)
  {
   if (imgFilters) delete imgFilters;
   Release();
  }

 void onStop()
  {
   if (imgFilters) imgFilters->onStop();
  }

 HRESULT processPict(TffPict &pict,int outcsp)
  {
   if (!imgFilters) imgFilters=createImgFilters();
   return ((TimgFiltersProc*)imgFilters)->processConvert(pict,presetSettings,outcsp);
  }
};

//==================================================================
CUnknown* WINAPI TffProcVideo::CreateInstance(LPUNKNOWN punk,HRESULT *phr)
{
 TffProcVideo *pNewObject=new TffProcVideo(punk,phr);
 if (pNewObject==NULL)
  *phr=E_OUTOFMEMORY;
 return pNewObject;
}
STDMETHODIMP TffProcVideo::NonDelegatingQueryInterface(REFIID riid,void **ppv)
{
 CheckPointer(ppv, E_POINTER);
 if (riid==IID_IffProc6 || riid==IID_IffProc7 || riid==IID_IffProc8)
  return GetInterface<IffProc>(this,ppv);
 else
  return CUnknown::NonDelegatingQueryInterface(riid,ppv);
}

TffProcVideo::TffProcVideo(LPUNKNOWN punk,HRESULT *phr):CUnknown(NAME("TffProcVideo"),punk),TffProcBase(IDFF_FILTERMODE_VIDEO)
{
 HRESULT hr=S_OK;
 proc=new TffdshowDecVideoProc(&hr,this);
 initDeci((IffdshowBase*)proc);
 convert=NULL;outcspInfo=NULL;
}
TffProcVideo::~TffProcVideo()
{
 end();
 proc->release();
}

STDMETHODIMP TffProcVideo::getNewSize(unsigned int srcDx,unsigned int srcDy,unsigned int *outDx,unsigned int *outDy)
{
 return proc->calcNewSize(srcDx,srcDy,outDx,outDy);
}

STDMETHODIMP TffProcVideo::begin(unsigned int srcDx,unsigned int srcDy,int IfpsNum,int IfpsDen)
{
 end();
 fpsNum=IfpsNum;fpsDen=IfpsDen;
 srcR=Trect(0,0,srcDx,srcDy);
 return S_OK;
}
STDMETHODIMP TffProcVideo::end(void)
{
 if (proc) proc->onStop();
 if (convert) delete convert;convert=NULL;
 dstbuf.clear();
 return S_OK;
}

STDMETHODIMP TffProcVideo::process(unsigned int framenum,int incsp,const unsigned char *src[4],stride_t srcStride[4],int ro,int outcsp,unsigned char *dst[4],stride_t dstStride[4])
{
 return processTime(framenum,REF_SECOND_MULT*fpsDen*framenum/fpsNum,REF_SECOND_MULT*fpsDen*(framenum+1)/fpsNum,incsp,src,srcStride,ro,outcsp,dst,dstStride);
}
STDMETHODIMP TffProcVideo::processTime(unsigned int framenum,int64_t ref_start,int64_t ref_stop,int incsp,const unsigned char *src[4],stride_t srcStride[4],int ro,int Ioutcsp,unsigned char *Idst[4],stride_t IdstStride[4])
{
 if (!Idst || !IdstStride) return S_FALSE;
 Trect r=srcR;
 TffPict pict(incsp,(unsigned char**)src,srcStride,r,!!ro,FRAME_TYPE::I,FIELD_TYPE::PROGRESSIVE_FRAME,0,NULL);
 pict.rtStart=ref_start;
 pict.rtStop=ref_stop;
 outcsp=Ioutcsp;dst=Idst;dstStride=IdstStride;
 return processPict(framenum,pict,outcsp);
}
HRESULT TffProcVideo::processPict(unsigned int framenum,TffPict &pict,int outcsp)
{
 deci->putParam(IDFF_currentFrame,framenum);
 return proc->processPict(pict,outcsp);
}

STDMETHODIMP TffProcVideo::deliverProcessedSample(TffPict &pict)
{
 if (!outcspInfo || outcspInfo->id!=(outcsp&FF_CSPS_MASK))
  outcspInfo=csp_getInfo(outcsp);
 if (pict.csp!=outcsp)
  {
   if (!convert) convert=new Tconvert(deci,pict.rectFull.dx,pict.rectFull.dy);
   if (dst[0])
    convert->convert(pict,outcsp,dst,dstStride);
   else
    {
     pict.convertCSP(outcsp,dstbuf,convert);
     for (unsigned int i=0;i<pict.cspInfo.numPlanes;i++)
      {
       dst[i]=pict.data[i];
       dstStride[i]=pict.stride[i];
      }
    }
  }
 else
  if (dst[0])
   for (unsigned int i=0;i<pict.cspInfo.numPlanes;i++)
    TffPict::copy(dst[i],dstStride[i],pict.data[i],pict.stride[i],(pict.rectFull.dx*outcspInfo->Bpp)>>outcspInfo->shiftX[i],pict.rectFull.dy>>outcspInfo->shiftY[i]);
  else
   for (unsigned int i=0;i<pict.cspInfo.numPlanes;i++)
    {
     dst[i]=pict.data[i];
     dstStride[i]=pict.stride[i];
    }
 return S_OK;
}

STDMETHODIMP_(const TcspInfo*) TffProcVideo::getCspInfo(int csp)
{
 return csp_getInfo(csp);
}

⌨️ 快捷键说明

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