dsutil.cpp.svn-base

来自「ffshow源码」· SVN-BASE 代码 · 共 454 行

SVN-BASE
454
字号
/* * Copyright (c) 2002-2006 Milan Cutka * uses many routines developed by Gabest * * 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 "dsutil.h"#include "TffRect.h"#include "theora/theora.h"#include "vorbis/vorbisformat.h"#include "ffdshow_mediaguids.h"// registry key info from RadLight Filter Manager v1.3 by RadScorpionstatic void getFilterReg(const CLSID &clsid,char_t *reg){ LPOLESTR sclsidW; StringFromIID(clsid,&sclsidW); //char sclsid[MAX_PATH]; //WideCharToMultiByte(CP_ACP,0,sclsidW,-1,sclsid,MAX_PATH,NULL,NULL); tsprintf(reg,_l("\\CLSID\\{083863F1-70DE-11d0-BD40-00A0C911CE86}\\Instance\\%s"),(const char_t*)text<char_t>(sclsidW)); CoTaskMemFree(sclsidW);}struct TfilterReg{ DWORD version; DWORD merit; BYTE b[16384];};HRESULT getFilterMerit(HKEY hive,const char_t *reg,DWORD *merit){ HKEY hKey; HRESULT res=E_FAIL; if (RegOpenKeyEx(hive,reg,0,KEY_READ,&hKey)==ERROR_SUCCESS)  {   TfilterReg buf;   DWORD buflen=sizeof(buf);   if (RegQueryValueEx(hKey,_l("FilterData"),NULL,NULL,LPBYTE(&buf),&buflen)==ERROR_SUCCESS)    {     *merit=buf.merit;     res=S_OK;    }    RegCloseKey(hKey);  } return res; }HRESULT getFilterMerit(const CLSID &clsid,DWORD *merit){ if (!merit) return E_POINTER; char_t reg[MAX_PATH];getFilterReg(clsid,reg); return getFilterMerit(HKEY_CLASSES_ROOT,reg,merit);}HRESULT setFilterMerit(HKEY hive,const char_t *reg,DWORD merit){ HKEY hKey; HRESULT res=E_FAIL; if (RegOpenKeyEx(hive,reg,0,KEY_READ|KEY_WRITE,&hKey)==ERROR_SUCCESS)  {   TfilterReg buf;   DWORD buflen=sizeof(buf);   if (RegQueryValueEx(hKey,_l("FilterData"),NULL,NULL,LPBYTE(&buf),&buflen)==ERROR_SUCCESS)    {     buf.merit=merit;     if (RegSetValueEx(hKey,_l("FilterData"),NULL,REG_BINARY,LPBYTE(&buf),buflen)==ERROR_SUCCESS)      res=S_OK;    }    RegCloseKey(hKey);  } return res; }HRESULT setFilterMerit(const CLSID &clsid,DWORD merit){ char_t reg[MAX_PATH];getFilterReg(clsid,reg); return setFilterMerit(HKEY_CLASSES_ROOT,reg,merit);}bool ExtractBIH(const AM_MEDIA_TYPE &mt, BITMAPINFOHEADER* bih){ if (mt.formattype==FORMAT_VideoInfo)  {   VIDEOINFOHEADER* vih = (VIDEOINFOHEADER*)mt.pbFormat;   memcpy(bih, &vih->bmiHeader, sizeof(BITMAPINFOHEADER));   return true;  } else if(mt.formattype == FORMAT_VideoInfo2)  {   VIDEOINFOHEADER2* vih = (VIDEOINFOHEADER2*)mt.pbFormat;   memcpy(bih, &vih->bmiHeader, sizeof(BITMAPINFOHEADER));   return true;  } if(mt.formattype == FORMAT_MPEGVideo)  {   VIDEOINFOHEADER* vih = &((MPEG1VIDEOINFO*)mt.pbFormat)->hdr;   memcpy(bih, &vih->bmiHeader, sizeof(BITMAPINFOHEADER));   return true;  } else if(mt.formattype == FORMAT_MPEG2_VIDEO)  {   VIDEOINFOHEADER2* vih = &((MPEG2VIDEOINFO*)mt.pbFormat)->hdr;   memcpy(bih, &vih->bmiHeader, sizeof(BITMAPINFOHEADER));   return true;  } else if(mt.formattype == FORMAT_TheoraIll)  {   sTheoraFormatBlock *oggFormat=(sTheoraFormatBlock*)mt.pbFormat;   memset(bih,0,sizeof(*bih));   bih->biCompression=FOURCC_THEO;   bih->biWidth=oggFormat->width;   bih->biHeight=oggFormat->height;   bih->biBitCount=12;   return true;  } else   return false;}void getFilterName(IBaseFilter *filter,char_t *name,char_t *filtername){ name[0]='\0';filtername[0]='\0'; CLSID iffclsid; filter->GetClassID(&iffclsid); getCLSIDname(iffclsid,name,256); FILTER_INFO iff; if (filter->QueryFilterInfo(&iff)==S_OK)  {   //WideCharToMultiByte(CP_ACP,0,iff.achName,-1,filtername,MAX_PATH,NULL,NULL);   text<char_t>(iff.achName,filtername);   if (iff.pGraph) iff.pGraph->Release();  } if (name[0]=='\0') strcpy(name,filtername);}pins_vector::~pins_vector(){ for (iterator p=begin();p!=end();p++)  (*p)->Release();}pins_vector::pins_vector(IBaseFilter *filter,PIN_DIRECTION dir){ clear(); comptr<IEnumPins> ep; if (SUCCEEDED(filter->EnumPins(&ep)))  {   ep->Reset();   for (comptr<IPin> p;ep->Next(1,&p,NULL)==S_OK;p=NULL)    {     PIN_INFO pi;     if (SUCCEEDED(p->QueryPinInfo(&pi)))      {       if (pi.dir==dir)        {         p->AddRef();         push_back(p);        }        pi.pFilter->Release();       }    }   }}struct TpinClsidCompare{private: const CLSID &clsid;public: TpinClsidCompare(const CLSID &Iclsid):clsid(Iclsid) {} bool operator()(const CLSID &c,IPin*) const  {   return !!(c==clsid);  }};bool searchPrevNextFilter(PIN_DIRECTION direction,IPin *pin,const CLSID &clsid){ return searchPrevNextFilter(direction,pin,pin,NULL,TpinClsidCompare(clsid));}template<class Tcompare> bool searchFilterInterface(IFilterGraph *graph,IUnknown* *dest,Tcompare compFc){ if (!graph) return false; comptr<IEnumFilters> eff; *dest=NULL; if (graph->EnumFilters(&eff)==S_OK)  {   eff->Reset();   for (comptr<IBaseFilter> bff;eff->Next(1,&bff,NULL)==S_OK;bff=NULL)    if (compFc(bff,dest))     return true;  } return false;}struct TfilterInterfaceCmp{private: const IID &iid;public: TfilterInterfaceCmp(const IID &Iiid):iid(Iiid) {}  bool operator()(IBaseFilter *f,IUnknown* *dest)  {   return f->QueryInterface(iid,(void**)dest)==S_OK && *dest;  }};bool searchFilterInterface(IFilterGraph *graph,const IID &iid,IUnknown* *dest){ return searchFilterInterface(graph,dest,TfilterInterfaceCmp(iid));}struct TpinInterfaceCmp{private: const IID &iid;public: TpinInterfaceCmp(const IID &Iiid):iid(Iiid) {}  bool operator()(IBaseFilter *f,IUnknown* *dest)  {   comptr<IEnumPins> epi;   if (f->EnumPins(&epi)==S_OK)    {     epi->Reset();     for (comptr<IPin> bpi;epi->Next(1,&bpi,NULL)==S_OK;bpi=NULL)      {       if (bpi->QueryInterface(iid,(void**)dest)==S_OK && *dest)        return true;      }    }   return false;   }};bool searchPinInterface(IFilterGraph *graph,const IID &iid,IUnknown **dest){ return searchFilterInterface(graph,dest,TpinInterfaceCmp(iid));}IBaseFilter* searchFilter(IFilterGraph *graph,const CLSID &clsid,IBaseFilter *exclude){ comptr<IEnumFilters> eff; if (graph->EnumFilters(&eff)==S_OK)  {   eff->Reset();   for (comptr<IBaseFilter> bff;eff->Next(1,&bff,NULL)==S_OK;bff=NULL)    if (!exclude || bff!=exclude)     {      CLSID bffclsid;      if (SUCCEEDED(bff->GetClassID(&bffclsid)) && bffclsid==clsid)       return bff;     }  } return NULL; }CLSID GetCLSID(IBaseFilter* pBF){ CLSID clsid=GUID_NULL; if (pBF) pBF->GetClassID(&clsid); return clsid;}class CPinInfo : public PIN_INFO{public: CPinInfo() {pFilter=NULL;} ~CPinInfo() {if (pFilter) pFilter->Release();}};static IBaseFilter* GetFilterFromPin(IPin* pPin){ if (!pPin) return NULL; IBaseFilter *pBF=NULL; CPinInfo pi; if (pPin && SUCCEEDED(pPin->QueryPinInfo(&pi)))  pBF=pi.pFilter; return pBF;}CLSID GetCLSID(IPin* pPin){ return GetCLSID(GetFilterFromPin(pPin));}void setVIH2aspect(VIDEOINFOHEADER2 *vih2,const Trect &r,int userDAR256){ if (userDAR256)  {   vih2->dwPictAspectRatioX=userDAR256>>8;   vih2->dwPictAspectRatioY=256;  } else  {   vih2->dwPictAspectRatioX=r.dar().num;   vih2->dwPictAspectRatioY=r.dar().den;   vih2->dwControlFlags=0;  } //DPRINTF("setVIH2aspect: aspectX:%i, aspectY:%i",vih2->dwPictAspectRatioX,vih2->dwPictAspectRatioY);}void bih2mediatype(const BITMAPINFOHEADER &bih,CMediaType *mt){ mt->SetType(&MEDIATYPE_Video); mt->SetFormatType(&FORMAT_VideoInfo); mt->SetTemporalCompression(FALSE); mt->SetSampleSize(bih.biSizeImage); unsigned int elen=bih.biSize-sizeof(BITMAPINFOHEADER); if (elen==0 && bih.biClrUsed>0)  elen=sizeof(RGBQUAD)*bih.biClrUsed; VIDEOINFOHEADER *vih=(VIDEOINFOHEADER*)mt->ReallocFormatBuffer(sizeof(VIDEOINFOHEADER)+elen); if (vih)  {   ZeroMemory(vih,sizeof(VIDEOINFOHEADER));   vih->rcSource.left=0;vih->rcSource.right=bih.biWidth;vih->rcSource.top=0;vih->rcSource.bottom=bih.biHeight;   vih->rcTarget=vih->rcSource;   vih->AvgTimePerFrame=0;   vih->bmiHeader=bih;   if (elen)    memcpy(&vih->bmiHeader+1,&bih+1,elen);  } }REFERENCE_TIME getAvgTimePerFrame(const CMediaType &mt){ if (mt.formattype==FORMAT_VideoInfo)  return ((VIDEOINFOHEADER*)mt.pbFormat)->AvgTimePerFrame; else if (mt.formattype==FORMAT_VideoInfo2)  return ((VIDEOINFOHEADER2*)mt.pbFormat)->AvgTimePerFrame; else if (mt.formattype==FORMAT_MPEGVideo)  return ((MPEG1VIDEOINFO*)mt.pbFormat)->hdr.AvgTimePerFrame; else if (mt.formattype==FORMAT_MPEG2Video)  return ((MPEG2VIDEOINFO*)mt.pbFormat)->hdr.AvgTimePerFrame; else if (mt.formattype==FORMAT_TheoraIll)  {   const sTheoraFormatBlock *oggFormat=(const sTheoraFormatBlock*)mt.pbFormat;   return oggFormat->frameRateDenominator*REF_SECOND_MULT/oggFormat->frameRateNumerator;  }  else  return 0; }Textradata::Textradata(const CMediaType &mt,int padding):data(NULL),size(0){ const unsigned char *data=NULL;unsigned int size=0; if (mt.formattype==FORMAT_WaveFormatEx)  {   set(parse((const WAVEFORMATEX*)mt.pbFormat),padding);   return;  }  else if (mt.formattype==FORMAT_VideoInfo)  {   size=mt.cbFormat-sizeof(VIDEOINFOHEADER);   data=size?mt.pbFormat+sizeof(VIDEOINFOHEADER):NULL;  }  else if (mt.formattype==FORMAT_VideoInfo2)  {   size=mt.cbFormat-sizeof(VIDEOINFOHEADER2);   data=size?mt.pbFormat+sizeof(VIDEOINFOHEADER2):NULL;  }  else if (mt.formattype==FORMAT_MPEGVideo)  {   set(parse((const MPEG1VIDEOINFO*)mt.pbFormat),padding);   return;  }  else if (mt.formattype==FORMAT_MPEG2Video)  {   set(parse((const MPEG2VIDEOINFO*)mt.pbFormat),padding);   return;  } else if (mt.formattype==FORMAT_VorbisFormat2)  {   const VORBISFORMAT2 *vf2=(const VORBISFORMAT2*)mt.pbFormat;   size=mt.cbFormat-sizeof(VORBISFORMAT2);   data=size?mt.pbFormat+sizeof(VORBISFORMAT2):NULL;  }  else if (mt.formattype==FORMAT_RLTheora)  {   size=mt.cbFormat-sizeof(VIDEOINFOHEADER);   data=size?mt.pbFormat+sizeof(VIDEOINFOHEADER):NULL;  }  set(data,size,padding);}Textradata::Textradata(const WAVEFORMATEX &wfex,int padding):data(NULL),size(0){ set(parse(&wfex),0); }Textradata::Textradata(const MPEG1VIDEOINFO &mpeg1info,int padding){ set(parse(&mpeg1info),0);}Textradata::Textradata(const MPEG2VIDEOINFO &mpeg2info,int padding){ set(parse(&mpeg2info),0);}Textradata::TdataSize Textradata::parse(const WAVEFORMATEX *wfex){ return wfex->cbSize?std::make_pair((const unsigned char*)(wfex+1),(size_t)wfex->cbSize):TdataSize();}Textradata::TdataSize Textradata::parse(const MPEG1VIDEOINFO *mpeg1info){ return std::make_pair(mpeg1info->cbSequenceHeader?mpeg1info->bSequenceHeader:NULL,mpeg1info->cbSequenceHeader);}Textradata::TdataSize Textradata::parse(const MPEG2VIDEOINFO *mpeg2info){ return std::make_pair(mpeg2info->cbSequenceHeader?(const uint8_t*)mpeg2info->dwSequenceHeader:NULL,mpeg2info->cbSequenceHeader);}Textradata::~Textradata(){ done();}void Textradata::done(void){ if (own && data)  free((void*)data);}void Textradata::clear(void){ set(NULL,0);}void Textradata::set(const void *Idata,size_t Isize,unsigned int padding,bool Iown){ set(TdataSize((const unsigned char*)Idata,Isize),padding,Iown);}void Textradata::set(const TdataSize &dataSize,unsigned int padding,bool Iown){ done(); if (dataSize.second>0 && (padding>0 || Iown))  {   own=true;   size=dataSize.second;   data=(const unsigned char*)calloc(1,size+padding);   memcpy((void*)data,dataSize.first,size);  } else  {   own=false;   data=(const unsigned char*)dataSize.first;   size=dataSize.second;  }  }

⌨️ 快捷键说明

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