/* * $Id$ * * (C) 2003-2006 Gabest * (C) 2006-2010 see AUTHORS * * This file is part of mplayerc. * * Mplayerc 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 3 of the License, or * (at your option) any later version. * * Mplayerc 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, see . * */ #include "stdafx.h" #include "mplayerc.h" #include "FGManager.h" #include "../../DSUtil/DSUtil.h" #include "../../filters/filters.h" #include "AllocatorCommon7.h" #include "AllocatorCommon.h" #include "SyncAllocatorPresenter.h" #include "DeinterlacerFilter.h" #include "internal_filter_config.h" #include #include #include #include #include #include #include #include // // CFGManager // CFGManager::CFGManager(LPCTSTR pName, LPUNKNOWN pUnk) : CUnknown(pName, pUnk) , m_dwRegister(0) { m_pUnkInner.CoCreateInstance(CLSID_FilterGraph, GetOwner()); m_pFM.CoCreateInstance(CLSID_FilterMapper2); } CFGManager::~CFGManager() { CAutoLock cAutoLock(this); while(!m_source.IsEmpty()) delete m_source.RemoveHead(); while(!m_transform.IsEmpty()) delete m_transform.RemoveHead(); while(!m_override.IsEmpty()) delete m_override.RemoveHead(); m_pUnks.RemoveAll(); m_pUnkInner.Release(); } STDMETHODIMP CFGManager::NonDelegatingQueryInterface(REFIID riid, void** ppv) { CheckPointer(ppv, E_POINTER); return QI(IFilterGraph) QI(IGraphBuilder) QI(IFilterGraph2) QI(IGraphBuilder2) QI(IGraphBuilderDeadEnd) m_pUnkInner && (riid != IID_IUnknown && SUCCEEDED(m_pUnkInner->QueryInterface(riid, ppv))) ? S_OK : __super::NonDelegatingQueryInterface(riid, ppv); } // void CFGManager::CStreamPath::Append(IBaseFilter* pBF, IPin* pPin) { path_t p; p.clsid = GetCLSID(pBF); p.filter = GetFilterName(pBF); p.pin = GetPinName(pPin); AddTail(p); } bool CFGManager::CStreamPath::Compare(const CStreamPath& path) { POSITION pos1 = GetHeadPosition(); POSITION pos2 = path.GetHeadPosition(); while(pos1 && pos2) { const path_t& p1 = GetNext(pos1); const path_t& p2 = path.GetNext(pos2); if(p1.filter != p2.filter) return true; else if(p1.pin != p2.pin) return false; } return true; } // bool CFGManager::CheckBytes(HANDLE hFile, CString chkbytes) { CAtlList sl; Explode(chkbytes, sl, ','); if(sl.GetCount() < 4) return false; ASSERT(!(sl.GetCount()&3)); LARGE_INTEGER size = {0, 0}; size.LowPart = GetFileSize(hFile, (DWORD*)&size.HighPart); while(sl.GetCount() >= 4) { CString offsetstr = sl.RemoveHead(); CString cbstr = sl.RemoveHead(); CString maskstr = sl.RemoveHead(); CString valstr = sl.RemoveHead(); long cb = _ttol(cbstr); if(offsetstr.IsEmpty() || cbstr.IsEmpty() || valstr.IsEmpty() || (valstr.GetLength() & 1) || cb*2 != valstr.GetLength()) return false; LARGE_INTEGER offset; offset.QuadPart = _ttoi64(offsetstr); if(offset.QuadPart < 0) offset.QuadPart = size.QuadPart - offset.QuadPart; SetFilePointer(hFile, offset.LowPart, &offset.HighPart, FILE_BEGIN); // LAME while(maskstr.GetLength() < valstr.GetLength()) maskstr += 'F'; CAtlArray mask, val; CStringToBin(maskstr, mask); CStringToBin(valstr, val); for(size_t i = 0; i < val.GetCount(); i++) { BYTE b; DWORD r; if(!ReadFile(hFile, &b, 1, &r, NULL) || (b & mask[i]) != val[i]) return false; } } return sl.IsEmpty(); } HRESULT CFGManager::EnumSourceFilters(LPCWSTR lpcwstrFileName, CFGFilterList& fl) { // TODO: use overrides CheckPointer(lpcwstrFileName, E_POINTER); fl.RemoveAll(); CStringW fn = CStringW(lpcwstrFileName).TrimLeft(); CStringW protocol = fn.Left(fn.Find(':')+1).TrimRight(':').MakeLower(); CStringW ext = CPathW(fn).GetExtension().MakeLower(); HANDLE hFile = INVALID_HANDLE_VALUE; if(protocol.GetLength() <= 1 || protocol == L"file") { hFile = CreateFile(CString(fn), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, (HANDLE)NULL); if(hFile == INVALID_HANDLE_VALUE) { return VFW_E_NOT_FOUND; } } // exceptions first if(ext == _T(".dvr-ms") || ext == _T(".wtv")) // doh, this is stupid { fl.Insert(DNew CFGFilterRegistry(CLSID_StreamBufferSource, MERIT64_PREFERRED), 0); } TCHAR buff[256], buff2[256]; ULONG len, len2; if(hFile == INVALID_HANDLE_VALUE) { // internal / protocol POSITION pos = m_source.GetHeadPosition(); while(pos) { CFGFilter* pFGF = m_source.GetNext(pos); if(pFGF->m_protocols.Find(CString(protocol))) fl.Insert(pFGF, 0, false, false); } } else { // internal / check bytes POSITION pos = m_source.GetHeadPosition(); while(pos) { CFGFilter* pFGF = m_source.GetNext(pos); POSITION pos2 = pFGF->m_chkbytes.GetHeadPosition(); while(pos2) { if(CheckBytes(hFile, pFGF->m_chkbytes.GetNext(pos2))) { fl.Insert(pFGF, 1, false, false); break; } } } } if(!ext.IsEmpty()) { // internal / file extension POSITION pos = m_source.GetHeadPosition(); while(pos) { CFGFilter* pFGF = m_source.GetNext(pos); if(pFGF->m_extensions.Find(CString(ext))) fl.Insert(pFGF, 2, false, false); } } { // internal / the rest POSITION pos = m_source.GetHeadPosition(); while(pos) { CFGFilter* pFGF = m_source.GetNext(pos); if(pFGF->m_protocols.IsEmpty() && pFGF->m_chkbytes.IsEmpty() && pFGF->m_extensions.IsEmpty()) fl.Insert(pFGF, 3, false, false); } } if(hFile == INVALID_HANDLE_VALUE) { // protocol CRegKey key; if(ERROR_SUCCESS == key.Open(HKEY_CLASSES_ROOT, CString(protocol), KEY_READ)) { CRegKey exts; if(ERROR_SUCCESS == exts.Open(key, _T("Extensions"), KEY_READ)) { len = countof(buff); if(ERROR_SUCCESS == exts.QueryStringValue(CString(ext), buff, &len)) fl.Insert(DNew CFGFilterRegistry(GUIDFromCString(buff)), 4); } len = countof(buff); if(ERROR_SUCCESS == key.QueryStringValue(_T("Source Filter"), buff, &len)) fl.Insert(DNew CFGFilterRegistry(GUIDFromCString(buff)), 5); } fl.Insert(DNew CFGFilterRegistry(CLSID_URLReader), 6); } else { // check bytes CRegKey key; if(ERROR_SUCCESS == key.Open(HKEY_CLASSES_ROOT, _T("Media Type"), KEY_READ)) { FILETIME ft; len = countof(buff); for(DWORD i = 0; ERROR_SUCCESS == key.EnumKey(i, buff, &len, &ft); i++, len = countof(buff)) { GUID majortype; if(FAILED(GUIDFromCString(buff, majortype))) continue; CRegKey majorkey; if(ERROR_SUCCESS == majorkey.Open(key, buff, KEY_READ)) { len = countof(buff); for(DWORD j = 0; ERROR_SUCCESS == majorkey.EnumKey(j, buff, &len, &ft); j++, len = countof(buff)) { GUID subtype; if(FAILED(GUIDFromCString(buff, subtype))) continue; CRegKey subkey; if(ERROR_SUCCESS == subkey.Open(majorkey, buff, KEY_READ)) { len = countof(buff); if(ERROR_SUCCESS != subkey.QueryStringValue(_T("Source Filter"), buff, &len)) continue; GUID clsid = GUIDFromCString(buff); len = countof(buff); len2 = sizeof(buff2); for(DWORD k = 0, type; clsid != GUID_NULL && ERROR_SUCCESS == RegEnumValue(subkey, k, buff2, &len2, 0, &type, (BYTE*)buff, &len); k++, len = countof(buff), len2 = sizeof(buff2)) { if(CheckBytes(hFile, CString(buff))) { CFGFilter* pFGF = DNew CFGFilterRegistry(clsid); pFGF->AddType(majortype, subtype); fl.Insert(pFGF, 9); break; } } } } } } } } if(!ext.IsEmpty()) { // file extension CRegKey key; if(ERROR_SUCCESS == key.Open(HKEY_CLASSES_ROOT, _T("Media Type\\Extensions\\") + CString(ext), KEY_READ)) { ULONG len = countof(buff); memset(buff, 0, sizeof(buff)); LONG ret = key.QueryStringValue(_T("Source Filter"), buff, &len); // QueryStringValue can return ERROR_INVALID_DATA on bogus strings (radlight mpc v1003, fixed in v1004) if(ERROR_SUCCESS == ret || ERROR_INVALID_DATA == ret && GUIDFromCString(buff) != GUID_NULL) { GUID clsid = GUIDFromCString(buff); GUID majortype = GUID_NULL; GUID subtype = GUID_NULL; len = countof(buff); if(ERROR_SUCCESS == key.QueryStringValue(_T("Media Type"), buff, &len)) majortype = GUIDFromCString(buff); len = countof(buff); if(ERROR_SUCCESS == key.QueryStringValue(_T("Subtype"), buff, &len)) subtype = GUIDFromCString(buff); CFGFilter* pFGF = DNew CFGFilterRegistry(clsid); pFGF->AddType(majortype, subtype); fl.Insert(pFGF, 7); } } } if(hFile != INVALID_HANDLE_VALUE) { CloseHandle(hFile); } CFGFilter* pFGF = DNew CFGFilterRegistry(CLSID_AsyncReader); pFGF->AddType(MEDIATYPE_Stream, MEDIASUBTYPE_NULL); fl.Insert(pFGF, 9); return S_OK; } HRESULT CFGManager::AddSourceFilter(CFGFilter* pFGF, LPCWSTR lpcwstrFileName, LPCWSTR lpcwstrFilterName, IBaseFilter** ppBF) { TRACE(_T("FGM: AddSourceFilter trying '%s'\n"), CStringFromGUID(pFGF->GetCLSID())); CheckPointer(lpcwstrFileName, E_POINTER); CheckPointer(ppBF, E_POINTER); ASSERT(*ppBF == NULL); HRESULT hr; CComPtr pBF; CInterfaceList pUnks; if(FAILED(hr = pFGF->Create(&pBF, pUnks))) return hr; CComQIPtr pFSF = pBF; if(!pFSF) return E_NOINTERFACE; if(FAILED(hr = AddFilter(pBF, lpcwstrFilterName))) return hr; const AM_MEDIA_TYPE* pmt = NULL; CMediaType mt; const CAtlList& types = pFGF->GetTypes(); if(types.GetCount() == 2 && (types.GetHead() != GUID_NULL || types.GetTail() != GUID_NULL)) { mt.majortype = types.GetHead(); mt.subtype = types.GetTail(); pmt = &mt; } // sometimes looping with AviSynth if(FAILED(hr = pFSF->Load(lpcwstrFileName, pmt))) { RemoveFilter(pBF); return hr; } // doh :P BeginEnumMediaTypes(GetFirstPin(pBF, PINDIR_OUTPUT), pEMT, pmt) { static const GUID guid1 = { 0x640999A0, 0xA946, 0x11D0, { 0xA5, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }; static const GUID guid2 = { 0x640999A1, 0xA946, 0x11D0, { 0xA5, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }; static const GUID guid3 = { 0xD51BD5AE, 0x7548, 0x11CF, { 0xA5, 0x20, 0x00, 0x80, 0xC7, 0x7E, 0xF5, 0x8A } }; if(pmt->subtype == guid1 || pmt->subtype == guid2 || pmt->subtype == guid3) { RemoveFilter(pBF); pFGF = DNew CFGFilterRegistry(CLSID_NetShowSource); hr = AddSourceFilter(pFGF, lpcwstrFileName, lpcwstrFilterName, ppBF); delete pFGF; return hr; } } EndEnumMediaTypes(pmt) *ppBF = pBF.Detach(); m_pUnks.AddTailList(&pUnks); return S_OK; } // IFilterGraph STDMETHODIMP CFGManager::AddFilter(IBaseFilter* pFilter, LPCWSTR pName) { if(!m_pUnkInner) return E_UNEXPECTED; CAutoLock cAutoLock(this); HRESULT hr; if(FAILED(hr = CComQIPtr(m_pUnkInner)->AddFilter(pFilter, pName))) return hr; // TODO hr = pFilter->JoinFilterGraph(NULL, NULL); hr = pFilter->JoinFilterGraph(this, pName); return hr; } STDMETHODIMP CFGManager::RemoveFilter(IBaseFilter* pFilter) { if(!m_pUnkInner) return E_UNEXPECTED; CAutoLock cAutoLock(this); return CComQIPtr(m_pUnkInner)->RemoveFilter(pFilter); } STDMETHODIMP CFGManager::EnumFilters(IEnumFilters** ppEnum) { if(!m_pUnkInner) return E_UNEXPECTED; // Not locking here fixes a deadlock involving ReClock //CAutoLock cAutoLock(this); return CComQIPtr(m_pUnkInner)->EnumFilters(ppEnum); } STDMETHODIMP CFGManager::FindFilterByName(LPCWSTR pName, IBaseFilter** ppFilter) { if(!m_pUnkInner) return E_UNEXPECTED; CAutoLock cAutoLock(this); return CComQIPtr(m_pUnkInner)->FindFilterByName(pName, ppFilter); } STDMETHODIMP CFGManager::ConnectDirect(IPin* pPinOut, IPin* pPinIn, const AM_MEDIA_TYPE* pmt) { if(!m_pUnkInner) return E_UNEXPECTED; CAutoLock cAutoLock(this); CComPtr pBF = GetFilterFromPin(pPinIn); CLSID clsid = GetCLSID(pBF); // TODO: GetUpStreamFilter goes up on the first input pin only for(CComPtr pBFUS = GetFilterFromPin(pPinOut); pBFUS; pBFUS = GetUpStreamFilter(pBFUS)) { if(pBFUS == pBF) return VFW_E_CIRCULAR_GRAPH; if(clsid!=CLSID_Proxy && GetCLSID(pBFUS) == clsid) return VFW_E_CANNOT_CONNECT; } return CComQIPtr(m_pUnkInner)->ConnectDirect(pPinOut, pPinIn, pmt); } STDMETHODIMP CFGManager::Reconnect(IPin* ppin) { if(!m_pUnkInner) return E_UNEXPECTED; CAutoLock cAutoLock(this); return CComQIPtr(m_pUnkInner)->Reconnect(ppin); } STDMETHODIMP CFGManager::Disconnect(IPin* ppin) { if(!m_pUnkInner) return E_UNEXPECTED; CAutoLock cAutoLock(this); return CComQIPtr(m_pUnkInner)->Disconnect(ppin); } STDMETHODIMP CFGManager::SetDefaultSyncSource() { if(!m_pUnkInner) return E_UNEXPECTED; CAutoLock cAutoLock(this); return CComQIPtr(m_pUnkInner)->SetDefaultSyncSource(); } // IGraphBuilder STDMETHODIMP CFGManager::Connect(IPin* pPinOut, IPin* pPinIn) { return Connect(pPinOut, pPinIn, true); } HRESULT CFGManager::Connect(IPin* pPinOut, IPin* pPinIn, bool bContinueRender) { CAutoLock cAutoLock(this); CheckPointer(pPinOut, E_POINTER); HRESULT hr; if(S_OK != IsPinDirection(pPinOut, PINDIR_OUTPUT) || pPinIn && S_OK != IsPinDirection(pPinIn, PINDIR_INPUT)) return VFW_E_INVALID_DIRECTION; if(S_OK == IsPinConnected(pPinOut) || pPinIn && S_OK == IsPinConnected(pPinIn)) return VFW_E_ALREADY_CONNECTED; bool fDeadEnd = true; if(pPinIn) { // 1. Try a direct connection between the filters, with no intermediate filters if(SUCCEEDED(hr = ConnectDirect(pPinOut, pPinIn, NULL))) return hr; } else { // 1. Use IStreamBuilder if(CComQIPtr pSB = pPinOut) { if(SUCCEEDED(hr = pSB->Render(pPinOut, this))) return hr; pSB->Backout(pPinOut, this); } } // 2. Try cached filters if(CComQIPtr pGC = (IGraphBuilder2*)this) { BeginEnumCachedFilters(pGC, pEF, pBF) { if(pPinIn && GetFilterFromPin(pPinIn) == pBF) continue; hr = pGC->RemoveFilterFromCache(pBF); // does RemoveFilterFromCache call AddFilter like AddFilterToCache calls RemoveFilter ? if(SUCCEEDED(hr = ConnectFilterDirect(pPinOut, pBF, NULL))) { if(!IsStreamEnd(pBF)) fDeadEnd = false; if(SUCCEEDED(hr = ConnectFilter(pBF, pPinIn))) return hr; } hr = pGC->AddFilterToCache(pBF); } EndEnumCachedFilters } // 3. Try filters in the graph { CInterfaceList pBFs; BeginEnumFilters(this, pEF, pBF) { if(pPinIn && GetFilterFromPin(pPinIn) == pBF || GetFilterFromPin(pPinOut) == pBF) continue; // HACK: ffdshow - audio capture filter if(GetCLSID(pPinOut) == GUIDFromCString(_T("{04FE9017-F873-410E-871E-AB91661A4EF7}")) && GetCLSID(pBF) == GUIDFromCString(_T("{E30629D2-27E5-11CE-875D-00608CB78066}"))) continue; pBFs.AddTail(pBF); } EndEnumFilters; POSITION pos = pBFs.GetHeadPosition(); while(pos) { IBaseFilter* pBF = pBFs.GetNext(pos); if(SUCCEEDED(hr = ConnectFilterDirect(pPinOut, pBF, NULL))) { if(!IsStreamEnd(pBF)) fDeadEnd = false; if(SUCCEEDED(hr = ConnectFilter(pBF, pPinIn))) return hr; } EXECUTE_ASSERT(Disconnect(pPinOut)); } } // 4. Look up filters in the registry { CFGFilterList fl; CAtlArray types; ExtractMediaTypes(pPinOut, types); POSITION pos = m_transform.GetHeadPosition(); while(pos) { CFGFilter* pFGF = m_transform.GetNext(pos); if(pFGF->GetMerit() < MERIT64_DO_USE || pFGF->CheckTypes(types, false)) fl.Insert(pFGF, 0, pFGF->CheckTypes(types, true), false); } pos = m_override.GetHeadPosition(); while(pos) { CFGFilter* pFGF = m_override.GetNext(pos); if(pFGF->GetMerit() < MERIT64_DO_USE || pFGF->CheckTypes(types, false)) fl.Insert(pFGF, 0, pFGF->CheckTypes(types, true), false); } CComPtr pEM; if(types.GetCount() > 0 && SUCCEEDED(m_pFM->EnumMatchingFilters( &pEM, 0, FALSE, MERIT_DO_NOT_USE+1, TRUE, types.GetCount()/2, types.GetData(), NULL, NULL, FALSE, !!pPinIn, 0, NULL, NULL, NULL))) { for(CComPtr pMoniker; S_OK == pEM->Next(1, &pMoniker, NULL); pMoniker = NULL) { CFGFilterRegistry* pFGF = DNew CFGFilterRegistry(pMoniker); fl.Insert(pFGF, 0, pFGF->CheckTypes(types, true)); } } pos = fl.GetHeadPosition(); while(pos) { CFGFilter* pFGF = fl.GetNext(pos); TRACE(_T("FGM: Connecting '%s'\n"), pFGF->GetName()); CComPtr pBF; CInterfaceList pUnks; if(FAILED(pFGF->Create(&pBF, pUnks))) continue; if(FAILED(hr = AddFilter(pBF, pFGF->GetName()))) continue; hr = E_FAIL; if(FAILED(hr)) { hr = ConnectFilterDirect(pPinOut, pBF, NULL); } /* if(FAILED(hr)) { if(types.GetCount() >= 2 && types[0] == MEDIATYPE_Stream && types[1] != GUID_NULL) { CMediaType mt; mt.majortype = types[0]; mt.subtype = types[1]; mt.formattype = FORMAT_None; if(FAILED(hr)) hr = ConnectFilterDirect(pPinOut, pBF, &mt); mt.formattype = GUID_NULL; if(FAILED(hr)) hr = ConnectFilterDirect(pPinOut, pBF, &mt); } } */ if(SUCCEEDED(hr)) { if(!IsStreamEnd(pBF)) fDeadEnd = false; if (bContinueRender) hr = ConnectFilter(pBF, pPinIn); if(SUCCEEDED(hr)) { m_pUnks.AddTailList(&pUnks); // maybe the application should do this... POSITION pos = pUnks.GetHeadPosition(); while(pos) { if(CComQIPtr pMPC = pUnks.GetNext(pos)) pMPC->SetAspectRatioMode(AM_ARMODE_STRETCHED); } if(CComQIPtr pARC = pBF) pARC->SetAspectRatioMode(VMR_ARMODE_NONE); if(CComQIPtr pARC = pBF) pARC->SetAspectRatioMode(VMR_ARMODE_NONE); if(CComQIPtr pMC = pBF) m_pUnks.AddTail (pMC); if(CComQIPtr pMB = pBF) m_pUnks.AddTail (pMB); if(CComQIPtr pMFGS = pBF) { CComPtr pMFVDC; CComPtr pMFMB; if (SUCCEEDED (pMFGS->GetService (MR_VIDEO_RENDER_SERVICE, IID_IMFVideoDisplayControl, (void**)&pMFVDC))) m_pUnks.AddTail (pMFVDC); if (SUCCEEDED (pMFGS->GetService (MR_VIDEO_MIXER_SERVICE, IID_IMFVideoMixerBitmap, (void**)&pMFMB))) m_pUnks.AddTail (pMFMB); // CComPtr pMFWQS; // pMFGS->GetService (MF_WORKQUEUE_SERVICES, IID_IMFWorkQueueServices, (void**)&pMFWQS); // pMFWQS->BeginRegisterPlatformWorkQueueWithMMCSS( } return hr; } } EXECUTE_ASSERT(SUCCEEDED(RemoveFilter(pBF))); TRACE(_T("FGM: Connecting '%s' FAILED!\n"), pFGF->GetName()); } } if(fDeadEnd) { CAutoPtr psde(DNew CStreamDeadEnd()); psde->AddTailList(&m_streampath); int skip = 0; BeginEnumMediaTypes(pPinOut, pEM, pmt) { if(pmt->majortype == MEDIATYPE_Stream && pmt->subtype == MEDIASUBTYPE_NULL) skip++; psde->mts.AddTail(CMediaType(*pmt)); } EndEnumMediaTypes(pmt) if(skip < psde->mts.GetCount()) m_deadends.Add(psde); } return pPinIn ? VFW_E_CANNOT_CONNECT : VFW_E_CANNOT_RENDER; } STDMETHODIMP CFGManager::Render(IPin* pPinOut) { CAutoLock cAutoLock(this); return RenderEx(pPinOut, 0, NULL); } STDMETHODIMP CFGManager::RenderFile(LPCWSTR lpcwstrFileName, LPCWSTR lpcwstrPlayList) { TRACE("--> CFGManager::RenderFile on thread: %d\n", GetCurrentThreadId()); CAutoLock cAutoLock(this); m_streampath.RemoveAll(); m_deadends.RemoveAll(); HRESULT hr; /* CComPtr pBF; if(FAILED(hr = AddSourceFilter(lpcwstrFile, lpcwstrFile, &pBF))) return hr; return ConnectFilter(pBF, NULL); */ CFGFilterList fl; if(FAILED(hr = EnumSourceFilters(lpcwstrFileName, fl))) return hr; CAutoPtrArray deadends; hr = VFW_E_CANNOT_RENDER; POSITION pos = fl.GetHeadPosition(); while(pos) { CComPtr pBF; if(SUCCEEDED(hr = AddSourceFilter(fl.GetNext(pos), lpcwstrFileName, lpcwstrFileName, &pBF))) { m_streampath.RemoveAll(); m_deadends.RemoveAll(); if(SUCCEEDED(hr = ConnectFilter(pBF, NULL))) return hr; NukeDownstream(pBF); RemoveFilter(pBF); deadends.Append(m_deadends); } } m_deadends.Copy(deadends); return hr; } STDMETHODIMP CFGManager::AddSourceFilter(LPCWSTR lpcwstrFileName, LPCWSTR lpcwstrFilterName, IBaseFilter** ppFilter) { CAutoLock cAutoLock(this); HRESULT hr; CFGFilterList fl; if(FAILED(hr = EnumSourceFilters(lpcwstrFileName, fl))) return hr; POSITION pos = fl.GetHeadPosition(); while(pos) { if(SUCCEEDED(hr = AddSourceFilter(fl.GetNext(pos), lpcwstrFileName, lpcwstrFilterName, ppFilter))) return hr; } return VFW_E_CANNOT_LOAD_SOURCE_FILTER; } STDMETHODIMP CFGManager::SetLogFile(DWORD_PTR hFile) { if(!m_pUnkInner) return E_UNEXPECTED; CAutoLock cAutoLock(this); return CComQIPtr(m_pUnkInner)->SetLogFile(hFile); } STDMETHODIMP CFGManager::Abort() { if(!m_pUnkInner) return E_UNEXPECTED; CAutoLock cAutoLock(this); return CComQIPtr(m_pUnkInner)->Abort(); } STDMETHODIMP CFGManager::ShouldOperationContinue() { if(!m_pUnkInner) return E_UNEXPECTED; CAutoLock cAutoLock(this); return CComQIPtr(m_pUnkInner)->ShouldOperationContinue(); } // IFilterGraph2 STDMETHODIMP CFGManager::AddSourceFilterForMoniker(IMoniker* pMoniker, IBindCtx* pCtx, LPCWSTR lpcwstrFilterName, IBaseFilter** ppFilter) { if(!m_pUnkInner) return E_UNEXPECTED; CAutoLock cAutoLock(this); return CComQIPtr(m_pUnkInner)->AddSourceFilterForMoniker(pMoniker, pCtx, lpcwstrFilterName, ppFilter); } STDMETHODIMP CFGManager::ReconnectEx(IPin* ppin, const AM_MEDIA_TYPE* pmt) { if(!m_pUnkInner) return E_UNEXPECTED; CAutoLock cAutoLock(this); return CComQIPtr(m_pUnkInner)->ReconnectEx(ppin, pmt); } STDMETHODIMP CFGManager::RenderEx(IPin* pPinOut, DWORD dwFlags, DWORD* pvContext) { CAutoLock cAutoLock(this); m_streampath.RemoveAll(); m_deadends.RemoveAll(); if(!pPinOut || dwFlags > AM_RENDEREX_RENDERTOEXISTINGRENDERERS || pvContext) return E_INVALIDARG; HRESULT hr; if(dwFlags & AM_RENDEREX_RENDERTOEXISTINGRENDERERS) { CInterfaceList pBFs; BeginEnumFilters(this, pEF, pBF) { if(CComQIPtr pAMMF = pBF) { if(pAMMF->GetMiscFlags() & AM_FILTER_MISC_FLAGS_IS_RENDERER) { pBFs.AddTail(pBF); } } else { BeginEnumPins(pBF, pEP, pPin) { CComPtr pPinIn; DWORD size = 1; if(SUCCEEDED(pPin->QueryInternalConnections(&pPinIn, &size)) && size == 0) { pBFs.AddTail(pBF); break; } } EndEnumPins; } } EndEnumFilters; while(!pBFs.IsEmpty()) { if(SUCCEEDED(hr = ConnectFilter(pPinOut, pBFs.RemoveHead()))) return hr; } return VFW_E_CANNOT_RENDER; } return Connect(pPinOut, (IPin*)NULL); } // IGraphBuilder2 STDMETHODIMP CFGManager::IsPinDirection(IPin* pPin, PIN_DIRECTION dir1) { CAutoLock cAutoLock(this); CheckPointer(pPin, E_POINTER); PIN_DIRECTION dir2; if(FAILED(pPin->QueryDirection(&dir2))) return E_FAIL; return dir1 == dir2 ? S_OK : S_FALSE; } STDMETHODIMP CFGManager::IsPinConnected(IPin* pPin) { CAutoLock cAutoLock(this); CheckPointer(pPin, E_POINTER); CComPtr pPinTo; return SUCCEEDED(pPin->ConnectedTo(&pPinTo)) && pPinTo ? S_OK : S_FALSE; } STDMETHODIMP CFGManager::ConnectFilter(IBaseFilter* pBF, IPin* pPinIn) { CAutoLock cAutoLock(this); CheckPointer(pBF, E_POINTER); if(pPinIn && S_OK != IsPinDirection(pPinIn, PINDIR_INPUT)) return VFW_E_INVALID_DIRECTION; int nTotal = 0, nRendered = 0; BeginEnumPins(pBF, pEP, pPin) { if(GetPinName(pPin)[0] != '~' && S_OK == IsPinDirection(pPin, PINDIR_OUTPUT) && S_OK != IsPinConnected(pPin)) { m_streampath.Append(pBF, pPin); HRESULT hr = Connect(pPin, pPinIn); if(SUCCEEDED(hr)) { for(int i = m_deadends.GetCount()-1; i >= 0; i--) if(m_deadends[i]->Compare(m_streampath)) m_deadends.RemoveAt(i); nRendered++; } nTotal++; m_streampath.RemoveTail(); if(SUCCEEDED(hr) && pPinIn) return S_OK; } } EndEnumPins; return nRendered == nTotal ? (nRendered > 0 ? S_OK : S_FALSE) : nRendered > 0 ? VFW_S_PARTIAL_RENDER : VFW_E_CANNOT_RENDER; } STDMETHODIMP CFGManager::ConnectFilter(IPin* pPinOut, IBaseFilter* pBF) { CAutoLock cAutoLock(this); CheckPointer(pPinOut, E_POINTER); CheckPointer(pBF, E_POINTER); if(S_OK != IsPinDirection(pPinOut, PINDIR_OUTPUT)) return VFW_E_INVALID_DIRECTION; BeginEnumPins(pBF, pEP, pPin) { if(GetPinName(pPin)[0] != '~' && S_OK == IsPinDirection(pPin, PINDIR_INPUT) && S_OK != IsPinConnected(pPin)) { HRESULT hr = Connect(pPinOut, pPin); if(SUCCEEDED(hr)) return hr; } } EndEnumPins; return VFW_E_CANNOT_CONNECT; } STDMETHODIMP CFGManager::ConnectFilterDirect(IPin* pPinOut, IBaseFilter* pBF, const AM_MEDIA_TYPE* pmt) { CAutoLock cAutoLock(this); CheckPointer(pPinOut, E_POINTER); CheckPointer(pBF, E_POINTER); if(S_OK != IsPinDirection(pPinOut, PINDIR_OUTPUT)) return VFW_E_INVALID_DIRECTION; BeginEnumPins(pBF, pEP, pPin) { if(GetPinName(pPin)[0] != '~' && S_OK == IsPinDirection(pPin, PINDIR_INPUT) && S_OK != IsPinConnected(pPin)) { HRESULT hr = ConnectDirect(pPinOut, pPin, pmt); if(SUCCEEDED(hr)) return hr; } } EndEnumPins; return VFW_E_CANNOT_CONNECT; } STDMETHODIMP CFGManager::NukeDownstream(IUnknown* pUnk) { CAutoLock cAutoLock(this); if(CComQIPtr pBF = pUnk) { BeginEnumPins(pBF, pEP, pPin) { NukeDownstream(pPin); } EndEnumPins; } else if(CComQIPtr pPin = pUnk) { CComPtr pPinTo; if(S_OK == IsPinDirection(pPin, PINDIR_OUTPUT) && SUCCEEDED(pPin->ConnectedTo(&pPinTo)) && pPinTo) { if(CComPtr pBF = GetFilterFromPin(pPinTo)) { NukeDownstream(pBF); Disconnect(pPinTo); Disconnect(pPin); RemoveFilter(pBF); } } } else { return E_INVALIDARG; } return S_OK; } STDMETHODIMP CFGManager::FindInterface(REFIID iid, void** ppv, BOOL bRemove) { CAutoLock cAutoLock(this); CheckPointer(ppv, E_POINTER); for(POSITION pos = m_pUnks.GetHeadPosition(); pos; m_pUnks.GetNext(pos)) { if(SUCCEEDED(m_pUnks.GetAt(pos)->QueryInterface(iid, ppv))) { if(bRemove) m_pUnks.RemoveAt(pos); return S_OK; } } return E_NOINTERFACE; } STDMETHODIMP CFGManager::AddToROT() { CAutoLock cAutoLock(this); HRESULT hr; if(m_dwRegister) return S_FALSE; CComPtr pROT; CComPtr pMoniker; WCHAR wsz[256]; swprintf(wsz, L"FilterGraph %08p pid %08x (MPC)", (DWORD_PTR)this, GetCurrentProcessId()); if(SUCCEEDED(hr = GetRunningObjectTable(0, &pROT)) && SUCCEEDED(hr = CreateItemMoniker(L"!", wsz, &pMoniker))) hr = pROT->Register(ROTFLAGS_REGISTRATIONKEEPSALIVE, (IGraphBuilder2*)this, pMoniker, &m_dwRegister); return hr; } STDMETHODIMP CFGManager::RemoveFromROT() { CAutoLock cAutoLock(this); HRESULT hr; if(!m_dwRegister) return S_FALSE; CComPtr pROT; if(SUCCEEDED(hr = GetRunningObjectTable(0, &pROT)) && SUCCEEDED(hr = pROT->Revoke(m_dwRegister))) m_dwRegister = 0; return hr; } // IGraphBuilderDeadEnd STDMETHODIMP_(size_t) CFGManager::GetCount() { CAutoLock cAutoLock(this); return m_deadends.GetCount(); } STDMETHODIMP CFGManager::GetDeadEnd(int iIndex, CAtlList& path, CAtlList& mts) { CAutoLock cAutoLock(this); if(iIndex < 0 || iIndex >= m_deadends.GetCount()) return E_FAIL; path.RemoveAll(); mts.RemoveAll(); POSITION pos = m_deadends[iIndex]->GetHeadPosition(); while(pos) { const path_t& p = m_deadends[iIndex]->GetNext(pos); CStringW str; str.Format(L"%s::%s", p.filter, p.pin); path.AddTail(str); } mts.AddTailList(&m_deadends[iIndex]->mts); return S_OK; } // // CFGManagerCustom // CFGManagerCustom::CFGManagerCustom(LPCTSTR pName, LPUNKNOWN pUnk) : CFGManager(pName, pUnk) { AppSettings& s = AfxGetAppSettings(); bool bOverrideBroadcom = false; CFGFilter* pFGF; UINT src = s.SrcFilters; UINT tra = s.TraFilters; UINT dxva_filters = s.DXVAFilters; UINT ffmpeg_filters = s.FFmpegFilters; // Source filters #if INTERNAL_SOURCEFILTER_SHOUTCAST if(src & SRC_SHOUTCAST) { pFGF = DNew CFGFilterInternal(); pFGF->m_protocols.AddTail(_T("http")); m_source.AddTail(pFGF); } #endif #if INTERNAL_SOURCEFILTER_UDP // if(src & SRC_UDP) { pFGF = DNew CFGFilterInternal(); pFGF->m_protocols.AddTail(_T("udp")); m_source.AddTail(pFGF); } #endif #if INTERNAL_SOURCEFILTER_AVI if(src & SRC_AVI) { pFGF = DNew CFGFilterInternal(); pFGF->m_chkbytes.AddTail(_T("0,4,,52494646,8,4,,41564920")); pFGF->m_chkbytes.AddTail(_T("0,4,,52494646,8,4,,41564958")); m_source.AddTail(pFGF); } #endif #if INTERNAL_SOURCEFILTER_MP4 if(src & SRC_MP4) { pFGF = DNew CFGFilterInternal(); pFGF->m_chkbytes.AddTail(_T("4,4,,66747970")); // ftyp pFGF->m_chkbytes.AddTail(_T("4,4,,6d6f6f76")); // moov pFGF->m_chkbytes.AddTail(_T("4,4,,6d646174")); // mdat pFGF->m_chkbytes.AddTail(_T("4,4,,736b6970")); // skip pFGF->m_chkbytes.AddTail(_T("4,12,ffffffff00000000ffffffff,77696465027fe3706d646174")); // wide ? mdat pFGF->m_chkbytes.AddTail(_T("3,3,,000001")); // raw mpeg4 video pFGF->m_extensions.AddTail(_T(".mov")); m_source.AddTail(pFGF); } #endif #if INTERNAL_SOURCEFILTER_FLV if(src & SRC_FLV) { pFGF = DNew CFGFilterInternal(); pFGF->m_chkbytes.AddTail(_T("0,4,,464C5601")); // FLV (v1) m_source.AddTail(pFGF); } #endif #if INTERNAL_SOURCEFILTER_MATROSKA if(src & SRC_MATROSKA) { pFGF = DNew CFGFilterInternal(); pFGF->m_chkbytes.AddTail(_T("0,4,,1A45DFA3")); m_source.AddTail(pFGF); } #endif #if INTERNAL_SOURCEFILTER_REALMEDIA if(src & SRC_REALMEDIA) { pFGF = DNew CFGFilterInternal(); pFGF->m_chkbytes.AddTail(_T("0,4,,2E524D46")); m_source.AddTail(pFGF); } #endif #if INTERNAL_SOURCEFILTER_DSM if(src & SRC_DSM) { pFGF = DNew CFGFilterInternal(); pFGF->m_chkbytes.AddTail(_T("0,4,,44534D53")); m_source.AddTail(pFGF); } #endif #if INTERNAL_SOURCEFILTER_FLIC if(src & SRC_FLIC) { pFGF = DNew CFGFilterInternal(); pFGF->m_chkbytes.AddTail(_T("4,2,,11AF")); pFGF->m_chkbytes.AddTail(_T("4,2,,12AF")); pFGF->m_extensions.AddTail(_T(".fli")); pFGF->m_extensions.AddTail(_T(".flc")); m_source.AddTail(pFGF); } #endif #if INTERNAL_SOURCEFILTER_FLAC if(src & SRC_FLAC) { pFGF = DNew CFGFilterInternal(); pFGF->m_chkbytes.AddTail(_T("0,4,,664C6143")); pFGF->m_extensions.AddTail(_T(".flac")); m_source.AddTail(pFGF); } #endif #if INTERNAL_SOURCEFILTER_CDDA if(src & SRC_CDDA) { pFGF = DNew CFGFilterInternal(); pFGF->m_extensions.AddTail(_T(".cda")); m_source.AddTail(pFGF); } #endif #if INTERNAL_SOURCEFILTER_CDXA if(src & SRC_CDXA) { pFGF = DNew CFGFilterInternal(); pFGF->m_chkbytes.AddTail(_T("0,4,,52494646,8,4,,43445841")); m_source.AddTail(pFGF); } #endif #if INTERNAL_SOURCEFILTER_VTS if(src & SRC_VTS) { pFGF = DNew CFGFilterInternal(); pFGF->m_chkbytes.AddTail(_T("0,12,,445644564944454F2D565453")); m_source.AddTail(pFGF); } #endif #if INTERNAL_SOURCEFILTER_DVSOURCE // TODOX64 : fix DVSource internal filter #ifndef _WIN64 __if_exists(CD2VSource) { if(src & SRC_D2V) { pFGF = DNew CFGFilterInternal(); pFGF->m_chkbytes.AddTail(_T("0,18,,4456443241564950726F6A65637446696C65")); pFGF->m_extensions.AddTail(_T(".d2v")); m_source.AddTail(pFGF); } } #endif #endif #if INTERNAL_SOURCEFILTER_ROQ if(src & SRC_ROQ) { pFGF = DNew CFGFilterInternal(); pFGF->m_chkbytes.AddTail(_T("0,8,,8410FFFFFFFF1E00")); m_source.AddTail(pFGF); } #endif #if INTERNAL_SOURCEFILTER_OGG if(src & SRC_OGG) { pFGF = DNew CFGFilterInternal(); pFGF->m_chkbytes.AddTail(_T("0,4,,4F676753")); m_source.AddTail(pFGF); } #endif #if INTERNAL_SOURCEFILTER_NUT __if_exists(CNutSourceFilter) { if(src & SRC_NUT) { pFGF = DNew CFGFilterInternal(); pFGF->m_chkbytes.AddTail(_T("0,8,,F9526A624E55544D")); m_source.AddTail(pFGF); } } #endif #if INTERNAL_SOURCEFILTER_DIRAC __if_exists(CDiracSourceFilter) { if(src & SRC_DIRAC) { pFGF = DNew CFGFilterInternal(); pFGF->m_chkbytes.AddTail(_T("0,8,,4B572D4449524143")); m_source.AddTail(pFGF); } } #endif #if INTERNAL_SOURCEFILTER_MPEG if(src & SRC_MPEG) { pFGF = DNew CFGFilterInternal(); pFGF->m_chkbytes.AddTail(_T("0,16,FFFFFFFFF100010001800001FFFFFFFF,000001BA2100010001800001000001BB")); pFGF->m_chkbytes.AddTail(_T("0,5,FFFFFFFFC0,000001BA40")); pFGF->m_chkbytes.AddTail(_T("0,1,,47,188,1,,47,376,1,,47")); pFGF->m_chkbytes.AddTail(_T("4,1,,47,196,1,,47,388,1,,47")); pFGF->m_chkbytes.AddTail(_T("0,4,,54467263,1660,1,,47")); pFGF->m_chkbytes.AddTail(_T("0,8,fffffc00ffe00000,4156000055000000")); pFGF->m_chkbytes.AddTail(_T("0,8,,4D504C5330323030")); // MPLS0200 pFGF->m_chkbytes.AddTail(_T("0,8,,4D504C5330313030")); // MPLS0100 m_source.AddTail(pFGF); } #endif #if INTERNAL_SOURCEFILTER_DTSAC3 if(src & SRC_DTSAC3) { pFGF = DNew CFGFilterInternal(); pFGF->m_chkbytes.AddTail(_T("0,4,,7FFE8001")); pFGF->m_chkbytes.AddTail(_T("0,2,,0B77")); pFGF->m_chkbytes.AddTail(_T("0,2,,770B")); pFGF->m_extensions.AddTail(_T(".ac3")); pFGF->m_extensions.AddTail(_T(".dts")); m_source.AddTail(pFGF); } #endif #if INTERNAL_SOURCEFILTER_MPEGAUDIO if(src & SRC_MPA) { pFGF = DNew CFGFilterInternal(); pFGF->m_chkbytes.AddTail(_T("0,2,FFE0,FFE0")); pFGF->m_chkbytes.AddTail(_T("0,10,FFFFFF00000080808080,49443300000000000000")); m_source.AddTail(pFGF); } #endif if(AfxGetAppSettings().fUseWMASFReader) { pFGF = DNew CFGFilterRegistry(CLSID_WMAsfReader); pFGF->m_chkbytes.AddTail(_T("0,4,,3026B275")); pFGF->m_chkbytes.AddTail(_T("0,4,,D129E2D6")); m_source.AddTail(pFGF); } #if INTERNAL_SOURCEFILTER_AVI2AC3 // hmmm, shouldn't there be an option in the GUI to enable/disable this filter? pFGF = DNew CFGFilterInternal(L"AVI<->AC3/DTS", MERIT64(0x00680000)+1); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_WAVE_DOLBY_AC3); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_WAVE_DTS); m_transform.AddTail(pFGF); #endif #if INTERNAL_SOURCEFILTER_MATROSKA if(src & SRC_MATROSKA) { pFGF = DNew CFGFilterInternal(L"Matroska Splitter", MERIT64_ABOVE_DSHOW); } else { pFGF = DNew CFGFilterInternal(L"Matroska Splitter (low merit)", MERIT64_DO_USE); } pFGF->AddType(MEDIATYPE_Stream, MEDIASUBTYPE_Matroska); pFGF->AddType(MEDIATYPE_Stream, GUID_NULL); m_transform.AddTail(pFGF); #endif #if INTERNAL_SOURCEFILTER_REALMEDIA if(src & SRC_REALMEDIA) { pFGF = DNew CFGFilterInternal(L"RealMedia Splitter", MERIT64_ABOVE_DSHOW); } else { pFGF = DNew CFGFilterInternal(L"RealMedia Splitter (low merit)", MERIT64_DO_USE); } pFGF->AddType(MEDIATYPE_Stream, MEDIASUBTYPE_RealMedia); pFGF->AddType(MEDIATYPE_Stream, GUID_NULL); m_transform.AddTail(pFGF); #endif #if INTERNAL_SOURCEFILTER_AVI if(src & SRC_AVI) { pFGF = DNew CFGFilterInternal(L"Avi Splitter", MERIT64_ABOVE_DSHOW); } else { pFGF = DNew CFGFilterInternal(L"Avi Splitter (low merit)", MERIT64_DO_USE); } pFGF->AddType(MEDIATYPE_Stream, MEDIASUBTYPE_Avi); pFGF->AddType(MEDIATYPE_Stream, GUID_NULL); m_transform.AddTail(pFGF); #endif #if INTERNAL_SOURCEFILTER_ROQ if(src & SRC_ROQ) { pFGF = DNew CFGFilterInternal(L"RoQ Splitter", MERIT64_ABOVE_DSHOW); } else { pFGF = DNew CFGFilterInternal(L"RoQ Splitter (low merit)", MERIT64_DO_USE); } pFGF->AddType(MEDIATYPE_Stream, MEDIASUBTYPE_RoQ); pFGF->AddType(MEDIATYPE_Stream, GUID_NULL); m_transform.AddTail(pFGF); #endif #if INTERNAL_SOURCEFILTER_OGG if(src & SRC_OGG) { pFGF = DNew CFGFilterInternal(L"Ogg Splitter", MERIT64_ABOVE_DSHOW); } else { pFGF = DNew CFGFilterInternal(L"Ogg Splitter (low merit)", MERIT64_DO_USE); } pFGF->AddType(MEDIATYPE_Stream, MEDIASUBTYPE_Ogg); pFGF->AddType(MEDIATYPE_Stream, GUID_NULL); m_transform.AddTail(pFGF); #endif #if INTERNAL_SOURCEFILTER_NUT __if_exists(CNutSplitterFilter) { if(src & SRC_NUT) { pFGF = DNew CFGFilterInternal(L"Nut Splitter", MERIT64_ABOVE_DSHOW); } else { pFGF = DNew CFGFilterInternal(L"Nut Splitter (low merit)", MERIT64_DO_USE); } pFGF->AddType(MEDIATYPE_Stream, MEDIASUBTYPE_Nut); pFGF->AddType(MEDIATYPE_Stream, GUID_NULL); m_transform.AddTail(pFGF); } #endif #if INTERNAL_SOURCEFILTER_MPEG if(src & SRC_MPEG) { pFGF = DNew CFGFilterInternal(L"Mpeg Splitter", MERIT64_ABOVE_DSHOW); } else { pFGF = DNew CFGFilterInternal(L"Mpeg Splitter (low merit)", MERIT64_DO_USE); } pFGF->AddType(MEDIATYPE_Stream, MEDIASUBTYPE_MPEG1System); pFGF->AddType(MEDIATYPE_Stream, MEDIASUBTYPE_MPEG2_PROGRAM); pFGF->AddType(MEDIATYPE_Stream, MEDIASUBTYPE_MPEG2_TRANSPORT); pFGF->AddType(MEDIATYPE_Stream, MEDIASUBTYPE_MPEG2_PVA); pFGF->AddType(MEDIATYPE_Stream, GUID_NULL); m_transform.AddTail(pFGF); #endif #if INTERNAL_SOURCEFILTER_DIRAC __if_exists(CDiracSplitterFilter) { if(src & SRC_DIRAC) { pFGF = DNew CFGFilterInternal(L"Dirac Splitter", MERIT64_ABOVE_DSHOW); } else { pFGF = DNew CFGFilterInternal(L"Dirac Splitter (low merit)", MERIT64_DO_USE); } pFGF->AddType(MEDIATYPE_Stream, MEDIASUBTYPE_Dirac); pFGF->AddType(MEDIATYPE_Stream, GUID_NULL); m_transform.AddTail(pFGF); } #endif #if INTERNAL_SOURCEFILTER_MPEGAUDIO if(src & SRC_MPA) { pFGF = DNew CFGFilterInternal(L"Mpa Splitter", MERIT64_ABOVE_DSHOW); } else { pFGF = DNew CFGFilterInternal(L"Mpa Splitter (low merit)", MERIT64_DO_USE); } pFGF->AddType(MEDIATYPE_Stream, MEDIASUBTYPE_MPEG1Audio); pFGF->AddType(MEDIATYPE_Stream, GUID_NULL); m_transform.AddTail(pFGF); #endif #if INTERNAL_SOURCEFILTER_DSM if(src & SRC_DSM) { pFGF = DNew CFGFilterInternal(L"DSM Splitter", MERIT64_ABOVE_DSHOW); } else { pFGF = DNew CFGFilterInternal(L"DSM Splitter (low merit)", MERIT64_DO_USE); } pFGF->AddType(MEDIATYPE_Stream, MEDIASUBTYPE_DirectShowMedia); pFGF->AddType(MEDIATYPE_Stream, GUID_NULL); m_transform.AddTail(pFGF); #endif #if INTERNAL_SOURCEFILTER_MP4 if(src & SRC_MP4) { pFGF = DNew CFGFilterInternal(L"MP4 Splitter", MERIT64_ABOVE_DSHOW); } else { pFGF = DNew CFGFilterInternal(L"MP4 Splitter (low merit)", MERIT64_DO_USE); } pFGF->AddType(MEDIATYPE_Stream, MEDIASUBTYPE_MP4); pFGF->AddType(MEDIATYPE_Stream, GUID_NULL); m_transform.AddTail(pFGF); #endif #if INTERNAL_SOURCEFILTER_FLV if(src & SRC_FLV) { pFGF = DNew CFGFilterInternal(L"FLV Splitter", MERIT64_ABOVE_DSHOW); } else { pFGF = DNew CFGFilterInternal(L"FLV Splitter (low merit)", MERIT64_DO_USE); } pFGF->AddType(MEDIATYPE_Stream, MEDIASUBTYPE_FLV); pFGF->AddType(MEDIATYPE_Stream, GUID_NULL); m_transform.AddTail(pFGF); #endif // Transform filters #if INTERNAL_DECODER_MPEG1 pFGF = DNew CFGFilterInternal( (tra & TRA_MPEG1) ? ResStr(IDS_FGMANAGER_0) : L"MPEG-1 Video Decoder (low merit)", (tra & TRA_MPEG1) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_MPEG1Packet); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_MPEG1Payload); m_transform.AddTail(pFGF); #endif #if INTERNAL_DECODER_MPEGAUDIO pFGF = DNew CFGFilterInternal( (tra & TRA_MPA) ? ResStr(IDS_FGMANAGER_2) : L"MPEG-1 Audio Decoder (low merit)", (tra & TRA_MPA) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_MP3); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_MPEG1AudioPayload); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_MPEG1Payload); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_MPEG1Packet); m_transform.AddTail(pFGF); pFGF = DNew CFGFilterInternal( (tra & TRA_MPA) ? ResStr(IDS_FGMANAGER_3) : L"MPEG-2 Audio Decoder (low merit)", (tra & TRA_MPA) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE); pFGF->AddType(MEDIATYPE_DVD_ENCRYPTED_PACK, MEDIASUBTYPE_MPEG2_AUDIO); pFGF->AddType(MEDIATYPE_MPEG2_PACK, MEDIASUBTYPE_MPEG2_AUDIO); pFGF->AddType(MEDIATYPE_MPEG2_PES, MEDIASUBTYPE_MPEG2_AUDIO); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_MPEG2_AUDIO); m_transform.AddTail(pFGF); #endif #if INTERNAL_DECODER_AMR pFGF = new CFGFilterInternal( (tra & TRA_AMR) ? L"AMR Audio Decoder" : L"AMR Audio Decoder (low merit)", (tra & TRA_AMR) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_SAMR); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_AMR); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_SAWB); m_transform.AddTail(pFGF); #endif #if INTERNAL_DECODER_LPCM pFGF = DNew CFGFilterInternal( (tra & TRA_LPCM) ? ResStr(IDS_FGMANAGER_4) : L"LPCM Audio Decoder (low merit)", (tra & TRA_LPCM) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE); pFGF->AddType(MEDIATYPE_DVD_ENCRYPTED_PACK, MEDIASUBTYPE_DVD_LPCM_AUDIO); pFGF->AddType(MEDIATYPE_MPEG2_PACK, MEDIASUBTYPE_DVD_LPCM_AUDIO); pFGF->AddType(MEDIATYPE_MPEG2_PES, MEDIASUBTYPE_DVD_LPCM_AUDIO); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_DVD_LPCM_AUDIO); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_HDMV_LPCM_AUDIO); m_transform.AddTail(pFGF); #endif #if INTERNAL_DECODER_AC3 pFGF = DNew CFGFilterInternal( (tra & TRA_AC3) ? ResStr(IDS_FGMANAGER_5) : L"AC3 Audio Decoder (low merit)", (tra & TRA_AC3) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE); pFGF->AddType(MEDIATYPE_DVD_ENCRYPTED_PACK, MEDIASUBTYPE_DOLBY_AC3); pFGF->AddType(MEDIATYPE_MPEG2_PACK, MEDIASUBTYPE_DOLBY_AC3); pFGF->AddType(MEDIATYPE_MPEG2_PES, MEDIASUBTYPE_DOLBY_AC3); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_DOLBY_AC3); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_WAVE_DOLBY_AC3); m_transform.AddTail(pFGF); #endif #if INTERNAL_DECODER_DTS pFGF = DNew CFGFilterInternal( (tra & TRA_DTS) ? ResStr(IDS_AG_DTS_DECODER) : L"DTS Decoder (low merit)", (tra & TRA_DTS) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE); pFGF->AddType(MEDIATYPE_DVD_ENCRYPTED_PACK, MEDIASUBTYPE_DTS); pFGF->AddType(MEDIATYPE_MPEG2_PACK, MEDIASUBTYPE_DTS); pFGF->AddType(MEDIATYPE_MPEG2_PES, MEDIASUBTYPE_DTS); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_DTS); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_WAVE_DTS); m_transform.AddTail(pFGF); #endif #if INTERNAL_DECODER_AAC pFGF = DNew CFGFilterInternal( (tra & TRA_AAC) ? ResStr(IDS_AG_AAC_DECODER) : L"AAC Decoder (low merit)", (tra & TRA_AAC) ? MERIT64_ABOVE_DSHOW+1 : MERIT64_DO_USE); pFGF->AddType(MEDIATYPE_DVD_ENCRYPTED_PACK, MEDIASUBTYPE_AAC); pFGF->AddType(MEDIATYPE_MPEG2_PACK, MEDIASUBTYPE_AAC); pFGF->AddType(MEDIATYPE_MPEG2_PES, MEDIASUBTYPE_AAC); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_AAC); pFGF->AddType(MEDIATYPE_DVD_ENCRYPTED_PACK, MEDIASUBTYPE_MP4A); pFGF->AddType(MEDIATYPE_MPEG2_PACK, MEDIASUBTYPE_MP4A); pFGF->AddType(MEDIATYPE_MPEG2_PES, MEDIASUBTYPE_MP4A); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_MP4A); pFGF->AddType(MEDIATYPE_DVD_ENCRYPTED_PACK, MEDIASUBTYPE_mp4a); pFGF->AddType(MEDIATYPE_MPEG2_PACK, MEDIASUBTYPE_mp4a); pFGF->AddType(MEDIATYPE_MPEG2_PES, MEDIASUBTYPE_mp4a); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_mp4a); m_transform.AddTail(pFGF); #endif #if INTERNAL_DECODER_PS2AUDIO pFGF = DNew CFGFilterInternal( (tra & TRA_PS2AUD) ? ResStr(IDS_FGMANAGER_8) : L"PS2 Audio Decoder (low merit)", (tra & TRA_PS2AUD) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE); pFGF->AddType(MEDIATYPE_DVD_ENCRYPTED_PACK, MEDIASUBTYPE_PS2_PCM); pFGF->AddType(MEDIATYPE_MPEG2_PACK, MEDIASUBTYPE_PS2_PCM); pFGF->AddType(MEDIATYPE_MPEG2_PES, MEDIASUBTYPE_PS2_PCM); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_PS2_PCM); m_transform.AddTail(pFGF); #endif #if INTERNAL_DECODER_REALVIDEO pFGF = DNew CFGFilterInternal( (tra & TRA_RV) ? ResStr(IDS_FGMANAGER_9) : L"RealVideo Decoder (low merit)", (tra & TRA_RV) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_RV10); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_RV20); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_RV30); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_RV40); m_transform.AddTail(pFGF); #endif #if INTERNAL_DECODER_REALAUDIO pFGF = DNew CFGFilterInternal( (tra & TRA_RA) ? ResStr(IDS_FGMANAGER_10) : L"RealAudio Decoder (low merit)", (tra & TRA_RA) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_14_4); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_28_8); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_ATRC); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_COOK); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_DNET); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_SIPR); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_RAAC); m_transform.AddTail(pFGF); #endif #if INTERNAL_DECODER_VORBIS pFGF = DNew CFGFilterInternal( (tra & TRA_VORBIS) ? ResStr(IDS_FGMANAGER_11) : L"Vorbis Audio Decoder (low merit)", (tra & TRA_VORBIS) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_Vorbis2); m_transform.AddTail(pFGF); #endif #if INTERNAL_DECODER_FLAC pFGF = DNew CFGFilterInternal( (tra & TRA_FLAC) ? L"Flac Audio Decoder" : L"Flac Audio Decoder (low merit)", // TODO : put in resource ! (tra & TRA_FLAC) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_FLAC_FRAMED); m_transform.AddTail(pFGF); #endif #if INTERNAL_DECODER_NELLYMOSER pFGF = DNew CFGFilterInternal( (tra & TRA_NELLY) ? L"Nellymoser Audio Decoder" : L"Nellymoser Audio Decoder (low merit)", // TODO : put in resource ! (tra & TRA_NELLY) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_NELLYMOSER); m_transform.AddTail(pFGF); #endif #if INTERNAL_DECODER_PCM pFGF = new CFGFilterInternal( (tra & TRA_PCM) ? ResStr(IDS_AG_PCM_DECODER) : L"PCM Audio Decoder (low merit)", (tra & TRA_PCM) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_PCM_RAW); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_PCM_SOWT); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_PCM_TWOS); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_PCM_IN32); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_PCM_FL32); m_transform.AddTail(pFGF); #endif #if INTERNAL_DECODER_ROQ pFGF = DNew CFGFilterInternal( (tra & TRA_RV) ? ResStr(IDS_FGMANAGER_12) : L"RoQ Video Decoder (low merit)", (tra & TRA_RV) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_RoQV); m_transform.AddTail(pFGF); pFGF = DNew CFGFilterInternal( (tra & TRA_RA) ? ResStr(IDS_FGMANAGER_13) : L"RoQ Audio Decoder (low merit)", (tra & TRA_RA) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_RoQA); m_transform.AddTail(pFGF); #endif #if INTERNAL_DECODER_DIRAC __if_exists(CDiracVideoDecoder) { pFGF = DNew CFGFilterInternal( (tra & TRA_DIRAC) ? ResStr(IDS_FGMANAGER_14) : L"Dirac Video Decoder (low merit)", (tra & TRA_DIRAC) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_DiracVideo); m_transform.AddTail(pFGF); } #endif pFGF = DNew CFGFilterInternal(L"NullTextRenderer", MERIT64_DO_USE); pFGF->AddType(MEDIATYPE_Text, MEDIASUBTYPE_NULL); pFGF->AddType(MEDIATYPE_ScriptCommand, MEDIASUBTYPE_NULL); pFGF->AddType(MEDIATYPE_Subtitle, MEDIASUBTYPE_NULL); pFGF->AddType(MEDIATYPE_Text, MEDIASUBTYPE_NULL); pFGF->AddType(MEDIATYPE_NULL, MEDIASUBTYPE_DVD_SUBPICTURE); pFGF->AddType(MEDIATYPE_NULL, MEDIASUBTYPE_CVD_SUBPICTURE); pFGF->AddType(MEDIATYPE_NULL, MEDIASUBTYPE_SVCD_SUBPICTURE); m_transform.AddTail(pFGF); // High merit MPC Video Decoder #if INCLUDE_MPC_VIDEO_DECODER | INCLUDE_MPC_DXVA_VIDEO_DECODER pFGF = DNew CFGFilterInternal(_T("MPC Video Decoder"), MERIT64_ABOVE_DSHOW); #if INTERNAL_DECODER_FLV if (ffmpeg_filters & FFM_FLV4) { pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_FLV1); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_flv1); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_FLV4); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_flv4); } #endif #if INTERNAL_DECODER_VP6 if (ffmpeg_filters & FFM_VP62) { pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_VP50); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_vp50); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_VP60); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_vp60); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_VP61); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_vp61); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_VP62); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_vp62); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_VP6F); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_vp6f); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_VP6A); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_vp6a); } #endif #if INTERNAL_DECODER_H264 | INTERNAL_DECODER_H264_DXVA if ((ffmpeg_filters & FFM_H264) || (dxva_filters & DXVA_H264)) { pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_H264); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_h264); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_X264); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_x264); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_VSSH); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_vssh); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_DAVC); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_davc); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_PAVC); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_pavc); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_AVC1); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_avc1); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_H264_bis); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_CCV1); } #endif #if INTERNAL_DECODER_MPEG2_DXVA if (dxva_filters & DXVA_MPEG2) { pFGF->AddType(MEDIATYPE_DVD_ENCRYPTED_PACK, MEDIASUBTYPE_MPEG2_VIDEO); pFGF->AddType(MEDIATYPE_MPEG2_PACK, MEDIASUBTYPE_MPEG2_VIDEO); pFGF->AddType(MEDIATYPE_MPEG2_PES, MEDIASUBTYPE_MPEG2_VIDEO); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_MPEG2_VIDEO); } #endif #if INTERNAL_DECODER_VC1 | INTERNAL_DECODER_VC1_DXVA if ((ffmpeg_filters & FFM_VC1) || (dxva_filters & DXVA_VC1)) { pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_WVC1); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_wvc1); } #endif #if INTERNAL_DECODER_XVID if (ffmpeg_filters & FFM_XVID) { pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_XVID); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_xvid); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_XVIX); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_xvix); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_MP4V); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_mp4v); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_M4S2); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_m4s2); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_MP4S); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_mp4s); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_3IV1); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_3iv1); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_3IV2); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_3iv2); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_3IVX); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_3ivx); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_BLZ0); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_blz0); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_DM4V); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_dm4v); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_DXGM); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_dxgm); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_FMP4); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_fmp4); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_HDX4); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_hdx4); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_LMP4); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_lmp4); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_NDIG); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_ndig); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_RMP4); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_rmp4); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_SMP4); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_smp4); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_SEDG); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_sedg); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_UMP4); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_ump4); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_WV1F); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_wv1f); } #endif #if INTERNAL_DECODER_DIVX if (ffmpeg_filters & FFM_DIVX) { pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_DIVX); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_divx); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_DX50); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_dx50); } #endif #if INTERNAL_DECODER_WMV if (ffmpeg_filters & FFM_WMV) { pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_WMV1); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_wmv1); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_WMV2); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_wmv2); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_WMV3); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_wmv3); } #endif #if INTERNAL_DECODER_MSMPEG4 if (ffmpeg_filters & FFM_MSMPEG4) { pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_DIV3); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_div3); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_DVX3); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_dvx3); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_MP43); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_mp43); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_COL1); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_col1); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_DIV4); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_div4); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_DIV5); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_div5); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_DIV6); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_div6); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_AP41); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_ap41); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_MPG3); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_mpg3); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_DIV2); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_div2); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_MP42); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_mp42); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_MPG4); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_mpg4); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_DIV1); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_div1); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_MP41); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_mp41); } #endif #if INTERNAL_DECODER_SVQ if (ffmpeg_filters & FFM_SVQ3) { pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_SVQ3); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_SVQ1); } #endif #if INTERNAL_DECODER_H263 if (ffmpeg_filters & FFM_H263) { pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_H263); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_h263); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_S263); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_s263); } #endif #if INTERNAL_DECODER_THEORA if (ffmpeg_filters & FFM_THEORA) { pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_THEORA); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_theora); } #endif #if INTERNAL_DECODER_AMVV if (ffmpeg_filters & FFM_AMVV) { pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_AMVV); } #endif #if INTERNAL_DECODER_VP8 if (ffmpeg_filters & FFM_VP8) { pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_VP80); } #endif m_transform.AddTail(pFGF); // Low merit MPC Video Decoder pFGF = DNew CFGFilterInternal(_T("MPC Video Decoder (low merit)"), MERIT64_DO_USE); #if INTERNAL_DECODER_FLV if (!(ffmpeg_filters & FFM_FLV4)) { pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_FLV1); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_flv1); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_FLV4); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_flv4); } #endif #if INTERNAL_DECODER_VP6 if (!(ffmpeg_filters & FFM_VP62)) { pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_VP50); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_vp50); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_VP60); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_vp60); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_VP61); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_vp61); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_VP62); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_vp62); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_VP6F); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_vp6f); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_VP6A); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_vp6a); } #endif #if INTERNAL_DECODER_H264 | INTERNAL_DECODER_H264_DXVA if (!(ffmpeg_filters & FFM_H264) && !(dxva_filters & DXVA_H264)) { pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_H264); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_h264); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_X264); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_x264); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_VSSH); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_vssh); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_DAVC); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_davc); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_PAVC); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_pavc); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_AVC1); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_avc1); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_H264_bis); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_CCV1); } #endif #if INTERNAL_DECODER_MPEG2_DXVA if (!(dxva_filters & DXVA_MPEG2)) { pFGF->AddType(MEDIATYPE_DVD_ENCRYPTED_PACK, MEDIASUBTYPE_MPEG2_VIDEO); pFGF->AddType(MEDIATYPE_MPEG2_PACK, MEDIASUBTYPE_MPEG2_VIDEO); pFGF->AddType(MEDIATYPE_MPEG2_PES, MEDIASUBTYPE_MPEG2_VIDEO); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_MPEG2_VIDEO); } #endif #if INTERNAL_DECODER_VC1 | INTERNAL_DECODER_VC1_DXVA if (!(ffmpeg_filters & FFM_VC1) && !(dxva_filters & DXVA_VC1)) { pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_WVC1); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_wvc1); } #endif #if INTERNAL_DECODER_XVID if (!(ffmpeg_filters & FFM_XVID)) { pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_XVID); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_xvid); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_XVIX); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_xvix); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_MP4V); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_mp4v); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_M4S2); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_m4s2); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_MP4S); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_mp4s); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_3IV1); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_3iv1); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_3IV2); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_3iv2); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_3IVX); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_3ivx); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_BLZ0); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_blz0); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_DM4V); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_dm4v); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_DXGM); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_dxgm); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_FMP4); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_fmp4); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_HDX4); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_hdx4); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_LMP4); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_lmp4); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_NDIG); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_ndig); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_RMP4); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_rmp4); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_SMP4); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_smp4); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_SEDG); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_sedg); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_UMP4); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_ump4); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_WV1F); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_wv1f); } #endif #if INTERNAL_DECODER_DIVX if (!(ffmpeg_filters & FFM_DIVX)) { pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_DIVX); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_divx); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_DX50); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_dx50); } #endif #if INTERNAL_DECODER_WMV if (!(ffmpeg_filters & FFM_WMV)) { pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_WMV1); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_wmv1); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_WMV2); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_wmv2); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_WMV3); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_wmv3); } #endif #if INTERNAL_DECODER_MSMPEG4 if (!(ffmpeg_filters & FFM_MSMPEG4)) { pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_DIV3); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_div3); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_DVX3); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_dvx3); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_MP43); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_mp43); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_COL1); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_col1); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_DIV4); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_div4); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_DIV5); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_div5); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_DIV6); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_div6); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_AP41); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_ap41); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_MPG3); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_mpg3); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_DIV2); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_div2); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_MP42); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_mp42); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_MPG4); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_mpg4); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_DIV1); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_div1); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_MP41); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_mp41); } #endif #if INTERNAL_DECODER_SVQ if (!(ffmpeg_filters & FFM_SVQ3)) { pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_SVQ3); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_SVQ1); } #endif #if INTERNAL_DECODER_H263 if (!(ffmpeg_filters & FFM_H263)) { pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_H263); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_h263); } #endif #if INTERNAL_DECODER_THEORA if (!(ffmpeg_filters & FFM_THEORA)) { pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_THEORA); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_theora); } #endif #if INTERNAL_DECODER_AMVV if (!(ffmpeg_filters & FFM_AMVV)) { pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_AMVV); } #endif #if INTERNAL_DECODER_VP8 if (!(ffmpeg_filters & FFM_VP8)) { pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_VP80); } #endif m_transform.AddTail(pFGF); #endif #if INTERNAL_DECODER_MPEG2 // Keep software decoder after DXVA decoder ! pFGF = DNew CFGFilterInternal( (tra & TRA_MPEG2) ? ResStr(IDS_FGMANAGER_1) : L"MPEG-2 Video Decoder (low merit)", (tra & TRA_MPEG2) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE); pFGF->AddType(MEDIATYPE_DVD_ENCRYPTED_PACK, MEDIASUBTYPE_MPEG2_VIDEO); pFGF->AddType(MEDIATYPE_MPEG2_PACK, MEDIASUBTYPE_MPEG2_VIDEO); pFGF->AddType(MEDIATYPE_MPEG2_PES, MEDIASUBTYPE_MPEG2_VIDEO); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_MPEG2_VIDEO); m_transform.AddTail(pFGF); #endif // Low merit MPC Audio Decoder /* // TODO : not finished! pFGF = DNew CFGFilterInternal(_T("MPC Audio Decoder (low merit)"), MERIT64_ABOVE_DSHOW); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_IMA_AMV); m_transform.AddTail(pFGF); */ #if INCLUDE_MPC_VIDEO_DECODER | INCLUDE_MPC_DXVA_VIDEO_DECODER CMPCVideoDecFilter::FFmpegFilters = s.FFmpegFilters; CMPCVideoDecFilter::DXVAFilters = s.DXVAFilters; CMPCVideoDecFilter::m_ref_frame_count_check_skip = false; if((!IsVistaOrAbove()) && ((s.iDSVideoRendererType == VIDRNDT_DS_DEFAULT) || (s.iDSVideoRendererType == VIDRNDT_DS_DXR))) { CMPCVideoDecFilter::m_ref_frame_count_check_skip = true; } #endif // Blocked filters // "Subtitle Mixer" makes an access violation around the // 11-12th media type when enumerating them on its output. m_transform.AddTail(DNew CFGFilterRegistry(GUIDFromCString(_T("{00A95963-3BE5-48C0-AD9F-3356D67EA09D}")), MERIT64_DO_NOT_USE)); // DiracSplitter.ax is crashing MPC-HC when opening invalid files... m_transform.AddTail(DNew CFGFilterRegistry(GUIDFromCString(_T("{09E7F58E-71A1-419D-B0A0-E524AE1454A9}")), MERIT64_DO_NOT_USE)); m_transform.AddTail(DNew CFGFilterRegistry(GUIDFromCString(_T("{5899CFB9-948F-4869-A999-5544ECB38BA5}")), MERIT64_DO_NOT_USE)); m_transform.AddTail(DNew CFGFilterRegistry(GUIDFromCString(_T("{F78CF248-180E-4713-B107-B13F7B5C31E1}")), MERIT64_DO_NOT_USE)); // ISCR suxx m_transform.AddTail(DNew CFGFilterRegistry(GUIDFromCString(_T("{48025243-2D39-11CE-875D-00608CB78066}")), MERIT64_DO_NOT_USE)); // Samsung's "mpeg-4 demultiplexor" can even open matroska files, amazing... m_transform.AddTail(DNew CFGFilterRegistry(GUIDFromCString(_T("{99EC0C72-4D1B-411B-AB1F-D561EE049D94}")), MERIT64_DO_NOT_USE)); // LG Video Renderer (lgvid.ax) just crashes when trying to connect it m_transform.AddTail(DNew CFGFilterRegistry(GUIDFromCString(_T("{9F711C60-0668-11D0-94D4-0000C02BA972}")), MERIT64_DO_NOT_USE)); // palm demuxer crashes (even crashes graphedit when dropping an .ac3 onto it) m_transform.AddTail(DNew CFGFilterRegistry(GUIDFromCString(_T("{BE2CF8A7-08CE-4A2C-9A25-FD726A999196}")), MERIT64_DO_NOT_USE)); // DCDSPFilter (early versions crash mpc) { CRegKey key; TCHAR buff[256]; ULONG len = sizeof(buff); memset(buff, 0, len); CString clsid = _T("{B38C58A0-1809-11D6-A458-EDAE78F1DF12}"); if(ERROR_SUCCESS == key.Open(HKEY_CLASSES_ROOT, _T("CLSID\\") + clsid + _T("\\InprocServer32"), KEY_READ) && ERROR_SUCCESS == key.QueryStringValue(NULL, buff, &len) && GetFileVersion(buff) < 0x0001000000030000ui64) { m_transform.AddTail(DNew CFGFilterRegistry(GUIDFromCString(clsid), MERIT64_DO_NOT_USE)); } } /* // NVIDIA Transport Demux crashed for someone, I could not reproduce it m_transform.AddTail(DNew CFGFilterRegistry(GUIDFromCString(_T("{735823C1-ACC4-11D3-85AC-006008376FB8}")), MERIT64_DO_NOT_USE)); */ // mainconcept color space converter m_transform.AddTail(DNew CFGFilterRegistry(GUIDFromCString(_T("{272D77A0-A852-4851-ADA4-9091FEAD4C86}")), MERIT64_DO_NOT_USE)); // Block VSFilter when internal subtitle renderer will get used if(s.fAutoloadSubtitles && s.fBlockVSFilter) { if(s.iDSVideoRendererType == VIDRNDT_DS_VMR7RENDERLESS || s.iDSVideoRendererType == VIDRNDT_DS_VMR9RENDERLESS || s.iDSVideoRendererType == VIDRNDT_DS_EVR_CUSTOM || s.iDSVideoRendererType == VIDRNDT_DS_DXR || s.iDSVideoRendererType == VIDRNDT_DS_SYNC) { m_transform.AddTail(DNew CFGFilterRegistry(GUIDFromCString(_T("{9852A670-F845-491B-9BE6-EBD841B8A613}")), MERIT64_DO_NOT_USE)); } } // Overrides WORD merit_low = 1; POSITION pos = s.filters.GetTailPosition(); while(pos) { FilterOverride* fo = s.filters.GetPrev(pos); if (!fo->fDisabled && fo->name == _T("Broadcom Video Decoder")) bOverrideBroadcom = true; if(fo->fDisabled || fo->type == FilterOverride::EXTERNAL && !CPath(MakeFullPath(fo->path)).FileExists()) continue; ULONGLONG merit = fo->iLoadType == FilterOverride::PREFERRED ? MERIT64_ABOVE_DSHOW : fo->iLoadType == FilterOverride::MERIT ? MERIT64(fo->dwMerit) : MERIT64_DO_NOT_USE; // fo->iLoadType == FilterOverride::BLOCKED merit += merit_low++; CFGFilter* pFGF = NULL; if(fo->type == FilterOverride::REGISTERED) { pFGF = DNew CFGFilterRegistry(fo->dispname, merit); } else if(fo->type == FilterOverride::EXTERNAL) { pFGF = DNew CFGFilterFile(fo->clsid, fo->path, CStringW(fo->name), merit); } if(pFGF) { pFGF->SetTypes(fo->guids); m_override.AddTail(pFGF); } } /* Use Broadcom decoder (if installed) for VC-1, H.264 and MPEG-2 */ if (!bOverrideBroadcom) { pFGF = DNew CFGFilterRegistry(GUIDFromCString(_T("{2DE1D17E-46B1-42A8-9AEC-E20E80D9B1A9}")), MERIT64_ABOVE_DSHOW); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_H264); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_h264); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_X264); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_x264); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_VSSH); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_vssh); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_DAVC); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_davc); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_PAVC); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_pavc); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_AVC1); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_avc1); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_H264_bis); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_CCV1); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_WVC1); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_wvc1); pFGF->AddType(MEDIATYPE_DVD_ENCRYPTED_PACK, MEDIASUBTYPE_MPEG2_VIDEO); pFGF->AddType(MEDIATYPE_MPEG2_PACK, MEDIASUBTYPE_MPEG2_VIDEO); pFGF->AddType(MEDIATYPE_MPEG2_PES, MEDIASUBTYPE_MPEG2_VIDEO); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_MPEG2_VIDEO); m_transform.AddHead(pFGF); } } STDMETHODIMP CFGManagerCustom::AddFilter(IBaseFilter* pBF, LPCWSTR pName) { CAutoLock cAutoLock(this); HRESULT hr; if(FAILED(hr = __super::AddFilter(pBF, pName))) return hr; AppSettings& s = AfxGetAppSettings(); if(GetCLSID(pBF) == CLSID_DMOWrapperFilter) { if(CComQIPtr pPB = pBF) { CComVariant var(true); pPB->Write(CComBSTR(L"_HIRESOUTPUT"), &var); } } if(CComQIPtr pASF = pBF) { pASF->EnableDownSamplingTo441(s.fDownSampleTo441); pASF->SetSpeakerConfig(s.fCustomChannelMapping, s.pSpeakerToChannelMap); pASF->SetAudioTimeShift(s.fAudioTimeShift ? 10000i64*s.tAudioTimeShift : 0); pASF->SetNormalizeBoost(s.fAudioNormalize, s.fAudioNormalizeRecover, s.AudioBoost); } return hr; } // // CFGManagerPlayer // CFGManagerPlayer::CFGManagerPlayer(LPCTSTR pName, LPUNKNOWN pUnk, HWND hWnd) : CFGManagerCustom(pName, pUnk) , m_hWnd(hWnd) , m_vrmerit(MERIT64(MERIT_PREFERRED)) , m_armerit(MERIT64(MERIT_PREFERRED)) { TRACE("--> CFGManagerPlayer::CFGManagerPlayer on thread: %d\n", GetCurrentThreadId()); CFGFilter* pFGF; AppSettings& s = AfxGetAppSettings(); if(m_pFM) { CComPtr pEM; GUID guids[] = {MEDIATYPE_Video, MEDIASUBTYPE_NULL}; if(SUCCEEDED(m_pFM->EnumMatchingFilters(&pEM, 0, FALSE, MERIT_DO_NOT_USE+1, TRUE, 1, guids, NULL, NULL, TRUE, FALSE, 0, NULL, NULL, NULL))) { for(CComPtr pMoniker; S_OK == pEM->Next(1, &pMoniker, NULL); pMoniker = NULL) { CFGFilterRegistry f(pMoniker); m_vrmerit = max(m_vrmerit, f.GetMerit()); } } m_vrmerit += 0x100; } if(m_pFM) { CComPtr pEM; GUID guids[] = {MEDIATYPE_Audio, MEDIASUBTYPE_NULL}; if(SUCCEEDED(m_pFM->EnumMatchingFilters(&pEM, 0, FALSE, MERIT_DO_NOT_USE+1, TRUE, 1, guids, NULL, NULL, TRUE, FALSE, 0, NULL, NULL, NULL))) { for(CComPtr pMoniker; S_OK == pEM->Next(1, &pMoniker, NULL); pMoniker = NULL) { CFGFilterRegistry f(pMoniker); m_armerit = max(m_armerit, f.GetMerit()); } } BeginEnumSysDev(CLSID_AudioRendererCategory, pMoniker) { CFGFilterRegistry f(pMoniker); m_armerit = max(m_armerit, f.GetMerit()); } EndEnumSysDev m_armerit += 0x100; } // Switchers if(s.fEnableAudioSwitcher) { pFGF = DNew CFGFilterInternal(L"Audio Switcher", m_armerit + 0x100); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_NULL); m_transform.AddTail(pFGF); // morgan stream switcher m_transform.AddTail(DNew CFGFilterRegistry(GUIDFromCString(_T("{D3CD7858-971A-4838-ACEC-40CA5D529DC8}")), MERIT64_DO_NOT_USE)); } // Renderers switch(s.iDSVideoRendererType) { case VIDRNDT_DS_OLDRENDERER: m_transform.AddTail(DNew CFGFilterRegistry(CLSID_VideoRenderer, m_vrmerit)); break; case VIDRNDT_DS_OVERLAYMIXER: m_transform.AddTail(DNew CFGFilterVideoRenderer(m_hWnd, CLSID_OverlayMixer, L"Overlay Mixer", m_vrmerit)); break; case VIDRNDT_DS_VMR7WINDOWED: m_transform.AddTail(DNew CFGFilterVideoRenderer(m_hWnd, CLSID_VideoMixingRenderer, L"Video Mixing Render 7 (Windowed)", m_vrmerit)); break; case VIDRNDT_DS_VMR9WINDOWED: m_transform.AddTail(DNew CFGFilterVideoRenderer(m_hWnd, CLSID_VideoMixingRenderer9, L"Video Mixing Render 9 (Windowed)", m_vrmerit)); break; case VIDRNDT_DS_VMR7RENDERLESS: m_transform.AddTail(DNew CFGFilterVideoRenderer(m_hWnd, CLSID_VMR7AllocatorPresenter, L"Video Mixing Render 7 (Renderless)", m_vrmerit)); break; case VIDRNDT_DS_VMR9RENDERLESS: m_transform.AddTail(DNew CFGFilterVideoRenderer(m_hWnd, CLSID_VMR9AllocatorPresenter, L"Video Mixing Render 9 (Renderless)", m_vrmerit)); break; case VIDRNDT_DS_EVR: m_transform.AddTail(DNew CFGFilterVideoRenderer(m_hWnd, CLSID_EnhancedVideoRenderer, L"Enhanced Video Renderer", m_vrmerit)); break; case VIDRNDT_DS_EVR_CUSTOM: m_transform.AddTail(DNew CFGFilterVideoRenderer(m_hWnd, CLSID_EVRAllocatorPresenter, L"Enhanced Video Renderer (custom presenter)", m_vrmerit)); break; case VIDRNDT_DS_DXR: m_transform.AddTail(DNew CFGFilterVideoRenderer(m_hWnd, CLSID_DXRAllocatorPresenter, L"Haali's Video Renderer", m_vrmerit)); break; case VIDRNDT_DS_MADVR: m_transform.AddTail(DNew CFGFilterVideoRenderer(m_hWnd, CLSID_madVRAllocatorPresenter, L"madVR Renderer", m_vrmerit)); break; case VIDRNDT_DS_SYNC: m_transform.AddTail(DNew CFGFilterVideoRenderer(m_hWnd, CLSID_SyncAllocatorPresenter, L"EVR Sync", m_vrmerit)); break; case VIDRNDT_DS_NULL_COMP: pFGF = DNew CFGFilterInternal(L"Null Video Renderer (Any)", MERIT64_ABOVE_DSHOW+2); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_NULL); m_transform.AddTail(pFGF); break; case VIDRNDT_DS_NULL_UNCOMP: pFGF = DNew CFGFilterInternal(L"Null Video Renderer (Uncompressed)", MERIT64_ABOVE_DSHOW+2); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_NULL); m_transform.AddTail(pFGF); break; } CString SelAudioRender = s.SelectedAudioRender(); if(SelAudioRender == AUDRNDT_NULL_COMP) { pFGF = DNew CFGFilterInternal(AUDRNDT_NULL_COMP, MERIT64_ABOVE_DSHOW+2); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_NULL); m_transform.AddTail(pFGF); } else if(SelAudioRender == AUDRNDT_NULL_UNCOMP) { pFGF = DNew CFGFilterInternal(AUDRNDT_NULL_UNCOMP, MERIT64_ABOVE_DSHOW+2); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_NULL); m_transform.AddTail(pFGF); } else if(SelAudioRender == AUDRNDT_MPC) { pFGF = DNew CFGFilterInternal(AUDRNDT_MPC, MERIT64_ABOVE_DSHOW+2); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_NULL); m_transform.AddTail(pFGF); } else if(SelAudioRender!="") { pFGF = DNew CFGFilterRegistry(SelAudioRender, m_armerit); pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_NULL); m_transform.AddTail(pFGF); } } STDMETHODIMP CFGManagerPlayer::ConnectDirect(IPin* pPinOut, IPin* pPinIn, const AM_MEDIA_TYPE* pmt) { CAutoLock cAutoLock(this); if(GetCLSID(pPinOut) == CLSID_MPEG2Demultiplexer) { CComQIPtr pMS = pPinOut; REFERENCE_TIME rtDur = 0; if(!pMS || FAILED(pMS->GetDuration(&rtDur)) || rtDur <= 0) return E_FAIL; } return __super::ConnectDirect(pPinOut, pPinIn, pmt); } // // CFGManagerDVD // CFGManagerDVD::CFGManagerDVD(LPCTSTR pName, LPUNKNOWN pUnk, HWND hWnd) : CFGManagerPlayer(pName, pUnk, hWnd) { AppSettings& s = AfxGetAppSettings(); // have to avoid the old video renderer if(!s.fXpOrBetter && s.iDSVideoRendererType != VIDRNDT_DS_OVERLAYMIXER || s.iDSVideoRendererType == VIDRNDT_DS_OLDRENDERER) m_transform.AddTail(DNew CFGFilterVideoRenderer(m_hWnd, CLSID_OverlayMixer, L"Overlay Mixer", m_vrmerit-1)); // elecard's decoder isn't suited for dvd playback (atm) m_transform.AddTail(DNew CFGFilterRegistry(GUIDFromCString(_T("{F50B3F13-19C4-11CF-AA9A-02608C9BABA2}")), MERIT64_DO_NOT_USE)); } #include "../../decss/VobFile.h" class CResetDVD : public CDVDSession { public: CResetDVD(LPCTSTR path) { if(Open(path)) { if(BeginSession()) { Authenticate(); /*GetDiscKey();*/ EndSession(); } Close(); } } }; STDMETHODIMP CFGManagerDVD::RenderFile(LPCWSTR lpcwstrFile, LPCWSTR lpcwstrPlayList) { CAutoLock cAutoLock(this); HRESULT hr; CComPtr pBF; if(FAILED(hr = AddSourceFilter(lpcwstrFile, lpcwstrFile, &pBF))) return hr; return ConnectFilter(pBF, NULL); } STDMETHODIMP CFGManagerDVD::AddSourceFilter(LPCWSTR lpcwstrFileName, LPCWSTR lpcwstrFilterName, IBaseFilter** ppFilter) { CAutoLock cAutoLock(this); CheckPointer(lpcwstrFileName, E_POINTER); CheckPointer(ppFilter, E_POINTER); HRESULT hr; CStringW fn = CStringW(lpcwstrFileName).TrimLeft(); CStringW protocol = fn.Left(fn.Find(':')+1).TrimRight(':').MakeLower(); CStringW ext = CPathW(fn).GetExtension().MakeLower(); GUID clsid = ext == L".ratdvd" ? GUIDFromCString(_T("{482d10b6-376e-4411-8a17-833800A065DB}")) : CLSID_DVDNavigator; CComPtr pBF; if(FAILED(hr = pBF.CoCreateInstance(clsid)) || FAILED(hr = AddFilter(pBF, L"DVD Navigator"))) return VFW_E_CANNOT_LOAD_SOURCE_FILTER; CComQIPtr pDVDC; CComQIPtr pDVDI; if(!((pDVDC = pBF) && (pDVDI = pBF))) return E_NOINTERFACE; WCHAR buff[_MAX_PATH]; ULONG len; if((!fn.IsEmpty() && FAILED(hr = pDVDC->SetDVDDirectory(fn)) && FAILED(hr = pDVDC->SetDVDDirectory(fn + L"VIDEO_TS")) && FAILED(hr = pDVDC->SetDVDDirectory(fn + L"\\VIDEO_TS"))) || FAILED(hr = pDVDI->GetDVDDirectory(buff, countof(buff), &len)) || len == 0) return E_INVALIDARG; pDVDC->SetOption(DVD_ResetOnStop, FALSE); pDVDC->SetOption(DVD_HMSF_TimeCodeEvents, TRUE); if(clsid == CLSID_DVDNavigator) CResetDVD(CString(buff)); *ppFilter = pBF.Detach(); return S_OK; } // // CFGManagerCapture // CFGManagerCapture::CFGManagerCapture(LPCTSTR pName, LPUNKNOWN pUnk, HWND hWnd) : CFGManagerPlayer(pName, pUnk, hWnd) { CFGFilter* pFGF = DNew CFGFilterInternal(L"Deinterlacer", m_vrmerit + 0x100); pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_NULL); m_transform.AddTail(pFGF); // morgan stream switcher m_transform.AddTail(DNew CFGFilterRegistry(GUIDFromCString(_T("{D3CD7858-971A-4838-ACEC-40CA5D529DC8}")), MERIT64_DO_NOT_USE)); } // // CFGManagerMuxer // CFGManagerMuxer::CFGManagerMuxer(LPCTSTR pName, LPUNKNOWN pUnk) : CFGManagerCustom(pName, pUnk) { m_source.AddTail(DNew CFGFilterInternal()); m_source.AddTail(DNew CFGFilterInternal()); } // // CFGAggregator // CFGAggregator::CFGAggregator(const CLSID& clsid, LPCTSTR pName, LPUNKNOWN pUnk, HRESULT& hr) : CUnknown(pName, pUnk) { hr = m_pUnkInner.CoCreateInstance(clsid, GetOwner()); } CFGAggregator::~CFGAggregator() { m_pUnkInner.Release(); } STDMETHODIMP CFGAggregator::NonDelegatingQueryInterface(REFIID riid, void** ppv) { CheckPointer(ppv, E_POINTER); return m_pUnkInner && (riid != IID_IUnknown && SUCCEEDED(m_pUnkInner->QueryInterface(riid, ppv))) ? S_OK : __super::NonDelegatingQueryInterface(riid, ppv); }