tffdshowdecaudio.cpp.svn-base

来自「ffshow源码」· SVN-BASE 代码 · 共 827 行 · 第 1/2 页

SVN-BASE
827
字号
/* * Copyright (c) 2003-2006 Milan Cutka * based on CoreAAC - AAC DirectShow Decoder Filter  (C) 2003 Robert Cioch *      and ac3filter by Vigovsky Alexander *      and mpadecfilter 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 "TffdshowDecAudio.h"#include "ffdebug.h"#include "ffdshow_mediaguids.h"#include "TaudioCodec.h"#include "TdialogSettings.h"#include "TglobalSettings.h"#include "Tpresets.h"#include "TpresetSettingsAudio.h"#include "ToutputAudioSettings.h"#include "TaudioFilters.h"#include "TtrayIcon.h"#include "winamp2/Twinamp2.h"#include "TffdshowDecAudioInputPin.h"#include "dsutil.h"#include "resource.h"#include "Tinfo.h"const TfilterIDFF TffdshowDecAudio::nextFilters[]={ {  /*name*/  _l("OSD"),  /*id*/    0,  /*is*/    IDFF_isOSD,  /*order*/ 0,  /*show*/  0,  /*full*/  0,  /*half*/  0,  /*dlgId*/ IDD_OSD, },  NULL,0}; STDMETHODIMP_(int) TffdshowDecAudio::getVersion2(void){ return VERSION;}CUnknown* WINAPI TffdshowDecAudio::CreateInstance(LPUNKNOWN punk,HRESULT *phr){ TffdshowDecAudio *pNewObject=new TffdshowDecAudio(CLSID_FFDSHOWAUDIO,_l("TffAudioDecoder"),CLSID_TFFDSHOWAUDIOPAGE,IDS_FFDSHOWDECAUDIO,IDI_FFDSHOWAUDIO,punk,phr,IDFF_FILTERMODE_PLAYER|IDFF_FILTERMODE_AUDIO,defaultMerit,new TintStrColl); if (pNewObject==NULL) *phr=E_OUTOFMEMORY; return pNewObject;}CUnknown* WINAPI TffdshowDecAudioRaw::CreateInstance(LPUNKNOWN punk,HRESULT *phr){ TffdshowDecAudioRaw *pNewObject=new TffdshowDecAudioRaw(punk,phr); if (pNewObject==NULL) *phr=E_OUTOFMEMORY; return pNewObject;}template<> interfaces<char_t>::IffdshowDecAudio* TffdshowDecAudio::getDecAudioInterface(void){ return this;}template<> interfaces<tchar_traits<char_t>::other_char_t>::IffdshowDecAudio* TffdshowDecAudio::getDecAudioInterface(void){ return &decAudio_char;}STDMETHODIMP TffdshowDecAudio::NonDelegatingQueryInterface(REFIID riid,void **ppv){ //char riidS[256];guid2str(riid,riidS);OutputDebugString(riidS); CheckPointer(ppv,E_POINTER); if (riid==IID_IffdshowDecAudioA)   return GetInterface<IffdshowDecAudioA>(getDecAudioInterface<IffdshowDecAudioA>(),ppv); else if (riid==IID_IffdshowDecAudioW)   return GetInterface<IffdshowDecAudioW>(getDecAudioInterface<IffdshowDecAudioW>(),ppv); else   return TffdshowDec::NonDelegatingQueryInterface(riid,ppv);}TffdshowDecAudio::TffdshowDecAudio(CLSID Iclsid,const char_t *className,const CLSID &Iproppageid,int IcfgDlgCaptionId,int IiconId,LPUNKNOWN punk,HRESULT *phr,int Imode,int IdefaultMerit,TintStrColl *Ioptions): TffdshowDec(  Ioptions,  className,punk,Iclsid,  globalSettings=Imode&IDFF_FILTERMODE_AUDIORAW?new TglobalSettingsDecAudioRaw(&config,Imode,Ioptions):new TglobalSettingsDecAudio(&config,Imode,Ioptions),  dialogSettings=Imode&IDFF_FILTERMODE_AUDIORAW?new TdialogSettingsDecAudioRaw(Ioptions):new TdialogSettingsDecAudio(Ioptions),  presets=Imode&IDFF_FILTERMODE_AUDIORAW?new TpresetsAudioRaw:new TpresetsAudio,(Tpreset*&)presetSettings,  this,  (TinputPin*&)inpin,  m_pOutput,  m_pGraph,  (Tfilters*&)audioFilters,  Iproppageid,IcfgDlgCaptionId,IiconId,  defaultMerit),  decAudio_char(punk,this),  isTmpgEnc(false),  prevpostgain(1){ setThreadName(DWORD(-1),"decAudio"); setOnChange(IDFF_winamp2dir,this,&TffdshowDecAudio::onWinamp2dirChange); winamp2=NULL; memset(&insf,0,sizeof(insf)); inpin=new TffdshowDecAudioInputPin(NAME("TffdshowDecAudioInputPin"),this,phr,L"In",0);if (!inpin) *phr=E_OUTOFMEMORY; if (FAILED(*phr)) return; inpins.push_back(inpin);m_pInput=inpin; m_pOutput=new CTransformOutputPin(NAME("CTransformOutputPin"),this,phr,L"Out");if (!m_pOutput) *phr=E_OUTOFMEMORY; if (FAILED(*phr))  {   delete m_pInput;   m_pInput=NULL;   return;  } DPRINTF(_l("TffdshowDecAudio::Constructor")); trayIconStart=&TtrayIconBase::start<TtrayIconDecAudio>; audioFilters=NULL; isAudioSwitcher=!!globalSettings->isAudioSwitcher; alwaysextensible=!!globalSettings->alwaysextensible; allowOutStream=!!globalSettings->allowOutStream; m_rtStartDec=m_rtStartProc=_I64_MAX/2; currentOutsf.reset(); actual.cbBuffer=0;}TffdshowDecAudioRaw::TffdshowDecAudioRaw(LPUNKNOWN punk,HRESULT *phr):TffdshowDecAudio(CLSID_FFDSHOWAUDIORAW,_l("TffdshowDecAudioRaw"),CLSID_TFFDSHOWAUDIORAWPAGE,IDS_FFDSHOWDECAUDIORAW,IDI_FFDSHOWAUDIO,punk,phr,IDFF_FILTERMODE_PLAYER|IDFF_FILTERMODE_AUDIORAW,defaultMerit,new TintStrColl){}TffdshowDecAudio::~TffdshowDecAudio(){ for (size_t i=1;i<inpins.size();i++) delete inpins[i]; if (winamp2) delete winamp2;}int TffdshowDecAudio::GetPinCount(void){ bool allconnect=isAudioSwitcher?(inpins.size()==inpins.getNumConnectedInpins()):false; return (int)inpins.size()+(allconnect?1:0)+1;}CBasePin* TffdshowDecAudio::GetPin(int n){ if (n==0)  return m_pOutput; n--; if (n<(int)inpins.size())   return inpins[n]; else  {   wchar_t name[50];swprintf(name,L"In%i",n+1);   HRESULT phr=0;   TffdshowDecAudioInputPin *ipin=new TffdshowDecAudioInputPin(_l("CDECSSInputPin"),this,&phr,name,n+1);   if (FAILED(phr)) return NULL;   inpins.push_back(ipin);   return ipin;  }}STDMETHODIMP TffdshowDecAudio::FindPin(LPCWSTR Id, IPin **ppPin){ if (!ppPin) return E_POINTER; if (wcscmp(Id,m_pOutput->Name())==0)  *ppPin=m_pOutput; else  *ppPin=inpins.find(Id); if (*ppPin)  {    (*ppPin)->AddRef();   return S_OK;  }  else   return VFW_E_NOT_FOUND;}CodecID TffdshowDecAudio::getCodecId(const CMediaType &mt){ DPRINTF(_l("TffdshowDecAudio::getCodecId")); //char typeS[256];DPRINTF("TffdshowDecAudio::getCodecId Type:%s",guid2str(type,typeS)); if (mt.majortype!=MEDIATYPE_Audio && mt.majortype!=MEDIATYPE_MPEG2_PES && mt.majortype!=MEDIATYPE_DVD_ENCRYPTED_PACK) return CODEC_ID_NONE; //char subtypeS[256],formattypeS[256];DPRINTF("TffdshowDecAudio::getCodecId Subtype:%s, FormatType:%s",guid2str(subtype,subtypeS),guid2str(formattype,formattypeS)); if (mt.formattype!=FORMAT_WaveFormatEx &&      mt.formattype!=FORMAT_VorbisFormat &&      mt.formattype!=FORMAT_VorbisFormat2 &&      mt.formattype!=FORMAT_VorbisFormatIll)  return CODEC_ID_NONE;  DWORD wFormatTag=0; if (mt.subtype==MEDIASUBTYPE_Vorbis || mt.subtype==MEDIASUBTYPE_Vorbis2 || mt.subtype==MEDIASUBTYPE_VorbisIll)  wFormatTag=WAVE_FORMAT_VORBIS; else if (mt.subtype==MEDIASUBTYPE_DOLBY_AC3)  wFormatTag=WAVE_FORMAT_AC3_W; else if (mt.subtype==MEDIASUBTYPE_DTS)  wFormatTag=WAVE_FORMAT_DTS_W;  else if (mt.subtype==MEDIASUBTYPE_DVD_LPCM_AUDIO)  wFormatTag=WAVE_FORMAT_LPCM; else if (mt.subtype==MEDIASUBTYPE_AAC3)  wFormatTag=WAVE_FORMAT_AAC3;  else if (mt.subtype==MEDIASUBTYPE_MPEG2_AUDIO)  wFormatTag=WAVE_FORMAT_MPEG;  else if (mt.subtype==MEDIASUBTYPE_SAMR)  wFormatTag=WAVE_FORMAT_SAMR;  else   {   const WAVEFORMATEX *wfex=(const WAVEFORMATEX*)mt.pbFormat;   if ((mt.subtype==MEDIASUBTYPE_MPEG1AudioPayload || wfex->wFormatTag==WAVE_FORMAT_MPEG) && mt.cbFormat)    {     MPEG1WAVEFORMAT *m1wf=(MPEG1WAVEFORMAT*)mt.pbFormat;     switch (m1wf->fwHeadLayer)      {       case ACM_MPEG_LAYER1:wFormatTag=WAVE_FORMAT_MPEG;break;       case ACM_MPEG_LAYER2:wFormatTag=WAVE_FORMAT_MPEG;break;       case ACM_MPEG_LAYER3:wFormatTag=WAVE_FORMAT_MPEGLAYER3;break;      }    }   else if ((mt.subtype==MEDIASUBTYPE_QDM2 || mt.subtype==MEDIASUBTYPE_qdm2) && wfex->wFormatTag==0 && wfex->cbSize>8 && (*((FOURCC*)((uint8_t*)(wfex+1)+4))==WAVE_FORMAT_QDM2 || *((FOURCC*)((uint8_t*)(wfex+1)+4))==WAVE_FORMAT_qdm2))    wFormatTag=WAVE_FORMAT_QDM2;   else if (mt.subtype==MEDIASUBTYPE_IMA4 && wfex->wFormatTag==0 && wfex->cbSize>8 && *((FOURCC*)((uint8_t*)(wfex+1)+4))==mmioFOURCC('i','m','a','4'))    wFormatTag=WAVE_FORMAT_IMA4;   else if (mt.subtype==MEDIASUBTYPE_MAC3)    wFormatTag=WAVE_FORMAT_MAC3;   else if (mt.subtype==MEDIASUBTYPE_MAC6)    wFormatTag=WAVE_FORMAT_MAC6;   else if (mt.subtype==MEDIASUBTYPE_ULAW || mt.subtype==MEDIASUBTYPE_ulaw)    wFormatTag=WAVE_FORMAT_MULAW;   else if (mt.subtype==MEDIASUBTYPE_ALAW || mt.subtype==MEDIASUBTYPE_alaw)    wFormatTag=WAVE_FORMAT_ALAW;   else if (mt.subtype==MEDIASUBTYPE_SOWT || mt.subtype==MEDIASUBTYPE_sowt || mt.subtype==MEDIASUBTYPE_TWOS || mt.subtype==MEDIASUBTYPE_twos)    wFormatTag=WAVE_FORMAT_PCM16;    else if (mt.subtype==MEDIASUBTYPE_IN32 || mt.subtype==MEDIASUBTYPE_in32)    wFormatTag=WAVE_FORMAT_PCM32;    else if (mt.subtype==MEDIASUBTYPE_IN24 || mt.subtype==MEDIASUBTYPE_in24)    wFormatTag=WAVE_FORMAT_PCM24;    else if (mt.subtype==MEDIASUBTYPE_FL32 || mt.subtype==MEDIASUBTYPE_fl32)    wFormatTag=WAVE_FORMAT_FLOAT32;   else if (mt.subtype==MEDIASUBTYPE_FL64 || mt.subtype==MEDIASUBTYPE_fl64)    wFormatTag=WAVE_FORMAT_FLOAT64;   if (wFormatTag==0)    wFormatTag=wfex->wFormatTag;   DPRINTF(_l("TffdshowDecAudio::getCodecId: %i Hz, %i channels"),(int)wfex->nSamplesPerSec,(int)wfex->nChannels);   wFormatTag=TsampleFormat::getPCMformat(mt,wFormatTag);  } CodecID codecId=globalSettings->getCodecId(wFormatTag,NULL); DPRINTF(_l("TffdshowDecAudio::getCodecId: codecId=%i"),codecId); return codecId;}HRESULT TffdshowDecAudio::CheckInputType(const CMediaType *mtIn){ DPRINTF(_l("TffdshowDecAudio::CheckInputType")); return getCodecId(*mtIn)==CODEC_ID_NONE?VFW_E_TYPE_NOT_ACCEPTED:S_OK;}HRESULT TffdshowDecAudio::CheckConnect(PIN_DIRECTION dir,IPin *pPin){ DPRINTF(_l("TffdshowDecAudio::CheckConnect (%s)"),dir==PINDIR_INPUT?_l("input"):_l("output")); HRESULT res=E_UNEXPECTED; switch (dir)  {   case PINDIR_INPUT:    res=checkInputConnect(pPin);    break;   case PINDIR_OUTPUT:    initPreset();    if (presetSettings->output->connectTo!=0)     {      if (presetSettings->output->connectToOnlySpdif)       {        TsampleFormat outsf=getOutsf();        if (outsf.sf!=TsampleFormat::SF_AC3)         {          res=S_OK;          break;         }       }      CLSID clsid=GetCLSID(pPin);      res=((presetSettings->output->connectTo==1 && clsid==CLSID_DSoundRender) || (presetSettings->output->connectTo==2 && clsid==CLSID_AudioRender))?S_OK:E_FAIL;     }    else      res=S_OK;    break;  }; return res==S_OK?CTransformFilter::CheckConnect(dir,pPin):res;}TsampleFormat TffdshowDecAudio::getOutsf(void){ TsampleFormat outsf; if (inpin->getsf(outsf)) // SPDIF  return outsf; else   {   if (!audioFilters) audioFilters=new TaudioFiltersPlayer(this,this);   audioFilters->getOutputFmt(outsf,presetSettings);   return outsf;  } }HRESULT TffdshowDecAudio::getMediaType(CMediaType *mtOut){ if (inpin->is_spdif_codec())  *mtOut=TsampleFormat::createMediaTypeSPDIF(); else  {   if (!presetSettings) initPreset();   TsampleFormat outsf=getOutsf();   if (outsf.sf==TsampleFormat::SF_AC3)    *mtOut=TsampleFormat::createMediaTypeSPDIF();   else    *mtOut=outsf.toCMediaType(alwaysextensible);   char_t descS[256];    outsf.descriptionPCM(descS,256);    DPRINTF(_l("TffdshowDecAudio::getMediaType:%s"),descS);  }  return S_OK;}HRESULT TffdshowDecAudio::GetMediaType(int iPosition, CMediaType *mtOut){ if (!inpin->IsConnected()) return E_UNEXPECTED; if (iPosition<0) return E_INVALIDARG; if (iPosition>(allowOutStream?1:0)) return VFW_S_NO_MORE_ITEMS;  switch (iPosition)  {   case 0:    getMediaType(mtOut);    break;   case 1:    mtOut->SetType(&MEDIATYPE_Stream);    mtOut->SetSubtype(&MEDIASUBTYPE_None);    mtOut->SetFormatType(&FORMAT_None);    mtOut->SetSampleSize(48000*6*4/5);    mtOut->SetVariableSize();    mtOut->SetTemporalCompression(FALSE);    break;  } return S_OK;}HRESULT TffdshowDecAudio::DecideBufferSize(IMemAllocator *pAllocator, ALLOCATOR_PROPERTIES *pProperties){ DPRINTF(_l("TffdshowDecAudio::DecideBufferSize")); if (!presetSettings) initPreset(); pProperties->cBuffers=4; pProperties->cbBuffer=48000*6*4/5; pProperties->cbAlign=1; pProperties->cbPrefix=0;  DPRINTF(_l("TffAudioDecoder::DecideBufferSize %d"),pProperties->cbBuffer); HRESULT hr; if(FAILED(hr=pAllocator->SetProperties(pProperties,&actual))) return hr; return pProperties->cBuffers>actual.cBuffers || pProperties->cbBuffer>actual.cbBuffer?E_FAIL:S_OK;}HRESULT TffdshowDecAudio::CheckTransform(const CMediaType *mtIn,const CMediaType *mtOut){ DPRINTF(_l("TffdshowDecAudio::CheckTransform"));#if 0 return SUCCEEDED(CheckInputType(&inpin->CurrentMediaType())) && (mtOut->majortype==MEDIATYPE_Audio && (mtOut->subtype==MEDIASUBTYPE_PCM || mtOut->subtype==MEDIASUBTYPE_IEEE_FLOAT))?S_OK:VFW_E_TYPE_NOT_ACCEPTED;#else //more strict check for output sample type if (!SUCCEEDED(CheckInputType(&inpin->CurrentMediaType()))) return VFW_E_TYPE_NOT_ACCEPTED; if (allowOutStream && *mtOut->Type()==MEDIATYPE_Stream)  {   fileout=true;   return S_OK;  } else  {   fileout=false;   if (!m_pInput->IsConnected() && m_pOutput->IsConnected())    return S_OK;   else    {     CMediaType ffOut;     if (getMediaType(&ffOut)!=S_OK) return VFW_E_TYPE_NOT_ACCEPTED;     return ffOut==*mtOut?S_OK:VFW_E_TYPE_NOT_ACCEPTED;    }  }#endif}HRESULT TffdshowDecAudio::CompleteConnect(PIN_DIRECTION direction,IPin *pReceivePin){ if (direction==PINDIR_OUTPUT)  {   const CLSID &out=GetCLSID(m_pOutput->GetConnected());   static const GUID CLSID_TMPGencGetSample={0x10AA1647,0xCECE,0x40D4,0x8C,0x35,0xD2,0x5D,0xDA,0x77,0x5B,0xEF};   isTmpgEnc=!!(out==CLSID_TMPGencGetSample);  }  return CTransformFilter::CompleteConnect(direction,pReceivePin);}HRESULT TffdshowDecAudio::StartStreaming(void){ DPRINTF(_l("TffdshowDecAudio::StartStreaming"));

⌨️ 快捷键说明

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