00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "stdafx.h"
00023 #include "mplayerc.h"
00024 #include "GraphBuilder.h"
00025 #include "..\..\DSUtil\DSUtil.h"
00026 #include "..\..\filters\filters.h"
00027 #include "..\..\..\include\moreuuids.h"
00028 #include "..\..\..\include\Ogg\OggDS.h"
00029 #include "..\..\..\include\matroska\matroska.h"
00030 #include "DX7AllocatorPresenter.h"
00031 #include "DX9AllocatorPresenter.h"
00032 #include "DeinterlacerFilter.h"
00033
00034 #include <initguid.h>
00035 #include <dmodshow.h>
00036
00037 #include <D3d9.h>
00038 #include <Vmr9.h>
00039
00040 static void CheckStupidSharedFilesourceFilter()
00041 {
00042 CRegKey key;
00043 CString str(_T("CLSID\\{E436EBB5-524F-11CE-9F53-0020AF0BA770}\\InprocServer32"));
00044
00045 if(ERROR_SUCCESS == key.Open(HKEY_CLASSES_ROOT, str, KEY_READ))
00046 {
00047 ULONG nChars = 0;
00048 if(ERROR_SUCCESS == key.QueryStringValue(NULL, NULL, &nChars))
00049 {
00050 CString dll;
00051 if(ERROR_SUCCESS == key.QueryStringValue(NULL, dll.GetBuffer(nChars), &nChars))
00052 {
00053 dll.ReleaseBuffer(nChars);
00054 dll.MakeLower();
00055 if(dll.Find(_T("shared_filesource.ax")) >= 0
00056 || dll.Find(_T("shared~1.ax")) >= 0)
00057 {
00058 if(IDYES == AfxMessageBox(
00059 _T("Warning: MPC has detected that DirectShow's \"File Source (async)\" filter\n")
00060 _T("was replaced by shared_filesource.ax. Please run \"regsvr32.exe quartz.dll\"\n")
00061 _T("in your system folder to restore it. If you are a user with administrator\n")
00062 _T("rights, MPC can also do this for you. Do you want to re-register quartz.dll now?"),
00063 MB_YESNO|MB_ICONEXCLAMATION))
00064 {
00065 TCHAR buff[MAX_PATH+1];
00066 GetSystemDirectory(buff, sizeof(buff));
00067
00068 CString path = CString(buff) + _T("\\quartz.dll");
00069
00070 HRESULT hr = E_FAIL;
00071
00072 if(HMODULE hModule = LoadLibrary(path))
00073 {
00074 typedef HRESULT (__stdcall * PDllRegisterServer)();
00075 if(PDllRegisterServer p = (PDllRegisterServer)GetProcAddress(hModule, "DllRegisterServer"))
00076 hr = p();
00077 }
00078
00079 if(SUCCEEDED(hr))
00080 AfxMessageBox(_T("Successfully re-registered quartz.dll, you may need to restart the player now."), MB_OK);
00081 else
00082 AfxMessageBox(_T("Failed to re-register quartz.dll!"), MB_OK|MB_ICONEXCLAMATION);
00083 }
00084 }
00085 }
00086 }
00087 }
00088 }
00089
00090
00091
00092
00093
00094 CGraphBuilder::CGraphBuilder(IGraphBuilder* pGB, HWND hWnd)
00095 : m_pGB(pGB), m_hWnd(hWnd)
00096 , m_nTotalStreams(0)
00097 , m_nCurrentStream(0)
00098 , m_VRMerit(LMERIT(MERIT_PREFERRED+1)+0x100)
00099 , m_ARMerit(LMERIT(MERIT_PREFERRED+1)+0x100)
00100 {
00101 AppSettings& s = AfxGetAppSettings();
00102
00103 m_pFM.CoCreateInstance(CLSID_FilterMapper2);
00104 if(!m_pFM) return;
00105
00106 {
00107 CArray<GUID> guids;
00108 CComPtr<IEnumMoniker> pEM;
00109
00110 m_VRMerit = LMERIT(MERIT_PREFERRED);
00111
00112 guids.Add(MEDIATYPE_Video);
00113 guids.Add(MEDIASUBTYPE_NULL);
00114 if(guids.GetCount() > 0
00115 && SUCCEEDED(m_pFM->EnumMatchingFilters(
00116 &pEM, 0, FALSE, MERIT_DO_NOT_USE+1,
00117 TRUE, guids.GetCount()/2, guids.GetData(), NULL, NULL, TRUE,
00118 FALSE, 0, NULL, NULL, NULL)))
00119 {
00120 for(CComPtr<IMoniker> pMoniker; S_OK == pEM->Next(1, &pMoniker, NULL); pMoniker = NULL)
00121 {
00122 CGraphRegFilter gf(pMoniker);
00123 m_VRMerit = max(m_VRMerit, gf.GetMerit());
00124 }
00125 }
00126 guids.RemoveAll();
00127 pEM = NULL;
00128
00129 m_VRMerit += 0x100;
00130
00131 m_ARMerit = LMERIT(MERIT_PREFERRED);
00132
00133 guids.Add(MEDIATYPE_Audio);
00134 guids.Add(MEDIASUBTYPE_NULL);
00135 if(guids.GetCount() > 0
00136 && SUCCEEDED(m_pFM->EnumMatchingFilters(
00137 &pEM, 0, FALSE, MERIT_DO_NOT_USE+1,
00138 TRUE, guids.GetCount()/2, guids.GetData(), NULL, NULL, TRUE,
00139 FALSE, 0, NULL, NULL, NULL)))
00140 {
00141 for(CComPtr<IMoniker> pMoniker; S_OK == pEM->Next(1, &pMoniker, NULL); pMoniker = NULL)
00142 {
00143 CGraphRegFilter gf(pMoniker);
00144 m_ARMerit = max(m_ARMerit, gf.GetMerit());
00145 }
00146 }
00147
00148 BeginEnumSysDev(CLSID_AudioRendererCategory, pMoniker)
00149 {
00150 CGraphRegFilter gf(pMoniker);
00151 m_ARMerit = max(m_ARMerit, gf.GetMerit());
00152 }
00153 EndEnumSysDev
00154
00155 guids.RemoveAll();
00156 pEM = NULL;
00157
00158 m_ARMerit += 0x100;
00159 }
00160
00161
00162
00163 CList<GUID> guids;
00164
00165 guids.AddTail(MEDIATYPE_Audio);
00166 guids.AddTail(MEDIASUBTYPE_WAVE_DOLBY_AC3);
00167 guids.AddTail(MEDIATYPE_Audio);
00168 guids.AddTail(MEDIASUBTYPE_WAVE_DTS);
00169 AddFilter(new CGraphCustomFilter(__uuidof(CAVI2AC3Filter), guids, L"AVI<->AC3/DTS", LMERIT(0x00680000)+1));
00170 guids.RemoveAll();
00171
00172 {
00173 guids.AddTail(MEDIATYPE_Stream);
00174 guids.AddTail(MEDIASUBTYPE_Matroska);
00175 AddFilter(new CGraphCustomFilter(__uuidof(CMatroskaSplitterFilter), guids,
00176 (s.SrcFilters&SRC_MATROSKA) ? L"Matroska Splitter" : L"Matroska Splitter (low merit)",
00177 (s.SrcFilters&SRC_MATROSKA) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
00178 guids.RemoveAll();
00179 }
00180
00181 {
00182 guids.AddTail(MEDIATYPE_Stream);
00183 guids.AddTail(MEDIASUBTYPE_RealMedia);
00184 AddFilter(new CGraphCustomFilter(__uuidof(CRealMediaSplitterFilter), guids,
00185 (s.SrcFilters&SRC_REALMEDIA) ? L"RealMedia Splitter" : L"RealMedia Splitter (low merit)",
00186 (s.SrcFilters&SRC_REALMEDIA) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
00187 guids.RemoveAll();
00188 }
00189
00190 {
00191 guids.AddTail(MEDIATYPE_Stream);
00192 guids.AddTail(MEDIASUBTYPE_Avi);
00193 AddFilter(new CGraphCustomFilter(__uuidof(CAviSplitterFilter), guids,
00194 (s.SrcFilters&SRC_AVI) ? L"Avi Splitter" : L"Avi Splitter (low merit)",
00195 (s.SrcFilters&SRC_AVI) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
00196 guids.RemoveAll();
00197 }
00198
00199 __if_exists(CRadGtSplitterFilter)
00200 {
00201 guids.AddTail(MEDIATYPE_Stream);
00202 guids.AddTail(MEDIASUBTYPE_Bink);
00203 guids.AddTail(MEDIATYPE_Stream);
00204 guids.AddTail(MEDIASUBTYPE_Smacker);
00205 AddFilter(new CGraphCustomFilter(__uuidof(CRadGtSplitterFilter), guids,
00206 (s.SrcFilters&SRC_RADGT) ? L"RadGt Splitter" : L"RadGt Splitter (low merit)",
00207 (s.SrcFilters&SRC_RADGT) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
00208 guids.RemoveAll();
00209 }
00210
00211 {
00212 guids.AddTail(MEDIATYPE_Stream);
00213 guids.AddTail(MEDIASUBTYPE_RoQ);
00214 AddFilter(new CGraphCustomFilter(__uuidof(CRoQSplitterFilter), guids,
00215 (s.SrcFilters&SRC_ROQ) ? L"RoQ Splitter" : L"RoQ Splitter (low merit)",
00216 (s.SrcFilters&SRC_ROQ) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
00217 guids.RemoveAll();
00218 }
00219
00220 {
00221 guids.AddTail(MEDIATYPE_Stream);
00222 guids.AddTail(MEDIASUBTYPE_Ogg);
00223 AddFilter(new CGraphCustomFilter(__uuidof(COggSplitterFilter), guids,
00224 (s.SrcFilters&SRC_OGG) ? L"Ogg Splitter" : L"Ogg Splitter (low merit)",
00225 (s.SrcFilters&SRC_OGG) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
00226 guids.RemoveAll();
00227 }
00228
00229 {
00230 guids.AddTail(MEDIATYPE_Stream);
00231 guids.AddTail(MEDIASUBTYPE_Nut);
00232 AddFilter(new CGraphCustomFilter(__uuidof(CNutSplitterFilter), guids,
00233 (s.SrcFilters&SRC_NUT) ? L"Nut Splitter" : L"Nut Splitter (low merit)",
00234 (s.SrcFilters&SRC_NUT) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
00235 guids.RemoveAll();
00236 }
00237
00238 {
00239 guids.AddTail(MEDIATYPE_Stream);
00240 guids.AddTail(MEDIASUBTYPE_MPEG1System);
00241 guids.AddTail(MEDIATYPE_Stream);
00242 guids.AddTail(MEDIASUBTYPE_MPEG2_PROGRAM);
00243 guids.AddTail(MEDIATYPE_Stream);
00244 guids.AddTail(MEDIASUBTYPE_MPEG2_TRANSPORT);
00245 guids.AddTail(MEDIATYPE_Stream);
00246 guids.AddTail(MEDIASUBTYPE_MPEG2_PVA);
00247 AddFilter(new CGraphCustomFilter(__uuidof(CMpegSplitterFilter), guids,
00248 (s.SrcFilters&SRC_MPEG) ? L"Mpeg Splitter" : L"Mpeg Splitter (low merit)",
00249 (s.SrcFilters&SRC_MPEG) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
00250 guids.RemoveAll();
00251 }
00252
00253 {
00254 guids.AddTail(MEDIATYPE_Video);
00255 guids.AddTail(MEDIASUBTYPE_MPEG1Packet);
00256 guids.AddTail(MEDIATYPE_Video);
00257 guids.AddTail(MEDIASUBTYPE_MPEG1Payload);
00258 AddFilter(new CGraphCustomFilter(__uuidof(CMpeg2DecFilter), guids,
00259 (s.TraFilters&TRA_MPEG1) ? L"MPEG-1 Video Decoder" : L"MPEG-1 Video Decoder (low merit)",
00260 (s.TraFilters&TRA_MPEG1) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
00261 guids.RemoveAll();
00262 }
00263
00264 {
00265 guids.AddTail(MEDIATYPE_DVD_ENCRYPTED_PACK);
00266 guids.AddTail(MEDIASUBTYPE_MPEG2_VIDEO);
00267 guids.AddTail(MEDIATYPE_MPEG2_PACK);
00268 guids.AddTail(MEDIASUBTYPE_MPEG2_VIDEO);
00269 guids.AddTail(MEDIATYPE_MPEG2_PES);
00270 guids.AddTail(MEDIASUBTYPE_MPEG2_VIDEO);
00271 guids.AddTail(MEDIATYPE_Video);
00272 guids.AddTail(MEDIASUBTYPE_MPEG2_VIDEO);
00273 AddFilter(new CGraphCustomFilter(__uuidof(CMpeg2DecFilter), guids,
00274 (s.TraFilters&TRA_MPEG2) ? L"MPEG-2 Video Decoder" : L"MPEG-2 Video Decoder (low merit)",
00275 (s.TraFilters&TRA_MPEG2) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
00276 guids.RemoveAll();
00277 }
00278
00279 {
00280 guids.AddTail(MEDIATYPE_Audio);
00281 guids.AddTail(MEDIASUBTYPE_MP3);
00282 guids.AddTail(MEDIATYPE_Audio);
00283 guids.AddTail(MEDIASUBTYPE_MPEG1AudioPayload);
00284 guids.AddTail(MEDIATYPE_Audio);
00285 guids.AddTail(MEDIASUBTYPE_MPEG1Payload);
00286 guids.AddTail(MEDIATYPE_Audio);
00287 guids.AddTail(MEDIASUBTYPE_MPEG1Packet);
00288 AddFilter(new CGraphCustomFilter(__uuidof(CMpaDecFilter), guids,
00289 (s.TraFilters&TRA_MPA) ? L"MPEG-1 Audio Decoder" : L"MPEG-1 Audio Decoder (low merit)",
00290 (s.TraFilters&TRA_MPA) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
00291 guids.RemoveAll();
00292 }
00293
00294 {
00295 guids.AddTail(MEDIATYPE_DVD_ENCRYPTED_PACK);
00296 guids.AddTail(MEDIASUBTYPE_MPEG2_AUDIO);
00297 guids.AddTail(MEDIATYPE_MPEG2_PACK);
00298 guids.AddTail(MEDIASUBTYPE_MPEG2_AUDIO);
00299 guids.AddTail(MEDIATYPE_MPEG2_PES);
00300 guids.AddTail(MEDIASUBTYPE_MPEG2_AUDIO);
00301 guids.AddTail(MEDIATYPE_Audio);
00302 guids.AddTail(MEDIASUBTYPE_MPEG2_AUDIO);
00303 AddFilter(new CGraphCustomFilter(__uuidof(CMpaDecFilter), guids,
00304 (s.TraFilters&TRA_MPA) ? L"MPEG-2 Audio Decoder" : L"MPEG-2 Audio Decoder (low merit)",
00305 (s.TraFilters&TRA_MPA) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
00306 guids.RemoveAll();
00307 }
00308
00309 {
00310 guids.AddTail(MEDIATYPE_DVD_ENCRYPTED_PACK);
00311 guids.AddTail(MEDIASUBTYPE_DVD_LPCM_AUDIO);
00312 guids.AddTail(MEDIATYPE_MPEG2_PACK);
00313 guids.AddTail(MEDIASUBTYPE_DVD_LPCM_AUDIO);
00314 guids.AddTail(MEDIATYPE_MPEG2_PES);
00315 guids.AddTail(MEDIASUBTYPE_DVD_LPCM_AUDIO);
00316 guids.AddTail(MEDIATYPE_Audio);
00317 guids.AddTail(MEDIASUBTYPE_DVD_LPCM_AUDIO);
00318 AddFilter(new CGraphCustomFilter(__uuidof(CMpaDecFilter), guids,
00319 (s.TraFilters&TRA_LPCM) ? L"LPCM Audio Decoder" : L"LPCM Audio Decoder (low merit)",
00320 (s.TraFilters&TRA_LPCM) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
00321 guids.RemoveAll();
00322 }
00323
00324 {
00325 guids.AddTail(MEDIATYPE_DVD_ENCRYPTED_PACK);
00326 guids.AddTail(MEDIASUBTYPE_DOLBY_AC3);
00327 guids.AddTail(MEDIATYPE_MPEG2_PACK);
00328 guids.AddTail(MEDIASUBTYPE_DOLBY_AC3);
00329 guids.AddTail(MEDIATYPE_MPEG2_PES);
00330 guids.AddTail(MEDIASUBTYPE_DOLBY_AC3);
00331 guids.AddTail(MEDIATYPE_Audio);
00332 guids.AddTail(MEDIASUBTYPE_DOLBY_AC3);
00333 guids.AddTail(MEDIATYPE_Audio);
00334 guids.AddTail(MEDIASUBTYPE_WAVE_DOLBY_AC3);
00335 AddFilter(new CGraphCustomFilter(__uuidof(CMpaDecFilter), guids,
00336 (s.TraFilters&TRA_AC3) ? L"AC3 Audio Decoder" : L"AC3 Audio Decoder (low merit)",
00337 (s.TraFilters&TRA_AC3) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
00338 guids.RemoveAll();
00339 }
00340
00341 {
00342 guids.AddTail(MEDIATYPE_DVD_ENCRYPTED_PACK);
00343 guids.AddTail(MEDIASUBTYPE_DTS);
00344 guids.AddTail(MEDIATYPE_MPEG2_PACK);
00345 guids.AddTail(MEDIASUBTYPE_DTS);
00346 guids.AddTail(MEDIATYPE_MPEG2_PES);
00347 guids.AddTail(MEDIASUBTYPE_DTS);
00348 guids.AddTail(MEDIATYPE_Audio);
00349 guids.AddTail(MEDIASUBTYPE_DTS);
00350 guids.AddTail(MEDIATYPE_Audio);
00351 guids.AddTail(MEDIASUBTYPE_WAVE_DTS);
00352 AddFilter(new CGraphCustomFilter(__uuidof(CMpaDecFilter), guids,
00353 (s.TraFilters&TRA_DTS) ? L"DTS Decoder" : L"DTS Decoder (low merit)",
00354 (s.TraFilters&TRA_DTS) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
00355 guids.RemoveAll();
00356 }
00357
00358 {
00359 guids.AddTail(MEDIATYPE_DVD_ENCRYPTED_PACK);
00360 guids.AddTail(MEDIASUBTYPE_AAC);
00361 guids.AddTail(MEDIATYPE_MPEG2_PACK);
00362 guids.AddTail(MEDIASUBTYPE_AAC);
00363 guids.AddTail(MEDIATYPE_MPEG2_PES);
00364 guids.AddTail(MEDIASUBTYPE_AAC);
00365 guids.AddTail(MEDIATYPE_Audio);
00366 guids.AddTail(MEDIASUBTYPE_AAC);
00367 guids.AddTail(MEDIATYPE_DVD_ENCRYPTED_PACK);
00368 guids.AddTail(MEDIASUBTYPE_MP4A);
00369 guids.AddTail(MEDIATYPE_MPEG2_PACK);
00370 guids.AddTail(MEDIASUBTYPE_MP4A);
00371 guids.AddTail(MEDIATYPE_MPEG2_PES);
00372 guids.AddTail(MEDIASUBTYPE_MP4A);
00373 guids.AddTail(MEDIATYPE_Audio);
00374 guids.AddTail(MEDIASUBTYPE_MP4A);
00375 AddFilter(new CGraphCustomFilter(__uuidof(CMpaDecFilter), guids,
00376 (s.TraFilters&TRA_AAC) ? L"AAC Decoder" : L"AAC Decoder (low merit)",
00377 (s.TraFilters&TRA_AAC) ? LMERIT_ABOVE_DSHOW+1 : LMERIT_DO_USE));
00378 guids.RemoveAll();
00379 }
00380
00381 {
00382 guids.AddTail(MEDIATYPE_DVD_ENCRYPTED_PACK);
00383 guids.AddTail(MEDIASUBTYPE_PS2_PCM);
00384 guids.AddTail(MEDIATYPE_MPEG2_PACK);
00385 guids.AddTail(MEDIASUBTYPE_PS2_PCM);
00386 guids.AddTail(MEDIATYPE_MPEG2_PES);
00387 guids.AddTail(MEDIASUBTYPE_PS2_PCM);
00388 guids.AddTail(MEDIATYPE_Audio);
00389 guids.AddTail(MEDIASUBTYPE_PS2_PCM);
00390 AddFilter(new CGraphCustomFilter(__uuidof(CMpaDecFilter), guids,
00391 (s.TraFilters&TRA_PS2AUD) ? L"PS2 Audio Decoder" : L"PS2 Audio Decoder (low merit)",
00392 (s.TraFilters&TRA_PS2AUD) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
00393 guids.RemoveAll();
00394 }
00395
00396 {
00397 guids.AddTail(MEDIATYPE_Video);
00398 guids.AddTail(MEDIASUBTYPE_RV10);
00399 guids.AddTail(MEDIATYPE_Video);
00400 guids.AddTail(MEDIASUBTYPE_RV20);
00401 guids.AddTail(MEDIATYPE_Video);
00402 guids.AddTail(MEDIASUBTYPE_RV30);
00403 guids.AddTail(MEDIATYPE_Video);
00404 guids.AddTail(MEDIASUBTYPE_RV40);
00405 AddFilter(new CGraphCustomFilter(__uuidof(CRealVideoDecoder), guids,
00406 (s.TraFilters&TRA_RV) ? L"RealVideo Decoder" : L"RealVideo Decoder (low merit)",
00407 (s.TraFilters&TRA_RV) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
00408 guids.RemoveAll();
00409 }
00410
00411 {
00412 guids.AddTail(MEDIATYPE_Audio);
00413 guids.AddTail(MEDIASUBTYPE_14_4);
00414 guids.AddTail(MEDIATYPE_Audio);
00415 guids.AddTail(MEDIASUBTYPE_28_8);
00416 guids.AddTail(MEDIATYPE_Audio);
00417 guids.AddTail(MEDIASUBTYPE_ATRC);
00418 guids.AddTail(MEDIATYPE_Audio);
00419 guids.AddTail(MEDIASUBTYPE_COOK);
00420 guids.AddTail(MEDIATYPE_Audio);
00421 guids.AddTail(MEDIASUBTYPE_DNET);
00422 guids.AddTail(MEDIATYPE_Audio);
00423 guids.AddTail(MEDIASUBTYPE_SIPR);
00424 guids.AddTail(MEDIATYPE_Audio);
00425 guids.AddTail(MEDIASUBTYPE_RAAC);
00426 AddFilter(new CGraphCustomFilter(__uuidof(CRealAudioDecoder), guids,
00427 (s.TraFilters&TRA_RA) ? L"RealAudio Decoder" : L"RealAudio Decoder (low merit)",
00428 (s.TraFilters&TRA_RA) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
00429 guids.RemoveAll();
00430 }
00431
00432 {
00433 guids.AddTail(MEDIATYPE_Video);
00434 guids.AddTail(MEDIASUBTYPE_RoQV);
00435 AddFilter(new CGraphCustomFilter(__uuidof(CRoQVideoDecoder), guids,
00436 (s.TraFilters&TRA_RV) ? L"RoQ Video Decoder" : L"RoQ Video Decoder (low merit)",
00437 (s.TraFilters&TRA_RV) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
00438 guids.RemoveAll();
00439 }
00440
00441 {
00442 guids.AddTail(MEDIATYPE_Audio);
00443 guids.AddTail(MEDIASUBTYPE_RoQA);
00444 AddFilter(new CGraphCustomFilter(__uuidof(CRoQAudioDecoder), guids,
00445 (s.TraFilters&TRA_RV) ? L"RoQ Audio Decoder" : L"RoQ Audio Decoder (low merit)",
00446 (s.TraFilters&TRA_RV) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
00447 guids.RemoveAll();
00448 }
00449
00450 {
00451 guids.AddTail(MEDIATYPE_Stream);
00452 guids.AddTail(MEDIASUBTYPE_Dirac);
00453 AddFilter(new CGraphCustomFilter(__uuidof(CDiracSplitterFilter), guids,
00454 (s.SrcFilters&SRC_DIRAC) ? L"Dirac Splitter" : L"Dirac Splitter (low merit)",
00455 (s.SrcFilters&SRC_DIRAC) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
00456 guids.RemoveAll();
00457 }
00458
00459 {
00460 guids.AddTail(MEDIATYPE_Video);
00461 guids.AddTail(MEDIASUBTYPE_DiracVideo);
00462 AddFilter(new CGraphCustomFilter(__uuidof(CDiracVideoDecoder), guids,
00463 (s.TraFilters&TRA_DIRAC) ? L"Dirac Video Decoder" : L"Dirac Video Decoder (low merit)",
00464 (s.TraFilters&TRA_DIRAC) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
00465 guids.RemoveAll();
00466 }
00467
00468 {
00469 guids.AddTail(MEDIATYPE_Stream);
00470 guids.AddTail(MEDIASUBTYPE_MPEG1Audio);
00471 AddFilter(new CGraphCustomFilter(__uuidof(CMpaSplitterFilter), guids,
00472 (s.SrcFilters&SRC_MPA) ? L"Mpa Splitter" : L"Mpa Splitter (low merit)",
00473 (s.SrcFilters&SRC_MPA) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
00474 guids.RemoveAll();
00475 }
00476
00477 {
00478 guids.AddTail(MEDIATYPE_Stream);
00479 guids.AddTail(MEDIASUBTYPE_DirectShowMedia);
00480 AddFilter(new CGraphCustomFilter(__uuidof(CDSMSplitterFilter), guids,
00481 (s.SrcFilters&SRC_DSM) ? L"DSM Splitter" : L"DSM Splitter (low merit)",
00482 (s.SrcFilters&SRC_DSM) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
00483 guids.RemoveAll();
00484 }
00485
00486 {
00487 guids.AddTail(MEDIATYPE_Stream);
00488 guids.AddTail(MEDIASUBTYPE_MP4);
00489 AddFilter(new CGraphCustomFilter(__uuidof(CMP4SplitterFilter), guids,
00490 (s.SrcFilters&SRC_MP4) ? L"MP4 Splitter" : L"MP4 Splitter (low merit)",
00491 (s.SrcFilters&SRC_MP4) ? LMERIT_ABOVE_DSHOW : LMERIT_DO_USE));
00492 guids.RemoveAll();
00493 }
00494
00495
00496
00497 switch(s.iDSVideoRendererType)
00498 {
00499 default:
00500 case VIDRNDT_DS_DEFAULT:
00501 break;
00502 case VIDRNDT_DS_OLDRENDERER:
00503 AddFilter(new CGraphRegFilter(CLSID_VideoRenderer, m_VRMerit));
00504 break;
00505 case VIDRNDT_DS_OVERLAYMIXER:
00506 AddFilter(new CGraphRendererFilter(CLSID_OverlayMixer, m_hWnd, L"Overlay Mixer", m_VRMerit));
00507 break;
00508 case VIDRNDT_DS_VMR7WINDOWED:
00509 AddFilter(new CGraphRendererFilter(CLSID_VideoMixingRenderer, m_hWnd, L"Video Mixing Render 7 (Windowed)", m_VRMerit));
00510 break;
00511 case VIDRNDT_DS_VMR9WINDOWED:
00512 AddFilter(new CGraphRendererFilter(CLSID_VideoMixingRenderer9, m_hWnd, L"Video Mixing Render 9 (Windowed)", m_VRMerit));
00513 break;
00514 case VIDRNDT_DS_VMR7RENDERLESS:
00515 AddFilter(new CGraphRendererFilter(CLSID_VMR7AllocatorPresenter, m_hWnd, L"Video Mixing Render 7 (Renderless)", m_VRMerit));
00516 break;
00517 case VIDRNDT_DS_VMR9RENDERLESS:
00518 AddFilter(new CGraphRendererFilter(CLSID_VMR9AllocatorPresenter, m_hWnd, L"Video Mixing Render 9 (Renderless)", m_VRMerit));
00519 break;
00520 case VIDRNDT_DS_NULL_COMP:
00521 guids.AddTail(MEDIATYPE_Video);
00522 guids.AddTail(MEDIASUBTYPE_NULL);
00523 AddFilter(new CGraphCustomFilter(__uuidof(CNullVideoRenderer), guids, L"Null Video Renderer (Any)", LMERIT_ABOVE_DSHOW+2));
00524 guids.RemoveAll();
00525 break;
00526 case VIDRNDT_DS_NULL_UNCOMP:
00527 guids.AddTail(MEDIATYPE_Video);
00528 guids.AddTail(MEDIASUBTYPE_NULL);
00529 AddFilter(new CGraphCustomFilter(__uuidof(CNullUVideoRenderer), guids, L"Null Video Renderer (Uncompressed)", LMERIT_ABOVE_DSHOW+2));
00530 guids.RemoveAll();
00531 break;
00532 }
00533
00534 if(s.AudioRendererDisplayName == AUDRNDT_NULL_COMP)
00535 {
00536 guids.AddTail(MEDIATYPE_Audio);
00537 guids.AddTail(MEDIASUBTYPE_NULL);
00538 AddFilter(new CGraphCustomFilter(__uuidof(CNullAudioRenderer), guids, AUDRNDT_NULL_COMP, LMERIT_ABOVE_DSHOW+2));
00539 guids.RemoveAll();
00540 }
00541 else if(s.AudioRendererDisplayName == AUDRNDT_NULL_UNCOMP)
00542 {
00543 guids.AddTail(MEDIATYPE_Audio);
00544 guids.AddTail(MEDIASUBTYPE_NULL);
00545 AddFilter(new CGraphCustomFilter(__uuidof(CNullUAudioRenderer), guids, AUDRNDT_NULL_UNCOMP, LMERIT_ABOVE_DSHOW+2));
00546 guids.RemoveAll();
00547 }
00548 else if(!s.AudioRendererDisplayName.IsEmpty())
00549 {
00550 AddFilter(new CGraphRegFilter(s.AudioRendererDisplayName, m_ARMerit));
00551 }
00552
00553 WORD lowmerit = 1;
00554 POSITION pos = s.filters.GetTailPosition();
00555 while(pos)
00556 {
00557 Filter* f = s.filters.GetPrev(pos);
00558
00559 if(f->fDisabled
00560 || f->type == Filter::EXTERNAL && !CPath(MakeFullPath(f->path)).FileExists())
00561 continue;
00562
00563 ULONGLONG merit =
00564 f->iLoadType == Filter::PREFERRED ? LMERIT_ABOVE_DSHOW :
00565 f->iLoadType == Filter::MERIT ? LMERIT(f->dwMerit) :
00566 LMERIT_DO_NOT_USE;
00567
00568 merit += lowmerit++;
00569
00570 CGraphFilter* gf = NULL;
00571
00572 if(f->type == Filter::REGISTERED)
00573 {
00574 gf = new CGraphRegFilter(f->dispname, merit);
00575 }
00576 else if(f->type == Filter::EXTERNAL)
00577 {
00578 gf = new CGraphFileFilter(f->clsid, f->guids, f->path, CStringW(f->name), merit);
00579 }
00580
00581 if(gf)
00582 {
00583 gf->SetGUIDs(f->guids);
00584 AddFilter(gf);
00585 }
00586 }
00587
00588 guids.AddTail(MEDIATYPE_Text);
00589 guids.AddTail(MEDIASUBTYPE_NULL);
00590 guids.AddTail(MEDIATYPE_ScriptCommand);
00591 guids.AddTail(MEDIASUBTYPE_NULL);
00592 guids.AddTail(MEDIATYPE_Subtitle);
00593 guids.AddTail(MEDIASUBTYPE_NULL);
00594 guids.AddTail(MEDIATYPE_NULL);
00595 guids.AddTail(MEDIASUBTYPE_DVD_SUBPICTURE);
00596 guids.AddTail(MEDIATYPE_NULL);
00597 guids.AddTail(MEDIASUBTYPE_CVD_SUBPICTURE);
00598 guids.AddTail(MEDIATYPE_NULL);
00599 guids.AddTail(MEDIASUBTYPE_SVCD_SUBPICTURE);
00600
00601 AddFilter(new CGraphCustomFilter(__uuidof(CNullTextRenderer), guids, L"NullTextRenderer", LMERIT_DO_USE));
00602 guids.RemoveAll();
00603
00604
00605
00606 CLSID CLSID_SubtitlerMixer = GUIDFromCString(_T("{00A95963-3BE5-48C0-AD9F-3356D67EA09D}"));
00607 AddFilter(new CGraphRegFilter(CLSID_SubtitlerMixer, LMERIT_DO_NOT_USE));
00608
00609
00610 AddFilter(new CGraphRegFilter(GUIDFromCString(_T("{48025243-2D39-11CE-875D-00608CB78066}")), LMERIT_DO_NOT_USE));
00611 }
00612
00613 CGraphBuilder::~CGraphBuilder()
00614 {
00615 }
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638 void CGraphBuilder::ExtractMediaTypes(IPin* pPin, CArray<GUID>& guids)
00639 {
00640 guids.RemoveAll();
00641
00642 BeginEnumMediaTypes(pPin, pEM, pmt)
00643 {
00644 bool fFound = false;
00645
00646 for(int i = 0; !fFound && i < guids.GetCount(); i += 2)
00647 {
00648 if(guids[i] == pmt->majortype && guids[i+1] == pmt->subtype)
00649 fFound = true;
00650 }
00651
00652 if(!fFound)
00653 {
00654 guids.Add(pmt->majortype);
00655 guids.Add(pmt->subtype);
00656 }
00657 }
00658 EndEnumMediaTypes(pmt)
00659 }
00660
00661 void CGraphBuilder::ExtractMediaTypes(IPin* pPin, CList<CMediaType>& mts)
00662 {
00663 mts.RemoveAll();
00664
00665 BeginEnumMediaTypes(pPin, pEM, pmt)
00666 {
00667 bool fFound = false;
00668
00669 POSITION pos = mts.GetHeadPosition();
00670 while(!fFound && pos)
00671 {
00672 CMediaType& mt = mts.GetNext(pos);
00673 if(mt.majortype == pmt->majortype && mt.subtype == pmt->subtype)
00674 fFound = true;
00675 }
00676
00677 if(!fFound)
00678 {
00679 mts.AddTail(CMediaType(*pmt));
00680 }
00681 }
00682 EndEnumMediaTypes(pmt)
00683 }
00684
00685 void CGraphBuilder::SaveFilters(CInterfaceList<IBaseFilter>& bfl)
00686 {
00687 bfl.RemoveAll();
00688 BeginEnumFilters(m_pGB, pEF, pBF)
00689 bfl.AddTail(pBF);
00690 EndEnumFilters
00691 }
00692
00693 void CGraphBuilder::RestoreFilters(CInterfaceList<IBaseFilter>& bfl)
00694 {
00695 BeginEnumFilters(m_pGB, pEF, pBF)
00696 if(!bfl.Find(pBF)) {m_pGB->RemoveFilter(pBF); pEF->Reset();}
00697 EndEnumFilters
00698 }
00699
00700 HRESULT CGraphBuilder::SafeAddFilter(IBaseFilter* pBF, LPCWSTR pName)
00701 {
00702 if(!m_pGB || !pBF)
00703 return E_FAIL;
00704
00705 bool fFound = false;
00706 BeginEnumFilters(m_pGB, pEF, pBF2)
00707 if(pBF == pBF2) fFound = true;
00708 EndEnumFilters
00709 if(fFound) return S_OK;
00710
00711 CFilterInfo fi;
00712 if(SUCCEEDED(pBF->QueryFilterInfo(&fi)))
00713 {
00714 if(!fi.pGraph)
00715 {
00716 CStringW name;
00717
00718 if(pName && wcslen(pName) > 0)
00719 {
00720 name = pName;
00721 }
00722 else
00723 {
00724 if(CComQIPtr<IFileSourceFilter> pFSF = pBF)
00725 {
00726 CMediaType mt;
00727 LPOLESTR str = NULL;
00728 if(SUCCEEDED(pFSF->GetCurFile(&str, &mt))) name = str;
00729 if(str) CoTaskMemFree(str);
00730 }
00731
00732 if(name.IsEmpty())
00733 {
00734 CLSID clsid = GetCLSID(pBF);
00735 name = clsid == GUID_NULL ? L"Unknown Filter" : CStringFromGUID(clsid);
00736 }
00737 }
00738
00739 if(FAILED(m_pGB->AddFilter(pBF, name)))
00740 {
00741 return E_FAIL;
00742 }
00743 }
00744
00745 return S_OK;
00746 }
00747
00748 return E_FAIL;
00749 }
00750
00751 void CGraphBuilder::Reset()
00752 {
00753 m_nTotalStreams = 0;
00754 m_nCurrentStream = 0;
00755 m_pUnks.RemoveAll();
00756 m_DeadEnds.RemoveAll();
00757
00758 }
00759
00760 HRESULT CGraphBuilder::AddSourceFilter(LPCTSTR lpsz, IBaseFilter** ppBF, UINT SrcFilters)
00761 {
00762 CheckPointer(lpsz, E_POINTER);
00763 CheckPointer(ppBF, E_POINTER);
00764
00765 if(!m_pGB) return E_UNEXPECTED;
00766
00767 CString fn = CString(lpsz).Trim();
00768 if(fn.IsEmpty()) return E_FAIL;
00769 CStringW fnw = fn;
00770 CString ext = CPath(fn).GetExtension().MakeLower();
00771
00772 HRESULT hr;
00773
00774 CComQIPtr<IBaseFilter> pBF;
00775
00776 CComQIPtr<IGraphEngine> pGE = m_pGB;
00777 if(!pGE || pGE->GetEngine() == DirectShow)
00778 {
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798 if((SrcFilters&SRC_SUBS) && !pBF)
00799 {
00800 hr = S_OK;
00801 CComPtr<IFileSourceFilter> pReader = new CSubtitleSourceASS(NULL, &hr);
00802 if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
00803 pBF = pReader;
00804 }
00805
00806 if((SrcFilters&SRC_CDDA) && !pBF && ext == _T(".cda"))
00807 {
00808 hr = S_OK;
00809 CComPtr<IFileSourceFilter> pReader = new CCDDAReader(NULL, &hr);
00810 if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
00811 pBF = pReader;
00812 }
00813
00814 if((SrcFilters&SRC_CDXA) && !pBF)
00815 {
00816 hr = S_OK;
00817 CComPtr<IFileSourceFilter> pReader = new CCDXAReader(NULL, &hr);
00818 if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
00819 pBF = pReader;
00820 }
00821
00822 if((SrcFilters&SRC_VTS) && !pBF)
00823 {
00824 hr = S_OK;
00825 CComPtr<IFileSourceFilter> pReader = new CVTSReader(NULL, &hr);
00826 if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
00827 pBF = pReader;
00828 }
00829
00830 if((SrcFilters&SRC_FLIC) && !pBF)
00831 {
00832 hr = S_OK;
00833 CComPtr<IFileSourceFilter> pReader = new CFLICSource(NULL, &hr);
00834 if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
00835 pBF = pReader;
00836 }
00837
00838 if((SrcFilters&SRC_D2V) && !pBF)
00839 {
00840 hr = S_OK;
00841 CComPtr<IFileSourceFilter> pReader = new CD2VSource(NULL, &hr);
00842 if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
00843 pBF = pReader;
00844 }
00845
00846 if((SrcFilters&SRC_DTSAC3) && !pBF)
00847 {
00848 hr = S_OK;
00849 CComPtr<IFileSourceFilter> pReader = new CDTSAC3Source(NULL, &hr);
00850 if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
00851 pBF = pReader;
00852 }
00853
00854 if((SrcFilters&SRC_SHOUTCAST) && !pBF && fn.Find(_T("://")) >= 0)
00855 {
00856 hr = S_OK;
00857 CComPtr<IFileSourceFilter> pReader = new CShoutcastSource(NULL, &hr);
00858 if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
00859 pBF = pReader;
00860 }
00861
00862 if((SrcFilters&SRC_MATROSKA) && !pBF)
00863 {
00864 hr = S_OK;
00865 CComPtr<IFileSourceFilter> pReader = new CMatroskaSourceFilter(NULL, &hr);
00866 if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
00867 pBF = pReader;
00868 }
00869
00870 if((SrcFilters&SRC_REALMEDIA) && !pBF)
00871 {
00872 hr = S_OK;
00873 CComPtr<IFileSourceFilter> pReader = new CRealMediaSourceFilter(NULL, &hr);
00874 if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
00875 pBF = pReader;
00876 }
00877
00878 if((SrcFilters&SRC_AVI) && !pBF)
00879 {
00880 hr = S_OK;
00881 CComPtr<IFileSourceFilter> pReader = new CAviSourceFilter(NULL, &hr);
00882 if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
00883 pBF = pReader;
00884 }
00885
00886 __if_exists(CRadGtSplitterFilter)
00887 {
00888 if((SrcFilters&SRC_RADGT) && !pBF)
00889 {
00890 hr = S_OK;
00891 CComPtr<IFileSourceFilter> pReader = new CRadGtSourceFilter(NULL, &hr);
00892 if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
00893 pBF = pReader;
00894 }
00895 }
00896
00897 if((SrcFilters&SRC_ROQ) && !pBF)
00898 {
00899 hr = S_OK;
00900 CComPtr<IFileSourceFilter> pReader = new CRoQSourceFilter(NULL, &hr);
00901 if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
00902 pBF = pReader;
00903 }
00904
00905 if((SrcFilters&SRC_OGG) && !pBF)
00906 {
00907 hr = S_OK;
00908 CComPtr<IFileSourceFilter> pReader = new COggSourceFilter(NULL, &hr);
00909 if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
00910 pBF = pReader;
00911 }
00912
00913 if((SrcFilters&SRC_NUT) && !pBF)
00914 {
00915 hr = S_OK;
00916 CComPtr<IFileSourceFilter> pReader = new CNutSourceFilter(NULL, &hr);
00917 if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
00918 pBF = pReader;
00919 }
00920
00921 if((SrcFilters&SRC_MPEG) && !pBF)
00922 {
00923 hr = S_OK;
00924 CComPtr<IFileSourceFilter> pReader = new CMpegSourceFilter(NULL, &hr);
00925 if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
00926 pBF = pReader;
00927 }
00928
00929 if((SrcFilters&SRC_DIRAC) && !pBF)
00930 {
00931 hr = S_OK;
00932 CComPtr<IFileSourceFilter> pReader = new CDiracSourceFilter(NULL, &hr);
00933 if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
00934 pBF = pReader;
00935 }
00936
00937 if((SrcFilters&SRC_MPA) && !pBF)
00938 {
00939 hr = S_OK;
00940 CComPtr<IFileSourceFilter> pReader = new CMpaSourceFilter(NULL, &hr);
00941 if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
00942 pBF = pReader;
00943 }
00944
00945 if((SrcFilters&SRC_DSM) && !pBF)
00946 {
00947 hr = S_OK;
00948 CComPtr<IFileSourceFilter> pReader = new CDSMSourceFilter(NULL, &hr);
00949 if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
00950 pBF = pReader;
00951 }
00952
00953 if((SrcFilters&SRC_MP4) && !pBF)
00954 {
00955 hr = S_OK;
00956 CComPtr<IFileSourceFilter> pReader = new CMP4SourceFilter(NULL, &hr);
00957 if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
00958 pBF = pReader;
00959 }
00960
00961 if(!pBF && fn.Find(_T("://")) < 0)
00962 {
00963 bool fWindowsMedia = (ext == _T(".asf") || ext == _T(".wmv") || ext == _T(".wma"));
00964
00965 if(!fWindowsMedia)
00966 {
00967 CFile f;
00968 if(f.Open(fn, CFile::modeRead))
00969 {
00970 BYTE buff[4];
00971 memset(buff, 0, sizeof(buff));
00972 f.Read(buff, sizeof(buff));
00973 if(*(DWORD*)buff == 0x75b22630)
00974 fWindowsMedia = true;
00975 }
00976 }
00977
00978 if(fWindowsMedia)
00979 {
00980 CComPtr<IFileSourceFilter> pReader;
00981 hr = pReader.CoCreateInstance(AfxGetAppSettings().fUseWMASFReader ? CLSID_WMAsfReader : CLSID_NetShowSource);
00982 if(SUCCEEDED(hr) && SUCCEEDED(pReader->Load(fnw, NULL)))
00983 pBF = pReader;
00984 }
00985 }
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011 }
01012
01013 if(!pBF)
01014 {
01015 CheckStupidSharedFilesourceFilter();
01016
01017 if(FAILED(hr = m_pGB->AddSourceFilter(fnw, fnw, &pBF)))
01018 return hr;
01019
01020 if(SUCCEEDED(hr) && !pBF)
01021 return hr;
01022 }
01023
01024 ASSERT(pBF);
01025
01026 if(FAILED(SafeAddFilter(pBF, NULL)))
01027 return E_FAIL;
01028
01029 *ppBF = pBF.Detach();
01030
01031 return S_OK;
01032 }
01033
01034 HRESULT CGraphBuilder::Render(LPCTSTR lpsz)
01035 {
01036 CComPtr<IBaseFilter> pBF;
01037
01038 HRESULT hr = AddSourceFilter(lpsz, &pBF, AfxGetAppSettings().SrcFilters & ~SRC_SUBS);
01039 if(FAILED(hr)) return hr;
01040
01041 return pBF ? Render(pBF) : S_OK;
01042 }
01043
01044 HRESULT CGraphBuilder::Render(IBaseFilter* pBF)
01045 {
01046 if(!m_pGB || !m_pFM || !pBF)
01047 return E_FAIL;
01048
01049 if(FAILED(SafeAddFilter(pBF, NULL)))
01050 return E_FAIL;
01051
01052 CInterfaceList<IPin> pOutputs;
01053 BeginEnumPins(pBF, pEP, pPin)
01054 {
01055 PIN_DIRECTION dir;
01056 CComPtr<IPin> pTmp;
01057 CPinInfo pi;
01058 if(FAILED(pPin->QueryDirection(&dir)) || dir != PINDIR_OUTPUT
01059 || SUCCEEDED(pPin->ConnectedTo(&pTmp))
01060 || FAILED(pPin->QueryPinInfo(&pi)) || pi.achName[0] == '~')
01061 continue;
01062
01063 pOutputs.AddTail(pPin);
01064 }
01065 EndEnumPins
01066
01067 int nRendered = 0;
01068
01069 if(pOutputs.GetCount() > 0)
01070 {
01071 POSITION pos = pOutputs.GetHeadPosition();
01072 while(pos)
01073 {
01074 if(SUCCEEDED(Render(pOutputs.GetNext(pos)))) nRendered++;
01075 if(pOutputs.GetCount() > 1) m_nCurrentStream++;
01076 }
01077 }
01078 else
01079 {
01080 m_nTotalStreams++;
01081
01082 for(int i = 0; i < m_DeadEnds.GetCount(); i++)
01083 {
01084 if(m_DeadEnds[i]->nStream == m_nCurrentStream)
01085 m_DeadEnds.RemoveAt(i--);
01086 }
01087 }
01088
01089 return
01090 nRendered == pOutputs.GetCount() ? (nRendered > 0 ? S_OK : S_FALSE) :
01091 nRendered > 0 ? VFW_S_PARTIAL_RENDER :
01092 VFW_E_CANNOT_RENDER;
01093 }
01094
01095 typedef struct {CGraphFilter* pFilter; bool fExactMatch;} SortFilter;
01096
01097 static int compare(const void* arg1, const void* arg2)
01098 {
01099 SortFilter* sf1 = (SortFilter*)arg1;
01100 SortFilter* sf2 = (SortFilter*)arg2;
01101
01102
01103
01104
01105
01106
01107
01108 if(sf1->pFilter->GetCLSID() == sf2->pFilter->GetCLSID())
01109 {
01110
01111 CGraphFileFilter* f1 = dynamic_cast<CGraphFileFilter*>(sf1->pFilter);
01112 CGraphFileFilter* f2 = dynamic_cast<CGraphFileFilter*>(sf2->pFilter);
01113 if(!f1 && f2) return 1;
01114 if(f1 && !f2) return -1;
01115 }
01116
01117 if(sf1->pFilter->GetMerit() < sf2->pFilter->GetMerit()) return 1;
01118 else if(sf1->pFilter->GetMerit() > sf2->pFilter->GetMerit()) return -1;
01119
01120 if(!sf1->fExactMatch && sf2->fExactMatch) return 1;
01121 else if(sf1->fExactMatch && !sf2->fExactMatch) return -1;
01122
01123 return 0;
01124 }
01125
01126 HRESULT CGraphBuilder::Render(IPin* pPin)
01127 {
01128 if(!m_pGB || !m_pFM || !pPin)
01129 return E_FAIL;
01130
01131 PIN_DIRECTION dir;
01132 CComPtr<IPin> pPinTmp;
01133 if(FAILED(pPin->QueryDirection(&dir)) || dir != PINDIR_OUTPUT
01134 || SUCCEEDED(pPin->ConnectedTo(&pPinTmp)))
01135 return E_UNEXPECTED;
01136
01137 if(GetCLSID(pPin) == CLSID_MPEG2Demultiplexer)
01138 {
01139 CComQIPtr<IMediaSeeking> pMS = pPin;
01140 if(!pMS) return E_FAIL;
01141 REFERENCE_TIME rtDur = 0;
01142 if(FAILED(pMS->GetDuration(&rtDur)) || rtDur <= 0)
01143 return E_FAIL;
01144 rtDur = rtDur;
01145 }
01146
01147 bool fDeadEnd = true;
01148
01149
01150
01151 if(CComQIPtr<IStreamBuilder> pSB = pPin)
01152 {
01153 CInterfaceList<IBaseFilter> bfl;
01154 SaveFilters(bfl);
01155
01156 if(SUCCEEDED(pSB->Render(pPin, m_pGB)))
01157 return S_OK;
01158
01159 pSB->Backout(pPin, m_pGB);
01160
01161 RestoreFilters(bfl);
01162 }
01163
01164
01165
01166 if(CComQIPtr<IGraphConfig> pGC = m_pGB)
01167 {
01168 CComPtr<IEnumFilters> pEF;
01169 if(SUCCEEDED(pGC->EnumCacheFilter(&pEF)))
01170 {
01171 for(CComPtr<IBaseFilter> pBF; S_OK == pEF->Next(1, &pBF, NULL); pBF = NULL)
01172 {
01173 CInterfaceList<IBaseFilter> bfl;
01174 SaveFilters(bfl);
01175
01176 pGC->RemoveFilterFromCache(pBF);
01177
01178 if(SUCCEEDED(ConnectDirect(pPin, pBF)))
01179 {
01180 fDeadEnd = false;
01181
01182 HRESULT hr;
01183 if(SUCCEEDED(hr = Render(pBF)))
01184 return hr;
01185 }
01186
01187 pGC->AddFilterToCache(pBF);
01188
01189 RestoreFilters(bfl);
01190 }
01191 }
01192 }
01193
01194
01195
01196 CInterfaceList<IBaseFilter> pFilters;
01197 SaveFilters(pFilters);
01198
01199 POSITION pos;
01200
01201
01202 if(!dynamic_cast<CGraphBuilderCapture*>(this))
01203 {
01204 pos = pFilters.GetHeadPosition();
01205 while(pos)
01206 {
01207 CComPtr<IBaseFilter> pBF = pFilters.GetNext(pos);
01208
01209 if(SUCCEEDED(ConnectDirect(pPin, pBF)))
01210 {
01211 fDeadEnd = false;
01212
01213 HRESULT hr;
01214 if(SUCCEEDED(hr = Render(pBF)))
01215 return hr;
01216 }
01217 }
01218 }
01219
01220
01221
01222
01223
01224 CArray<GUID> guids;
01225 ExtractMediaTypes(pPin, guids);
01226
01227 if(guids.GetCount() == 2 && guids[0] == MEDIATYPE_Stream && guids[1] == MEDIASUBTYPE_NULL)
01228 {
01229 if(CComQIPtr<IAsyncReader> pReader = pPin)
01230 {
01231 BYTE buff[4];
01232 if(S_OK == pReader->SyncRead(0, 4, buff) && *(DWORD*)buff == 'SggO')
01233 guids[1] = MEDIASUBTYPE_Ogg;
01234 }
01235 }
01236 else if(guids.GetCount() == 2 && guids[0] == MEDIATYPE_Video && guids[1] == FOURCCMap('MGXD'))
01237 {
01238 guids[1] = FOURCCMap('XVID');
01239 }
01240
01241 CAutoPtrList<CGraphFilter> autogfs;
01242 CArray<CGraphFilter*> gfs;
01243
01244 CComPtr<IEnumMoniker> pEM;
01245 if(guids.GetCount() > 0
01246 && SUCCEEDED(m_pFM->EnumMatchingFilters(
01247 &pEM, 0, FALSE, MERIT_DO_NOT_USE+1,
01248 TRUE, guids.GetCount()/2, guids.GetData(), NULL, NULL, FALSE,
01249 FALSE, 0, NULL, NULL, NULL)))
01250 {
01251 for(CComPtr<IMoniker> pMoniker; S_OK == pEM->Next(1, &pMoniker, NULL); pMoniker = NULL)
01252 {
01253 CAutoPtr<CGraphFilter> pGraphFilter(new CGraphRegFilter(pMoniker));
01254
01255 if(pGraphFilter)
01256 {
01257 POSITION pos = m_pMoreFilters.GetHeadPosition();
01258 while(pos)
01259 {
01260 CGraphRegFilter* f = dynamic_cast<CGraphRegFilter*>((CGraphFilter*)m_pMoreFilters.GetNext(pos));
01261 if(!f) continue;
01262
01263 if(f->GetMoniker() && S_OK == pMoniker->IsEqual(f->GetMoniker())
01264 || f->GetCLSID() != GUID_NULL && f->GetCLSID() == pGraphFilter->GetCLSID())
01265 {
01266 pGraphFilter.Free();
01267 break;
01268 }
01269 }
01270 }
01271
01272 if(pGraphFilter)
01273 {
01274 autogfs.AddTail(pGraphFilter);
01275 }
01276 }
01277 }
01278
01279 pos = autogfs.GetHeadPosition();
01280 while(pos)
01281 {
01282 CGraphFilter* f = autogfs.GetNext(pos);
01283
01284 bool fFound = false;
01285
01286 POSITION pos2 = m_chain.GetHeadPosition();
01287 while(pos2)
01288 {
01289 if(f->GetCLSID() == m_chain.GetNext(pos2)->GetCLSID())
01290 {
01291 fFound = true;
01292 break;
01293 }
01294 }
01295
01296 if(!fFound)
01297 gfs.Add(f);
01298 }
01299
01300 pos = m_pMoreFilters.GetHeadPosition();
01301 while(pos)
01302 {
01303 CGraphFilter* f = m_pMoreFilters.GetNext(pos);
01304 if(f->GetMerit() >= LMERIT_DO_USE && !m_chain.Find(f) && f->IsCompatible(guids))
01305 gfs.Add(f);
01306 }
01307
01308 CArray<SortFilter> sfs;
01309 sfs.SetSize(gfs.GetCount());
01310 for(int i = 0; i < gfs.GetCount(); i++)
01311 {
01312 sfs[i].pFilter = gfs[i];
01313 sfs[i].fExactMatch = gfs[i]->IsExactMatch(guids);
01314 }
01315 if(sfs.GetCount() > 1) qsort(sfs.GetData(), sfs.GetCount(), sizeof(SortFilter), compare);
01316
01317 for(int i = 0; i < sfs.GetCount(); i++)
01318 {
01319 CGraphFilter* gf = sfs[i].pFilter;
01320 if(!gf) continue;
01321
01322 CComPtr<IBaseFilter> pBF;
01323 CComPtr<IUnknown> pUnk;
01324 if(FAILED(gf->Create(&pBF, &pUnk)))
01325 continue;
01326
01327 CInterfaceList<IBaseFilter> bfl;
01328 SaveFilters(bfl);
01329
01330 if(FAILED(SafeAddFilter(pBF, gf->GetName())))
01331 continue;
01332
01333 if(gf->GetCLSID() == CLSID_DMOWrapperFilter)
01334 {
01335 if(CComQIPtr<IPropertyBag> pPBag = pBF)
01336 {
01337 CComVariant var(true);
01338 pPBag->Write(CComBSTR(L"_HIRESOUTPUT"), &var);
01339 }
01340 }
01341
01342 if(CComQIPtr<IMpeg2DecFilter> m_pMpeg2DecFilter = pBF)
01343 {
01344 AppSettings& s = AfxGetAppSettings();
01345 m_pMpeg2DecFilter->SetDeinterlaceMethod((ditype)s.mpegdi);
01346 m_pMpeg2DecFilter->SetBrightness(s.mpegbright);
01347 m_pMpeg2DecFilter->SetContrast(s.mpegcont);
01348 m_pMpeg2DecFilter->SetHue(s.mpeghue);
01349 m_pMpeg2DecFilter->SetSaturation(s.mpegsat);
01350 m_pMpeg2DecFilter->EnableForcedSubtitles(s.mpegforcedsubs);
01351 m_pMpeg2DecFilter->EnablePlanarYUV(s.mpegplanaryuv);
01352 }
01353
01354 if(CComQIPtr<IMpaDecFilter> m_pMpaDecFilter = pBF)
01355 {
01356 AppSettings& s = AfxGetAppSettings();
01357 m_pMpaDecFilter->SetSampleFormat((SampleFormat)s.mpasf);
01358 m_pMpaDecFilter->SetNormalize(s.mpanormalize);
01359 m_pMpaDecFilter->SetSpeakerConfig(IMpaDecFilter::ac3, s.ac3sc);
01360 m_pMpaDecFilter->SetDynamicRangeControl(IMpaDecFilter::ac3, s.ac3drc);
01361 m_pMpaDecFilter->SetSpeakerConfig(IMpaDecFilter::dts, s.dtssc);
01362 m_pMpaDecFilter->SetDynamicRangeControl(IMpaDecFilter::dts, s.dtsdrc);
01363 m_pMpaDecFilter->SetSpeakerConfig(IMpaDecFilter::aac, s.aacsc);
01364 m_pMpaDecFilter->SetBoost(s.mpaboost);
01365 }
01366
01367 HRESULT hr = E_FAIL;
01368
01369 if(guids.GetCount() == 2 && guids[0] == MEDIATYPE_Stream && guids[1] != MEDIATYPE_NULL)
01370 {
01371 CMediaType mt;
01372 mt.majortype = guids[0];
01373 mt.subtype = guids[1];
01374 mt.formattype = FORMAT_None;
01375 hr = ConnectDirect(pPin, pBF, &mt);
01376
01377 if(FAILED(hr))
01378 {
01379 mt.formattype = GUID_NULL;
01380 hr = ConnectDirect(pPin, pBF, &mt);
01381 }
01382 }
01383
01384 if(SUCCEEDED(hr) || SUCCEEDED(ConnectDirect(pPin, pBF, NULL)))
01385 {
01386 fDeadEnd = false;
01387
01388 int nCurrentStream = m_nCurrentStream;
01389
01390 m_chain.AddTail(gf);
01391
01392 hr = Render(pBF);
01393
01394 m_chain.RemoveTail();
01395
01396 if(SUCCEEDED(hr))
01397 {
01398 if(pUnk) m_pUnks.AddTail(pUnk);
01399
01400
01401 if(CComQIPtr<IMixerPinConfig, &IID_IMixerPinConfig> pMPC = pUnk)
01402 pMPC->SetAspectRatioMode(AM_ARMODE_STRETCHED);
01403 if(CComQIPtr<IVMRAspectRatioControl> pARC = pBF)
01404 pARC->SetAspectRatioMode(VMR_ARMODE_NONE);
01405 if(CComQIPtr<IVMRAspectRatioControl9> pARC = pBF)
01406 pARC->SetAspectRatioMode(VMR_ARMODE_NONE);
01407
01408 return hr;
01409 }
01410
01411 m_nCurrentStream = nCurrentStream;
01412 }
01413
01414 m_pGB->RemoveFilter(pBF);
01415
01416 RestoreFilters(bfl);
01417 }
01418
01419
01420
01421 if(fDeadEnd)
01422 {
01423 CAutoPtr<DeadEnd> de(new DeadEnd);
01424 de->nStream = m_nCurrentStream;
01425 de->clsid = CStringFromGUID(GetCLSID(pPin));
01426 de->filter = GetFilterName(GetFilterFromPin(pPin));
01427 de->pin = GetPinName(pPin);
01428 ExtractMediaTypes(pPin, de->mts);
01429 if(!(m_chain.GetCount() == 0 && de->mts.GetCount() == 1
01430 && de->mts.GetHead().majortype == MEDIATYPE_Stream && de->mts.GetHead().subtype == MEDIASUBTYPE_NULL))
01431 {
01432 CString str;
01433 str.Format(_T("Stream %d"), m_nCurrentStream);
01434 de->path.AddTail(str);
01435 POSITION pos = m_chain.GetHeadPosition();
01436 while(pos) de->path.AddTail(CString(m_chain.GetNext(pos)->GetName()));
01437 m_DeadEnds.Add(de);
01438 }
01439 }
01440
01441 return E_FAIL;
01442 }
01443
01444 HRESULT CGraphBuilder::ConnectDirect(IPin* pPin, IBaseFilter* pBF, const AM_MEDIA_TYPE* pmt)
01445 {
01446 if(!pPin || !pBF)
01447 return E_INVALIDARG;
01448
01449 if(FAILED(SafeAddFilter(pBF, NULL)))
01450 return E_FAIL;
01451
01452 BeginEnumPins(pBF, pEP, pPinTo)
01453 {
01454 PIN_DIRECTION dir;
01455 CComPtr<IPin> pTmp;
01456 if(FAILED(pPinTo->QueryDirection(&dir)) || dir != PINDIR_INPUT
01457 || SUCCEEDED(pPinTo->ConnectedTo(&pTmp)))
01458 continue;
01459
01460 if(SUCCEEDED(m_pGB->ConnectDirect(pPin, pPinTo, pmt)))
01461 return S_OK;
01462 }
01463 EndEnumPins
01464
01465 return VFW_E_CANNOT_CONNECT;
01466 }
01467
01468 HRESULT CGraphBuilder::FindInterface(REFIID iid, void** ppv)
01469 {
01470 CheckPointer(ppv, E_POINTER);
01471
01472 POSITION pos = m_pUnks.GetHeadPosition();
01473 while(pos)
01474 {
01475 IUnknown* pUnk = m_pUnks.GetNext(pos);
01476 HRESULT hr;
01477 if(SUCCEEDED(hr = pUnk->QueryInterface(iid, ppv)))
01478 return hr;
01479 }
01480
01481 return E_NOINTERFACE;
01482 }
01483
01484
01485
01486
01487
01488 CGraphBuilderFile::CGraphBuilderFile(IGraphBuilder* pGB, HWND hWnd)
01489 : CGraphBuilder(pGB, hWnd)
01490 {
01491 CList<GUID> guids;
01492
01493 if(AfxGetAppSettings().fEnableAudioSwitcher)
01494 {
01495 guids.AddTail(MEDIATYPE_Audio);
01496 guids.AddTail(MEDIASUBTYPE_NULL);
01497 AddFilter(new CGraphCustomFilter(__uuidof(CAudioSwitcherFilter), guids, L"Audio Switcher", m_ARMerit + 0x100));
01498 guids.RemoveAll();
01499
01500 CLSID CLSID_MorganStreamSwitcher = GUIDFromCString(_T("{D3CD7858-971A-4838-ACEC-40CA5D529DC8}"));
01501 AddFilter(new CGraphRegFilter(CLSID_MorganStreamSwitcher, LMERIT_DO_NOT_USE));
01502 }
01503 }
01504
01505
01506
01507
01508
01509 CGraphBuilderDVD::CGraphBuilderDVD(IGraphBuilder* pGB, HWND hWnd)
01510 : CGraphBuilderFile(pGB, hWnd)
01511 {
01512 CList<GUID> guids;
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523 DWORD ver = ::GetVersion();
01524 bool m_fXp = (int)ver >= 0 && (((ver<<8)&0xff00)|((ver>>8)&0xff)) >= 0x0501;
01525
01526 AppSettings& s = AfxGetAppSettings();
01527 if(!m_fXp && s.iDSVideoRendererType != VIDRNDT_DS_OVERLAYMIXER
01528 || s.iDSVideoRendererType == VIDRNDT_DS_OLDRENDERER)
01529 AddFilter(new CGraphRendererFilter(CLSID_OverlayMixer, m_hWnd, L"Overlay Mixer", m_VRMerit-1));
01530
01531
01532 CLSID CLSID_ElecardMpeg2 = GUIDFromCString(_T("{F50B3F13-19C4-11CF-AA9A-02608C9BABA2}"));
01533 AddFilter(new CGraphRegFilter(CLSID_ElecardMpeg2, LMERIT_DO_NOT_USE));
01534 }
01535
01536 #include "..\..\decss\VobFile.h"
01537
01538 class CResetDVD : public CDVDSession
01539 {
01540 public:
01541 CResetDVD(LPCTSTR path)
01542 {
01543 if(Open(path))
01544 {
01545 if(BeginSession())
01546 {
01547 Authenticate();
01548
01549 EndSession();
01550 }
01551
01552 Close();
01553 }
01554 }
01555 };
01556
01557 [uuid("482d10b6-376e-4411-8a17-833800A065DB")]
01558 class ratDVDNavigator {};
01559
01560 HRESULT CGraphBuilderDVD::Render(CString fn, CString& path)
01561 {
01562 if(!m_pGB) return E_INVALIDARG;
01563
01564 HRESULT hr;
01565
01566 GUID clsid = CLSID_DVDNavigator;
01567 if(fn.MakeLower().Find(_T(".ratdvd")) >= 0)
01568 clsid = __uuidof(ratDVDNavigator);
01569
01570 CComPtr<IBaseFilter> pBF;
01571 if(FAILED(hr = pBF.CoCreateInstance(clsid)))
01572 return E_FAIL;
01573
01574 if(FAILED(hr = m_pGB->AddFilter(pBF, L"DVD Navigator")))
01575 return VFW_E_CANNOT_LOAD_SOURCE_FILTER;
01576
01577 CComQIPtr<IDvdControl2> pDVDC;
01578 CComQIPtr<IDvdInfo2> pDVDI;
01579
01580 if(!((pDVDC = pBF) && (pDVDI = pBF)))
01581 return E_NOINTERFACE;
01582
01583 WCHAR buff[MAX_PATH];
01584 ULONG len;
01585 if((!fn.IsEmpty()
01586 && FAILED(hr = pDVDC->SetDVDDirectory(CStringW(fn)))
01587 && FAILED(hr = pDVDC->SetDVDDirectory(CStringW(fn + _T("VIDEO_TS"))))
01588 && FAILED(hr = pDVDC->SetDVDDirectory(CStringW(fn + _T("\\VIDEO_TS")))))
01589 || FAILED(hr = pDVDI->GetDVDDirectory(buff, MAX_PATH, &len)) || len == 0)
01590 return VFW_E_CANNOT_LOAD_SOURCE_FILTER;
01591
01592 path = buff;
01593
01594 pDVDC->SetOption(DVD_ResetOnStop, FALSE);
01595 pDVDC->SetOption(DVD_HMSF_TimeCodeEvents, TRUE);
01596
01597 m_pUnks.AddTail(pDVDC);
01598 m_pUnks.AddTail(pDVDI);
01599
01600 if(clsid == CLSID_DVDNavigator)
01601 CResetDVD tmp(path);
01602
01603 return __super::Render(pBF);
01604 }
01605
01606
01607
01608
01609
01610 CGraphBuilderCapture::CGraphBuilderCapture(IGraphBuilder* pGB, HWND hWnd)
01611 : CGraphBuilderFile(pGB, hWnd)
01612 {
01613 CList<GUID> guids;
01614
01615
01616 {
01617 guids.AddTail(MEDIATYPE_Video);
01618 guids.AddTail(MEDIASUBTYPE_NULL);
01619 AddFilter(new CGraphCustomFilter(__uuidof(CDeinterlacerFilter), guids, L"Deinterlacer", m_VRMerit + 0x100));
01620 guids.RemoveAll();
01621 }
01622
01623 CLSID CLSID_MorganStreamSwitcher = GUIDFromCString(_T("{D3CD7858-971A-4838-ACEC-40CA5D529DC8}"));
01624 AddFilter(new CGraphRegFilter(CLSID_MorganStreamSwitcher, LMERIT_DO_NOT_USE));
01625 }
01626
01627
01628
01629
01630
01631 CGraphFilter::CGraphFilter(CStringW name, ULONGLONG merit)
01632 : m_name(name), m_clsid(GUID_NULL)
01633 {
01634 m_merit.val = merit;
01635 }
01636
01637 bool CGraphFilter::IsExactMatch(CArray<GUID>& guids)
01638 {
01639 POSITION pos = m_guids.GetHeadPosition();
01640 while(pos)
01641 {
01642 GUID& major = m_guids.GetNext(pos);
01643 if(!pos) {ASSERT(0); break;}
01644 GUID& sub = m_guids.GetNext(pos);
01645
01646 for(int i = 0; i < (guids.GetCount()&~1); i += 2)
01647 {
01648 if(major == guids[i] && major != GUID_NULL
01649 && sub == guids[i+1] && sub != GUID_NULL)
01650 return(true);
01651 }
01652 }
01653
01654 return(false);
01655 }
01656
01657 bool CGraphFilter::IsCompatible(CArray<GUID>& guids)
01658 {
01659 POSITION pos = m_guids.GetHeadPosition();
01660 while(pos)
01661 {
01662 GUID& major = m_guids.GetNext(pos);
01663 if(!pos) {ASSERT(0); break;}
01664 GUID& sub = m_guids.GetNext(pos);
01665
01666 for(int i = 0; i < (guids.GetCount()&~1); i += 2)
01667 {
01668 if((major == GUID_NULL || guids[i] == GUID_NULL || major == guids[i])
01669 && (sub == GUID_NULL || guids[i+1] == GUID_NULL || sub == guids[i+1]))
01670 return(true);
01671 }
01672 }
01673
01674 return(false);
01675 }
01676
01677
01678
01679
01680
01681 CGraphRegFilter::CGraphRegFilter(IMoniker* pMoniker, ULONGLONG merit)
01682 : CGraphFilter(L"", merit), m_pMoniker(pMoniker)
01683 {
01684 if(!m_pMoniker) return;
01685
01686 LPOLESTR str = NULL;
01687 if(FAILED(m_pMoniker->GetDisplayName(0, 0, &str))) return;
01688 m_dispname = m_name = str;
01689 CoTaskMemFree(str), str = NULL;
01690
01691 CComPtr<IPropertyBag> pPB;
01692 if(SUCCEEDED(m_pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pPB)))
01693 {
01694 CComVariant var;
01695 if(SUCCEEDED(pPB->Read(CComBSTR(_T("FriendlyName")), &var, NULL)))
01696 {
01697 m_name = var.bstrVal;
01698 var.Clear();
01699 }
01700
01701 if(SUCCEEDED(pPB->Read(CComBSTR(_T("CLSID")), &var, NULL)))
01702 {
01703 CLSIDFromString(var.bstrVal, &m_clsid);
01704 var.Clear();
01705 }
01706
01707 if(SUCCEEDED(pPB->Read(CComBSTR(_T("FilterData")), &var, NULL)))
01708 {
01709 BSTR* pstr;
01710 if(SUCCEEDED(SafeArrayAccessData(var.parray, (void**)&pstr)))
01711 {
01712 ExtractFilterData((BYTE*)pstr, var.parray->cbElements*(var.parray->rgsabound[0].cElements));
01713 SafeArrayUnaccessData(var.parray);
01714 }
01715 var.Clear();
01716 }
01717 }
01718
01719 if(merit != LMERIT_DO_USE) m_merit.val = merit;
01720 }
01721
01722 CGraphRegFilter::CGraphRegFilter(CStringW m_dispname, ULONGLONG merit)
01723 : CGraphFilter(L"", merit), m_dispname(m_dispname)
01724 {
01725 if(m_dispname.IsEmpty()) return;
01726
01727 CComPtr<IBindCtx> pBC;
01728 CreateBindCtx(0, &pBC);
01729
01730 ULONG chEaten;
01731 if(S_OK != MkParseDisplayName(pBC, CComBSTR(m_dispname), &chEaten, &m_pMoniker))
01732 return;
01733
01734 CComPtr<IPropertyBag> pPB;
01735 if(SUCCEEDED(m_pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pPB)))
01736 {
01737 CComVariant var;
01738 if(SUCCEEDED(pPB->Read(CComBSTR(_T("FriendlyName")), &var, NULL)))
01739 {
01740 m_name = var.bstrVal;
01741 var.Clear();
01742 }
01743
01744 if(SUCCEEDED(pPB->Read(CComBSTR(_T("CLSID")), &var, NULL)))
01745 {
01746 CLSIDFromString(var.bstrVal, &m_clsid);
01747 var.Clear();
01748 }
01749
01750 if(SUCCEEDED(pPB->Read(CComBSTR(_T("FilterData")), &var, NULL)))
01751 {
01752 BSTR* pstr;
01753 if(SUCCEEDED(SafeArrayAccessData(var.parray, (void**)&pstr)))
01754 {
01755 ExtractFilterData((BYTE*)pstr, var.parray->cbElements*(var.parray->rgsabound[0].cElements));
01756 SafeArrayUnaccessData(var.parray);
01757 }
01758 var.Clear();
01759 }
01760 }
01761
01762 if(merit != LMERIT_DO_USE) m_merit.val = merit;
01763 }
01764
01765 CGraphRegFilter::CGraphRegFilter(const CLSID& clsid, ULONGLONG merit)
01766 : CGraphFilter(L"", merit)
01767 {
01768 if((m_clsid = clsid) == GUID_NULL) return;
01769
01770 CString guid = CStringFromGUID(m_clsid);
01771 CString str = CString(_T("CLSID\\{083863F1-70DE-11d0-BD40-00A0C911CE86}\\Instance\\")) + guid;
01772 CString str2 = CString(_T("CLSID\\")) + guid;
01773
01774 CRegKey key;
01775
01776 if(ERROR_SUCCESS == key.Open(HKEY_CLASSES_ROOT, str2, KEY_READ))
01777 {
01778 ULONG nChars = 0;
01779 if(ERROR_SUCCESS == key.QueryStringValue(NULL, NULL, &nChars))
01780 {
01781 CString name;
01782 if(ERROR_SUCCESS == key.QueryStringValue(NULL, name.GetBuffer(nChars), &nChars))
01783 {
01784 name.ReleaseBuffer(nChars);
01785 m_name = name;
01786 }
01787 }
01788
01789 key.Close();
01790 }
01791
01792 if(ERROR_SUCCESS == key.Open(HKEY_CLASSES_ROOT, str, KEY_READ))
01793 {
01794 ULONG nChars = 0;
01795 if(ERROR_SUCCESS == key.QueryStringValue(_T("FriendlyName"), NULL, &nChars))
01796 {
01797 CString name;
01798 if(ERROR_SUCCESS == key.QueryStringValue(_T("FriendlyName"), name.GetBuffer(nChars), &nChars))
01799 {
01800 name.ReleaseBuffer(nChars);
01801 m_name = name;
01802 }
01803 }
01804
01805 ULONG nBytes = 0;
01806 if(ERROR_SUCCESS == key.QueryBinaryValue(_T("FilterData"), NULL, &nBytes))
01807 {
01808 CAutoVectorPtr<BYTE> buff;
01809 if(buff.Allocate(nBytes) && ERROR_SUCCESS == key.QueryBinaryValue(_T("FilterData"), buff, &nBytes))
01810 {
01811 ExtractFilterData(buff, nBytes);
01812 }
01813 }
01814
01815 key.Close();
01816 }
01817
01818 if(merit != LMERIT_DO_USE) m_merit.val = merit;
01819 }
01820
01821 [uuid("97f7c4d4-547b-4a5f-8332-536430ad2e4d")]
01822 interface IAMFilterData : public IUnknown
01823 {
01824 STDMETHOD (ParseFilterData) (BYTE* rgbFilterData, ULONG cb, BYTE** prgbRegFilter2) PURE;
01825 STDMETHOD (CreateFilterData) (REGFILTER2* prf2, BYTE** prgbFilterData, ULONG* pcb) PURE;
01826 };
01827
01828 void CGraphRegFilter::ExtractFilterData(BYTE* p, UINT len)
01829 {
01830 CComPtr<IAMFilterData> pFD;
01831 BYTE* ptr = NULL;
01832
01833 if(SUCCEEDED(pFD.CoCreateInstance(CLSID_FilterMapper2))
01834 && SUCCEEDED(pFD->ParseFilterData(p, len, (BYTE**)&ptr)))
01835 {
01836 REGFILTER2* prf = (REGFILTER2*)*(DWORD*)ptr;
01837
01838 m_merit.mid = prf->dwMerit;
01839
01840 if(prf->dwVersion == 1)
01841 {
01842 for(UINT i = 0; i < prf->cPins; i++)
01843 {
01844 if(prf->rgPins[i].bOutput)
01845 continue;
01846
01847 for(UINT j = 0; j < prf->rgPins[i].nMediaTypes; j++)
01848 {
01849 if(!prf->rgPins[i].lpMediaType[j].clsMajorType || !prf->rgPins[i].lpMediaType[j].clsMinorType)
01850 break;
01851 m_guids.AddTail(*(GUID*)prf->rgPins[i].lpMediaType[j].clsMajorType);
01852 m_guids.AddTail(*(GUID*)prf->rgPins[i].lpMediaType[j].clsMinorType);
01853 }
01854 }
01855 }
01856 else if(prf->dwVersion == 2)
01857 {
01858 for(UINT i = 0; i < prf->cPins2; i++)
01859 {
01860 if(prf->rgPins2[i].dwFlags®_PINFLAG_B_OUTPUT)
01861 continue;
01862
01863 for(UINT j = 0; j < prf->rgPins2[i].nMediaTypes; j++)
01864 {
01865 if(!prf->rgPins2[i].lpMediaType[j].clsMajorType || !prf->rgPins2[i].lpMediaType[j].clsMinorType)
01866 break;
01867 m_guids.AddTail(*(GUID*)prf->rgPins2[i].lpMediaType[j].clsMajorType);
01868 m_guids.AddTail(*(GUID*)prf->rgPins2[i].lpMediaType[j].clsMinorType);
01869 }
01870 }
01871 }
01872
01873 CoTaskMemFree(prf);
01874 }
01875 else
01876 {
01877 BYTE* base = p;
01878
01879 #define ChkLen(size) if(p - base + size > (int)len) return;
01880
01881 ChkLen(4)
01882 if(*(DWORD*)p != 0x00000002) return;
01883 p += 4;
01884
01885 ChkLen(4)
01886 m_merit.mid = *(DWORD*)p; p += 4;
01887
01888 m_guids.RemoveAll();
01889
01890 ChkLen(8)
01891 DWORD nPins = *(DWORD*)p; p += 8;
01892 while(nPins-- > 0)
01893 {
01894 ChkLen(1)
01895 BYTE n = *p-0x30; p++;
01896 ChkLen(2)
01897 WORD pi = *(WORD*)p; p += 2;
01898 ASSERT(pi == 'ip');
01899 ChkLen(1)
01900 BYTE x33 = *p; p++;
01901 ASSERT(x33 == 0x33);
01902 ChkLen(8)
01903 bool fOutput = !!(*p®_PINFLAG_B_OUTPUT);
01904 p += 8;
01905 ChkLen(12)
01906 DWORD nTypes = *(DWORD*)p; p += 12;
01907 while(nTypes-- > 0)
01908 {
01909 ChkLen(1)
01910 BYTE n = *p-0x30; p++;
01911 ChkLen(2)
01912 WORD ty = *(WORD*)p; p += 2;
01913 ASSERT(ty == 'yt');
01914 ChkLen(5)
01915 BYTE x33 = *p; p++;
01916 ASSERT(x33 == 0x33);
01917 p += 4;
01918
01919 ChkLen(8)
01920 if(*(DWORD*)p < (p-base+8) || *(DWORD*)p >= len
01921 || *(DWORD*)(p+4) < (p-base+8) || *(DWORD*)(p+4) >= len)
01922 {
01923 p += 8;
01924 continue;
01925 }
01926
01927 GUID guid;
01928 memcpy(&guid, &base[*(DWORD*)p], sizeof(GUID)); p += 4;
01929 if(!fOutput) m_guids.AddTail(guid);
01930 memcpy(&guid, &base[*(DWORD*)p], sizeof(GUID)); p += 4;
01931 if(!fOutput) m_guids.AddTail(guid);
01932 }
01933 }
01934
01935 #undef ChkLen
01936
01937 }
01938
01939
01940
01941
01942
01943
01944 }
01945
01946 HRESULT CGraphRegFilter::Create(IBaseFilter** ppBF, IUnknown** ppUnk)
01947 {
01948 CheckPointer(ppBF, E_POINTER);
01949
01950 if(ppUnk) *ppUnk = NULL;
01951
01952 HRESULT hr = E_FAIL;
01953
01954
01955 if(m_pMoniker)
01956 {
01957 if(SUCCEEDED(hr = m_pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)ppBF)))
01958 m_clsid = ::GetCLSID(*ppBF);
01959 }
01960 else if(m_clsid != GUID_NULL)
01961 {
01962 CComPtr<IBaseFilter> pBF;
01963 if(FAILED(pBF.CoCreateInstance(m_clsid))) return E_FAIL;
01964 *ppBF = pBF.Detach();
01965 hr = S_OK;
01966 }
01967
01968 return hr;
01969 };
01970
01971
01972
01973
01974
01975 CGraphCustomFilter::CGraphCustomFilter(const CLSID& clsid, CList<GUID>& guids, CStringW name, ULONGLONG merit)
01976 : CGraphFilter(name, merit)
01977 {
01978 m_clsid = clsid;
01979 ASSERT(guids.GetCount() > 0);
01980 m_guids.AddTail(&guids);
01981 }
01982
01983 HRESULT CGraphCustomFilter::Create(IBaseFilter** ppBF, IUnknown** ppUnk)
01984 {
01985 CheckPointer(ppBF, E_POINTER);
01986
01987 if(ppUnk) *ppUnk = NULL;
01988
01989 HRESULT hr = S_OK;
01990
01991 *ppBF =
01992 m_clsid == __uuidof(CAVI2AC3Filter) ? (IBaseFilter*)new CAVI2AC3Filter(NULL, &hr) :
01993 m_clsid == __uuidof(CDeCSSFilter) ? (IBaseFilter*)new CDeCSSFilter(NULL, &hr) :
01994 m_clsid == __uuidof(CAudioSwitcherFilter) ? (IBaseFilter*)new CAudioSwitcherFilter(NULL, &hr) :
01995 m_clsid == __uuidof(CMatroskaSplitterFilter) ? (IBaseFilter*)new CMatroskaSplitterFilter(NULL, &hr) :
01996 m_clsid == __uuidof(CRealMediaSplitterFilter) ? (IBaseFilter*)new CRealMediaSplitterFilter(NULL, &hr) :
01997 m_clsid == __uuidof(CRealVideoDecoder) ? (IBaseFilter*)new CRealVideoDecoder(NULL, &hr) :
01998 m_clsid == __uuidof(CRealAudioDecoder) ? (IBaseFilter*)new CRealAudioDecoder(NULL, &hr) :
01999 m_clsid == __uuidof(CRoQVideoDecoder) ? (IBaseFilter*)new CRoQVideoDecoder(NULL, &hr) :
02000 m_clsid == __uuidof(CRoQAudioDecoder) ? (IBaseFilter*)new CRoQAudioDecoder(NULL, &hr) :
02001 m_clsid == __uuidof(CAviSplitterFilter) ? (IBaseFilter*)new CAviSplitterFilter(NULL, &hr) :
02002 m_clsid == __uuidof(CRoQSplitterFilter) ? (IBaseFilter*)new CRoQSplitterFilter(NULL, &hr) :
02003 m_clsid == __uuidof(COggSplitterFilter) ? (IBaseFilter*)new COggSplitterFilter(NULL, &hr) :
02004 m_clsid == __uuidof(CNutSplitterFilter) ? (IBaseFilter*)new CNutSplitterFilter(NULL, &hr) :
02005 m_clsid == __uuidof(CMpegSplitterFilter) ? (IBaseFilter*)new CMpegSplitterFilter(NULL, &hr) :
02006 m_clsid == __uuidof(CMpeg2DecFilter) ? (IBaseFilter*)new CMpeg2DecFilter(NULL, &hr) :
02007 m_clsid == __uuidof(CDiracSplitterFilter) ? (IBaseFilter*)new CDiracSplitterFilter(NULL, &hr) :
02008 m_clsid == __uuidof(CDiracVideoDecoder) ? (IBaseFilter*)new CDiracVideoDecoder(NULL, &hr) :
02009 m_clsid == __uuidof(CMpaSplitterFilter) ? (IBaseFilter*)new CMpaSplitterFilter(NULL, &hr) :
02010 m_clsid == __uuidof(CMpaDecFilter) ? (IBaseFilter*)new CMpaDecFilter(NULL, &hr) :
02011 m_clsid == __uuidof(CDSMSplitterFilter) ? (IBaseFilter*)new CDSMSplitterFilter(NULL, &hr) :
02012 m_clsid == __uuidof(CMP4SplitterFilter) ? (IBaseFilter*)new CMP4SplitterFilter(NULL, &hr) :
02013 m_clsid == __uuidof(CNullVideoRenderer) ? (IBaseFilter*)new CNullVideoRenderer() :
02014 m_clsid == __uuidof(CNullAudioRenderer) ? (IBaseFilter*)new CNullAudioRenderer() :
02015 m_clsid == __uuidof(CNullUVideoRenderer) ? (IBaseFilter*)new CNullUVideoRenderer() :
02016 m_clsid == __uuidof(CNullUAudioRenderer) ? (IBaseFilter*)new CNullUAudioRenderer() :
02017 m_clsid == __uuidof(CNullTextRenderer) ? (IBaseFilter*)new CNullTextRenderer(NULL, &hr) :
02018 m_clsid == __uuidof(CDeinterlacerFilter) ? (IBaseFilter*)new CDeinterlacerFilter(NULL, &hr) :
02019 NULL;
02020
02021 __if_exists(CRadGtSplitterFilter)
02022 {
02023 if(*ppBF == NULL && m_clsid == __uuidof(CRadGtSplitterFilter))
02024 *ppBF = (IBaseFilter*)new CRadGtSplitterFilter(NULL, &hr);
02025 }
02026
02027 if(!*ppBF) hr = E_FAIL;
02028 else (*ppBF)->AddRef();
02029
02030 if(!*ppBF)
02031 {
02032 CComPtr<IBaseFilter> pBF;
02033 if(SUCCEEDED(hr = pBF.CoCreateInstance(m_clsid)))
02034 *ppBF = pBF.Detach();
02035 }
02036
02037 if(SUCCEEDED(hr) && ppUnk)
02038 {
02039 if(m_clsid == __uuidof(CAudioSwitcherFilter))
02040 {
02041 *ppUnk = (IUnknown*)CComQIPtr<IAudioSwitcherFilter>(*ppBF).Detach();
02042 CComQIPtr<IAudioSwitcherFilter> pASF = *ppUnk;
02043
02044 if(pASF)
02045 {
02046 AppSettings& s = AfxGetAppSettings();
02047 pASF->SetSpeakerConfig(s.fCustomChannelMapping, s.pSpeakerToChannelMap);
02048 pASF->EnableDownSamplingTo441(s.fDownSampleTo441);
02049 pASF->SetAudioTimeShift(s.fAudioTimeShift ? 10000i64*s.tAudioTimeShift : 0);
02050 }
02051 }
02052 }
02053
02054 return hr;
02055 }
02056
02057
02058
02059
02060
02061 CGraphFileFilter::CGraphFileFilter(const CLSID& clsid, CList<GUID>& guids, CString path, CStringW name, ULONGLONG merit)
02062 : CGraphCustomFilter(clsid, guids, name, merit), m_path(path), m_hInst(NULL)
02063 {
02064 }
02065
02066 HRESULT CGraphFileFilter::Create(IBaseFilter** ppBF, IUnknown** ppUnk)
02067 {
02068 CheckPointer(ppBF, E_POINTER);
02069
02070 if(ppUnk) *ppUnk = NULL;
02071
02072 HRESULT hr = S_OK;
02073
02074 if(SUCCEEDED(hr = __super::Create(ppBF, ppUnk)))
02075 return hr;
02076
02077 return LoadExternalFilter(m_path, m_clsid, ppBF);
02078 }
02079
02080
02081
02082
02083
02084 CGraphRendererFilter::CGraphRendererFilter(const CLSID& clsid, HWND hWnd, CStringW name, ULONGLONG merit)
02085 : CGraphFilter(name, merit), m_clsid(clsid), m_hWnd(hWnd)
02086 {
02087 m_guids.AddTail(MEDIATYPE_Video);
02088 m_guids.AddTail(MEDIASUBTYPE_NULL);
02089 }
02090
02091 HRESULT CGraphRendererFilter::Create(IBaseFilter** ppBF, IUnknown** ppUnk)
02092 {
02093 CheckPointer(ppBF, E_POINTER);
02094
02095 HRESULT hr = S_OK;
02096
02097 if(m_clsid == CLSID_OverlayMixer)
02098 {
02099 CComPtr<IBaseFilter> pBF;
02100 if(SUCCEEDED(pBF.CoCreateInstance(CLSID_OverlayMixer)))
02101 {
02102 BeginEnumPins(pBF, pEP, pPin)
02103 {
02104 if(CComQIPtr<IMixerPinConfig, &IID_IMixerPinConfig> pMPC = pPin)
02105 {
02106 if(ppUnk) *ppUnk = pMPC.Detach();
02107 break;
02108 }
02109 }
02110 EndEnumPins
02111
02112 *ppBF = pBF.Detach();
02113 }
02114 }
02115 else if(m_clsid == CLSID_VideoMixingRenderer)
02116 {
02117 CComPtr<IBaseFilter> pBF;
02118 if(SUCCEEDED(pBF.CoCreateInstance(CLSID_VideoMixingRenderer)))
02119 *ppBF = pBF.Detach();
02120 }
02121 else if(m_clsid == CLSID_VideoMixingRenderer9)
02122 {
02123 CComPtr<IBaseFilter> pBF;
02124 if(SUCCEEDED(pBF.CoCreateInstance(CLSID_VideoMixingRenderer9)))
02125 *ppBF = pBF.Detach();
02126 }
02127 else if(m_clsid == CLSID_VMR7AllocatorPresenter)
02128 {
02129 CComPtr<ISubPicAllocatorPresenter> pCAP;
02130 CComPtr<IUnknown> pRenderer;
02131 if(SUCCEEDED(hr = CreateAP7(CLSID_VMR7AllocatorPresenter, m_hWnd, &pCAP))
02132 && SUCCEEDED(hr = pCAP->CreateRenderer(&pRenderer)))
02133 {
02134 *ppBF = CComQIPtr<IBaseFilter>(pRenderer).Detach();
02135 if(ppUnk) *ppUnk = (IUnknown*)pCAP.Detach();
02136 }
02137 }
02138 else if(m_clsid == CLSID_VMR9AllocatorPresenter)
02139 {
02140 CComPtr<ISubPicAllocatorPresenter> pCAP;
02141 CComPtr<IUnknown> pRenderer;
02142 if(SUCCEEDED(hr = CreateAP9(CLSID_VMR9AllocatorPresenter, m_hWnd, &pCAP))
02143 && SUCCEEDED(hr = pCAP->CreateRenderer(&pRenderer)))
02144 {
02145 *ppBF = CComQIPtr<IBaseFilter>(pRenderer).Detach();
02146 if(ppUnk) *ppUnk = (IUnknown*)pCAP.Detach();
02147 }
02148 }
02149
02150 if(!*ppBF) hr = E_FAIL;
02151
02152 return hr;
02153 }
02154