GraphBuilder.cpp
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:60k
- /*
- * Copyright (C) 2003-2005 Gabest
- * http://www.gabest.org
- *
- * 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, 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 GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- */
- #include "stdafx.h"
- #include "mplayerc.h"
- #include "GraphBuilder.h"
- #include "....DSUtilDSUtil.h"
- #include "....filtersfilters.h"
- #include "......includemoreuuids.h"
- #include "......includeOggOggDS.h"
- #include "......includematroskamatroska.h"
- #include "DX7AllocatorPresenter.h"
- #include "DX9AllocatorPresenter.h"
- #include "DeinterlacerFilter.h"
- #include <initguid.h>
- #include <dmodshow.h>
- #include <D3d9.h>
- #include <Vmr9.h>
- static void CheckStupidSharedFilesourceFilter()
- {
- CRegKey key;
- CString str(_T("CLSID\{E436EBB5-524F-11CE-9F53-0020AF0BA770}\InprocServer32"));
- if(ERROR_SUCCESS == key.Open(HKEY_CLASSES_ROOT, str, KEY_READ))
- {
- ULONG nChars = 0;
- if(ERROR_SUCCESS == key.QueryStringValue(NULL, NULL, &nChars))
- {
- CString dll;
- if(ERROR_SUCCESS == key.QueryStringValue(NULL, dll.GetBuffer(nChars), &nChars))
- {
- dll.ReleaseBuffer(nChars);
- dll.MakeLower();
- if(dll.Find(_T("shared_filesource.ax")) >= 0
- || dll.Find(_T("shared~1.ax")) >= 0)
- {
- if(IDYES == AfxMessageBox(
- _T("Warning: MPC has detected that DirectShow's "File Source (async)" filtern")
- _T("was replaced by shared_filesource.ax. Please run "regsvr32.exe quartz.dll"n")
- _T("in your system folder to restore it. If you are a user with administratorn")
- _T("rights, MPC can also do this for you. Do you want to re-register quartz.dll now?"),
- MB_YESNO|MB_ICONEXCLAMATION))
- {
- TCHAR buff[MAX_PATH+1];
- GetSystemDirectory(buff, sizeof(buff));
-
- CString path = CString(buff) + _T("\quartz.dll");
- HRESULT hr = E_FAIL;
- if(HMODULE hModule = LoadLibrary(path))
- {
- typedef HRESULT (__stdcall * PDllRegisterServer)();
- if(PDllRegisterServer p = (PDllRegisterServer)GetProcAddress(hModule, "DllRegisterServer"))
- hr = p();
- }
- if(SUCCEEDED(hr))
- AfxMessageBox(_T("Successfully re-registered quartz.dll, you may need to restart the player now."), MB_OK);
- else
- AfxMessageBox(_T("Failed to re-register quartz.dll!"), MB_OK|MB_ICONEXCLAMATION);
- }
- }
- }
- }
- }
- }
- //
- // CGraphBuilder
- //
- CGraphBuilder::CGraphBuilder(IGraphBuilder* pGB, HWND hWnd)
- : m_pGB(pGB), m_hWnd(hWnd)
- , m_nTotalStreams(0)
- , m_nCurrentStream(0)
- , m_VRMerit(LMERIT(MERIT_PREFERRED+1)+0x100)
- , m_ARMerit(LMERIT(MERIT_PREFERRED+1)+0x100)
- {
- AppSettings& s = AfxGetAppSettings();
- m_pFM.CoCreateInstance(CLSID_FilterMapper2);
- if(!m_pFM) return;
- {
- CArray<GUID> guids;
- CComPtr<IEnumMoniker> pEM;
- m_VRMerit = LMERIT(MERIT_PREFERRED);
- guids.Add(MEDIATYPE_Video);
- guids.Add(MEDIASUBTYPE_NULL);
- if(guids.GetCount() > 0
- && SUCCEEDED(m_pFM->EnumMatchingFilters(
- &pEM, 0, FALSE, MERIT_DO_NOT_USE+1,
- TRUE, guids.GetCount()/2, guids.GetData(), NULL, NULL, TRUE,
- FALSE, 0, NULL, NULL, NULL)))
- {
- for(CComPtr<IMoniker> pMoniker; S_OK == pEM->Next(1, &pMoniker, NULL); pMoniker = NULL)
- {
- CGraphRegFilter gf(pMoniker);
- m_VRMerit = max(m_VRMerit, gf.GetMerit());
- }
- }
- guids.RemoveAll();
- pEM = NULL;
- m_VRMerit += 0x100;
- m_ARMerit = LMERIT(MERIT_PREFERRED);
- guids.Add(MEDIATYPE_Audio);
- guids.Add(MEDIASUBTYPE_NULL);
- if(guids.GetCount() > 0
- && SUCCEEDED(m_pFM->EnumMatchingFilters(
- &pEM, 0, FALSE, MERIT_DO_NOT_USE+1,
- TRUE, guids.GetCount()/2, guids.GetData(), NULL, NULL, TRUE,
- FALSE, 0, NULL, NULL, NULL)))
- {
- for(CComPtr<IMoniker> pMoniker; S_OK == pEM->Next(1, &pMoniker, NULL); pMoniker = NULL)
- {
- CGraphRegFilter gf(pMoniker);
- m_ARMerit = max(m_ARMerit, gf.GetMerit());
- }
- }
- BeginEnumSysDev(CLSID_AudioRendererCategory, pMoniker)
- {
- CGraphRegFilter gf(pMoniker);
- m_ARMerit = max(m_ARMerit, gf.GetMerit());
- }
- EndEnumSysDev
- guids.RemoveAll();
- pEM = NULL;
- m_ARMerit += 0x100;
- }
- // transform filters
- CList<GUID> guids;
- guids.AddTail(MEDIATYPE_Audio);
- guids.AddTail(MEDIASUBTYPE_WAVE_DOLBY_AC3);
- guids.AddTail(MEDIATYPE_Audio);
- guids.AddTail(MEDIASUBTYPE_WAVE_DTS);
- AddFilter(new CGraphCustomFilter(__uuidof(CAVI2AC3Filter), guids, L"AVI<->AC3/DTS", LMERIT(0x00680000)+1));
- guids.RemoveAll();
- {
- guids.AddTail(MEDIATYPE_Stream);
- guids.AddTail(MEDIASUBTYPE_Matroska);
- AddFilter(new CGraphCustomFilter(__uuidof(CMatroskaSplitterFilter), guids,
- (s.SrcFilters&SRC_MATROSKA) ? L"Matroska Splitter" : L"Matroska Splitter (low merit)",
- (s.SrcFilters&SRC_MATROSKA) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
- guids.RemoveAll();
- }
- {
- guids.AddTail(MEDIATYPE_Stream);
- guids.AddTail(MEDIASUBTYPE_RealMedia);
- AddFilter(new CGraphCustomFilter(__uuidof(CRealMediaSplitterFilter), guids,
- (s.SrcFilters&SRC_REALMEDIA) ? L"RealMedia Splitter" : L"RealMedia Splitter (low merit)",
- (s.SrcFilters&SRC_REALMEDIA) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
- guids.RemoveAll();
- }
- {
- guids.AddTail(MEDIATYPE_Stream);
- guids.AddTail(MEDIASUBTYPE_Avi);
- AddFilter(new CGraphCustomFilter(__uuidof(CAviSplitterFilter), guids,
- (s.SrcFilters&SRC_AVI) ? L"Avi Splitter" : L"Avi Splitter (low merit)",
- (s.SrcFilters&SRC_AVI) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
- guids.RemoveAll();
- }
-
- __if_exists(CRadGtSplitterFilter)
- {
- guids.AddTail(MEDIATYPE_Stream);
- guids.AddTail(MEDIASUBTYPE_Bink);
- guids.AddTail(MEDIATYPE_Stream);
- guids.AddTail(MEDIASUBTYPE_Smacker);
- AddFilter(new CGraphCustomFilter(__uuidof(CRadGtSplitterFilter), guids,
- (s.SrcFilters&SRC_RADGT) ? L"RadGt Splitter" : L"RadGt Splitter (low merit)",
- (s.SrcFilters&SRC_RADGT) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
- guids.RemoveAll();
- }
- {
- guids.AddTail(MEDIATYPE_Stream);
- guids.AddTail(MEDIASUBTYPE_RoQ);
- AddFilter(new CGraphCustomFilter(__uuidof(CRoQSplitterFilter), guids,
- (s.SrcFilters&SRC_ROQ) ? L"RoQ Splitter" : L"RoQ Splitter (low merit)",
- (s.SrcFilters&SRC_ROQ) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
- guids.RemoveAll();
- }
- {
- guids.AddTail(MEDIATYPE_Stream);
- guids.AddTail(MEDIASUBTYPE_Ogg);
- AddFilter(new CGraphCustomFilter(__uuidof(COggSplitterFilter), guids,
- (s.SrcFilters&SRC_OGG) ? L"Ogg Splitter" : L"Ogg Splitter (low merit)",
- (s.SrcFilters&SRC_OGG) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
- guids.RemoveAll();
- }
- {
- guids.AddTail(MEDIATYPE_Stream);
- guids.AddTail(MEDIASUBTYPE_Nut);
- AddFilter(new CGraphCustomFilter(__uuidof(CNutSplitterFilter), guids,
- (s.SrcFilters&SRC_NUT) ? L"Nut Splitter" : L"Nut Splitter (low merit)",
- (s.SrcFilters&SRC_NUT) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
- guids.RemoveAll();
- }
- {
- guids.AddTail(MEDIATYPE_Stream);
- guids.AddTail(MEDIASUBTYPE_MPEG1System);
- guids.AddTail(MEDIATYPE_Stream);
- guids.AddTail(MEDIASUBTYPE_MPEG2_PROGRAM);
- guids.AddTail(MEDIATYPE_Stream);
- guids.AddTail(MEDIASUBTYPE_MPEG2_TRANSPORT);
- guids.AddTail(MEDIATYPE_Stream);
- guids.AddTail(MEDIASUBTYPE_MPEG2_PVA);
- AddFilter(new CGraphCustomFilter(__uuidof(CMpegSplitterFilter), guids,
- (s.SrcFilters&SRC_MPEG) ? L"Mpeg Splitter" : L"Mpeg Splitter (low merit)",
- (s.SrcFilters&SRC_MPEG) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
- guids.RemoveAll();
- }
- {
- guids.AddTail(MEDIATYPE_Video);
- guids.AddTail(MEDIASUBTYPE_MPEG1Packet);
- guids.AddTail(MEDIATYPE_Video);
- guids.AddTail(MEDIASUBTYPE_MPEG1Payload);
- AddFilter(new CGraphCustomFilter(__uuidof(CMpeg2DecFilter), guids,
- (s.TraFilters&TRA_MPEG1) ? L"MPEG-1 Video Decoder" : L"MPEG-1 Video Decoder (low merit)",
- (s.TraFilters&TRA_MPEG1) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
- guids.RemoveAll();
- }
- {
- guids.AddTail(MEDIATYPE_DVD_ENCRYPTED_PACK);
- guids.AddTail(MEDIASUBTYPE_MPEG2_VIDEO);
- guids.AddTail(MEDIATYPE_MPEG2_PACK);
- guids.AddTail(MEDIASUBTYPE_MPEG2_VIDEO);
- guids.AddTail(MEDIATYPE_MPEG2_PES);
- guids.AddTail(MEDIASUBTYPE_MPEG2_VIDEO);
- guids.AddTail(MEDIATYPE_Video);
- guids.AddTail(MEDIASUBTYPE_MPEG2_VIDEO);
- AddFilter(new CGraphCustomFilter(__uuidof(CMpeg2DecFilter), guids,
- (s.TraFilters&TRA_MPEG2) ? L"MPEG-2 Video Decoder" : L"MPEG-2 Video Decoder (low merit)",
- (s.TraFilters&TRA_MPEG2) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
- guids.RemoveAll();
- }
- {
- guids.AddTail(MEDIATYPE_Audio);
- guids.AddTail(MEDIASUBTYPE_MP3);
- guids.AddTail(MEDIATYPE_Audio);
- guids.AddTail(MEDIASUBTYPE_MPEG1AudioPayload);
- guids.AddTail(MEDIATYPE_Audio);
- guids.AddTail(MEDIASUBTYPE_MPEG1Payload);
- guids.AddTail(MEDIATYPE_Audio);
- guids.AddTail(MEDIASUBTYPE_MPEG1Packet);
- AddFilter(new CGraphCustomFilter(__uuidof(CMpaDecFilter), guids,
- (s.TraFilters&TRA_MPA) ? L"MPEG-1 Audio Decoder" : L"MPEG-1 Audio Decoder (low merit)",
- (s.TraFilters&TRA_MPA) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
- guids.RemoveAll();
- }
- {
- guids.AddTail(MEDIATYPE_DVD_ENCRYPTED_PACK);
- guids.AddTail(MEDIASUBTYPE_MPEG2_AUDIO);
- guids.AddTail(MEDIATYPE_MPEG2_PACK);
- guids.AddTail(MEDIASUBTYPE_MPEG2_AUDIO);
- guids.AddTail(MEDIATYPE_MPEG2_PES);
- guids.AddTail(MEDIASUBTYPE_MPEG2_AUDIO);
- guids.AddTail(MEDIATYPE_Audio);
- guids.AddTail(MEDIASUBTYPE_MPEG2_AUDIO);
- AddFilter(new CGraphCustomFilter(__uuidof(CMpaDecFilter), guids,
- (s.TraFilters&TRA_MPA) ? L"MPEG-2 Audio Decoder" : L"MPEG-2 Audio Decoder (low merit)",
- (s.TraFilters&TRA_MPA) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
- guids.RemoveAll();
- }
- {
- guids.AddTail(MEDIATYPE_DVD_ENCRYPTED_PACK);
- guids.AddTail(MEDIASUBTYPE_DVD_LPCM_AUDIO);
- guids.AddTail(MEDIATYPE_MPEG2_PACK);
- guids.AddTail(MEDIASUBTYPE_DVD_LPCM_AUDIO);
- guids.AddTail(MEDIATYPE_MPEG2_PES);
- guids.AddTail(MEDIASUBTYPE_DVD_LPCM_AUDIO);
- guids.AddTail(MEDIATYPE_Audio);
- guids.AddTail(MEDIASUBTYPE_DVD_LPCM_AUDIO);
- AddFilter(new CGraphCustomFilter(__uuidof(CMpaDecFilter), guids,
- (s.TraFilters&TRA_LPCM) ? L"LPCM Audio Decoder" : L"LPCM Audio Decoder (low merit)",
- (s.TraFilters&TRA_LPCM) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
- guids.RemoveAll();
- }
- {
- guids.AddTail(MEDIATYPE_DVD_ENCRYPTED_PACK);
- guids.AddTail(MEDIASUBTYPE_DOLBY_AC3);
- guids.AddTail(MEDIATYPE_MPEG2_PACK);
- guids.AddTail(MEDIASUBTYPE_DOLBY_AC3);
- guids.AddTail(MEDIATYPE_MPEG2_PES);
- guids.AddTail(MEDIASUBTYPE_DOLBY_AC3);
- guids.AddTail(MEDIATYPE_Audio);
- guids.AddTail(MEDIASUBTYPE_DOLBY_AC3);
- guids.AddTail(MEDIATYPE_Audio);
- guids.AddTail(MEDIASUBTYPE_WAVE_DOLBY_AC3);
- AddFilter(new CGraphCustomFilter(__uuidof(CMpaDecFilter), guids,
- (s.TraFilters&TRA_AC3) ? L"AC3 Audio Decoder" : L"AC3 Audio Decoder (low merit)",
- (s.TraFilters&TRA_AC3) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
- guids.RemoveAll();
- }
- {
- guids.AddTail(MEDIATYPE_DVD_ENCRYPTED_PACK);
- guids.AddTail(MEDIASUBTYPE_DTS);
- guids.AddTail(MEDIATYPE_MPEG2_PACK);
- guids.AddTail(MEDIASUBTYPE_DTS);
- guids.AddTail(MEDIATYPE_MPEG2_PES);
- guids.AddTail(MEDIASUBTYPE_DTS);
- guids.AddTail(MEDIATYPE_Audio);
- guids.AddTail(MEDIASUBTYPE_DTS);
- guids.AddTail(MEDIATYPE_Audio);
- guids.AddTail(MEDIASUBTYPE_WAVE_DTS);
- AddFilter(new CGraphCustomFilter(__uuidof(CMpaDecFilter), guids,
- (s.TraFilters&TRA_DTS) ? L"DTS Decoder" : L"DTS Decoder (low merit)",
- (s.TraFilters&TRA_DTS) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
- guids.RemoveAll();
- }
- {
- guids.AddTail(MEDIATYPE_DVD_ENCRYPTED_PACK);
- guids.AddTail(MEDIASUBTYPE_AAC);
- guids.AddTail(MEDIATYPE_MPEG2_PACK);
- guids.AddTail(MEDIASUBTYPE_AAC);
- guids.AddTail(MEDIATYPE_MPEG2_PES);
- guids.AddTail(MEDIASUBTYPE_AAC);
- guids.AddTail(MEDIATYPE_Audio);
- guids.AddTail(MEDIASUBTYPE_AAC);
- guids.AddTail(MEDIATYPE_DVD_ENCRYPTED_PACK);
- guids.AddTail(MEDIASUBTYPE_MP4A);
- guids.AddTail(MEDIATYPE_MPEG2_PACK);
- guids.AddTail(MEDIASUBTYPE_MP4A);
- guids.AddTail(MEDIATYPE_MPEG2_PES);
- guids.AddTail(MEDIASUBTYPE_MP4A);
- guids.AddTail(MEDIATYPE_Audio);
- guids.AddTail(MEDIASUBTYPE_MP4A);
- AddFilter(new CGraphCustomFilter(__uuidof(CMpaDecFilter), guids,
- (s.TraFilters&TRA_AAC) ? L"AAC Decoder" : L"AAC Decoder (low merit)",
- (s.TraFilters&TRA_AAC) ? LMERIT_ABOVE_DSHOW+1 : LMERIT_DO_USE));
- guids.RemoveAll();
- }
- {
- guids.AddTail(MEDIATYPE_DVD_ENCRYPTED_PACK);
- guids.AddTail(MEDIASUBTYPE_PS2_PCM);
- guids.AddTail(MEDIATYPE_MPEG2_PACK);
- guids.AddTail(MEDIASUBTYPE_PS2_PCM);
- guids.AddTail(MEDIATYPE_MPEG2_PES);
- guids.AddTail(MEDIASUBTYPE_PS2_PCM);
- guids.AddTail(MEDIATYPE_Audio);
- guids.AddTail(MEDIASUBTYPE_PS2_PCM);
- AddFilter(new CGraphCustomFilter(__uuidof(CMpaDecFilter), guids,
- (s.TraFilters&TRA_PS2AUD) ? L"PS2 Audio Decoder" : L"PS2 Audio Decoder (low merit)",
- (s.TraFilters&TRA_PS2AUD) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
- guids.RemoveAll();
- }
- {
- guids.AddTail(MEDIATYPE_Video);
- guids.AddTail(MEDIASUBTYPE_RV10);
- guids.AddTail(MEDIATYPE_Video);
- guids.AddTail(MEDIASUBTYPE_RV20);
- guids.AddTail(MEDIATYPE_Video);
- guids.AddTail(MEDIASUBTYPE_RV30);
- guids.AddTail(MEDIATYPE_Video);
- guids.AddTail(MEDIASUBTYPE_RV40);
- AddFilter(new CGraphCustomFilter(__uuidof(CRealVideoDecoder), guids,
- (s.TraFilters&TRA_RV) ? L"RealVideo Decoder" : L"RealVideo Decoder (low merit)",
- (s.TraFilters&TRA_RV) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
- guids.RemoveAll();
- }
- {
- guids.AddTail(MEDIATYPE_Audio);
- guids.AddTail(MEDIASUBTYPE_14_4);
- guids.AddTail(MEDIATYPE_Audio);
- guids.AddTail(MEDIASUBTYPE_28_8);
- guids.AddTail(MEDIATYPE_Audio);
- guids.AddTail(MEDIASUBTYPE_ATRC);
- guids.AddTail(MEDIATYPE_Audio);
- guids.AddTail(MEDIASUBTYPE_COOK);
- guids.AddTail(MEDIATYPE_Audio);
- guids.AddTail(MEDIASUBTYPE_DNET);
- guids.AddTail(MEDIATYPE_Audio);
- guids.AddTail(MEDIASUBTYPE_SIPR);
- guids.AddTail(MEDIATYPE_Audio);
- guids.AddTail(MEDIASUBTYPE_RAAC);
- AddFilter(new CGraphCustomFilter(__uuidof(CRealAudioDecoder), guids,
- (s.TraFilters&TRA_RA) ? L"RealAudio Decoder" : L"RealAudio Decoder (low merit)",
- (s.TraFilters&TRA_RA) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
- guids.RemoveAll();
- }
- {
- guids.AddTail(MEDIATYPE_Video);
- guids.AddTail(MEDIASUBTYPE_RoQV);
- AddFilter(new CGraphCustomFilter(__uuidof(CRoQVideoDecoder), guids,
- (s.TraFilters&TRA_RV) ? L"RoQ Video Decoder" : L"RoQ Video Decoder (low merit)",
- (s.TraFilters&TRA_RV) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
- guids.RemoveAll();
- }
- {
- guids.AddTail(MEDIATYPE_Audio);
- guids.AddTail(MEDIASUBTYPE_RoQA);
- AddFilter(new CGraphCustomFilter(__uuidof(CRoQAudioDecoder), guids,
- (s.TraFilters&TRA_RV) ? L"RoQ Audio Decoder" : L"RoQ Audio Decoder (low merit)",
- (s.TraFilters&TRA_RV) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
- guids.RemoveAll();
- }
- {
- guids.AddTail(MEDIATYPE_Stream);
- guids.AddTail(MEDIASUBTYPE_Dirac);
- AddFilter(new CGraphCustomFilter(__uuidof(CDiracSplitterFilter), guids,
- (s.SrcFilters&SRC_DIRAC) ? L"Dirac Splitter" : L"Dirac Splitter (low merit)",
- (s.SrcFilters&SRC_DIRAC) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
- guids.RemoveAll();
- }
- {
- guids.AddTail(MEDIATYPE_Video);
- guids.AddTail(MEDIASUBTYPE_DiracVideo);
- AddFilter(new CGraphCustomFilter(__uuidof(CDiracVideoDecoder), guids,
- (s.TraFilters&TRA_DIRAC) ? L"Dirac Video Decoder" : L"Dirac Video Decoder (low merit)",
- (s.TraFilters&TRA_DIRAC) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
- guids.RemoveAll();
- }
- {
- guids.AddTail(MEDIATYPE_Stream);
- guids.AddTail(MEDIASUBTYPE_MPEG1Audio);
- AddFilter(new CGraphCustomFilter(__uuidof(CMpaSplitterFilter), guids,
- (s.SrcFilters&SRC_MPA) ? L"Mpa Splitter" : L"Mpa Splitter (low merit)",
- (s.SrcFilters&SRC_MPA) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
- guids.RemoveAll();
- }
- {
- guids.AddTail(MEDIATYPE_Stream);
- guids.AddTail(MEDIASUBTYPE_DirectShowMedia);
- AddFilter(new CGraphCustomFilter(__uuidof(CDSMSplitterFilter), guids,
- (s.SrcFilters&SRC_DSM) ? L"DSM Splitter" : L"DSM Splitter (low merit)",
- (s.SrcFilters&SRC_DSM) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
- guids.RemoveAll();
- }
- {
- guids.AddTail(MEDIATYPE_Stream);
- guids.AddTail(MEDIASUBTYPE_MP4);
- AddFilter(new CGraphCustomFilter(__uuidof(CMP4SplitterFilter), guids,
- (s.SrcFilters&SRC_MP4) ? L"MP4 Splitter" : L"MP4 Splitter (low merit)",
- (s.SrcFilters&SRC_MP4) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
- guids.RemoveAll();
- }
- // renderer filters
- switch(s.iDSVideoRendererType)
- {
- default:
- case VIDRNDT_DS_DEFAULT:
- break;
- case VIDRNDT_DS_OLDRENDERER:
- AddFilter(new CGraphRegFilter(CLSID_VideoRenderer, m_VRMerit));
- break;
- case VIDRNDT_DS_OVERLAYMIXER:
- AddFilter(new CGraphRendererFilter(CLSID_OverlayMixer, m_hWnd, L"Overlay Mixer", m_VRMerit));
- break;
- case VIDRNDT_DS_VMR7WINDOWED:
- AddFilter(new CGraphRendererFilter(CLSID_VideoMixingRenderer, m_hWnd, L"Video Mixing Render 7 (Windowed)", m_VRMerit));
- break;
- case VIDRNDT_DS_VMR9WINDOWED:
- AddFilter(new CGraphRendererFilter(CLSID_VideoMixingRenderer9, m_hWnd, L"Video Mixing Render 9 (Windowed)", m_VRMerit));
- break;
- case VIDRNDT_DS_VMR7RENDERLESS:
- AddFilter(new CGraphRendererFilter(CLSID_VMR7AllocatorPresenter, m_hWnd, L"Video Mixing Render 7 (Renderless)", m_VRMerit));
- break;
- case VIDRNDT_DS_VMR9RENDERLESS:
- AddFilter(new CGraphRendererFilter(CLSID_VMR9AllocatorPresenter, m_hWnd, L"Video Mixing Render 9 (Renderless)", m_VRMerit));
- break;
- case VIDRNDT_DS_NULL_COMP:
- guids.AddTail(MEDIATYPE_Video);
- guids.AddTail(MEDIASUBTYPE_NULL);
- AddFilter(new CGraphCustomFilter(__uuidof(CNullVideoRenderer), guids, L"Null Video Renderer (Any)", LMERIT_ABOVE_DSHOW+2));
- guids.RemoveAll();
- break;
- case VIDRNDT_DS_NULL_UNCOMP:
- guids.AddTail(MEDIATYPE_Video);
- guids.AddTail(MEDIASUBTYPE_NULL);
- AddFilter(new CGraphCustomFilter(__uuidof(CNullUVideoRenderer), guids, L"Null Video Renderer (Uncompressed)", LMERIT_ABOVE_DSHOW+2));
- guids.RemoveAll();
- break;
- }
- if(s.AudioRendererDisplayName == AUDRNDT_NULL_COMP)
- {
- guids.AddTail(MEDIATYPE_Audio);
- guids.AddTail(MEDIASUBTYPE_NULL);
- AddFilter(new CGraphCustomFilter(__uuidof(CNullAudioRenderer), guids, AUDRNDT_NULL_COMP, LMERIT_ABOVE_DSHOW+2));
- guids.RemoveAll();
- }
- else if(s.AudioRendererDisplayName == AUDRNDT_NULL_UNCOMP)
- {
- guids.AddTail(MEDIATYPE_Audio);
- guids.AddTail(MEDIASUBTYPE_NULL);
- AddFilter(new CGraphCustomFilter(__uuidof(CNullUAudioRenderer), guids, AUDRNDT_NULL_UNCOMP, LMERIT_ABOVE_DSHOW+2));
- guids.RemoveAll();
- }
- else if(!s.AudioRendererDisplayName.IsEmpty())
- {
- AddFilter(new CGraphRegFilter(s.AudioRendererDisplayName, m_ARMerit));
- }
- WORD lowmerit = 1;
- POSITION pos = s.filters.GetTailPosition();
- while(pos)
- {
- Filter* f = s.filters.GetPrev(pos);
- if(f->fDisabled
- || f->type == Filter::EXTERNAL && !CPath(MakeFullPath(f->path)).FileExists())
- continue;
- ULONGLONG merit =
- f->iLoadType == Filter::PREFERRED ? LMERIT_ABOVE_DSHOW :
- f->iLoadType == Filter::MERIT ? LMERIT(f->dwMerit) :
- LMERIT_DO_NOT_USE; // f->iLoadType == Filter::BLOCKED
- merit += lowmerit++;
- CGraphFilter* gf = NULL;
- if(f->type == Filter::REGISTERED)
- {
- gf = new CGraphRegFilter(f->dispname, merit);
- }
- else if(f->type == Filter::EXTERNAL)
- {
- gf = new CGraphFileFilter(f->clsid, f->guids, f->path, CStringW(f->name), merit);
- }
- if(gf)
- {
- gf->SetGUIDs(f->guids);
- AddFilter(gf);
- }
- }
- guids.AddTail(MEDIATYPE_Text);
- guids.AddTail(MEDIASUBTYPE_NULL);
- guids.AddTail(MEDIATYPE_ScriptCommand);
- guids.AddTail(MEDIASUBTYPE_NULL);
- guids.AddTail(MEDIATYPE_Subtitle);
- guids.AddTail(MEDIASUBTYPE_NULL);
- guids.AddTail(MEDIATYPE_NULL);
- guids.AddTail(MEDIASUBTYPE_DVD_SUBPICTURE);
- guids.AddTail(MEDIATYPE_NULL);
- guids.AddTail(MEDIASUBTYPE_CVD_SUBPICTURE);
- guids.AddTail(MEDIATYPE_NULL);
- guids.AddTail(MEDIASUBTYPE_SVCD_SUBPICTURE);
- AddFilter(new CGraphCustomFilter(__uuidof(CNullTextRenderer), guids, L"NullTextRenderer", LMERIT_DO_USE));
- guids.RemoveAll();
- // FIXME: "Subtitle Mixer" makes an access violation around
- // the 11-12th media type when enumerating them on its output.
- CLSID CLSID_SubtitlerMixer = GUIDFromCString(_T("{00A95963-3BE5-48C0-AD9F-3356D67EA09D}"));
- AddFilter(new CGraphRegFilter(CLSID_SubtitlerMixer, LMERIT_DO_NOT_USE));
- // ISCR suxx
- AddFilter(new CGraphRegFilter(GUIDFromCString(_T("{48025243-2D39-11CE-875D-00608CB78066}")), LMERIT_DO_NOT_USE));
- }
- CGraphBuilder::~CGraphBuilder()
- {
- }
- /*
- void CGraphBuilder::LOG(LPCTSTR fmt, ...)
- {
- va_list args;
- va_start(args, fmt);
- if(TCHAR* buff = new TCHAR[_vsctprintf(fmt, args) + 1])
- {
- _vstprintf(buff, fmt, args);
- m_log.AddTail(buff);
- TRACE(_T("GraphBuilder: Stream[%d]: %sn"), m_iStream, buff);
- if(FILE* f = _tfopen(_T("c:\mpcgb.txt"), _T("at")))
- {
- fseek(f, 0, 2);
- _ftprintf(f, _T("Stream[%d]: %sn"), m_iStream, buff);
- fclose(f);
- }
- delete [] buff;
- }
- va_end(args);
- }
- */
- void CGraphBuilder::ExtractMediaTypes(IPin* pPin, CArray<GUID>& guids)
- {
- guids.RemoveAll();
- BeginEnumMediaTypes(pPin, pEM, pmt)
- {
- bool fFound = false;
- for(int i = 0; !fFound && i < guids.GetCount(); i += 2)
- {
- if(guids[i] == pmt->majortype && guids[i+1] == pmt->subtype)
- fFound = true;
- }
- if(!fFound)
- {
- guids.Add(pmt->majortype);
- guids.Add(pmt->subtype);
- }
- }
- EndEnumMediaTypes(pmt)
- }
- void CGraphBuilder::ExtractMediaTypes(IPin* pPin, CList<CMediaType>& mts)
- {
- mts.RemoveAll();
- BeginEnumMediaTypes(pPin, pEM, pmt)
- {
- bool fFound = false;
- POSITION pos = mts.GetHeadPosition();
- while(!fFound && pos)
- {
- CMediaType& mt = mts.GetNext(pos);
- if(mt.majortype == pmt->majortype && mt.subtype == pmt->subtype)
- fFound = true;
- }
- if(!fFound)
- {
- mts.AddTail(CMediaType(*pmt));
- }
- }
- EndEnumMediaTypes(pmt)
- }
- void CGraphBuilder::SaveFilters(CInterfaceList<IBaseFilter>& bfl)
- {
- bfl.RemoveAll();
- BeginEnumFilters(m_pGB, pEF, pBF)
- bfl.AddTail(pBF);
- EndEnumFilters
- }
- void CGraphBuilder::RestoreFilters(CInterfaceList<IBaseFilter>& bfl)
- {
- BeginEnumFilters(m_pGB, pEF, pBF)
- if(!bfl.Find(pBF)) {m_pGB->RemoveFilter(pBF); pEF->Reset();}
- EndEnumFilters
- }
- HRESULT CGraphBuilder::SafeAddFilter(IBaseFilter* pBF, LPCWSTR pName)
- {
- if(!m_pGB || !pBF)
- return E_FAIL;
- bool fFound = false;
- BeginEnumFilters(m_pGB, pEF, pBF2)
- if(pBF == pBF2) fFound = true;
- EndEnumFilters
- if(fFound) return S_OK;
- CFilterInfo fi;
- if(SUCCEEDED(pBF->QueryFilterInfo(&fi)))
- {
- if(!fi.pGraph) // not in graph yet?
- {
- CStringW name;
-
- if(pName && wcslen(pName) > 0)
- {
- name = pName;
- }
- else
- {
- if(CComQIPtr<IFileSourceFilter> pFSF = pBF)
- {
- CMediaType mt;
- LPOLESTR str = NULL;
- if(SUCCEEDED(pFSF->GetCurFile(&str, &mt))) name = str;
- if(str) CoTaskMemFree(str);
- }
- if(name.IsEmpty())
- {
- CLSID clsid = GetCLSID(pBF);
- name = clsid == GUID_NULL ? L"Unknown Filter" : CStringFromGUID(clsid);
- }
- }
- if(FAILED(m_pGB->AddFilter(pBF, name)))
- {
- return E_FAIL;
- }
- }
- return S_OK;
- }
- return E_FAIL;
- }
- void CGraphBuilder::Reset()
- {
- m_nTotalStreams = 0;
- m_nCurrentStream = 0;
- m_pUnks.RemoveAll();
- m_DeadEnds.RemoveAll();
- // m_log.RemoveAll();
- }
- HRESULT CGraphBuilder::AddSourceFilter(LPCTSTR lpsz, IBaseFilter** ppBF, UINT SrcFilters)
- {
- CheckPointer(lpsz, E_POINTER);
- CheckPointer(ppBF, E_POINTER);
- if(!m_pGB) return E_UNEXPECTED;
- CString fn = CString(lpsz).Trim();
- if(fn.IsEmpty()) return E_FAIL;
- CStringW fnw = fn;
- CString ext = CPath(fn).GetExtension().MakeLower();
- HRESULT hr;
- CComQIPtr<IBaseFilter> pBF;
- CComQIPtr<IGraphEngine> pGE = m_pGB;
- if(!pGE || pGE->GetEngine() == DirectShow)
- {
- /*
- if(!pBF && fn.Find(_T("://")) > 0)
- {
- CList<CString> mms;
- CString ct = GetContentType(fn, &mms); // TODO: if there are more to check, do GetContentType only once
- if(ct == _T("video/x-ms-asf") || ct == _T("video/x-ms-wmv")
- || ct == _T("video/x-ms-wvx") || ct == _T("video/x-ms-wax")
- || ct == _T("video/x-ms-wmp"))
- {
- if(!mms.IsEmpty()) fnw = mms.GetHead();
- fnw.Replace(L"&MSWMExt=.asf", L"");
- CComPtr<IFileSourceFilter> pReader;
- hr = pReader.CoCreateInstance(CLSID_NetShowSource);
- if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
- pBF = pReader;
- }
- }
- */
- if((SrcFilters&SRC_SUBS) && !pBF)
- {
- hr = S_OK;
- CComPtr<IFileSourceFilter> pReader = new CSubtitleSourceASS(NULL, &hr);
- if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
- pBF = pReader;
- }
- if((SrcFilters&SRC_CDDA) && !pBF && ext == _T(".cda"))
- {
- hr = S_OK;
- CComPtr<IFileSourceFilter> pReader = new CCDDAReader(NULL, &hr);
- if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
- pBF = pReader;
- }
- if((SrcFilters&SRC_CDXA) && !pBF)
- {
- hr = S_OK;
- CComPtr<IFileSourceFilter> pReader = new CCDXAReader(NULL, &hr);
- if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
- pBF = pReader;
- }
- if((SrcFilters&SRC_VTS) && !pBF) //&& ext == _T(".ifo"))
- {
- hr = S_OK;
- CComPtr<IFileSourceFilter> pReader = new CVTSReader(NULL, &hr);
- if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
- pBF = pReader;
- }
- if((SrcFilters&SRC_FLIC) && !pBF) //&& (ext == _T(".fli") || ext == _T(".flc")))
- {
- hr = S_OK;
- CComPtr<IFileSourceFilter> pReader = new CFLICSource(NULL, &hr);
- if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
- pBF = pReader;
- }
- if((SrcFilters&SRC_D2V) && !pBF) //&& ext == _T(".d2v"))
- {
- hr = S_OK;
- CComPtr<IFileSourceFilter> pReader = new CD2VSource(NULL, &hr);
- if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
- pBF = pReader;
- }
- if((SrcFilters&SRC_DTSAC3) && !pBF) //&& (ext == _T(".dts") || ext == _T(".ac3")))
- {
- hr = S_OK;
- CComPtr<IFileSourceFilter> pReader = new CDTSAC3Source(NULL, &hr);
- if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
- pBF = pReader;
- }
- if((SrcFilters&SRC_SHOUTCAST) && !pBF && fn.Find(_T("://")) >= 0)
- {
- hr = S_OK;
- CComPtr<IFileSourceFilter> pReader = new CShoutcastSource(NULL, &hr);
- if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
- pBF = pReader;
- }
- if((SrcFilters&SRC_MATROSKA) && !pBF) //&& (ext == _T(".mkv") || ext == _T(".mka") || ext == _T(".mks")))
- {
- hr = S_OK;
- CComPtr<IFileSourceFilter> pReader = new CMatroskaSourceFilter(NULL, &hr);
- if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
- pBF = pReader;
- }
- if((SrcFilters&SRC_REALMEDIA) && !pBF)
- {
- hr = S_OK;
- CComPtr<IFileSourceFilter> pReader = new CRealMediaSourceFilter(NULL, &hr);
- if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
- pBF = pReader;
- }
- if((SrcFilters&SRC_AVI) && !pBF)
- {
- hr = S_OK;
- CComPtr<IFileSourceFilter> pReader = new CAviSourceFilter(NULL, &hr);
- if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
- pBF = pReader;
- }
- __if_exists(CRadGtSplitterFilter)
- {
- if((SrcFilters&SRC_RADGT) && !pBF)
- {
- hr = S_OK;
- CComPtr<IFileSourceFilter> pReader = new CRadGtSourceFilter(NULL, &hr);
- if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
- pBF = pReader;
- }
- }
- if((SrcFilters&SRC_ROQ) && !pBF)
- {
- hr = S_OK;
- CComPtr<IFileSourceFilter> pReader = new CRoQSourceFilter(NULL, &hr);
- if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
- pBF = pReader;
- }
- if((SrcFilters&SRC_OGG) && !pBF)
- {
- hr = S_OK;
- CComPtr<IFileSourceFilter> pReader = new COggSourceFilter(NULL, &hr);
- if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
- pBF = pReader;
- }
- if((SrcFilters&SRC_NUT) && !pBF)
- {
- hr = S_OK;
- CComPtr<IFileSourceFilter> pReader = new CNutSourceFilter(NULL, &hr);
- if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
- pBF = pReader;
- }
- if((SrcFilters&SRC_MPEG) && !pBF)
- {
- hr = S_OK;
- CComPtr<IFileSourceFilter> pReader = new CMpegSourceFilter(NULL, &hr);
- if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
- pBF = pReader;
- }
- if((SrcFilters&SRC_DIRAC) && !pBF)
- {
- hr = S_OK;
- CComPtr<IFileSourceFilter> pReader = new CDiracSourceFilter(NULL, &hr);
- if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
- pBF = pReader;
- }
- if((SrcFilters&SRC_MPA) && !pBF)
- {
- hr = S_OK;
- CComPtr<IFileSourceFilter> pReader = new CMpaSourceFilter(NULL, &hr);
- if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
- pBF = pReader;
- }
- if((SrcFilters&SRC_DSM) && !pBF)
- {
- hr = S_OK;
- CComPtr<IFileSourceFilter> pReader = new CDSMSourceFilter(NULL, &hr);
- if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
- pBF = pReader;
- }
- if((SrcFilters&SRC_MP4) && !pBF)
- {
- hr = S_OK;
- CComPtr<IFileSourceFilter> pReader = new CMP4SourceFilter(NULL, &hr);
- if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
- pBF = pReader;
- }
- if(!pBF && fn.Find(_T("://")) < 0)
- {
- bool fWindowsMedia = (ext == _T(".asf") || ext == _T(".wmv") || ext == _T(".wma"));
- if(!fWindowsMedia)
- {
- CFile f;
- if(f.Open(fn, CFile::modeRead))
- {
- BYTE buff[4];
- memset(buff, 0, sizeof(buff));
- f.Read(buff, sizeof(buff));
- if(*(DWORD*)buff == 0x75b22630)
- fWindowsMedia = true;
- }
- }
- if(fWindowsMedia)
- {
- CComPtr<IFileSourceFilter> pReader;
- hr = pReader.CoCreateInstance(AfxGetAppSettings().fUseWMASFReader ? CLSID_WMAsfReader : CLSID_NetShowSource);
- if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
- pBF = pReader;
- }
- }
- /*
- if(!pBF && fn.Find(_T("://")) < 0)
- {
- CFile f;
- if(f.Open(fn, CFile::modeRead|CFile::shareDenyWrite))
- {
- ULONGLONG len = f.GetLength();
- BYTE buff[12];
- memset(buff, 0, sizeof(buff));
- f.Read(buff, sizeof(buff));
- if(*((DWORD*)&buff[0]) == 'FFIR' && *((DWORD*)&buff[8]) == ' IVA')
- {
- if(len < *((DWORD*)&buff[4])+8)
- {
- MessageBeep(-1);
- CComPtr<IFileSourceFilter> pReader;
- hr = pReader.CoCreateInstance(CLSID_AVIDoc);
- if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
- pBF = pReader;
- }
- }
- }
- }
- */
- }
- if(!pBF)
- {
- CheckStupidSharedFilesourceFilter();
- if(FAILED(hr = m_pGB->AddSourceFilter(fnw, fnw, &pBF)))
- return hr;
- if(SUCCEEDED(hr) && !pBF) // custom graphs don't need filters
- return hr;
- }
- ASSERT(pBF);
- if(FAILED(SafeAddFilter(pBF, NULL)))
- return E_FAIL;
- *ppBF = pBF.Detach();
- return S_OK;
- }
- HRESULT CGraphBuilder::Render(LPCTSTR lpsz)
- {
- CComPtr<IBaseFilter> pBF;
- HRESULT hr = AddSourceFilter(lpsz, &pBF, AfxGetAppSettings().SrcFilters & ~SRC_SUBS);
- if(FAILED(hr)) return hr;
- return pBF ? Render(pBF) : S_OK;
- }
- HRESULT CGraphBuilder::Render(IBaseFilter* pBF)
- {
- if(!m_pGB || !m_pFM || !pBF)
- return E_FAIL;
- if(FAILED(SafeAddFilter(pBF, NULL)))
- return E_FAIL;
- CInterfaceList<IPin> pOutputs;
- BeginEnumPins(pBF, pEP, pPin)
- {
- PIN_DIRECTION dir;
- CComPtr<IPin> pTmp;
- CPinInfo pi;
- if(FAILED(pPin->QueryDirection(&dir)) || dir != PINDIR_OUTPUT // not an output?
- || SUCCEEDED(pPin->ConnectedTo(&pTmp)) // already connected?
- || FAILED(pPin->QueryPinInfo(&pi)) || pi.achName[0] == '~') // hidden?
- continue;
- pOutputs.AddTail(pPin);
- }
- EndEnumPins
- int nRendered = 0;
- if(pOutputs.GetCount() > 0)
- {
- POSITION pos = pOutputs.GetHeadPosition();
- while(pos)
- {
- if(SUCCEEDED(Render(pOutputs.GetNext(pos)))) nRendered++;
- if(pOutputs.GetCount() > 1) m_nCurrentStream++;
- }
- }
- else
- {
- m_nTotalStreams++;
- for(int i = 0; i < m_DeadEnds.GetCount(); i++)
- {
- if(m_DeadEnds[i]->nStream == m_nCurrentStream)
- m_DeadEnds.RemoveAt(i--);
- }
- }
- return
- nRendered == pOutputs.GetCount() ? (nRendered > 0 ? S_OK : S_FALSE) :
- nRendered > 0 ? VFW_S_PARTIAL_RENDER :
- VFW_E_CANNOT_RENDER;
- }
- typedef struct {CGraphFilter* pFilter; bool fExactMatch;} SortFilter;
- static int compare(const void* arg1, const void* arg2)
- {
- SortFilter* sf1 = (SortFilter*)arg1;
- SortFilter* sf2 = (SortFilter*)arg2;
- /*
- if(sf1->pFilter->GetMerit() < LMERIT(MERIT_PREFERRED) && sf2->pFilter->GetMerit() < LMERIT(MERIT_PREFERRED))
- {
- if(!sf1->fExactMatch && sf2->fExactMatch) return 1;
- else if(sf1->fExactMatch && !sf2->fExactMatch) return -1;
- }
- */
- if(sf1->pFilter->GetCLSID() == sf2->pFilter->GetCLSID())
- {
- // prefer externals
- CGraphFileFilter* f1 = dynamic_cast<CGraphFileFilter*>(sf1->pFilter);
- CGraphFileFilter* f2 = dynamic_cast<CGraphFileFilter*>(sf2->pFilter);
- if(!f1 && f2) return 1;
- if(f1 && !f2) return -1;
- }
- if(sf1->pFilter->GetMerit() < sf2->pFilter->GetMerit()) return 1;
- else if(sf1->pFilter->GetMerit() > sf2->pFilter->GetMerit()) return -1;
- if(!sf1->fExactMatch && sf2->fExactMatch) return 1;
- else if(sf1->fExactMatch && !sf2->fExactMatch) return -1;
- return 0;
- }
- HRESULT CGraphBuilder::Render(IPin* pPin)
- {
- if(!m_pGB || !m_pFM || !pPin)
- return E_FAIL;
- PIN_DIRECTION dir;
- CComPtr<IPin> pPinTmp;
- if(FAILED(pPin->QueryDirection(&dir)) || dir != PINDIR_OUTPUT
- || SUCCEEDED(pPin->ConnectedTo(&pPinTmp)))
- return E_UNEXPECTED;
- if(GetCLSID(pPin) == CLSID_MPEG2Demultiplexer)
- {
- CComQIPtr<IMediaSeeking> pMS = pPin;
- if(!pMS) return E_FAIL;
- REFERENCE_TIME rtDur = 0;
- if(FAILED(pMS->GetDuration(&rtDur)) || rtDur <= 0)
- return E_FAIL;
- rtDur = rtDur;
- }
- bool fDeadEnd = true;
- // 1. stream builder interface
- if(CComQIPtr<IStreamBuilder> pSB = pPin)
- {
- CInterfaceList<IBaseFilter> bfl;
- SaveFilters(bfl);
- if(SUCCEEDED(pSB->Render(pPin, m_pGB)))
- return S_OK;
- pSB->Backout(pPin, m_pGB);
- RestoreFilters(bfl);
- }
- // 2. filter cache
- if(CComQIPtr<IGraphConfig> pGC = m_pGB)
- {
- CComPtr<IEnumFilters> pEF;
- if(SUCCEEDED(pGC->EnumCacheFilter(&pEF)))
- {
- for(CComPtr<IBaseFilter> pBF; S_OK == pEF->Next(1, &pBF, NULL); pBF = NULL)
- {
- CInterfaceList<IBaseFilter> bfl;
- SaveFilters(bfl);
- pGC->RemoveFilterFromCache(pBF);
- if(SUCCEEDED(ConnectDirect(pPin, pBF)))
- {
- fDeadEnd = false;
- HRESULT hr;
- if(SUCCEEDED(hr = Render(pBF)))
- return hr;
- }
- pGC->AddFilterToCache(pBF);
- RestoreFilters(bfl);
- }
- }
- }
- // 3. disconnected inputs
- CInterfaceList<IBaseFilter> pFilters;
- SaveFilters(pFilters);
- POSITION pos;
- // FIXME: ffdshow likes to connect to the audio capture filter's fake input pins
- if(!dynamic_cast<CGraphBuilderCapture*>(this))
- {
- pos = pFilters.GetHeadPosition();
- while(pos)
- {
- CComPtr<IBaseFilter> pBF = pFilters.GetNext(pos);
- if(SUCCEEDED(ConnectDirect(pPin, pBF)))
- {
- fDeadEnd = false;
- HRESULT hr;
- if(SUCCEEDED(hr = Render(pBF)))
- return hr;
- }
- }
- }
- // 4. registry+internal+external
- // TODO: try media types one-by-one and pass pmt to ConnectDirect (this may not be better than the current!!!)
- CArray<GUID> guids;
- ExtractMediaTypes(pPin, guids);
- if(guids.GetCount() == 2 && guids[0] == MEDIATYPE_Stream && guids[1] == MEDIASUBTYPE_NULL)
- {
- if(CComQIPtr<IAsyncReader> pReader = pPin)
- {
- BYTE buff[4];
- if(S_OK == pReader->SyncRead(0, 4, buff) && *(DWORD*)buff == 'SggO')
- guids[1] = MEDIASUBTYPE_Ogg;
- }
- }
- else if(guids.GetCount() == 2 && guids[0] == MEDIATYPE_Video && guids[1] == FOURCCMap('MGXD'))
- {
- guids[1] = FOURCCMap('XVID');
- }
- CAutoPtrList<CGraphFilter> autogfs;
- CArray<CGraphFilter*> gfs;
- CComPtr<IEnumMoniker> pEM;
- if(guids.GetCount() > 0
- && SUCCEEDED(m_pFM->EnumMatchingFilters(
- &pEM, 0, FALSE, MERIT_DO_NOT_USE+1,
- TRUE, guids.GetCount()/2, guids.GetData(), NULL, NULL, FALSE,
- FALSE, 0, NULL, NULL, NULL)))
- {
- for(CComPtr<IMoniker> pMoniker; S_OK == pEM->Next(1, &pMoniker, NULL); pMoniker = NULL)
- {
- CAutoPtr<CGraphFilter> pGraphFilter(new CGraphRegFilter(pMoniker));
- if(pGraphFilter)
- {
- POSITION pos = m_pMoreFilters.GetHeadPosition();
- while(pos)
- {
- CGraphRegFilter* f = dynamic_cast<CGraphRegFilter*>((CGraphFilter*)m_pMoreFilters.GetNext(pos));
- if(!f) continue;
- if(f->GetMoniker() && S_OK == pMoniker->IsEqual(f->GetMoniker())
- || f->GetCLSID() != GUID_NULL && f->GetCLSID() == pGraphFilter->GetCLSID())
- {
- pGraphFilter.Free();
- break;
- }
- }
- }
- if(pGraphFilter)
- {
- autogfs.AddTail(pGraphFilter);
- }
- }
- }
- pos = autogfs.GetHeadPosition();
- while(pos)
- {
- CGraphFilter* f = autogfs.GetNext(pos);
- bool fFound = false;
- POSITION pos2 = m_chain.GetHeadPosition();
- while(pos2)
- {
- if(f->GetCLSID() == m_chain.GetNext(pos2)->GetCLSID())
- {
- fFound = true;
- break;
- }
- }
- if(!fFound)
- gfs.Add(f);
- }
- pos = m_pMoreFilters.GetHeadPosition();
- while(pos)
- {
- CGraphFilter* f = m_pMoreFilters.GetNext(pos);
- if(f->GetMerit() >= LMERIT_DO_USE && !m_chain.Find(f) && f->IsCompatible(guids))
- gfs.Add(f);
- }
- CArray<SortFilter> sfs;
- sfs.SetSize(gfs.GetCount());
- for(int i = 0; i < gfs.GetCount(); i++)
- {
- sfs[i].pFilter = gfs[i];
- sfs[i].fExactMatch = gfs[i]->IsExactMatch(guids);
- }
- if(sfs.GetCount() > 1) qsort(sfs.GetData(), sfs.GetCount(), sizeof(SortFilter), compare);
- for(int i = 0; i < sfs.GetCount(); i++)
- {
- CGraphFilter* gf = sfs[i].pFilter;
- if(!gf) continue;
- CComPtr<IBaseFilter> pBF;
- CComPtr<IUnknown> pUnk;
- if(FAILED(gf->Create(&pBF, &pUnk)))
- continue;
- CInterfaceList<IBaseFilter> bfl;
- SaveFilters(bfl);
- if(FAILED(SafeAddFilter(pBF, gf->GetName())))
- continue;
- if(gf->GetCLSID() == CLSID_DMOWrapperFilter)
- {
- if(CComQIPtr<IPropertyBag> pPBag = pBF)
- {
- CComVariant var(true);
- pPBag->Write(CComBSTR(L"_HIRESOUTPUT"), &var);
- }
- }
- if(CComQIPtr<IMpeg2DecFilter> m_pMpeg2DecFilter = pBF)
- {
- AppSettings& s = AfxGetAppSettings();
- m_pMpeg2DecFilter->SetDeinterlaceMethod((ditype)s.mpegdi);
- m_pMpeg2DecFilter->SetBrightness(s.mpegbright);
- m_pMpeg2DecFilter->SetContrast(s.mpegcont);
- m_pMpeg2DecFilter->SetHue(s.mpeghue);
- m_pMpeg2DecFilter->SetSaturation(s.mpegsat);
- m_pMpeg2DecFilter->EnableForcedSubtitles(s.mpegforcedsubs);
- m_pMpeg2DecFilter->EnablePlanarYUV(s.mpegplanaryuv);
- }
- if(CComQIPtr<IMpaDecFilter> m_pMpaDecFilter = pBF)
- {
- AppSettings& s = AfxGetAppSettings();
- m_pMpaDecFilter->SetSampleFormat((SampleFormat)s.mpasf);
- m_pMpaDecFilter->SetNormalize(s.mpanormalize);
- m_pMpaDecFilter->SetSpeakerConfig(IMpaDecFilter::ac3, s.ac3sc);
- m_pMpaDecFilter->SetDynamicRangeControl(IMpaDecFilter::ac3, s.ac3drc);
- m_pMpaDecFilter->SetSpeakerConfig(IMpaDecFilter::dts, s.dtssc);
- m_pMpaDecFilter->SetDynamicRangeControl(IMpaDecFilter::dts, s.dtsdrc);
- m_pMpaDecFilter->SetSpeakerConfig(IMpaDecFilter::aac, s.aacsc);
- m_pMpaDecFilter->SetBoost(s.mpaboost);
- }
- HRESULT hr = E_FAIL;
- if(guids.GetCount() == 2 && guids[0] == MEDIATYPE_Stream && guids[1] != MEDIATYPE_NULL)
- {
- CMediaType mt;
- mt.majortype = guids[0];
- mt.subtype = guids[1];
- mt.formattype = FORMAT_None;
- hr = ConnectDirect(pPin, pBF, &mt);
- if(FAILED(hr))
- {
- mt.formattype = GUID_NULL;
- hr = ConnectDirect(pPin, pBF, &mt);
- }
- }
- if(SUCCEEDED(hr) || SUCCEEDED(ConnectDirect(pPin, pBF, NULL)))
- {
- fDeadEnd = false;
- int nCurrentStream = m_nCurrentStream;
- m_chain.AddTail(gf);
- hr = Render(pBF);
- m_chain.RemoveTail();
- if(SUCCEEDED(hr))
- {
- if(pUnk) m_pUnks.AddTail(pUnk);
- // maybe the application should do this...
- if(CComQIPtr<IMixerPinConfig, &IID_IMixerPinConfig> pMPC = pUnk)
- pMPC->SetAspectRatioMode(AM_ARMODE_STRETCHED);
- if(CComQIPtr<IVMRAspectRatioControl> pARC = pBF)
- pARC->SetAspectRatioMode(VMR_ARMODE_NONE);
- if(CComQIPtr<IVMRAspectRatioControl9> pARC = pBF)
- pARC->SetAspectRatioMode(VMR_ARMODE_NONE);
- return hr;
- }
- m_nCurrentStream = nCurrentStream;
- }
- m_pGB->RemoveFilter(pBF);
- RestoreFilters(bfl);
- }
- // 5. record filter/pin/mts if this was the end of a chain
- if(fDeadEnd)
- {
- CAutoPtr<DeadEnd> de(new DeadEnd);
- de->nStream = m_nCurrentStream;
- de->clsid = CStringFromGUID(GetCLSID(pPin));
- de->filter = GetFilterName(GetFilterFromPin(pPin));
- de->pin = GetPinName(pPin);
- ExtractMediaTypes(pPin, de->mts);
- if(!(m_chain.GetCount() == 0 && de->mts.GetCount() == 1
- && de->mts.GetHead().majortype == MEDIATYPE_Stream && de->mts.GetHead().subtype == MEDIASUBTYPE_NULL))
- {
- CString str;
- str.Format(_T("Stream %d"), m_nCurrentStream);
- de->path.AddTail(str);
- POSITION pos = m_chain.GetHeadPosition();
- while(pos) de->path.AddTail(CString(m_chain.GetNext(pos)->GetName()));
- m_DeadEnds.Add(de);
- }
- }
- return E_FAIL;
- }
- HRESULT CGraphBuilder::ConnectDirect(IPin* pPin, IBaseFilter* pBF, const AM_MEDIA_TYPE* pmt)
- {
- if(!pPin || !pBF)
- return E_INVALIDARG;
- if(FAILED(SafeAddFilter(pBF, NULL)))
- return E_FAIL;
- BeginEnumPins(pBF, pEP, pPinTo)
- {
- PIN_DIRECTION dir;
- CComPtr<IPin> pTmp;
- if(FAILED(pPinTo->QueryDirection(&dir)) || dir != PINDIR_INPUT
- || SUCCEEDED(pPinTo->ConnectedTo(&pTmp)))
- continue;
- if(SUCCEEDED(m_pGB->ConnectDirect(pPin, pPinTo, pmt)))
- return S_OK;
- }
- EndEnumPins
- return VFW_E_CANNOT_CONNECT;
- }
- HRESULT CGraphBuilder::FindInterface(REFIID iid, void** ppv)
- {
- CheckPointer(ppv, E_POINTER);
- POSITION pos = m_pUnks.GetHeadPosition();
- while(pos)
- {
- IUnknown* pUnk = m_pUnks.GetNext(pos);
- HRESULT hr;
- if(SUCCEEDED(hr = pUnk->QueryInterface(iid, ppv)))
- return hr;
- }
- return E_NOINTERFACE;
- }
- //
- // CGraphBuilderFile
- //
- CGraphBuilderFile::CGraphBuilderFile(IGraphBuilder* pGB, HWND hWnd)
- : CGraphBuilder(pGB, hWnd)
- {
- CList<GUID> guids;
- if(AfxGetAppSettings().fEnableAudioSwitcher)
- {
- guids.AddTail(MEDIATYPE_Audio);
- guids.AddTail(MEDIASUBTYPE_NULL);
- AddFilter(new CGraphCustomFilter(__uuidof(CAudioSwitcherFilter), guids, L"Audio Switcher", m_ARMerit + 0x100));
- guids.RemoveAll();
- CLSID CLSID_MorganStreamSwitcher = GUIDFromCString(_T("{D3CD7858-971A-4838-ACEC-40CA5D529DC8}"));
- AddFilter(new CGraphRegFilter(CLSID_MorganStreamSwitcher, LMERIT_DO_NOT_USE));
- }
- }
- //
- // CGraphBuilderDVD
- //
- CGraphBuilderDVD::CGraphBuilderDVD(IGraphBuilder* pGB, HWND hWnd)
- : CGraphBuilderFile(pGB, hWnd)
- {
- CList<GUID> guids;
- /*
- // there wasn't much use of this and the users were just
- // confused by "decss" being in the report after a failed
- // dvd nav pin rendering
- guids.AddTail(MEDIATYPE_DVD_ENCRYPTED_PACK);
- guids.AddTail(MEDIASUBTYPE_NULL);
- AddFilter(new CGraphCustomFilter(__uuidof(CDeCSSFilter), guids, L"DeCSS", LMERIT_UNLIKELY));
- guids.RemoveAll();
- */
- DWORD ver = ::GetVersion();
- bool m_fXp = (int)ver >= 0 && (((ver<<8)&0xff00)|((ver>>8)&0xff)) >= 0x0501;
- AppSettings& s = AfxGetAppSettings();
- if(!m_fXp && s.iDSVideoRendererType != VIDRNDT_DS_OVERLAYMIXER
- || s.iDSVideoRendererType == VIDRNDT_DS_OLDRENDERER)
- AddFilter(new CGraphRendererFilter(CLSID_OverlayMixer, m_hWnd, L"Overlay Mixer", m_VRMerit-1));
- // this filter just simply sucks for dvd playback (atm)
- CLSID CLSID_ElecardMpeg2 = GUIDFromCString(_T("{F50B3F13-19C4-11CF-AA9A-02608C9BABA2}"));
- AddFilter(new CGraphRegFilter(CLSID_ElecardMpeg2, LMERIT_DO_NOT_USE));
- }
- #include "....decssVobFile.h"
- class CResetDVD : public CDVDSession
- {
- public:
- CResetDVD(LPCTSTR path)
- {
- if(Open(path))
- {
- if(BeginSession())
- {
- Authenticate();
- // GetDiscKey();
- EndSession();
- }
- Close();
- }
- }
- };
- [uuid("482d10b6-376e-4411-8a17-833800A065DB")]
- class ratDVDNavigator {};
- HRESULT CGraphBuilderDVD::Render(CString fn, CString& path)
- {
- if(!m_pGB) return E_INVALIDARG;
- HRESULT hr;
- GUID clsid = CLSID_DVDNavigator;
- if(fn.MakeLower().Find(_T(".ratdvd")) >= 0)
- clsid = __uuidof(ratDVDNavigator);
- CComPtr<IBaseFilter> pBF;
- if(FAILED(hr = pBF.CoCreateInstance(clsid)))
- return E_FAIL;
- if(FAILED(hr = m_pGB->AddFilter(pBF, L"DVD Navigator")))
- return VFW_E_CANNOT_LOAD_SOURCE_FILTER;
- CComQIPtr<IDvdControl2> pDVDC;
- CComQIPtr<IDvdInfo2> pDVDI;
- if(!((pDVDC = pBF) && (pDVDI = pBF)))
- return E_NOINTERFACE;
- WCHAR buff[MAX_PATH];
- ULONG len;
- if((!fn.IsEmpty()
- && FAILED(hr = pDVDC->SetDVDDirectory(CStringW(fn)))
- && FAILED(hr = pDVDC->SetDVDDirectory(CStringW(fn + _T("VIDEO_TS"))))
- && FAILED(hr = pDVDC->SetDVDDirectory(CStringW(fn + _T("\VIDEO_TS")))))
- || FAILED(hr = pDVDI->GetDVDDirectory(buff, MAX_PATH, &len)) || len == 0)
- return VFW_E_CANNOT_LOAD_SOURCE_FILTER;
- path = buff;
- pDVDC->SetOption(DVD_ResetOnStop, FALSE);
- pDVDC->SetOption(DVD_HMSF_TimeCodeEvents, TRUE);
- m_pUnks.AddTail(pDVDC);
- m_pUnks.AddTail(pDVDI);
- if(clsid == CLSID_DVDNavigator)
- CResetDVD tmp(path);
- return __super::Render(pBF);
- }
- //
- // CGraphBuilderCapture
- //
- CGraphBuilderCapture::CGraphBuilderCapture(IGraphBuilder* pGB, HWND hWnd)
- : CGraphBuilderFile(pGB, hWnd)
- {
- CList<GUID> guids;
- // if(AfxGetAppSettings().fEnableDeinterlacer)
- {
- guids.AddTail(MEDIATYPE_Video);
- guids.AddTail(MEDIASUBTYPE_NULL);
- AddFilter(new CGraphCustomFilter(__uuidof(CDeinterlacerFilter), guids, L"Deinterlacer", m_VRMerit + 0x100));
- guids.RemoveAll();
- }
- /**/
- CLSID CLSID_MorganStreamSwitcher = GUIDFromCString(_T("{D3CD7858-971A-4838-ACEC-40CA5D529DC8}"));
- AddFilter(new CGraphRegFilter(CLSID_MorganStreamSwitcher, LMERIT_DO_NOT_USE));
- }
- //
- // CGraphFilter
- //
- CGraphFilter::CGraphFilter(CStringW name, ULONGLONG merit)
- : m_name(name), m_clsid(GUID_NULL)
- {
- m_merit.val = merit;
- }
- bool CGraphFilter::IsExactMatch(CArray<GUID>& guids)
- {
- POSITION pos = m_guids.GetHeadPosition();
- while(pos)
- {
- GUID& major = m_guids.GetNext(pos);
- if(!pos) {ASSERT(0); break;}
- GUID& sub = m_guids.GetNext(pos);
- for(int i = 0; i < (guids.GetCount()&~1); i += 2)
- {
- if(major == guids[i] && major != GUID_NULL
- && sub == guids[i+1] && sub != GUID_NULL)
- return(true);
- }
- }
- return(false);
- }
- bool CGraphFilter::IsCompatible(CArray<GUID>& guids)
- {
- POSITION pos = m_guids.GetHeadPosition();
- while(pos)
- {
- GUID& major = m_guids.GetNext(pos);
- if(!pos) {ASSERT(0); break;}
- GUID& sub = m_guids.GetNext(pos);
- for(int i = 0; i < (guids.GetCount()&~1); i += 2)
- {
- if((major == GUID_NULL || guids[i] == GUID_NULL || major == guids[i])
- && (sub == GUID_NULL || guids[i+1] == GUID_NULL || sub == guids[i+1]))
- return(true);
- }
- }
- return(false);
- }
- //
- // CGraphRegFilter
- //
- CGraphRegFilter::CGraphRegFilter(IMoniker* pMoniker, ULONGLONG merit)
- : CGraphFilter(L"", merit), m_pMoniker(pMoniker)
- {
- if(!m_pMoniker) return;
- LPOLESTR str = NULL;
- if(FAILED(m_pMoniker->GetDisplayName(0, 0, &str))) return;
- m_dispname = m_name = str;
- CoTaskMemFree(str), str = NULL;
- CComPtr<IPropertyBag> pPB;
- if(SUCCEEDED(m_pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pPB)))
- {
- CComVariant var;
- if(SUCCEEDED(pPB->Read(CComBSTR(_T("FriendlyName")), &var, NULL)))
- {
- m_name = var.bstrVal;
- var.Clear();
- }
- if(SUCCEEDED(pPB->Read(CComBSTR(_T("CLSID")), &var, NULL)))
- {
- CLSIDFromString(var.bstrVal, &m_clsid);
- var.Clear();
- }
- if(SUCCEEDED(pPB->Read(CComBSTR(_T("FilterData")), &var, NULL)))
- {
- BSTR* pstr;
- if(SUCCEEDED(SafeArrayAccessData(var.parray, (void**)&pstr)))
- {
- ExtractFilterData((BYTE*)pstr, var.parray->cbElements*(var.parray->rgsabound[0].cElements));
- SafeArrayUnaccessData(var.parray);
- }
- var.Clear();
- }
- }
- if(merit != LMERIT_DO_USE) m_merit.val = merit;
- }
- CGraphRegFilter::CGraphRegFilter(CStringW m_dispname, ULONGLONG merit)
- : CGraphFilter(L"", merit), m_dispname(m_dispname)
- {
- if(m_dispname.IsEmpty()) return;
- CComPtr<IBindCtx> pBC;
- CreateBindCtx(0, &pBC);
- ULONG chEaten;
- if(S_OK != MkParseDisplayName(pBC, CComBSTR(m_dispname), &chEaten, &m_pMoniker))
- return;
- CComPtr<IPropertyBag> pPB;
- if(SUCCEEDED(m_pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pPB)))
- {
- CComVariant var;
- if(SUCCEEDED(pPB->Read(CComBSTR(_T("FriendlyName")), &var, NULL)))
- {
- m_name = var.bstrVal;
- var.Clear();
- }
- if(SUCCEEDED(pPB->Read(CComBSTR(_T("CLSID")), &var, NULL)))
- {
- CLSIDFromString(var.bstrVal, &m_clsid);
- var.Clear();
- }
- if(SUCCEEDED(pPB->Read(CComBSTR(_T("FilterData")), &var, NULL)))
- {
- BSTR* pstr;
- if(SUCCEEDED(SafeArrayAccessData(var.parray, (void**)&pstr)))
- {
- ExtractFilterData((BYTE*)pstr, var.parray->cbElements*(var.parray->rgsabound[0].cElements));
- SafeArrayUnaccessData(var.parray);
- }
- var.Clear();
- }
- }
- if(merit != LMERIT_DO_USE) m_merit.val = merit;
- }
- CGraphRegFilter::CGraphRegFilter(const CLSID& clsid, ULONGLONG merit)
- : CGraphFilter(L"", merit)
- {
- if((m_clsid = clsid) == GUID_NULL) return;
- CString guid = CStringFromGUID(m_clsid);
- CString str = CString(_T("CLSID\{083863F1-70DE-11d0-BD40-00A0C911CE86}\Instance\")) + guid;
- CString str2 = CString(_T("CLSID\")) + guid;
- CRegKey key;
- if(ERROR_SUCCESS == key.Open(HKEY_CLASSES_ROOT, str2, KEY_READ))
- {
- ULONG nChars = 0;
- if(ERROR_SUCCESS == key.QueryStringValue(NULL, NULL, &nChars))
- {
- CString name;
- if(ERROR_SUCCESS == key.QueryStringValue(NULL, name.GetBuffer(nChars), &nChars))
- {
- name.ReleaseBuffer(nChars);
- m_name = name;
- }
- }
- key.Close();
- }
- if(ERROR_SUCCESS == key.Open(HKEY_CLASSES_ROOT, str, KEY_READ))
- {
- ULONG nChars = 0;
- if(ERROR_SUCCESS == key.QueryStringValue(_T("FriendlyName"), NULL, &nChars))
- {
- CString name;
- if(ERROR_SUCCESS == key.QueryStringValue(_T("FriendlyName"), name.GetBuffer(nChars), &nChars))
- {
- name.ReleaseBuffer(nChars);
- m_name = name;
- }
- }
- ULONG nBytes = 0;
- if(ERROR_SUCCESS == key.QueryBinaryValue(_T("FilterData"), NULL, &nBytes))
- {
- CAutoVectorPtr<BYTE> buff;
- if(buff.Allocate(nBytes) && ERROR_SUCCESS == key.QueryBinaryValue(_T("FilterData"), buff, &nBytes))
- {
- ExtractFilterData(buff, nBytes);
- }
- }
- key.Close();
- }
- if(merit != LMERIT_DO_USE) m_merit.val = merit;
- }
- [uuid("97f7c4d4-547b-4a5f-8332-536430ad2e4d")]
- interface IAMFilterData : public IUnknown
- {
- STDMETHOD (ParseFilterData) (BYTE* rgbFilterData, ULONG cb, BYTE** prgbRegFilter2) PURE;
- STDMETHOD (CreateFilterData) (REGFILTER2* prf2, BYTE** prgbFilterData, ULONG* pcb) PURE;
- };
- void CGraphRegFilter::ExtractFilterData(BYTE* p, UINT len)
- {
- CComPtr<IAMFilterData> pFD;
- BYTE* ptr = NULL;
- if(SUCCEEDED(pFD.CoCreateInstance(CLSID_FilterMapper2))
- && SUCCEEDED(pFD->ParseFilterData(p, len, (BYTE**)&ptr)))
- {
- REGFILTER2* prf = (REGFILTER2*)*(DWORD*)ptr; // this is f*cked up
- m_merit.mid = prf->dwMerit;
- if(prf->dwVersion == 1)
- {
- for(UINT i = 0; i < prf->cPins; i++)
- {
- if(prf->rgPins[i].bOutput)
- continue;
- for(UINT j = 0; j < prf->rgPins[i].nMediaTypes; j++)
- {
- if(!prf->rgPins[i].lpMediaType[j].clsMajorType || !prf->rgPins[i].lpMediaType[j].clsMinorType)
- break;
- m_guids.AddTail(*(GUID*)prf->rgPins[i].lpMediaType[j].clsMajorType);
- m_guids.AddTail(*(GUID*)prf->rgPins[i].lpMediaType[j].clsMinorType);
- }
- }
- }
- else if(prf->dwVersion == 2)
- {
- for(UINT i = 0; i < prf->cPins2; i++)
- {
- if(prf->rgPins2[i].dwFlags®_PINFLAG_B_OUTPUT)
- continue;
- for(UINT j = 0; j < prf->rgPins2[i].nMediaTypes; j++)
- {
- if(!prf->rgPins2[i].lpMediaType[j].clsMajorType || !prf->rgPins2[i].lpMediaType[j].clsMinorType)
- break;
- m_guids.AddTail(*(GUID*)prf->rgPins2[i].lpMediaType[j].clsMajorType);
- m_guids.AddTail(*(GUID*)prf->rgPins2[i].lpMediaType[j].clsMinorType);
- }
- }
- }
- CoTaskMemFree(prf);
- }
- else
- {
- BYTE* base = p;
- #define ChkLen(size) if(p - base + size > (int)len) return;
- ChkLen(4)
- if(*(DWORD*)p != 0x00000002) return; // only version 2 supported, no samples found for 1
- p += 4;
- ChkLen(4)
- m_merit.mid = *(DWORD*)p; p += 4;
- m_guids.RemoveAll();
- ChkLen(8)
- DWORD nPins = *(DWORD*)p; p += 8;
- while(nPins-- > 0)
- {
- ChkLen(1)
- BYTE n = *p-0x30; p++;
- ChkLen(2)
- WORD pi = *(WORD*)p; p += 2;
- ASSERT(pi == 'ip');
- ChkLen(1)
- BYTE x33 = *p; p++;
- ASSERT(x33 == 0x33);
- ChkLen(8)
- bool fOutput = !!(*p®_PINFLAG_B_OUTPUT);
- p += 8;
- ChkLen(12)
- DWORD nTypes = *(DWORD*)p; p += 12;
- while(nTypes-- > 0)
- {
- ChkLen(1)
- BYTE n = *p-0x30; p++;
- ChkLen(2)
- WORD ty = *(WORD*)p; p += 2;
- ASSERT(ty == 'yt');
- ChkLen(5)
- BYTE x33 = *p; p++;
- ASSERT(x33 == 0x33);
- p += 4;
- ChkLen(8)
- if(*(DWORD*)p < (p-base+8) || *(DWORD*)p >= len
- || *(DWORD*)(p+4) < (p-base+8) || *(DWORD*)(p+4) >= len)
- {
- p += 8;
- continue;
- }
- GUID guid;
- memcpy(&guid, &base[*(DWORD*)p], sizeof(GUID)); p += 4;
- if(!fOutput) m_guids.AddTail(guid);
- memcpy(&guid, &base[*(DWORD*)p], sizeof(GUID)); p += 4;
- if(!fOutput) m_guids.AddTail(guid);
- }
- }
- #undef ChkLen
- }
- /*
- if(CLSID_MMSPLITTER == m_clsid && m_merit.val == LMERIT(MERIT_NORMAL-1))
- {
- m_merit.val = LMERIT(MERIT_NORMAL)+1; // take this mpeg2 demux...
- }
- */
- }
- HRESULT CGraphRegFilter::Create(IBaseFilter** ppBF, IUnknown** ppUnk)
- {
- CheckPointer(ppBF, E_POINTER);
- if(ppUnk) *ppUnk = NULL;
- HRESULT hr = E_FAIL;
-
- if(m_pMoniker)
- {
- if(SUCCEEDED(hr = m_pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)ppBF)))
- m_clsid = ::GetCLSID(*ppBF);
- }
- else if(m_clsid != GUID_NULL)
- {
- CComPtr<IBaseFilter> pBF;
- if(FAILED(pBF.CoCreateInstance(m_clsid))) return E_FAIL;
- *ppBF = pBF.Detach();
- hr = S_OK;
- }
- return hr;
- };
- //
- // CGraphCustomFilter
- //
- CGraphCustomFilter::CGraphCustomFilter(const CLSID& clsid, CList<GUID>& guids, CStringW name, ULONGLONG merit)
- : CGraphFilter(name, merit)
- {
- m_clsid = clsid;
- ASSERT(guids.GetCount() > 0);
- m_guids.AddTail(&guids);
- }
- HRESULT CGraphCustomFilter::Create(IBaseFilter** ppBF, IUnknown** ppUnk)
- {
- CheckPointer(ppBF, E_POINTER);
- if(ppUnk) *ppUnk = NULL;
- HRESULT hr = S_OK;
- *ppBF =
- m_clsid == __uuidof(CAVI2AC3Filter) ? (IBaseFilter*)new CAVI2AC3Filter(NULL, &hr) :
- m_clsid == __uuidof(CDeCSSFilter) ? (IBaseFilter*)new CDeCSSFilter(NULL, &hr) :
- m_clsid == __uuidof(CAudioSwitcherFilter) ? (IBaseFilter*)new CAudioSwitcherFilter(NULL, &hr) :
- m_clsid == __uuidof(CMatroskaSplitterFilter) ? (IBaseFilter*)new CMatroskaSplitterFilter(NULL, &hr) :
- m_clsid == __uuidof(CRealMediaSplitterFilter) ? (IBaseFilter*)new CRealMediaSplitterFilter(NULL, &hr) :
- m_clsid == __uuidof(CRealVideoDecoder) ? (IBaseFilter*)new CRealVideoDecoder(NULL, &hr) :
- m_clsid == __uuidof(CRealAudioDecoder) ? (IBaseFilter*)new CRealAudioDecoder(NULL, &hr) :
- m_clsid == __uuidof(CRoQVideoDecoder) ? (IBaseFilter*)new CRoQVideoDecoder(NULL, &hr) :
- m_clsid == __uuidof(CRoQAudioDecoder) ? (IBaseFilter*)new CRoQAudioDecoder(NULL, &hr) :
- m_clsid == __uuidof(CAviSplitterFilter) ? (IBaseFilter*)new CAviSplitterFilter(NULL, &hr) :
- m_clsid == __uuidof(CRoQSplitterFilter) ? (IBaseFilter*)new CRoQSplitterFilter(NULL, &hr) :
- m_clsid == __uuidof(COggSplitterFilter) ? (IBaseFilter*)new COggSplitterFilter(NULL, &hr) :
- m_clsid == __uuidof(CNutSplitterFilter) ? (IBaseFilter*)new CNutSplitterFilter(NULL, &hr) :
- m_clsid == __uuidof(CMpegSplitterFilter) ? (IBaseFilter*)new CMpegSplitterFilter(NULL, &hr) :
- m_clsid == __uuidof(CMpeg2DecFilter) ? (IBaseFilter*)new CMpeg2DecFilter(NULL, &hr) :
- m_clsid == __uuidof(CDiracSplitterFilter) ? (IBaseFilter*)new CDiracSplitterFilter(NULL, &hr) :
- m_clsid == __uuidof(CDiracVideoDecoder) ? (IBaseFilter*)new CDiracVideoDecoder(NULL, &hr) :
- m_clsid == __uuidof(CMpaSplitterFilter) ? (IBaseFilter*)new CMpaSplitterFilter(NULL, &hr) :
- m_clsid == __uuidof(CMpaDecFilter) ? (IBaseFilter*)new CMpaDecFilter(NULL, &hr) :
- m_clsid == __uuidof(CDSMSplitterFilter) ? (IBaseFilter*)new CDSMSplitterFilter(NULL, &hr) :
- m_clsid == __uuidof(CMP4SplitterFilter) ? (IBaseFilter*)new CMP4SplitterFilter(NULL, &hr) :
- m_clsid == __uuidof(CNullVideoRenderer) ? (IBaseFilter*)new CNullVideoRenderer() :
- m_clsid == __uuidof(CNullAudioRenderer) ? (IBaseFilter*)new CNullAudioRenderer() :
- m_clsid == __uuidof(CNullUVideoRenderer) ? (IBaseFilter*)new CNullUVideoRenderer() :
- m_clsid == __uuidof(CNullUAudioRenderer) ? (IBaseFilter*)new CNullUAudioRenderer() :
- m_clsid == __uuidof(CNullTextRenderer) ? (IBaseFilter*)new CNullTextRenderer(NULL, &hr) :
- m_clsid == __uuidof(CDeinterlacerFilter) ? (IBaseFilter*)new CDeinterlacerFilter(NULL, &hr) :
- NULL;
- __if_exists(CRadGtSplitterFilter)
- {
- if(*ppBF == NULL && m_clsid == __uuidof(CRadGtSplitterFilter))
- *ppBF = (IBaseFilter*)new CRadGtSplitterFilter(NULL, &hr);
- }
- if(!*ppBF) hr = E_FAIL;
- else (*ppBF)->AddRef();
- if(!*ppBF)
- {
- CComPtr<IBaseFilter> pBF;
- if(SUCCEEDED(hr = pBF.CoCreateInstance(m_clsid)))
- *ppBF = pBF.Detach();
- }
- if(SUCCEEDED(hr) && ppUnk)
- {
- if(m_clsid == __uuidof(CAudioSwitcherFilter))
- {
- *ppUnk = (IUnknown*)CComQIPtr<IAudioSwitcherFilter>(*ppBF).Detach();
- CComQIPtr<IAudioSwitcherFilter> pASF = *ppUnk;
- if(pASF)
- {
- AppSettings& s = AfxGetAppSettings();
- pASF->SetSpeakerConfig(s.fCustomChannelMapping, s.pSpeakerToChannelMap);
- pASF->EnableDownSamplingTo441(s.fDownSampleTo441);
- pASF->SetAudioTimeShift(s.fAudioTimeShift ? 10000i64*s.tAudioTimeShift : 0);
- }
- }
- }
- return hr;
- }
- //
- // CGraphFileFilter
- //
- CGraphFileFilter::CGraphFileFilter(const CLSID& clsid, CList<GUID>& guids, CString path, CStringW name, ULONGLONG merit)
- : CGraphCustomFilter(clsid, guids, name, merit), m_path(path), m_hInst(NULL)
- {
- }
- HRESULT CGraphFileFilter::Create(IBaseFilter** ppBF, IUnknown** ppUnk)
- {
- CheckPointer(ppBF, E_POINTER);
- if(ppUnk) *ppUnk = NULL;
- HRESULT hr = S_OK;
- if(SUCCEEDED(hr = __super::Create(ppBF, ppUnk)))
- return hr;
- return LoadExternalFilter(m_path, m_clsid, ppBF);
- }
- //
- // CGraphRendererFilter
- //
- CGraphRendererFilter::CGraphRendererFilter(const CLSID& clsid, HWND hWnd, CStringW name, ULONGLONG merit)
- : CGraphFilter(name, merit), m_clsid(clsid), m_hWnd(hWnd)
- {
- m_guids.AddTail(MEDIATYPE_Video);
- m_guids.AddTail(MEDIASUBTYPE_NULL);
- }
- HRESULT CGraphRendererFilter::Create(IBaseFilter** ppBF, IUnknown** ppUnk)
- {
- CheckPointer(ppBF, E_POINTER);
- HRESULT hr = S_OK;
- if(m_clsid == CLSID_OverlayMixer)
- {
- CComPtr<IBaseFilter> pBF;
- if(SUCCEEDED(pBF.CoCreateInstance(CLSID_OverlayMixer)))
- {
- BeginEnumPins(pBF, pEP, pPin)
- {
- if(CComQIPtr<IMixerPinConfig, &IID_IMixerPinConfig> pMPC = pPin)
- {
- if(ppUnk) *ppUnk = pMPC.Detach();
- break;
- }
- }
- EndEnumPins
- *ppBF = pBF.Detach();
- }
- }
- else if(m_clsid == CLSID_VideoMixingRenderer)
- {
- CComPtr<IBaseFilter> pBF;
- if(SUCCEEDED(pBF.CoCreateInstance(CLSID_VideoMixingRenderer)))
- *ppBF = pBF.Detach();
- }
- else if(m_clsid == CLSID_VideoMixingRenderer9)
- {
- CComPtr<IBaseFilter> pBF;
- if(SUCCEEDED(pBF.CoCreateInstance(CLSID_VideoMixingRenderer9)))
- *ppBF = pBF.Detach();
- }
- else if(m_clsid == CLSID_VMR7AllocatorPresenter)
- {
- CComPtr<ISubPicAllocatorPresenter> pCAP;
- CComPtr<IUnknown> pRenderer;
- if(SUCCEEDED(hr = CreateAP7(CLSID_VMR7AllocatorPresenter, m_hWnd, &pCAP))
- && SUCCEEDED(hr = pCAP->CreateRenderer(&pRenderer)))
- {
- *ppBF = CComQIPtr<IBaseFilter>(pRenderer).Detach();
- if(ppUnk) *ppUnk = (IUnknown*)pCAP.Detach();
- }
- }
- else if(m_clsid == CLSID_VMR9AllocatorPresenter)
- {
- CComPtr<ISubPicAllocatorPresenter> pCAP;
- CComPtr<IUnknown> pRenderer;
- if(SUCCEEDED(hr = CreateAP9(CLSID_VMR9AllocatorPresenter, m_hWnd, &pCAP))
- && SUCCEEDED(hr = pCAP->CreateRenderer(&pRenderer)))
- {
- *ppBF = CComQIPtr<IBaseFilter>(pRenderer).Detach();
- if(ppUnk) *ppUnk = (IUnknown*)pCAP.Detach();
- }
- }
- if(!*ppBF) hr = E_FAIL;
- return hr;
- }