| /* GStreamer | |
| * Copyright (C) 2007 Sebastien Moutte <sebastien@moutte.net> | |
| * | |
| * gstdshow.cpp: | |
| * | |
| * This library is free software; you can redistribute it and/or | |
| * modify it under the terms of the GNU Library General Public | |
| * License as published by the Free Software Foundation; either | |
| * version 2 of the License, or (at your option) any later version. | |
| * | |
| * This library 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 | |
| * Library General Public License for more details. | |
| * | |
| * You should have received a copy of the GNU Library General Public | |
| * License along with this library; if not, write to the | |
| * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, | |
| * Boston, MA 02110-1301, USA. | |
| */ | |
| #include <dmodshow.h> | |
| #include <dmoreg.h> | |
| #include "gstdshowutil.h" | |
| #include "gstdshowfakesrc.h" | |
| _COM_SMARTPTR_TYPEDEF(IDMOWrapperFilter, __uuidof(IDMOWrapperFilter)); | |
| IPin * | |
| gst_dshow_get_pin_from_filter (IBaseFilter *filter, PIN_DIRECTION pindir) | |
| { | |
| IEnumPinsPtr enumpins; | |
| IPinPtr pin; | |
| HRESULT hres; | |
| hres = filter->EnumPins (&enumpins); | |
| if (FAILED(hres)) { | |
| return NULL; | |
| } | |
| while (enumpins->Next (1, &pin, NULL) == S_OK) | |
| { | |
| PIN_DIRECTION pindirtmp; | |
| hres = pin->QueryDirection (&pindirtmp); | |
| if (hres == S_OK && pindir == pindirtmp) { | |
| return pin; | |
| } | |
| pin.Release(); | |
| } | |
| return NULL; | |
| } | |
| IBaseFilter * | |
| gst_dshow_find_filter(CLSID input_majortype, CLSID input_subtype, | |
| CLSID output_majortype, CLSID output_subtype, | |
| PreferredFilter *preferred_filters) | |
| { | |
| HRESULT hres; | |
| GUID inTypes[2]; | |
| GUID outTypes[2]; | |
| IFilterMapper2Ptr mapper; | |
| IEnumMonikerPtr enum_moniker; | |
| IMonikerPtr moniker; | |
| ULONG fetched; | |
| IBaseFilter *filter; | |
| /* First, see if any of our preferred filters is available. | |
| * If not, we fall back to the highest-ranked installed filter */ | |
| if (preferred_filters) { | |
| while (preferred_filters->filter_guid) | |
| { | |
| /* If the filter is a DMO, we need to do this a bit differently */ | |
| if (preferred_filters->dmo_category) | |
| { | |
| IDMOWrapperFilterPtr wrapper; | |
| hres = CoCreateInstance (CLSID_DMOWrapperFilter, NULL, | |
| CLSCTX_INPROC, | |
| IID_IBaseFilter, (void **)&filter); | |
| if (SUCCEEDED(hres)) { | |
| hres = filter->QueryInterface (&wrapper); | |
| if (SUCCEEDED(hres)) { | |
| hres = wrapper->Init (*preferred_filters->filter_guid, | |
| *preferred_filters->dmo_category); | |
| if (SUCCEEDED(hres)) | |
| return filter; | |
| } | |
| filter->Release(); | |
| } | |
| } | |
| else | |
| { | |
| hres = CoCreateInstance (*preferred_filters->filter_guid, | |
| NULL, CLSCTX_INPROC, | |
| IID_IBaseFilter, (void **)&filter); | |
| if (SUCCEEDED(hres)) | |
| return filter; | |
| } | |
| /* Continue to the next filter */ | |
| preferred_filters++; | |
| } | |
| } | |
| hres = CoCreateInstance(CLSID_FilterMapper2, NULL, CLSCTX_INPROC, | |
| IID_IFilterMapper2, (void **) &mapper); | |
| if (FAILED(hres)) | |
| return NULL; | |
| inTypes[0] = input_majortype; | |
| inTypes[1] = input_subtype; | |
| outTypes[0] = output_majortype; | |
| outTypes[1] = output_subtype; | |
| hres = mapper->EnumMatchingFilters (&enum_moniker, 0, | |
| FALSE, MERIT_DO_NOT_USE+1, | |
| TRUE, 1, inTypes, NULL, NULL, FALSE, | |
| TRUE, 1, outTypes, NULL, NULL); | |
| if (FAILED(hres)) | |
| return NULL; | |
| enum_moniker->Reset (); | |
| while(enum_moniker->Next (1, &moniker, &fetched) == S_OK) | |
| { | |
| hres = moniker->BindToObject(NULL, NULL, | |
| IID_IBaseFilter, (void**)&filter); | |
| if(SUCCEEDED(hres)) { | |
| return filter; | |
| } | |
| moniker.Release (); | |
| } | |
| return NULL; | |
| } | |