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 + -
显示快捷键?