www.pudn.com > AVChat1.rar > UDsUtils.cpp
// // UDsUtils.cpp // /*-----------------------------------------------------*\ HQ Tech, Make Technology Easy! More information, please go to http://hqtech.nease.net. /*-----------------------------------------------------*/ #include "stdafx.h" #include#include "UDsUtils.h" #include "UFilterUtils.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif /////////////////////////////////////////////////////////////////////////////// // Only USB camera or DV camcorder will be created IBaseFilter * UDsUtils::CreateCamera(CAVDevice& outDevice) { return CreateAVDevice(CLSID_VideoInputDeviceCategory, outDevice); } // Create the first found audio device IBaseFilter * UDsUtils::CreateAudioDevice(CAVDevice& outDevice) { return CreateAVDevice(CLSID_AudioInputDeviceCategory, outDevice); } // Create the first found audio device IBaseFilter * UDsUtils::CreateAVDevice(GUID inCategory, CAVDevice& outDevice) { IBaseFilter * pDevice = NULL; ICreateDevEnum * enumHardware = NULL; if (SUCCEEDED(CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_ALL, IID_ICreateDevEnum, (void**) &enumHardware))) { IEnumMoniker * enumMoniker = NULL; if (SUCCEEDED(enumHardware->CreateClassEnumerator(inCategory, &enumMoniker, 0))) { if (enumMoniker) { enumMoniker->Reset(); ULONG cFetched = 0; IMoniker * moniker = NULL; while (SUCCEEDED(enumMoniker->Next(1, &moniker, &cFetched)) && cFetched && !pDevice) { if (moniker) { WCHAR *wzDisplayName = NULL; // Get display name if (SUCCEEDED (moniker->GetDisplayName(NULL, NULL, &wzDisplayName))) { char displayName[1024]; WideCharToMultiByte(CP_ACP, 0, wzDisplayName, -1, displayName, 1024, "", NULL); CoTaskMemFree(wzDisplayName); IPropertyBag * propertyBag = NULL; if (SUCCEEDED(moniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&propertyBag))) { VARIANT name; name.vt = VT_BSTR; // Get friendly name if (SUCCEEDED(propertyBag->Read(L"FriendlyName", &name, NULL))) { char friendlyName[256]; friendlyName[0] = 0; WideCharToMultiByte(CP_ACP, 0, name.bstrVal, -1, friendlyName, 80, NULL, NULL); IBaseFilter * filter = NULL; if (SUCCEEDED(moniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&filter))) { Device_Type type = DetermineDeviceType(filter); if (type != DT_Unknown) { // Save this device info outDevice.SetDeviceDisplayName(displayName); outDevice.SetDeviceFriendlyName(friendlyName); outDevice.SetDevideType(type); pDevice = filter; pDevice->AddRef(); } filter->Release(); } } propertyBag->Release(); } } moniker->Release(); } } enumMoniker->Release(); } } enumHardware->Release(); } return pDevice; } Device_Type UDsUtils::DetermineDeviceType(IBaseFilter * inFilter) { // Check if DV device IAMExtTransport * pAMExtTransPost = NULL; inFilter->QueryInterface(IID_IAMExtTransport, (void **)&pAMExtTransPost); if (pAMExtTransPost) { pAMExtTransPost->Release(); return DT_DV; } // Check if WDM analog // USB camera usually has only one output pin IAMAnalogVideoDecoder * pDecoder = NULL; IAMCameraControl * pCamera = NULL; IAMVideoProcAmp * pAmp = NULL; inFilter->QueryInterface(IID_IAMAnalogVideoDecoder, (void **)&pDecoder); inFilter->QueryInterface(IID_IAMCameraControl, (void **)&pCamera); inFilter->QueryInterface(IID_IAMVideoProcAmp, (void **)&pAmp); if (pDecoder || pCamera || pAmp) { SAFE_RELEASE(pDecoder); SAFE_RELEASE(pCamera); SAFE_RELEASE(pAmp); // Further checking for USB camema int inputs = 0, outputs = 0; UFilterUtils::GetPinCount(inFilter, inputs, outputs); if (inputs + outputs <= 2) { return DT_USB_Camera; } else { return DT_Unknown; } } // Check if audio capture device IAMAudioInputMixer * pAudioMixer = NULL; inFilter->QueryInterface(IID_IAMAudioInputMixer, (void **)&pAudioMixer); if (pAudioMixer) { pAudioMixer->Release(); return DT_Audio_Capture; } return DT_Unknown; } void UDsUtils::NukeDownstream(IGraphBuilder * inGraph, IBaseFilter * inFilter) { if (inGraph && inFilter) { IEnumPins * pinEnum = NULL; if (SUCCEEDED(inFilter->EnumPins(&pinEnum))) { pinEnum->Reset(); IPin * pin = NULL; ULONG cFetched = 0; BOOL pass = TRUE; while (pass && SUCCEEDED(pinEnum->Next(1, &pin, &cFetched))) { if (pin && cFetched) { IPin * connectedPin = 0; pin->ConnectedTo(&connectedPin); if (connectedPin) { PIN_INFO pininfo; if (SUCCEEDED(connectedPin->QueryPinInfo(&pininfo))) { pininfo.pFilter->Release(); if (pininfo.dir == PINDIR_INPUT) { NukeDownstream(inGraph, pininfo.pFilter); inGraph->Disconnect(connectedPin); inGraph->Disconnect(pin); inGraph->RemoveFilter(pininfo.pFilter); } } connectedPin->Release(); } pin->Release(); } else { pass = FALSE; } } pinEnum->Release(); } } } void UDsUtils::NukeUpstream(IGraphBuilder * inGraph, IBaseFilter * inFilter) { if (inGraph && inFilter) { IEnumPins * pinEnum = NULL; if (SUCCEEDED(inFilter->EnumPins(&pinEnum))) { pinEnum->Reset(); IPin * pin = NULL; ULONG cFetched = 0; BOOL pass = TRUE; while (pass && SUCCEEDED(pinEnum->Next(1, &pin, &cFetched)) && cFetched) { if (pin) { IPin * connectedPin = 0; pin->ConnectedTo(&connectedPin); if(connectedPin) { PIN_INFO pininfo; if (SUCCEEDED(connectedPin->QueryPinInfo(&pininfo))) { if(pininfo.dir == PINDIR_OUTPUT) { NukeUpstream(inGraph, pininfo.pFilter); inGraph->Disconnect(connectedPin); inGraph->Disconnect(pin); inGraph->RemoveFilter(pininfo.pFilter); } pininfo.pFilter->Release(); } connectedPin->Release(); } pin->Release(); } else { pass = FALSE; } } pinEnum->Release(); } } } BOOL UDsUtils::ShowFilterPropertyPage(IBaseFilter * inFilter) { if (!inFilter) { return FALSE; } ISpecifyPropertyPages * pSpecify; HRESULT hr = inFilter->QueryInterface(IID_ISpecifyPropertyPages, (void **)&pSpecify); if (SUCCEEDED(hr)) { CAUUID caGUID; pSpecify->GetPages(&caGUID); pSpecify->Release(); OleCreatePropertyFrame( ::GetActiveWindow(), // Parent window 0, // x (Reserved) 0, // y (Reserved) NULL, // Caption for the dialog box 1, // Number of filters (IUnknown **) &inFilter, // Pointer to the filter caGUID.cElems, // Number of property pages caGUID.pElems, // Pointer of property page CLSIDs 0, // Locale identifier 0, // Reserved NULL // Reserved ); CoTaskMemFree(caGUID.pElems); return TRUE; } return FALSE; }