/** * Pops up a user dialog allowing them to adjust properties for the given filter, if possible. */ void dshow_show_filter_properties(IBaseFilter *device_filter, AVFormatContext *avctx) { ISpecifyPropertyPages *property_pages = NULL; IUnknown *device_filter_iunknown = NULL; HRESULT hr; FILTER_INFO filter_info = {0}; /* a warning on this line is false positive GCC bug 53119 AFAICT */ CAUUID ca_guid = {0}; hr = IBaseFilter_QueryInterface(device_filter, &IID_ISpecifyPropertyPages, (void **)&property_pages); if (hr != S_OK) { av_log(avctx, AV_LOG_WARNING, "requested filter does not have a property page to show"); goto end; } hr = IBaseFilter_QueryFilterInfo(device_filter, &filter_info); if (hr != S_OK) { goto fail; } hr = IBaseFilter_QueryInterface(device_filter, &IID_IUnknown, (void **)&device_filter_iunknown); if (hr != S_OK) { goto fail; } hr = ISpecifyPropertyPages_GetPages(property_pages, &ca_guid); if (hr != S_OK) { goto fail; } hr = OleCreatePropertyFrame(NULL, 0, 0, filter_info.achName, 1, &device_filter_iunknown, ca_guid.cElems, ca_guid.pElems, 0, 0, NULL); if (hr != S_OK) { goto fail; } goto end; fail: av_log(avctx, AV_LOG_ERROR, "Failure showing property pages for filter"); end: if (property_pages) ISpecifyPropertyPages_Release(property_pages); if (device_filter_iunknown) IUnknown_Release(device_filter_iunknown); if (filter_info.pGraph) IFilterGraph_Release(filter_info.pGraph); if (ca_guid.pElems) CoTaskMemFree(ca_guid.pElems); }
static void test_smart_tee_filter(void) { HRESULT hr; IBaseFilter *smartTeeFilter = NULL; IEnumPins *enumPins = NULL; IPin *pin; FILTER_INFO filterInfo; int pinNumber = 0; hr = CoCreateInstance(&CLSID_SmartTee, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (void**)&smartTeeFilter); todo_wine ok(SUCCEEDED(hr), "couldn't create smart tee filter, hr=%08x\n", hr); if (FAILED(hr)) goto end; hr = IBaseFilter_QueryFilterInfo(smartTeeFilter, &filterInfo); ok(SUCCEEDED(hr), "QueryFilterInfo failed, hr=%08x\n", hr); if (FAILED(hr)) goto end; ok(lstrlenW(filterInfo.achName) == 0, "filter's name is meant to be empty but it's %s\n", wine_dbgstr_w(filterInfo.achName)); hr = IBaseFilter_EnumPins(smartTeeFilter, &enumPins); ok(SUCCEEDED(hr), "cannot enum filter pins, hr=%08x\n", hr); if (FAILED(hr)) goto end; while (IEnumPins_Next(enumPins, 1, &pin, NULL) == S_OK) { PIN_INFO pinInfo; hr = IPin_QueryPinInfo(pin, &pinInfo); ok(SUCCEEDED(hr), "QueryPinInfo failed, hr=%08x\n", hr); if (FAILED(hr)) goto endwhile; if (pinNumber == 0) { static const WCHAR wszInput[] = {'I','n','p','u','t',0}; ok(pinInfo.dir == PINDIR_INPUT, "pin 0 isn't an input pin\n"); ok(!lstrcmpW(pinInfo.achName, wszInput), "pin 0 is called %s, not 'Input'\n", wine_dbgstr_w(pinInfo.achName)); } else if (pinNumber == 1) { static const WCHAR wszCapture[] = {'C','a','p','t','u','r','e',0}; ok(pinInfo.dir == PINDIR_OUTPUT, "pin 1 isn't an output pin\n"); ok(!lstrcmpW(pinInfo.achName, wszCapture), "pin 1 is called %s, not 'Capture'\n", wine_dbgstr_w(pinInfo.achName)); } else if (pinNumber == 2) { static const WCHAR wszPreview[] = {'P','r','e','v','i','e','w',0}; ok(pinInfo.dir == PINDIR_OUTPUT, "pin 2 isn't an output pin\n"); ok(!lstrcmpW(pinInfo.achName, wszPreview), "pin 2 is called %s, not 'Preview'\n", wine_dbgstr_w(pinInfo.achName)); } else ok(0, "pin %d isn't supposed to exist\n", pinNumber); endwhile: IPin_Release(pin); pinNumber++; } end: if (smartTeeFilter) IBaseFilter_Release(smartTeeFilter); if (enumPins) IEnumPins_Release(enumPins); }