You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2701 lines
92 KiB
2701 lines
92 KiB
/*****************************************************************************
|
|
*
|
|
* (C) COPYRIGHT MICROSOFT CORPORATION, 1999-2000
|
|
*
|
|
* TITLE: DShowUtl.cpp
|
|
*
|
|
* VERSION: 1.0
|
|
*
|
|
* AUTHOR: OrenR
|
|
*
|
|
* DATE: 2000/10/25
|
|
*
|
|
* DESCRIPTION: Provides support functions for preview graph class
|
|
*
|
|
*****************************************************************************/
|
|
|
|
#include <precomp.h>
|
|
#include <atlconv.h>
|
|
#pragma hdrstop
|
|
|
|
///////////////////////////////
|
|
// Constants
|
|
//
|
|
const UINT FIND_FLAG_BY_ENUM_POS = 1;
|
|
const UINT FIND_FLAG_BY_DSHOW_ID = 2;
|
|
const UINT FIND_FLAG_BY_FRIENDLY_NAME = 3;
|
|
|
|
//
|
|
// These are values found in the registry, specified in the
|
|
// DeviceData section of the vendor's INF file.
|
|
//
|
|
const TCHAR* REG_VAL_PREFERRED_MEDIASUBTYPE = _T("PreferredMediaSubType");
|
|
const TCHAR* REG_VAL_PREFERRED_VIDEO_WIDTH = _T("PreferredVideoWidth");
|
|
const TCHAR* REG_VAL_PREFERRED_VIDEO_HEIGHT = _T("PreferredVideoHeight");
|
|
const TCHAR* REG_VAL_PREFERRED_VIDEO_FRAMERATE = _T("PreferredVideoFrameRate");
|
|
|
|
///////////////////////////////
|
|
// SizeVideoToWindow
|
|
//
|
|
// Static Fn
|
|
//
|
|
HRESULT CDShowUtil::SizeVideoToWindow(HWND hwnd,
|
|
IVideoWindow *pVideoWindow,
|
|
BOOL bStretchToFit)
|
|
{
|
|
DBG_FN("CDShowUtil::SizeVideoToWindow");
|
|
|
|
ASSERT(hwnd != NULL);
|
|
ASSERT(pVideoWindow != NULL);
|
|
|
|
RECT rc = {0};
|
|
HRESULT hr = S_OK;
|
|
|
|
//
|
|
// Check for invalid args
|
|
//
|
|
|
|
if ((hwnd == NULL) ||
|
|
(pVideoWindow == NULL))
|
|
{
|
|
hr = E_POINTER;
|
|
CHECK_S_OK2(hr, ("CDShowUtil::SizeVideoToWindow received NULL pointer"));
|
|
return hr;
|
|
}
|
|
|
|
//
|
|
// Try to position preview window as best we
|
|
// can in the context of the containing window
|
|
//
|
|
|
|
::GetClientRect(hwnd, &rc);
|
|
|
|
//
|
|
// First, get ideal sizes (that won't incur scaling penalty)
|
|
//
|
|
|
|
LONG maxWidth = 0;
|
|
LONG maxHeight = 0;
|
|
LONG minWidth = 0;
|
|
LONG minHeight = 0;
|
|
LONG nativeWidth = 0;
|
|
LONG nativeHeight = 0;
|
|
|
|
LONG w = rc.right - rc.left;
|
|
LONG h = rc.bottom - rc.top;
|
|
BOOL bDone = FALSE;
|
|
|
|
//
|
|
// ***NOTE***
|
|
//
|
|
// Little known fact (i.e. not in MSDN)
|
|
// 'GetMaxIdealSize' and 'GetMinIdealSize' will FAIL if the graph is
|
|
// in the stopped state. Therefore, the graph must be in the paused
|
|
// or in the playing state.
|
|
//
|
|
|
|
hr = pVideoWindow->GetMaxIdealImageSize(&maxWidth, &maxHeight);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
maxWidth = w;
|
|
maxHeight = h;
|
|
|
|
DBG_WRN(("pVideoWindow->GetMaxIdealImageSize failed. "
|
|
"This is a non-fatal error, setting our max video "
|
|
"width '%lu' and height '%lu' to the window's "
|
|
"boundaries", maxWidth, maxHeight));
|
|
}
|
|
|
|
hr = pVideoWindow->GetMinIdealImageSize(&minWidth, &minHeight);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
minWidth = w;
|
|
minHeight = h;
|
|
|
|
DBG_WRN(("pVideoWindow->GetMinIdealImageSize failed. "
|
|
"This is a non-fatal error, setting our minimum video "
|
|
"width '%lu' and height '%lu' to the window's "
|
|
"boundaries", maxWidth, maxHeight));
|
|
}
|
|
|
|
//
|
|
// Now, get nominal size of preview
|
|
//
|
|
if (pVideoWindow)
|
|
{
|
|
CComPtr<IBasicVideo> pBasicVideo;
|
|
|
|
hr = pVideoWindow->QueryInterface(IID_IBasicVideo,
|
|
reinterpret_cast<void **>(&pBasicVideo));
|
|
|
|
CHECK_S_OK2(hr, ("pVideoWindow->QueryInterface for IBasicVideo failed"));
|
|
|
|
if (SUCCEEDED(hr) && pBasicVideo)
|
|
{
|
|
hr = pBasicVideo->GetVideoSize( &nativeWidth, &nativeHeight );
|
|
|
|
CHECK_S_OK2(hr, ("pBasicVideo->GetVideoSize() failed" ));
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
nativeWidth = nativeHeight = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if (bStretchToFit)
|
|
{
|
|
nativeWidth = w;
|
|
nativeHeight = h;
|
|
}
|
|
|
|
//
|
|
// Try native size first
|
|
//
|
|
if (nativeWidth && nativeHeight)
|
|
{
|
|
if ((nativeWidth <= w) && (nativeHeight <= h))
|
|
{
|
|
hr = pVideoWindow->SetWindowPosition((w - nativeWidth) / 2,
|
|
(h - nativeHeight) / 2,
|
|
nativeWidth,
|
|
nativeHeight);
|
|
|
|
CHECK_S_OK2( hr, ("pVideoWindow->SetWindowPosition( "
|
|
"native size )"));
|
|
bDone = TRUE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Don't scale outside of min/max range so we don't incur performance hit,
|
|
// also, as we scale, keep the aspect ratio of the native size
|
|
//
|
|
if (!bDone)
|
|
{
|
|
INT x = 0;
|
|
INT y = 0;
|
|
INT _h = h;
|
|
INT _w = w;
|
|
|
|
//
|
|
// cap (in both directions) for no loss of performance...
|
|
//
|
|
|
|
if ((_w > maxWidth) && (maxWidth <= w))
|
|
{
|
|
_w = maxWidth;
|
|
}
|
|
else if ((_w < minWidth) && (minWidth <= w))
|
|
{
|
|
_w = minWidth;
|
|
}
|
|
|
|
if ((_h > maxHeight) && (maxHeight <= h))
|
|
{
|
|
_h = maxHeight;
|
|
}
|
|
else if ((_h < minHeight) && (minHeight <= h))
|
|
{
|
|
_h = minHeight;
|
|
}
|
|
|
|
//
|
|
// Notice that if the client window size is 0,0 then
|
|
// the video will be set to that size. We will warn the
|
|
// caller below in a warning statement, but if they want
|
|
// to do that I'm not going to stop them.
|
|
//
|
|
|
|
//
|
|
// Find the smallest axis
|
|
//
|
|
if (h < w)
|
|
{
|
|
//
|
|
// Space is wider than tall
|
|
//
|
|
if (nativeHeight)
|
|
{
|
|
_w = ((_h * nativeWidth) / nativeHeight);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Space is taller than wide
|
|
//
|
|
if (nativeWidth)
|
|
{
|
|
_h = ((nativeHeight * _w) / nativeWidth);
|
|
}
|
|
}
|
|
|
|
x = ((w - _w) / 2);
|
|
y = ((h - _h) / 2);
|
|
|
|
if ((_w == 0) || (_h == 0))
|
|
{
|
|
DBG_WRN(("WARNING: CDShowUtils::SizeVideoToWindow "
|
|
"video width and/or height is 0. This will "
|
|
"result in video that is not visible. This is "
|
|
"because the owning window dimensions are probably 0. "
|
|
"Video -> Width:'%lu', Height:'%lu', Window -> "
|
|
"Top:'%lu', Bottom:'%lu', Left:'%lu', Right:'%lu'",
|
|
_w, _h, rc.top, rc.bottom, rc.left, rc.right));
|
|
}
|
|
|
|
hr = pVideoWindow->SetWindowPosition( x, y, _w, _h );
|
|
|
|
CHECK_S_OK2(hr, ("pVideoWindow->SetWindowPosition to set the "
|
|
"aspect scaled size failed"));
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
///////////////////////////////
|
|
// ShowVideo
|
|
//
|
|
// Static Fn
|
|
//
|
|
HRESULT CDShowUtil::ShowVideo(BOOL bShow,
|
|
IVideoWindow *pVideoWindow)
|
|
{
|
|
DBG_FN("CDShowUtil::ShowVideo");
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
if (pVideoWindow == NULL)
|
|
{
|
|
hr = E_POINTER;
|
|
CHECK_S_OK2(hr, ("CDShowUtil::ShowVideo failed to show video "
|
|
"successfully"));
|
|
}
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
if (bShow)
|
|
{
|
|
//
|
|
// We were told to show the preview window therefore we will show
|
|
// it.
|
|
//
|
|
hr = pVideoWindow->put_Visible(OATRUE);
|
|
CHECK_S_OK2(hr, ("pVideoWindow->put_Visible(OATRUE)"));
|
|
|
|
hr = pVideoWindow->put_AutoShow(OATRUE);
|
|
CHECK_S_OK2(hr, ("pVideoWindow->put_AutoShow(OATRUE)"));
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// We were told to hide the preview window.
|
|
//
|
|
|
|
pVideoWindow->put_Visible(OAFALSE);
|
|
pVideoWindow->put_AutoShow(OAFALSE);
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
///////////////////////////////
|
|
// SetVideoWindowParent
|
|
//
|
|
// Static Fn
|
|
//
|
|
HRESULT CDShowUtil::SetVideoWindowParent(HWND hwndParent,
|
|
IVideoWindow *pVideoWindow,
|
|
LONG *plOldWindowStyle)
|
|
{
|
|
DBG_FN("CDShowUtil::SetVideoRendererParent");
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
if (pVideoWindow == NULL)
|
|
{
|
|
hr = E_POINTER;
|
|
CHECK_S_OK2(hr, ("CDShowUtil::SetVideoWindowParent received NULL "
|
|
"Param"));
|
|
}
|
|
else if (hwndParent && !IsWindow(hwndParent))
|
|
{
|
|
hr = E_INVALIDARG;
|
|
CHECK_S_OK2(hr, ("CDShowUtil::SetVideoWindowParent received invalid "
|
|
"hwnd = 0x%08x", hwndParent));
|
|
}
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
if (!hwndParent)
|
|
{
|
|
//
|
|
// Okay, we are setting the preview window to NULL, which
|
|
// means we are disassociating it from its parent.
|
|
//
|
|
//
|
|
// Reseting graph preview window
|
|
//
|
|
|
|
hr = pVideoWindow->put_Owner(NULL);
|
|
CHECK_S_OK2(hr, ("pVideoWindow->put_Owner(NULL)"));
|
|
|
|
if ((plOldWindowStyle) && (*plOldWindowStyle))
|
|
{
|
|
hr = pVideoWindow->put_WindowStyle(*plOldWindowStyle);
|
|
|
|
CHECK_S_OK2(hr, ("pVideoWindow->put_WindowStyle"
|
|
"(*plOldWindowStyle)"));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LONG WinStyle;
|
|
HRESULT hr2;
|
|
|
|
//
|
|
// Okay, we are giving the preview window a new parent
|
|
//
|
|
|
|
// Set the owning window
|
|
//
|
|
|
|
hr = pVideoWindow->put_Owner(PtrToUlong(hwndParent));
|
|
CHECK_S_OK2(hr, ("pVideoWindow->putOwner( hwndParent )"));
|
|
|
|
//
|
|
// Set the style for the preview
|
|
//
|
|
|
|
//
|
|
// First, store the window style so that we can restore it
|
|
// when we disassociate the parent from the window
|
|
//
|
|
hr2 = pVideoWindow->get_WindowStyle(&WinStyle);
|
|
CHECK_S_OK2(hr2, ("pVideoWindow->get_WindowStyle"
|
|
"( pOldWindowStyle )"));
|
|
|
|
//
|
|
// Set the Video Renderer window so that it will be a child of
|
|
// the parent window, i.e. it does not have a border etc.
|
|
//
|
|
|
|
if (plOldWindowStyle)
|
|
{
|
|
*plOldWindowStyle = WinStyle;
|
|
}
|
|
|
|
WinStyle &= ~WS_OVERLAPPEDWINDOW;
|
|
WinStyle &= ~WS_CLIPCHILDREN;
|
|
WinStyle |= WS_CHILD;
|
|
|
|
hr2 = pVideoWindow->put_WindowStyle(WinStyle);
|
|
CHECK_S_OK2(hr2, ("pVideoWindow->put_WindowStyle( WinStyle )"));
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
///////////////////////////////
|
|
// GetDeviceProperty
|
|
//
|
|
// Static Fn
|
|
//
|
|
HRESULT CDShowUtil::GetDeviceProperty(IPropertyBag *pPropertyBag,
|
|
LPCWSTR pwszProperty,
|
|
CSimpleString *pstrProperty)
|
|
{
|
|
DBG_FN("CDShowUtil::GetDeviceProperty");
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
ASSERT(pPropertyBag != NULL);
|
|
ASSERT(pwszProperty != NULL);
|
|
ASSERT(pstrProperty != NULL);
|
|
|
|
VARIANT VarName;
|
|
|
|
if ((pPropertyBag == NULL) ||
|
|
(pwszProperty == NULL) ||
|
|
(pstrProperty == NULL))
|
|
{
|
|
hr = E_POINTER;
|
|
CHECK_S_OK2(hr, ("CDShowUtil::GetDeviceProperty received a NULL "
|
|
"param"));
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
VariantInit(&VarName);
|
|
VarName.vt = VT_BSTR;
|
|
hr = pPropertyBag->Read(pwszProperty, &VarName, 0);
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
*pstrProperty = CSimpleStringConvert::NaturalString(
|
|
CSimpleStringWide(VarName.bstrVal));
|
|
VariantClear(&VarName);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
///////////////////////////////
|
|
// GetMonikerProperty
|
|
//
|
|
// Static Fn
|
|
//
|
|
HRESULT CDShowUtil::GetMonikerProperty(IMoniker *pMoniker,
|
|
LPCWSTR pwszProperty,
|
|
CSimpleString *pstrProperty)
|
|
{
|
|
DBG_FN("CDShowUtil::GetMonikerProperty");
|
|
|
|
HRESULT hr = S_OK;
|
|
VARIANT VarName;
|
|
CComPtr<IPropertyBag> pPropertyBag;
|
|
|
|
ASSERT(pMoniker != NULL);
|
|
ASSERT(pwszProperty != NULL);
|
|
ASSERT(pstrProperty != NULL);
|
|
|
|
if ((pMoniker == NULL) ||
|
|
(pwszProperty == NULL) ||
|
|
(pstrProperty == NULL))
|
|
{
|
|
hr = E_POINTER;
|
|
CHECK_S_OK2(hr, ("CDShowUtil::GetMonikerProperty received a "
|
|
"NULL param"));
|
|
}
|
|
|
|
hr = pMoniker->BindToStorage(0,
|
|
0,
|
|
IID_IPropertyBag,
|
|
(void **)&pPropertyBag);
|
|
|
|
CHECK_S_OK2(hr, ("CDShowUtil::GetMonikerProperty, BindToStorage failed"));
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
hr = GetDeviceProperty(pPropertyBag,
|
|
pwszProperty,
|
|
pstrProperty);
|
|
|
|
CHECK_S_OK2(hr, ("CDShowUtil::GetMonikerProperty, failed "
|
|
"to get device property '%ls'", pwszProperty));
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
///////////////////////////////
|
|
// FindDeviceGeneric
|
|
//
|
|
// Given the device ID, we will
|
|
// find all the remaining parameters.
|
|
// If a parameter is NULL, that information
|
|
// is not looked up.
|
|
//
|
|
//
|
|
// Static Fn
|
|
//
|
|
HRESULT CDShowUtil::FindDeviceGeneric(UINT uiFindFlag,
|
|
CSimpleString *pstrDShowDeviceID,
|
|
LONG *plEnumPos,
|
|
CSimpleString *pstrFriendlyName,
|
|
IMoniker **ppDeviceMoniker)
|
|
{
|
|
DBG_FN("CDShowUtil::FindDeviceGeneric");
|
|
|
|
HRESULT hr = S_OK;
|
|
BOOL bFound = FALSE;
|
|
LONG lPosNum = 0;
|
|
CComPtr<ICreateDevEnum> pCreateDevEnum;
|
|
CComPtr<IEnumMoniker> pEnumMoniker;
|
|
|
|
if ((uiFindFlag == FIND_FLAG_BY_ENUM_POS) && (plEnumPos == NULL))
|
|
{
|
|
hr = E_POINTER;
|
|
CHECK_S_OK2(hr, ("CDShow::FindDeviceGeneric requesting search by enum "
|
|
"pos, but plEnumPos is NULL"));
|
|
}
|
|
else if ((uiFindFlag == FIND_FLAG_BY_DSHOW_ID) &&
|
|
(pstrDShowDeviceID == NULL))
|
|
{
|
|
hr = E_POINTER;
|
|
CHECK_S_OK2(hr, ("CDShow::FindDeviceGeneric requesting search by "
|
|
"DShow ID, but pstrDShowDeviceID is NULL"));
|
|
}
|
|
else if ((uiFindFlag == FIND_FLAG_BY_FRIENDLY_NAME) &&
|
|
(pstrFriendlyName == NULL))
|
|
{
|
|
hr = E_POINTER;
|
|
CHECK_S_OK2(hr, ("CDShow::FindDeviceGeneric requesting search by "
|
|
"friendly name, but pstrFriendlyName is NULL"));
|
|
}
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
|
|
//
|
|
// Create the device enumerator
|
|
//
|
|
hr = CoCreateInstance(CLSID_SystemDeviceEnum,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_ICreateDevEnum,
|
|
(void**)&pCreateDevEnum);
|
|
|
|
CHECK_S_OK2(hr, ("CDShowUtil::CreateCaptureFilter failed to create "
|
|
"CLSID_SystemDeviceEnum enumerator"));
|
|
}
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
hr = pCreateDevEnum->CreateClassEnumerator(
|
|
CLSID_VideoInputDeviceCategory,
|
|
&pEnumMoniker,
|
|
0);
|
|
|
|
CHECK_S_OK2(hr, ("CDShowUtil::CreateCaptureFilter failed to "
|
|
"create enumerator for Video Input Device "
|
|
"Category"));
|
|
}
|
|
|
|
//
|
|
// Loop through all the devices
|
|
//
|
|
|
|
while ((!bFound) && (hr == S_OK))
|
|
{
|
|
CComPtr<IMoniker> pMoniker;
|
|
CComPtr<IPropertyBag> pPropertyBag;
|
|
CSimpleString strDShowDeviceID(TEXT(""));
|
|
CSimpleString strFriendlyName(TEXT(""));
|
|
|
|
hr = pEnumMoniker->Next(1, &pMoniker, NULL);
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
//
|
|
// Get property storage for this DS device so we can get it's
|
|
// device id...
|
|
//
|
|
|
|
hr = pMoniker->BindToStorage(0,
|
|
0,
|
|
IID_IPropertyBag,
|
|
(void **)&pPropertyBag);
|
|
|
|
CHECK_S_OK2(hr, ("CDShowUtil::FindDeviceGeneric, failed to "
|
|
"bind to storage"));
|
|
}
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
hr = GetDeviceProperty(pPropertyBag,
|
|
L"DevicePath",
|
|
&strDShowDeviceID);
|
|
|
|
CHECK_S_OK2(hr, ("Failed to get DevicePath for DShow # '%lu",
|
|
lPosNum));
|
|
|
|
hr = GetDeviceProperty(pPropertyBag,
|
|
L"FriendlyName",
|
|
&strFriendlyName);
|
|
|
|
CHECK_S_OK2(hr, ("Failed to get FriendlyName for DShow # '%lu",
|
|
lPosNum));
|
|
}
|
|
|
|
|
|
//
|
|
// This is the search criteria.
|
|
//
|
|
switch (uiFindFlag)
|
|
{
|
|
case FIND_FLAG_BY_ENUM_POS:
|
|
|
|
if (lPosNum == *plEnumPos)
|
|
{
|
|
bFound = TRUE;
|
|
}
|
|
|
|
break;
|
|
|
|
case FIND_FLAG_BY_DSHOW_ID:
|
|
|
|
if (pstrDShowDeviceID->CompareNoCase(strDShowDeviceID) == 0)
|
|
{
|
|
bFound = TRUE;
|
|
}
|
|
|
|
break;
|
|
|
|
case FIND_FLAG_BY_FRIENDLY_NAME:
|
|
|
|
if (pstrFriendlyName->CompareNoCase(strFriendlyName) == 0)
|
|
{
|
|
bFound = TRUE;
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
hr = E_FAIL;
|
|
break;
|
|
}
|
|
|
|
if (bFound)
|
|
{
|
|
if (pstrDShowDeviceID)
|
|
{
|
|
pstrDShowDeviceID->Assign(strDShowDeviceID);
|
|
}
|
|
|
|
if (pstrFriendlyName)
|
|
{
|
|
pstrFriendlyName->Assign(strFriendlyName);
|
|
}
|
|
|
|
if (plEnumPos)
|
|
{
|
|
*plEnumPos = lPosNum;
|
|
}
|
|
|
|
if (ppDeviceMoniker)
|
|
{
|
|
*ppDeviceMoniker = pMoniker;
|
|
(*ppDeviceMoniker)->AddRef();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
++lPosNum;
|
|
}
|
|
}
|
|
|
|
if (!bFound)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
///////////////////////////////
|
|
// FindDeviceByEnumPos
|
|
//
|
|
// Static Fn
|
|
//
|
|
HRESULT CDShowUtil::FindDeviceByEnumPos(LONG lEnumPos,
|
|
CSimpleString *pstrDShowDeviceID,
|
|
CSimpleString *pstrFriendlyName,
|
|
IMoniker **ppDeviceMoniker)
|
|
{
|
|
DBG_FN("CDShowUtil::FindDeviceByEnumPos");
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
hr = FindDeviceGeneric(FIND_FLAG_BY_ENUM_POS,
|
|
pstrDShowDeviceID,
|
|
&lEnumPos,
|
|
pstrFriendlyName,
|
|
ppDeviceMoniker);
|
|
}
|
|
|
|
CHECK_S_OK2(hr, ("CDShowUtil::FindDeviceByEnumPos failed to find a "
|
|
"Directshow device with an enum position "
|
|
"of '%lu'", lEnumPos));
|
|
|
|
return hr;
|
|
}
|
|
|
|
///////////////////////////////
|
|
// FindDeviceByFriendlyName
|
|
//
|
|
// Static Fn
|
|
//
|
|
HRESULT CDShowUtil::FindDeviceByFriendlyName(
|
|
const CSimpleString *pstrFriendlyName,
|
|
LONG *plEnumPos,
|
|
CSimpleString *pstrDShowDeviceID,
|
|
IMoniker **ppDeviceMoniker)
|
|
{
|
|
DBG_FN("CDShowUtil::FindDeviceByFriendlyName");
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
ASSERT(pstrFriendlyName != NULL);
|
|
|
|
if (pstrFriendlyName == NULL)
|
|
{
|
|
hr = E_POINTER;
|
|
CHECK_S_OK2(hr, ("CDShowUtil::FindDeviceByFriendlyName received a "
|
|
"NULL param"));
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
hr = FindDeviceGeneric(FIND_FLAG_BY_FRIENDLY_NAME,
|
|
pstrDShowDeviceID,
|
|
plEnumPos,
|
|
const_cast<CSimpleString*>(pstrFriendlyName),
|
|
ppDeviceMoniker);
|
|
}
|
|
|
|
CHECK_S_OK2(hr, ("CDShowUtil::FindDeviceByFriendlyName failed to find a "
|
|
"Directshow device named '%ls'",
|
|
pstrFriendlyName->String()));
|
|
|
|
return hr;
|
|
}
|
|
|
|
///////////////////////////////
|
|
// FindDeviceByWiaID
|
|
//
|
|
// Static Fn
|
|
//
|
|
HRESULT CDShowUtil::FindDeviceByWiaID(CWiaLink *pWiaLink,
|
|
const CSimpleString *pstrWiaDeviceID,
|
|
CSimpleString *pstrFriendlyName,
|
|
LONG *plEnumPos,
|
|
CSimpleString *pstrDShowDeviceID,
|
|
IMoniker **ppDeviceMoniker)
|
|
{
|
|
DBG_FN("CDShowUtil::FindDeviceByWiaID");
|
|
|
|
HRESULT hr = S_OK;
|
|
CSimpleStringWide strDShowID(TEXT(""));
|
|
CComPtr<IWiaPropertyStorage> pPropStorage;
|
|
|
|
ASSERT(pWiaLink != NULL);
|
|
ASSERT(pstrWiaDeviceID != NULL);
|
|
|
|
if ((pWiaLink == NULL) ||
|
|
(pstrWiaDeviceID == NULL))
|
|
{
|
|
hr = E_POINTER;
|
|
CHECK_S_OK2(hr, ("CDShowUtil::FindDeviceByWiaID received a NULL "
|
|
"param"));
|
|
|
|
return hr;
|
|
}
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
hr = pWiaLink->GetDeviceStorage(&pPropStorage);
|
|
}
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
hr = CWiaUtil::GetProperty(pPropStorage,
|
|
WIA_DPV_DSHOW_DEVICE_PATH,
|
|
&strDShowID);
|
|
}
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
//
|
|
// If all three of these are NULL, then there is no point searching,
|
|
// we already have the DShow device ID. On the other hand, if we
|
|
// want at least one of them, then we need to find the device.
|
|
//
|
|
if ((pstrFriendlyName != NULL) ||
|
|
(plEnumPos != NULL) ||
|
|
(ppDeviceMoniker != NULL))
|
|
{
|
|
hr = FindDeviceGeneric(
|
|
FIND_FLAG_BY_DSHOW_ID,
|
|
&(CSimpleStringConvert::NaturalString(strDShowID)),
|
|
plEnumPos,
|
|
pstrFriendlyName,
|
|
ppDeviceMoniker);
|
|
}
|
|
|
|
if (pstrDShowDeviceID)
|
|
{
|
|
*pstrDShowDeviceID = strDShowID;
|
|
}
|
|
}
|
|
|
|
CHECK_S_OK2(hr, ("CDShowUtil::FindDeviceByWiaID failed to find a "
|
|
"Directshow device with a WIA device ID of '%ls'",
|
|
pstrWiaDeviceID->String()));
|
|
|
|
return hr;
|
|
}
|
|
|
|
///////////////////////////////
|
|
// CreateGraphBuilder
|
|
//
|
|
//
|
|
// Static Fn
|
|
//
|
|
HRESULT CDShowUtil::CreateGraphBuilder(
|
|
ICaptureGraphBuilder2 **ppCaptureGraphBuilder,
|
|
IGraphBuilder **ppGraphBuilder)
|
|
{
|
|
DBG_FN("CDShowUtil::CreateGraphBuilder");
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
ASSERT(ppCaptureGraphBuilder != NULL);
|
|
ASSERT(ppGraphBuilder != NULL);
|
|
|
|
if ((ppCaptureGraphBuilder == NULL) ||
|
|
(ppGraphBuilder == NULL))
|
|
{
|
|
hr = E_POINTER;
|
|
CHECK_S_OK2(hr, ("CDShowUtil::CreateGraphBuilder received NULL "
|
|
"params"));
|
|
|
|
return hr;
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
//
|
|
// First, get a CaptureGraph builder
|
|
//
|
|
|
|
hr = CoCreateInstance(CLSID_CaptureGraphBuilder2,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_ICaptureGraphBuilder2,
|
|
(void**)ppCaptureGraphBuilder);
|
|
|
|
CHECK_S_OK2( hr, ("CDShowUtil::CreateGraphBuilder, failed to create "
|
|
"the DShow Capture Graph Builder object"));
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = CoCreateInstance(CLSID_FilterGraph,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_IGraphBuilder,
|
|
(void**)ppGraphBuilder);
|
|
|
|
CHECK_S_OK2( hr, ("CDShowUtil::CreateGraphBuilder, failed to create "
|
|
"the DShow Filter Graph Object"));
|
|
}
|
|
|
|
|
|
if (SUCCEEDED(hr) && (*ppCaptureGraphBuilder) && (*ppGraphBuilder))
|
|
{
|
|
hr = (*ppCaptureGraphBuilder)->SetFiltergraph(*ppGraphBuilder);
|
|
|
|
CHECK_S_OK2( hr, ("CDShowUtil::CreateGraphBuilder, failed to set "
|
|
"the capture graph builder's filter graph object"));
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
///////////////////////////////
|
|
// TurnOffGraphClock
|
|
//
|
|
// Turn off the clock that the
|
|
// graph would use so that
|
|
// the graph won't drop frames
|
|
// if some frames are delivered
|
|
// late.
|
|
//
|
|
//
|
|
HRESULT CDShowUtil::TurnOffGraphClock(IGraphBuilder *pGraphBuilder)
|
|
{
|
|
DBG_FN("CDShowUtil::TurnOffGraphClock");
|
|
|
|
ASSERT(pGraphBuilder != NULL);
|
|
|
|
HRESULT hr = S_OK;
|
|
CComPtr<IMediaFilter> pMediaFilter;
|
|
|
|
if (pGraphBuilder == NULL)
|
|
{
|
|
hr = E_POINTER;
|
|
CHECK_S_OK2(hr, ("CDShowUtil::TurnOffGraphClock received a NULL pointer"));
|
|
}
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
hr = pGraphBuilder->QueryInterface(IID_IMediaFilter, (void**) &pMediaFilter);
|
|
}
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
hr = pMediaFilter->SetSyncSource(NULL);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
///////////////////////////////
|
|
// SetPreferredVideoFormat
|
|
//
|
|
// This builds the preview graph
|
|
// based on the device ID we
|
|
// pass it.
|
|
//
|
|
HRESULT CDShowUtil::SetPreferredVideoFormat(IPin *pCapturePin,
|
|
const GUID *pPreferredSubType,
|
|
LONG lPreferredWidth,
|
|
LONG lPreferredHeight,
|
|
CWiaVideoProperties *pVideoProperties)
|
|
{
|
|
ASSERT(pCapturePin != NULL);
|
|
ASSERT(pPreferredSubType != NULL);
|
|
ASSERT(pVideoProperties != NULL);
|
|
|
|
DBG_FN("CDShowUtil::SetPreferredVideoFormat");
|
|
|
|
CComPtr<IAMStreamConfig> pStreamConfig;
|
|
HRESULT hr = S_OK;
|
|
INT iCount = 0;
|
|
INT iSize = 0;
|
|
INT iIndex = 0;
|
|
BOOL bDone = FALSE;
|
|
BYTE *pConfig = NULL;
|
|
AM_MEDIA_TYPE *pMediaType = NULL;
|
|
AM_MEDIA_TYPE *pFoundType = NULL;
|
|
VIDEOINFOHEADER *pVideoInfo = NULL;
|
|
|
|
//
|
|
// Check for invalid parameters
|
|
//
|
|
if ((pCapturePin == NULL) ||
|
|
(pPreferredSubType == NULL) ||
|
|
(pVideoProperties == NULL))
|
|
{
|
|
hr = E_POINTER;
|
|
CHECK_S_OK2(hr, ("ERROR: CDShowUtil::SetPreferredFormat "
|
|
"received a NULL param"));
|
|
}
|
|
|
|
//
|
|
// Attempt to get the stream config interface on this pin. Not
|
|
// all capture filters will allow you to configure them, so if
|
|
// this fails, we will just exit the function, and the BuildPreviewGraph
|
|
// function will attempt to render the graph with the default settings
|
|
// of the pin.
|
|
//
|
|
if (hr == S_OK)
|
|
{
|
|
hr = pCapturePin->QueryInterface(IID_IAMStreamConfig, (void**) &pStreamConfig);
|
|
}
|
|
|
|
//
|
|
// We can configure this pin, so lets see how many options it has.
|
|
//
|
|
if (hr == S_OK)
|
|
{
|
|
hr = pStreamConfig->GetNumberOfCapabilities(&iCount, &iSize);
|
|
}
|
|
|
|
//
|
|
// We need to alloc memory for the GetStreamCaps function below.
|
|
//
|
|
if (hr == S_OK)
|
|
{
|
|
pConfig = new BYTE[iSize];
|
|
|
|
if (pConfig == NULL)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
|
|
while ((hr == S_OK) && (iIndex < iCount) && (!bDone))
|
|
{
|
|
//
|
|
// Clear out the memory
|
|
//
|
|
ZeroMemory(pConfig, iSize);
|
|
|
|
//
|
|
// Get the capabilities for the stream. There are iCount options,
|
|
// we will iterate searching for the best one.
|
|
//
|
|
hr = pStreamConfig->GetStreamCaps(iIndex, &pMediaType, pConfig);
|
|
|
|
if ((hr == S_OK) && (pMediaType))
|
|
{
|
|
pVideoInfo = NULL;
|
|
|
|
//
|
|
// We successfully got the media type, check to see if it is
|
|
// a VideoInfo, if not we are not interested.
|
|
//
|
|
if (pMediaType->formattype == FORMAT_VideoInfo)
|
|
{
|
|
pVideoInfo = reinterpret_cast<VIDEOINFOHEADER*>(pMediaType->pbFormat);
|
|
}
|
|
|
|
if (pVideoInfo)
|
|
{
|
|
//
|
|
// Check to see if this option contains the preferred settings we
|
|
// are looking for.
|
|
//
|
|
|
|
if ((pMediaType->subtype == *pPreferredSubType) &&
|
|
(pVideoInfo->bmiHeader.biWidth == lPreferredWidth) &&
|
|
(pVideoInfo->bmiHeader.biHeight == lPreferredHeight))
|
|
{
|
|
//
|
|
// Is this our ideal media type. That is, does it have the
|
|
// preferred subtype we want and the preferred width and height.
|
|
// If so, then great, we can't do better than this, so exit the loop.
|
|
//
|
|
|
|
if (pFoundType)
|
|
{
|
|
DeleteMediaType(pFoundType);
|
|
pFoundType = NULL;
|
|
}
|
|
|
|
pFoundType = pMediaType;
|
|
bDone = TRUE;
|
|
}
|
|
else if ((pVideoInfo->bmiHeader.biWidth == lPreferredWidth) &&
|
|
(pVideoInfo->bmiHeader.biHeight == lPreferredHeight))
|
|
{
|
|
//
|
|
// Okay, we found a media type with the width and height that
|
|
// we would like, but we it doesn't have our preferred subtype.
|
|
// So lets hang on to this media subtype, but continue looking,
|
|
// maybe we will find something better. If we don't, then
|
|
// we will use this media type anyway.
|
|
//
|
|
|
|
if (pFoundType)
|
|
{
|
|
DeleteMediaType(pFoundType);
|
|
pFoundType = NULL;
|
|
}
|
|
|
|
pFoundType = pMediaType;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// This media type is not even close to what we want, so
|
|
// delete it and keep looking.
|
|
//
|
|
//
|
|
DeleteMediaType(pMediaType);
|
|
pMediaType = NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DeleteMediaType(pMediaType);
|
|
pMediaType = NULL;
|
|
}
|
|
}
|
|
|
|
++iIndex;
|
|
}
|
|
|
|
//
|
|
// Set the format on the output pin if we found a good one.
|
|
//
|
|
if (pFoundType)
|
|
{
|
|
WCHAR szGUID[CHARS_IN_GUID] = {0};
|
|
|
|
GUIDToString(pFoundType->subtype, szGUID, sizeof(szGUID) / sizeof(WCHAR));
|
|
|
|
DBG_TRC(("CDShowUtil::SetPreferredVideoFormat, setting "
|
|
"capture pin's settings to MediaSubType = '%ls', "
|
|
"Video Width = %lu, Video Height = %lu",
|
|
szGUID, lPreferredWidth, lPreferredHeight));
|
|
|
|
hr = pStreamConfig->SetFormat(pFoundType);
|
|
|
|
//
|
|
// ***Pay attention***
|
|
//
|
|
// We set the new media type in the pVideoProperties object. If
|
|
// the media type is already set, we delete it first, then set a new
|
|
// one.
|
|
//
|
|
if (hr == S_OK)
|
|
{
|
|
pVideoProperties->pVideoInfoHeader = NULL;
|
|
|
|
if (pVideoProperties->pMediaType)
|
|
{
|
|
DeleteMediaType(pVideoProperties->pMediaType);
|
|
}
|
|
|
|
pVideoProperties->pMediaType = pFoundType;
|
|
pVideoProperties->pVideoInfoHeader = reinterpret_cast<VIDEOINFOHEADER*>(pFoundType->pbFormat);
|
|
}
|
|
|
|
pFoundType = NULL;
|
|
}
|
|
|
|
delete [] pConfig;
|
|
|
|
return hr;
|
|
}
|
|
|
|
///////////////////////////////
|
|
// GetFrameRate
|
|
//
|
|
HRESULT CDShowUtil::GetFrameRate(IPin *pCapturePin,
|
|
LONG *plFrameRate)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CComPtr<IAMStreamConfig> pStreamConfig;
|
|
AM_MEDIA_TYPE *pMediaType = NULL;
|
|
|
|
//
|
|
// Check for invalid parameters
|
|
//
|
|
if ((pCapturePin == NULL) ||
|
|
(plFrameRate == NULL))
|
|
{
|
|
hr = E_POINTER;
|
|
CHECK_S_OK2(hr, ("ERROR: CDShowUtil::GetFrameRate "
|
|
"received a NULL param"));
|
|
}
|
|
|
|
//
|
|
// Attempt to get the stream config interface on this pin. Not
|
|
// all capture filters will allow you to configure them, so if
|
|
// this fails, we will just exit the function.
|
|
//
|
|
if (hr == S_OK)
|
|
{
|
|
hr = pCapturePin->QueryInterface(IID_IAMStreamConfig, (void**) &pStreamConfig);
|
|
}
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
hr = pStreamConfig->GetFormat(&pMediaType);
|
|
}
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
if (pMediaType->formattype == FORMAT_VideoInfo)
|
|
{
|
|
VIDEOINFOHEADER *pHdr = reinterpret_cast<VIDEOINFOHEADER*>(pMediaType->pbFormat);
|
|
|
|
*plFrameRate = (LONG) (pHdr->AvgTimePerFrame / 10000000);
|
|
}
|
|
}
|
|
|
|
if (pMediaType)
|
|
{
|
|
DeleteMediaType(pMediaType);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
///////////////////////////////
|
|
// SetFrameRate
|
|
//
|
|
HRESULT CDShowUtil::SetFrameRate(IPin *pCapturePin,
|
|
LONG lNewFrameRate,
|
|
CWiaVideoProperties *pVideoProperties)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CComPtr<IAMStreamConfig> pStreamConfig;
|
|
|
|
//
|
|
// Check for invalid parameters
|
|
//
|
|
if (pCapturePin == NULL)
|
|
{
|
|
hr = E_POINTER;
|
|
CHECK_S_OK2(hr, ("ERROR: CDShowUtil::SetFrameRate "
|
|
"received a NULL param"));
|
|
}
|
|
|
|
//
|
|
// Attempt to get the stream config interface on this pin. Not
|
|
// all capture filters will allow you to configure them, so if
|
|
// this fails, we will just exit the function.
|
|
//
|
|
if (hr == S_OK)
|
|
{
|
|
hr = pCapturePin->QueryInterface(IID_IAMStreamConfig, (void**) &pStreamConfig);
|
|
}
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
AM_MEDIA_TYPE *pMediaType = NULL;
|
|
|
|
hr = pStreamConfig->GetFormat(&pMediaType);
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
if (pMediaType->formattype == FORMAT_VideoInfo)
|
|
{
|
|
VIDEOINFOHEADER *pHdr = reinterpret_cast<VIDEOINFOHEADER*>(pMediaType->pbFormat);
|
|
|
|
pHdr->AvgTimePerFrame = (LONGLONG)(10000000 / lNewFrameRate);
|
|
|
|
hr = pStreamConfig->SetFormat(pMediaType);
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
if (pVideoProperties)
|
|
{
|
|
pVideoProperties->dwFrameRate = lNewFrameRate;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DBG_WRN(("CDShowUtil::SetFrameRate, failed to set frame rate, "
|
|
"hr = %08lx, this is not fatal", hr));
|
|
}
|
|
}
|
|
}
|
|
|
|
if (pMediaType)
|
|
{
|
|
DeleteMediaType(pMediaType);
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
///////////////////////////////
|
|
// GetVideoProperties
|
|
//
|
|
HRESULT CDShowUtil::GetVideoProperties(IBaseFilter *pCaptureFilter,
|
|
IPin *pCapturePin,
|
|
CWiaVideoProperties *pVideoProperties)
|
|
{
|
|
USES_CONVERSION;
|
|
|
|
ASSERT(pCaptureFilter != NULL);
|
|
ASSERT(pCapturePin != NULL);
|
|
ASSERT(pVideoProperties != NULL);
|
|
|
|
HRESULT hr = S_OK;
|
|
CComPtr<IAMStreamConfig> pStreamConfig;
|
|
|
|
if ((pCaptureFilter == NULL) ||
|
|
(pCapturePin == NULL) ||
|
|
(pVideoProperties == NULL))
|
|
{
|
|
hr = E_POINTER;
|
|
CHECK_S_OK2(hr, ("CDShowUtil::GetVideoProperties received a NULL pointer"));
|
|
return hr;
|
|
}
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
hr = pCapturePin->QueryInterface(IID_IAMStreamConfig, (void**) &pStreamConfig);
|
|
}
|
|
|
|
//
|
|
// Get the current AM_MEDIA_TYPE. Notice that we do not call DeleteMediaType. It is
|
|
// stored in the CWiaVideoProperties and deleted when the object is freed.
|
|
//
|
|
if (hr == S_OK)
|
|
{
|
|
hr = pStreamConfig->GetFormat(&pVideoProperties->pMediaType);
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
if (pVideoProperties->pMediaType->formattype == FORMAT_VideoInfo)
|
|
{
|
|
pVideoProperties->pVideoInfoHeader = reinterpret_cast<VIDEOINFOHEADER*>(pVideoProperties->pMediaType->pbFormat);
|
|
}
|
|
}
|
|
|
|
CHECK_S_OK2(hr, ("CDShowUtil::GetVideoProperties, failed to get AM_MEDIA_TYPE"));
|
|
|
|
hr = S_OK;
|
|
}
|
|
|
|
//
|
|
// Get the frame rate.
|
|
//
|
|
if (hr == S_OK)
|
|
{
|
|
pVideoProperties->dwFrameRate = (DWORD) (pVideoProperties->pVideoInfoHeader->AvgTimePerFrame / 10000000);
|
|
}
|
|
|
|
//
|
|
// Get all the picture attributes we can.
|
|
//
|
|
if (hr == S_OK)
|
|
{
|
|
HRESULT hrRange = S_OK;
|
|
HRESULT hrValue = S_OK;
|
|
|
|
CComPtr<IAMVideoProcAmp> pVideoProcAmp;
|
|
|
|
hr = pCaptureFilter->QueryInterface(IID_IAMVideoProcAmp, (void**) &pVideoProcAmp);
|
|
|
|
if (pVideoProcAmp)
|
|
{
|
|
pVideoProperties->bPictureAttributesUsed = TRUE;
|
|
|
|
//
|
|
// Brightness
|
|
//
|
|
pVideoProperties->Brightness.Name = VideoProcAmp_Brightness;
|
|
hrRange = pVideoProcAmp->GetRange(pVideoProperties->Brightness.Name,
|
|
&pVideoProperties->Brightness.lMinValue,
|
|
&pVideoProperties->Brightness.lMaxValue,
|
|
&pVideoProperties->Brightness.lIncrement,
|
|
&pVideoProperties->Brightness.lDefaultValue,
|
|
(long*) &pVideoProperties->Brightness.ValidFlags);
|
|
|
|
hrValue = pVideoProcAmp->Get(pVideoProperties->Brightness.Name,
|
|
&pVideoProperties->Brightness.lCurrentValue,
|
|
(long*) &pVideoProperties->Brightness.CurrentFlag);
|
|
|
|
if ((hrRange != S_OK) || (hrValue != S_OK))
|
|
{
|
|
pVideoProperties->Brightness.bUsed = FALSE;
|
|
}
|
|
else
|
|
{
|
|
pVideoProperties->Brightness.bUsed = TRUE;
|
|
}
|
|
|
|
//
|
|
// Contrast
|
|
//
|
|
pVideoProperties->Contrast.Name = VideoProcAmp_Contrast;
|
|
hrRange = pVideoProcAmp->GetRange(pVideoProperties->Contrast.Name,
|
|
&pVideoProperties->Contrast.lMinValue,
|
|
&pVideoProperties->Contrast.lMaxValue,
|
|
&pVideoProperties->Contrast.lIncrement,
|
|
&pVideoProperties->Contrast.lDefaultValue,
|
|
(long*) &pVideoProperties->Contrast.ValidFlags);
|
|
|
|
hrValue = pVideoProcAmp->Get(pVideoProperties->Contrast.Name,
|
|
&pVideoProperties->Contrast.lCurrentValue,
|
|
(long*) &pVideoProperties->Contrast.CurrentFlag);
|
|
|
|
if ((hrRange != S_OK) || (hrValue != S_OK))
|
|
{
|
|
pVideoProperties->Contrast.bUsed = FALSE;
|
|
}
|
|
else
|
|
{
|
|
pVideoProperties->Contrast.bUsed = TRUE;
|
|
}
|
|
|
|
//
|
|
// Hue
|
|
//
|
|
pVideoProperties->Hue.Name = VideoProcAmp_Hue;
|
|
hrRange = pVideoProcAmp->GetRange(pVideoProperties->Hue.Name,
|
|
&pVideoProperties->Hue.lMinValue,
|
|
&pVideoProperties->Hue.lMaxValue,
|
|
&pVideoProperties->Hue.lIncrement,
|
|
&pVideoProperties->Hue.lDefaultValue,
|
|
(long*) &pVideoProperties->Hue.ValidFlags);
|
|
|
|
hrValue = pVideoProcAmp->Get(pVideoProperties->Hue.Name,
|
|
&pVideoProperties->Hue.lCurrentValue,
|
|
(long*) &pVideoProperties->Hue.CurrentFlag);
|
|
|
|
if ((hrRange != S_OK) || (hrValue != S_OK))
|
|
{
|
|
pVideoProperties->Hue.bUsed = FALSE;
|
|
}
|
|
else
|
|
{
|
|
pVideoProperties->Hue.bUsed = TRUE;
|
|
}
|
|
|
|
|
|
//
|
|
// Saturation
|
|
//
|
|
pVideoProperties->Saturation.Name = VideoProcAmp_Saturation;
|
|
hrRange = pVideoProcAmp->GetRange(pVideoProperties->Saturation.Name,
|
|
&pVideoProperties->Saturation.lMinValue,
|
|
&pVideoProperties->Saturation.lMaxValue,
|
|
&pVideoProperties->Saturation.lIncrement,
|
|
&pVideoProperties->Saturation.lDefaultValue,
|
|
(long*) &pVideoProperties->Saturation.ValidFlags);
|
|
|
|
hrValue = pVideoProcAmp->Get(pVideoProperties->Saturation.Name,
|
|
&pVideoProperties->Saturation.lCurrentValue,
|
|
(long*) &pVideoProperties->Saturation.CurrentFlag);
|
|
|
|
if ((hrRange != S_OK) || (hrValue != S_OK))
|
|
{
|
|
pVideoProperties->Saturation.bUsed = FALSE;
|
|
}
|
|
else
|
|
{
|
|
pVideoProperties->Saturation.bUsed = TRUE;
|
|
}
|
|
|
|
|
|
//
|
|
// Sharpness
|
|
//
|
|
pVideoProperties->Sharpness.Name = VideoProcAmp_Sharpness;
|
|
hrRange = pVideoProcAmp->GetRange(pVideoProperties->Sharpness.Name,
|
|
&pVideoProperties->Sharpness.lMinValue,
|
|
&pVideoProperties->Sharpness.lMaxValue,
|
|
&pVideoProperties->Sharpness.lIncrement,
|
|
&pVideoProperties->Sharpness.lDefaultValue,
|
|
(long*) &pVideoProperties->Sharpness.ValidFlags);
|
|
|
|
hrValue = pVideoProcAmp->Get(pVideoProperties->Sharpness.Name,
|
|
&pVideoProperties->Sharpness.lCurrentValue,
|
|
(long*) &pVideoProperties->Sharpness.CurrentFlag);
|
|
|
|
if ((hrRange != S_OK) || (hrValue != S_OK))
|
|
{
|
|
pVideoProperties->Sharpness.bUsed = FALSE;
|
|
}
|
|
else
|
|
{
|
|
pVideoProperties->Sharpness.bUsed = TRUE;
|
|
}
|
|
|
|
|
|
//
|
|
// Gamma
|
|
//
|
|
pVideoProperties->Gamma.Name = VideoProcAmp_Gamma;
|
|
hrRange = pVideoProcAmp->GetRange(pVideoProperties->Gamma.Name,
|
|
&pVideoProperties->Gamma.lMinValue,
|
|
&pVideoProperties->Gamma.lMaxValue,
|
|
&pVideoProperties->Gamma.lIncrement,
|
|
&pVideoProperties->Gamma.lDefaultValue,
|
|
(long*) &pVideoProperties->Gamma.ValidFlags);
|
|
|
|
hrValue = pVideoProcAmp->Get(pVideoProperties->Gamma.Name,
|
|
&pVideoProperties->Gamma.lCurrentValue,
|
|
(long*) &pVideoProperties->Gamma.CurrentFlag);
|
|
|
|
if ((hrRange != S_OK) || (hrValue != S_OK))
|
|
{
|
|
pVideoProperties->Gamma.bUsed = FALSE;
|
|
}
|
|
else
|
|
{
|
|
pVideoProperties->Gamma.bUsed = TRUE;
|
|
}
|
|
|
|
|
|
//
|
|
// ColorEnable
|
|
//
|
|
pVideoProperties->ColorEnable.Name = VideoProcAmp_ColorEnable;
|
|
hrRange = pVideoProcAmp->GetRange(pVideoProperties->ColorEnable.Name,
|
|
&pVideoProperties->ColorEnable.lMinValue,
|
|
&pVideoProperties->ColorEnable.lMaxValue,
|
|
&pVideoProperties->ColorEnable.lIncrement,
|
|
&pVideoProperties->ColorEnable.lDefaultValue,
|
|
(long*) &pVideoProperties->ColorEnable.ValidFlags);
|
|
|
|
hrValue = pVideoProcAmp->Get(pVideoProperties->ColorEnable.Name,
|
|
&pVideoProperties->ColorEnable.lCurrentValue,
|
|
(long*) &pVideoProperties->ColorEnable.CurrentFlag);
|
|
|
|
if ((hrRange != S_OK) || (hrValue != S_OK))
|
|
{
|
|
pVideoProperties->ColorEnable.bUsed = FALSE;
|
|
}
|
|
else
|
|
{
|
|
pVideoProperties->ColorEnable.bUsed = TRUE;
|
|
}
|
|
|
|
|
|
//
|
|
// WhiteBalance
|
|
//
|
|
pVideoProperties->WhiteBalance.Name = VideoProcAmp_WhiteBalance;
|
|
hrRange = pVideoProcAmp->GetRange(pVideoProperties->WhiteBalance.Name,
|
|
&pVideoProperties->WhiteBalance.lMinValue,
|
|
&pVideoProperties->WhiteBalance.lMaxValue,
|
|
&pVideoProperties->WhiteBalance.lIncrement,
|
|
&pVideoProperties->WhiteBalance.lDefaultValue,
|
|
(long*) &pVideoProperties->WhiteBalance.ValidFlags);
|
|
|
|
hrValue = pVideoProcAmp->Get(pVideoProperties->WhiteBalance.Name,
|
|
&pVideoProperties->WhiteBalance.lCurrentValue,
|
|
(long*) &pVideoProperties->WhiteBalance.CurrentFlag);
|
|
|
|
if ((hrRange != S_OK) || (hrValue != S_OK))
|
|
{
|
|
pVideoProperties->WhiteBalance.bUsed = FALSE;
|
|
}
|
|
else
|
|
{
|
|
pVideoProperties->WhiteBalance.bUsed = TRUE;
|
|
}
|
|
|
|
|
|
//
|
|
// BacklightCompensation
|
|
//
|
|
pVideoProperties->BacklightCompensation.Name = VideoProcAmp_BacklightCompensation;
|
|
hrRange = pVideoProcAmp->GetRange(pVideoProperties->BacklightCompensation.Name,
|
|
&pVideoProperties->BacklightCompensation.lMinValue,
|
|
&pVideoProperties->BacklightCompensation.lMaxValue,
|
|
&pVideoProperties->BacklightCompensation.lIncrement,
|
|
&pVideoProperties->BacklightCompensation.lDefaultValue,
|
|
(long*) &pVideoProperties->BacklightCompensation.ValidFlags);
|
|
|
|
hrValue = pVideoProcAmp->Get(pVideoProperties->BacklightCompensation.Name,
|
|
&pVideoProperties->BacklightCompensation.lCurrentValue,
|
|
(long*) &pVideoProperties->BacklightCompensation.CurrentFlag);
|
|
|
|
if ((hrRange != S_OK) || (hrValue != S_OK))
|
|
{
|
|
pVideoProperties->BacklightCompensation.bUsed = FALSE;
|
|
}
|
|
else
|
|
{
|
|
pVideoProperties->BacklightCompensation.bUsed = TRUE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pVideoProperties->bPictureAttributesUsed = FALSE;
|
|
}
|
|
|
|
hr = S_OK;
|
|
}
|
|
|
|
//
|
|
// Get all the camera attributes we can.
|
|
//
|
|
if (hr == S_OK)
|
|
{
|
|
HRESULT hrRange = S_OK;
|
|
HRESULT hrValue = S_OK;
|
|
|
|
CComPtr<IAMCameraControl> pCameraControl;
|
|
|
|
hr = pCaptureFilter->QueryInterface(IID_IAMCameraControl, (void**) &pCameraControl);
|
|
|
|
if (pCameraControl)
|
|
{
|
|
pVideoProperties->bCameraAttributesUsed = TRUE;
|
|
|
|
//
|
|
// Pan
|
|
//
|
|
pVideoProperties->Pan.Name = CameraControl_Pan;
|
|
hrRange = pCameraControl->GetRange(pVideoProperties->Pan.Name,
|
|
&pVideoProperties->Pan.lMinValue,
|
|
&pVideoProperties->Pan.lMaxValue,
|
|
&pVideoProperties->Pan.lIncrement,
|
|
&pVideoProperties->Pan.lDefaultValue,
|
|
(long*) &pVideoProperties->Pan.ValidFlags);
|
|
|
|
hrValue = pCameraControl->Get(pVideoProperties->Pan.Name,
|
|
&pVideoProperties->Pan.lCurrentValue,
|
|
(long*) &pVideoProperties->Pan.CurrentFlag);
|
|
|
|
if ((hrRange != S_OK) || (hrValue != S_OK))
|
|
{
|
|
pVideoProperties->Pan.bUsed = FALSE;
|
|
}
|
|
else
|
|
{
|
|
pVideoProperties->Pan.bUsed = TRUE;
|
|
}
|
|
|
|
//
|
|
// Tilt
|
|
//
|
|
pVideoProperties->Tilt.Name = CameraControl_Tilt;
|
|
hrRange = pCameraControl->GetRange(pVideoProperties->Tilt.Name,
|
|
&pVideoProperties->Tilt.lMinValue,
|
|
&pVideoProperties->Tilt.lMaxValue,
|
|
&pVideoProperties->Tilt.lIncrement,
|
|
&pVideoProperties->Tilt.lDefaultValue,
|
|
(long*) &pVideoProperties->Tilt.ValidFlags);
|
|
|
|
hrValue = pCameraControl->Get(pVideoProperties->Tilt.Name,
|
|
&pVideoProperties->Tilt.lCurrentValue,
|
|
(long*) &pVideoProperties->Tilt.CurrentFlag);
|
|
|
|
if ((hrRange != S_OK) || (hrValue != S_OK))
|
|
{
|
|
pVideoProperties->Tilt.bUsed = FALSE;
|
|
}
|
|
else
|
|
{
|
|
pVideoProperties->Tilt.bUsed = TRUE;
|
|
}
|
|
|
|
|
|
//
|
|
// Roll
|
|
//
|
|
pVideoProperties->Roll.Name = CameraControl_Roll;
|
|
hrRange = pCameraControl->GetRange(pVideoProperties->Roll.Name,
|
|
&pVideoProperties->Roll.lMinValue,
|
|
&pVideoProperties->Roll.lMaxValue,
|
|
&pVideoProperties->Roll.lIncrement,
|
|
&pVideoProperties->Roll.lDefaultValue,
|
|
(long*) &pVideoProperties->Roll.ValidFlags);
|
|
|
|
hrValue = pCameraControl->Get(pVideoProperties->Roll.Name,
|
|
&pVideoProperties->Roll.lCurrentValue,
|
|
(long*) &pVideoProperties->Roll.CurrentFlag);
|
|
|
|
if ((hrRange != S_OK) || (hrValue != S_OK))
|
|
{
|
|
pVideoProperties->Roll.bUsed = FALSE;
|
|
}
|
|
else
|
|
{
|
|
pVideoProperties->Roll.bUsed = TRUE;
|
|
}
|
|
|
|
|
|
//
|
|
// Zoom
|
|
//
|
|
pVideoProperties->Zoom.Name = CameraControl_Zoom;
|
|
hrRange = pCameraControl->GetRange(pVideoProperties->Zoom.Name,
|
|
&pVideoProperties->Zoom.lMinValue,
|
|
&pVideoProperties->Zoom.lMaxValue,
|
|
&pVideoProperties->Zoom.lIncrement,
|
|
&pVideoProperties->Zoom.lDefaultValue,
|
|
(long*) &pVideoProperties->Zoom.ValidFlags);
|
|
|
|
hrValue = pCameraControl->Get(pVideoProperties->Zoom.Name,
|
|
&pVideoProperties->Zoom.lCurrentValue,
|
|
(long*) &pVideoProperties->Zoom.CurrentFlag);
|
|
|
|
if ((hrRange != S_OK) || (hrValue != S_OK))
|
|
{
|
|
pVideoProperties->Zoom.bUsed = FALSE;
|
|
}
|
|
else
|
|
{
|
|
pVideoProperties->Zoom.bUsed = TRUE;
|
|
}
|
|
|
|
//
|
|
// Exposure
|
|
//
|
|
pVideoProperties->Exposure.Name = CameraControl_Exposure;
|
|
hrRange = pCameraControl->GetRange(pVideoProperties->Exposure.Name,
|
|
&pVideoProperties->Exposure.lMinValue,
|
|
&pVideoProperties->Exposure.lMaxValue,
|
|
&pVideoProperties->Exposure.lIncrement,
|
|
&pVideoProperties->Exposure.lDefaultValue,
|
|
(long*) &pVideoProperties->Exposure.ValidFlags);
|
|
|
|
hrValue = pCameraControl->Get(pVideoProperties->Exposure.Name,
|
|
&pVideoProperties->Exposure.lCurrentValue,
|
|
(long*) &pVideoProperties->Exposure.CurrentFlag);
|
|
|
|
if ((hrRange != S_OK) || (hrValue != S_OK))
|
|
{
|
|
pVideoProperties->Exposure.bUsed = FALSE;
|
|
}
|
|
else
|
|
{
|
|
pVideoProperties->Exposure.bUsed = TRUE;
|
|
}
|
|
|
|
|
|
//
|
|
// Iris
|
|
//
|
|
pVideoProperties->Iris.Name = CameraControl_Iris;
|
|
hrRange = pCameraControl->GetRange(pVideoProperties->Iris.Name,
|
|
&pVideoProperties->Iris.lMinValue,
|
|
&pVideoProperties->Iris.lMaxValue,
|
|
&pVideoProperties->Iris.lIncrement,
|
|
&pVideoProperties->Iris.lDefaultValue,
|
|
(long*) &pVideoProperties->Iris.ValidFlags);
|
|
|
|
hrValue = pCameraControl->Get(pVideoProperties->Iris.Name,
|
|
&pVideoProperties->Iris.lCurrentValue,
|
|
(long*) &pVideoProperties->Iris.CurrentFlag);
|
|
|
|
if ((hrRange != S_OK) || (hrValue != S_OK))
|
|
{
|
|
pVideoProperties->Iris.bUsed = FALSE;
|
|
}
|
|
else
|
|
{
|
|
pVideoProperties->Iris.bUsed = TRUE;
|
|
}
|
|
|
|
//
|
|
// Focus
|
|
//
|
|
pVideoProperties->Focus.Name = CameraControl_Focus;
|
|
hrRange = pCameraControl->GetRange(pVideoProperties->Focus.Name,
|
|
&pVideoProperties->Focus.lMinValue,
|
|
&pVideoProperties->Focus.lMaxValue,
|
|
&pVideoProperties->Focus.lIncrement,
|
|
&pVideoProperties->Focus.lDefaultValue,
|
|
(long*) &pVideoProperties->Focus.ValidFlags);
|
|
|
|
hrValue = pCameraControl->Get(pVideoProperties->Focus.Name,
|
|
&pVideoProperties->Focus.lCurrentValue,
|
|
(long*) &pVideoProperties->Focus.CurrentFlag);
|
|
|
|
if ((hrRange != S_OK) || (hrValue != S_OK))
|
|
{
|
|
pVideoProperties->Focus.bUsed = FALSE;
|
|
}
|
|
else
|
|
{
|
|
pVideoProperties->Focus.bUsed = TRUE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pVideoProperties->bCameraAttributesUsed = FALSE;
|
|
}
|
|
|
|
hr = S_OK;
|
|
}
|
|
|
|
if (pVideoProperties->szWiaDeviceID[0] != 0)
|
|
{
|
|
CComPtr<IStillImage> pSti = NULL;
|
|
TCHAR szGUID[CHARS_IN_GUID + 1] = {0};
|
|
|
|
pVideoProperties->PreferredSettingsMask = 0;
|
|
|
|
hr = StiCreateInstance(_Module.GetModuleInstance(),
|
|
STI_VERSION,
|
|
&pSti,
|
|
NULL);
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
DWORD dwType = REG_DWORD;
|
|
DWORD dwSize = sizeof(pVideoProperties->PreferredWidth);
|
|
|
|
hr = pSti->GetDeviceValue(T2W(pVideoProperties->szWiaDeviceID),
|
|
T2W((TCHAR*)REG_VAL_PREFERRED_VIDEO_WIDTH),
|
|
&dwType,
|
|
(BYTE*) &pVideoProperties->PreferredWidth,
|
|
&dwSize);
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
dwSize = sizeof(pVideoProperties->PreferredHeight);
|
|
|
|
hr = pSti->GetDeviceValue(T2W(pVideoProperties->szWiaDeviceID),
|
|
T2W((TCHAR*) REG_VAL_PREFERRED_VIDEO_HEIGHT),
|
|
&dwType,
|
|
(BYTE*) &pVideoProperties->PreferredHeight,
|
|
&dwSize);
|
|
}
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
pVideoProperties->PreferredSettingsMask |= PREFERRED_SETTING_MASK_VIDEO_WIDTH_HEIGHT;
|
|
}
|
|
|
|
hr = S_OK;
|
|
}
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
DWORD dwType = REG_SZ;
|
|
DWORD dwSize = sizeof(szGUID);
|
|
|
|
hr = pSti->GetDeviceValue(T2W(pVideoProperties->szWiaDeviceID),
|
|
T2W((TCHAR*)REG_VAL_PREFERRED_MEDIASUBTYPE),
|
|
&dwType,
|
|
(BYTE*) szGUID,
|
|
&dwSize);
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
CLSIDFromString(T2OLE(szGUID), &pVideoProperties->PreferredMediaSubType);
|
|
pVideoProperties->PreferredSettingsMask |= PREFERRED_SETTING_MASK_MEDIASUBTYPE;
|
|
}
|
|
|
|
hr = S_OK;
|
|
}
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
DWORD dwType = REG_SZ;
|
|
DWORD dwSize = sizeof(pVideoProperties->PreferredFrameRate);
|
|
|
|
|
|
hr = pSti->GetDeviceValue(T2W(pVideoProperties->szWiaDeviceID),
|
|
T2W((TCHAR*) REG_VAL_PREFERRED_VIDEO_FRAMERATE),
|
|
&dwType,
|
|
(BYTE*) &pVideoProperties->PreferredFrameRate,
|
|
&dwSize);
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
pVideoProperties->PreferredSettingsMask |= PREFERRED_SETTING_MASK_VIDEO_FRAMERATE;
|
|
}
|
|
|
|
hr = S_OK;
|
|
}
|
|
|
|
DBG_TRC(("Settings found for Device '%ls' in DeviceData section of INF file",
|
|
pVideoProperties->szWiaDeviceID));
|
|
|
|
DBG_PRT((" PreferredVideoWidth = '%lu', Is In INF and value is of type REG_DWORD? '%ls'",
|
|
pVideoProperties->PreferredWidth,
|
|
(pVideoProperties->PreferredSettingsMask &
|
|
PREFERRED_SETTING_MASK_VIDEO_WIDTH_HEIGHT) ? _T("TRUE") : _T("FALSE")));
|
|
|
|
DBG_PRT((" PreferredVideoHeight = '%lu', Is In INF and value is of type REG_DWORD? '%ls'",
|
|
pVideoProperties->PreferredHeight,
|
|
(pVideoProperties->PreferredSettingsMask &
|
|
PREFERRED_SETTING_MASK_VIDEO_WIDTH_HEIGHT) ? _T("TRUE") : _T("FALSE")));
|
|
|
|
DBG_PRT((" PreferredVideoFrameRate = '%lu', Is In INF and value is of type REG_DWORD? '%ls'",
|
|
pVideoProperties->PreferredFrameRate,
|
|
(pVideoProperties->PreferredSettingsMask &
|
|
PREFERRED_SETTING_MASK_VIDEO_FRAMERATE) ? _T("TRUE") : _T("FALSE")));
|
|
|
|
DBG_PRT((" PreferredMediaSubType = '%ls', Is In INF and value is of type REG_SZ? '%ls'",
|
|
szGUID,
|
|
(pVideoProperties->PreferredSettingsMask &
|
|
PREFERRED_SETTING_MASK_MEDIASUBTYPE) ? _T("TRUE") : _T("FALSE")));
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
///////////////////////////////
|
|
// SetPictureAttribute
|
|
//
|
|
HRESULT CDShowUtil::SetPictureAttribute(IBaseFilter *pCaptureFilter,
|
|
CWiaVideoProperties::PictureAttribute_t *pPictureAttribute,
|
|
LONG lNewValue,
|
|
VideoProcAmpFlags lNewFlag)
|
|
{
|
|
ASSERT(pCaptureFilter != NULL);
|
|
ASSERT(pPictureAttribute != NULL);
|
|
|
|
HRESULT hr = S_OK;
|
|
CComPtr<IAMVideoProcAmp> pVideoProcAmp;
|
|
|
|
if ((pCaptureFilter == NULL) ||
|
|
(pPictureAttribute == NULL))
|
|
{
|
|
hr = E_POINTER;
|
|
CHECK_S_OK2(hr, ("CDShowUtil::SetPictureAttribute, received a NULL pointer"));
|
|
return hr;
|
|
}
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
hr = pCaptureFilter->QueryInterface(IID_IAMVideoProcAmp, (void**) &pVideoProcAmp);
|
|
}
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
if (pPictureAttribute->bUsed)
|
|
{
|
|
//
|
|
// Attempt to set the new value for the property.
|
|
//
|
|
hr = pVideoProcAmp->Set(pPictureAttribute->Name,
|
|
lNewValue,
|
|
(long) lNewFlag);
|
|
|
|
|
|
//
|
|
// If we successfully set the new value, then get it again. We do this
|
|
// in case the capture filter decided to change the values a little upon
|
|
// setting them (it shouldn't, but each filter could act differently)
|
|
//
|
|
if (hr == S_OK)
|
|
{
|
|
hr = pVideoProcAmp->Get(pPictureAttribute->Name,
|
|
&pPictureAttribute->lCurrentValue,
|
|
(long*) &pPictureAttribute->CurrentFlag);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = S_FALSE;
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
///////////////////////////////
|
|
// SetCameraAttribute
|
|
//
|
|
HRESULT CDShowUtil::SetCameraAttribute(IBaseFilter *pCaptureFilter,
|
|
CWiaVideoProperties::CameraAttribute_t *pCameraAttribute,
|
|
LONG lNewValue,
|
|
CameraControlFlags lNewFlag)
|
|
{
|
|
ASSERT(pCaptureFilter != NULL);
|
|
ASSERT(pCameraAttribute != NULL);
|
|
|
|
HRESULT hr = S_OK;
|
|
CComPtr<IAMCameraControl> pCameraControl;
|
|
|
|
if ((pCaptureFilter == NULL) ||
|
|
(pCameraControl == NULL))
|
|
{
|
|
hr = E_POINTER;
|
|
CHECK_S_OK2(hr, ("CDShowUtil::SetCameraAttribute, received a NULL pointer"));
|
|
return hr;
|
|
}
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
hr = pCaptureFilter->QueryInterface(IID_IAMCameraControl, (void**) &pCameraControl);
|
|
}
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
if (pCameraAttribute->bUsed)
|
|
{
|
|
//
|
|
// Attempt to set the new value for the property.
|
|
//
|
|
hr = pCameraControl->Set(pCameraAttribute->Name,
|
|
lNewValue,
|
|
(long) lNewFlag);
|
|
|
|
//
|
|
// If we successfully set the new value, then get it again. We do this
|
|
// in case the capture filter decided to change the values a little upon
|
|
// setting them (it shouldn't, but each filter could act differently)
|
|
//
|
|
if (hr == S_OK)
|
|
{
|
|
hr = pCameraControl->Get(pCameraAttribute->Name,
|
|
&pCameraAttribute->lCurrentValue,
|
|
(long*) &pCameraAttribute->CurrentFlag);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = S_FALSE;
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
///////////////////////////////
|
|
// GetPin
|
|
//
|
|
// This function returns the first
|
|
// pin on the specified filter
|
|
// matching the requested
|
|
// pin direction
|
|
//
|
|
HRESULT CDShowUtil::GetPin(IBaseFilter *pFilter,
|
|
PIN_DIRECTION PinDirection,
|
|
IPin **ppPin)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
BOOL bFound = FALSE;
|
|
ULONG ulNumFetched = 0;
|
|
PIN_DIRECTION PinDir;
|
|
CComPtr<IEnumPins> pEnum;
|
|
|
|
if ((pFilter == NULL) ||
|
|
(ppPin == NULL))
|
|
{
|
|
hr = E_POINTER;
|
|
CHECK_S_OK2(hr, ("CDShowUtil::GetPin, received a NULL param"));
|
|
return hr;
|
|
}
|
|
|
|
hr = pFilter->EnumPins(&pEnum);
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
hr = pEnum->Reset();
|
|
}
|
|
|
|
while ((hr == S_OK) && (!bFound))
|
|
{
|
|
CComPtr<IPin> pPin;
|
|
|
|
hr = pEnum->Next(1, &pPin, &ulNumFetched);
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
hr = pPin->QueryDirection(&PinDir);
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
if (PinDir == PinDirection)
|
|
{
|
|
*ppPin = pPin;
|
|
(*ppPin)->AddRef();
|
|
|
|
bFound = TRUE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CHECK_S_OK2(hr, ("CDShowUtil::GetPin, failed to get "
|
|
"Pin Direction, aborting find attempt"));
|
|
}
|
|
}
|
|
}
|
|
|
|
if (hr == S_FALSE)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
|
|
CHECK_S_OK2(hr, ("CDShowUtil::GetPin, failed to find "
|
|
"pin with direction %lu", PinDirection));
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
///////////////////////////////
|
|
// GUIDToString
|
|
//
|
|
// Static Fn
|
|
//
|
|
void CDShowUtil::GUIDToString(const GUID & clsid,
|
|
WCHAR* pwszGUID,
|
|
ULONG ulNumChars)
|
|
{
|
|
OLECHAR sz_clsid[CHARS_IN_GUID] = L"{Unknown}";
|
|
|
|
if (pwszGUID)
|
|
{
|
|
StringFromGUID2(clsid,
|
|
sz_clsid,
|
|
sizeof(sz_clsid)/sizeof(sz_clsid[0]));
|
|
|
|
wcsncpy(pwszGUID, sz_clsid, ulNumChars - 1);
|
|
pwszGUID[ulNumChars - 1] = '\0';
|
|
}
|
|
return;
|
|
}
|
|
|
|
///////////////////////////////
|
|
// MyDumpVideoProperties
|
|
//
|
|
// Static Fn
|
|
//
|
|
void CDShowUtil::MyDumpVideoProperties(CWiaVideoProperties *pVideoProperties)
|
|
{
|
|
WCHAR wszMajorType[CHARS_IN_GUID + 1] = {0};
|
|
WCHAR wszSubType[CHARS_IN_GUID + 1] = {0};
|
|
WCHAR wszFormatType[CHARS_IN_GUID + 1] = {0};
|
|
|
|
if (pVideoProperties == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
DBG_TRC(("***Dumping Wia Video Properties***"));
|
|
|
|
GUIDToString(pVideoProperties->pMediaType->majortype, wszMajorType, sizeof(wszMajorType) / sizeof(WCHAR));
|
|
GUIDToString(pVideoProperties->pMediaType->subtype, wszSubType, sizeof(wszSubType) / sizeof(WCHAR));
|
|
GUIDToString(pVideoProperties->pMediaType->formattype, wszFormatType, sizeof(wszFormatType) / sizeof(WCHAR));
|
|
|
|
DBG_PRT(("Media Type Information:"));
|
|
DBG_PRT((" Major Type: %ls", wszMajorType));
|
|
DBG_PRT((" Sub Type: %ls", wszSubType));
|
|
DBG_PRT((" Fixed Size Samples? %d ", pVideoProperties->pMediaType->bFixedSizeSamples));
|
|
DBG_PRT((" Temporal Compression? %d ", pVideoProperties->pMediaType->bTemporalCompression));
|
|
DBG_PRT((" Sample Size: %d ", pVideoProperties->pMediaType->lSampleSize));
|
|
DBG_PRT((" Format Type: %ls ", wszFormatType));
|
|
|
|
DBG_PRT(("Video Header Information:"));
|
|
DBG_PRT((" Source Rect: Left %d, Top %d, Right %d, Bottom %d",
|
|
pVideoProperties->pVideoInfoHeader->rcSource.left,
|
|
pVideoProperties->pVideoInfoHeader->rcSource.top,
|
|
pVideoProperties->pVideoInfoHeader->rcSource.right,
|
|
pVideoProperties->pVideoInfoHeader->rcSource.bottom));
|
|
DBG_PRT((" Target Rect: Left %d, Top %d, Right %d, Bottom %d",
|
|
pVideoProperties->pVideoInfoHeader->rcTarget.left,
|
|
pVideoProperties->pVideoInfoHeader->rcTarget.top,
|
|
pVideoProperties->pVideoInfoHeader->rcTarget.right,
|
|
pVideoProperties->pVideoInfoHeader->rcTarget.bottom));
|
|
DBG_PRT((" Bit Rate: %d", pVideoProperties->pVideoInfoHeader->dwBitRate));
|
|
DBG_PRT((" Bit Error Rate: %d", pVideoProperties->pVideoInfoHeader->dwBitErrorRate));
|
|
DBG_PRT((" Frame Rate: %d", pVideoProperties->dwFrameRate));
|
|
|
|
DBG_PRT(("Bitmap Information Header:"));
|
|
DBG_PRT((" Width: %d", pVideoProperties->pVideoInfoHeader->bmiHeader.biWidth));
|
|
DBG_PRT((" Height: %d", pVideoProperties->pVideoInfoHeader->bmiHeader.biHeight));
|
|
DBG_PRT((" Planes: %d", pVideoProperties->pVideoInfoHeader->bmiHeader.biPlanes));
|
|
DBG_PRT((" Bitcount: %d", pVideoProperties->pVideoInfoHeader->bmiHeader.biBitCount));
|
|
DBG_PRT((" Compresssion: %d", pVideoProperties->pVideoInfoHeader->bmiHeader.biCompression));
|
|
DBG_PRT((" Size Image: %d", pVideoProperties->pVideoInfoHeader->bmiHeader.biSizeImage));
|
|
DBG_PRT((" XPelsPerMeter: %d", pVideoProperties->pVideoInfoHeader->bmiHeader.biXPelsPerMeter));
|
|
DBG_PRT((" YPelsPerMeter: %d", pVideoProperties->pVideoInfoHeader->bmiHeader.biYPelsPerMeter));
|
|
DBG_PRT((" ClrUsed: %d", pVideoProperties->pVideoInfoHeader->bmiHeader.biClrUsed));
|
|
DBG_PRT((" ClrImportant: %d", pVideoProperties->pVideoInfoHeader->bmiHeader.biClrImportant));
|
|
|
|
if (pVideoProperties->bPictureAttributesUsed)
|
|
{
|
|
DBG_PRT(("Picture Attributes: Available"));
|
|
|
|
DBG_PRT((" Brightness:"));
|
|
DBG_PRT((" Available: %d", pVideoProperties->Brightness.bUsed));
|
|
|
|
if (pVideoProperties->Brightness.bUsed)
|
|
{
|
|
DBG_PRT((" Current Value: %d", pVideoProperties->Brightness.lCurrentValue));
|
|
DBG_PRT((" Current Flag: %d", pVideoProperties->Brightness.CurrentFlag));
|
|
DBG_PRT((" Min Value: %d", pVideoProperties->Brightness.lMinValue));
|
|
DBG_PRT((" Max Value: %d", pVideoProperties->Brightness.lMaxValue));
|
|
DBG_PRT((" Default Value: %d", pVideoProperties->Brightness.lDefaultValue));
|
|
DBG_PRT((" Increment: %d", pVideoProperties->Brightness.lIncrement));
|
|
DBG_PRT((" Valid Flags: %d", pVideoProperties->Brightness.ValidFlags));
|
|
}
|
|
|
|
DBG_PRT((" Contrast:"));
|
|
DBG_PRT((" Available: %d", pVideoProperties->Contrast.bUsed));
|
|
|
|
if (pVideoProperties->Contrast.bUsed)
|
|
{
|
|
DBG_PRT((" Current Value: %d", pVideoProperties->Contrast.lCurrentValue));
|
|
DBG_PRT((" Current Flag: %d", pVideoProperties->Contrast.CurrentFlag));
|
|
DBG_PRT((" Min Value: %d", pVideoProperties->Contrast.lMinValue));
|
|
DBG_PRT((" Max Value: %d", pVideoProperties->Contrast.lMaxValue));
|
|
DBG_PRT((" Default Value: %d", pVideoProperties->Contrast.lDefaultValue));
|
|
DBG_PRT((" Increment: %d", pVideoProperties->Contrast.lIncrement));
|
|
DBG_PRT((" Valid Flags: %d", pVideoProperties->Contrast.ValidFlags));
|
|
}
|
|
|
|
DBG_PRT((" Hue:"));
|
|
DBG_PRT((" Available: %d", pVideoProperties->Hue.bUsed));
|
|
|
|
if (pVideoProperties->Hue.bUsed)
|
|
{
|
|
DBG_PRT((" Current Value: %d", pVideoProperties->Hue.lCurrentValue));
|
|
DBG_PRT((" Current Flag: %d", pVideoProperties->Hue.CurrentFlag));
|
|
DBG_PRT((" Min Value: %d", pVideoProperties->Hue.lMinValue));
|
|
DBG_PRT((" Max Value: %d", pVideoProperties->Hue.lMaxValue));
|
|
DBG_PRT((" Default Value: %d", pVideoProperties->Hue.lDefaultValue));
|
|
DBG_PRT((" Increment: %d", pVideoProperties->Hue.lIncrement));
|
|
DBG_PRT((" Valid Flags: %d", pVideoProperties->Hue.ValidFlags));
|
|
}
|
|
|
|
DBG_PRT((" Saturation:"));
|
|
DBG_PRT((" Available: %d", pVideoProperties->Saturation.bUsed));
|
|
|
|
if (pVideoProperties->Saturation.bUsed)
|
|
{
|
|
DBG_PRT((" Current Value: %d", pVideoProperties->Saturation.lCurrentValue));
|
|
DBG_PRT((" Current Flag: %d", pVideoProperties->Saturation.CurrentFlag));
|
|
DBG_PRT((" Min Value: %d", pVideoProperties->Saturation.lMinValue));
|
|
DBG_PRT((" Max Value: %d", pVideoProperties->Saturation.lMaxValue));
|
|
DBG_PRT((" Default Value: %d", pVideoProperties->Saturation.lDefaultValue));
|
|
DBG_PRT((" Increment: %d", pVideoProperties->Saturation.lIncrement));
|
|
DBG_PRT((" Valid Flags: %d", pVideoProperties->Saturation.ValidFlags));
|
|
}
|
|
|
|
DBG_PRT((" Sharpness:"));
|
|
DBG_PRT((" Available: %d", pVideoProperties->Sharpness.bUsed));
|
|
|
|
if (pVideoProperties->Sharpness.bUsed)
|
|
{
|
|
DBG_PRT((" Current Value: %d", pVideoProperties->Sharpness.lCurrentValue));
|
|
DBG_PRT((" Current Flag: %d", pVideoProperties->Sharpness.CurrentFlag));
|
|
DBG_PRT((" Min Value: %d", pVideoProperties->Sharpness.lMinValue));
|
|
DBG_PRT((" Max Value: %d", pVideoProperties->Sharpness.lMaxValue));
|
|
DBG_PRT((" Default Value: %d", pVideoProperties->Sharpness.lDefaultValue));
|
|
DBG_PRT((" Increment: %d", pVideoProperties->Sharpness.lIncrement));
|
|
DBG_PRT((" Valid Flags: %d", pVideoProperties->Sharpness.ValidFlags));
|
|
}
|
|
|
|
DBG_PRT((" Gamma:"));
|
|
DBG_PRT((" Available: %d", pVideoProperties->Gamma.bUsed));
|
|
|
|
if (pVideoProperties->Gamma.bUsed)
|
|
{
|
|
DBG_PRT((" Current Value: %d", pVideoProperties->Gamma.lCurrentValue));
|
|
DBG_PRT((" Current Flag: %d", pVideoProperties->Gamma.CurrentFlag));
|
|
DBG_PRT((" Min Value: %d", pVideoProperties->Gamma.lMinValue));
|
|
DBG_PRT((" Max Value: %d", pVideoProperties->Gamma.lMaxValue));
|
|
DBG_PRT((" Default Value: %d", pVideoProperties->Gamma.lDefaultValue));
|
|
DBG_PRT((" Increment: %d", pVideoProperties->Gamma.lIncrement));
|
|
DBG_PRT((" Valid Flags: %d", pVideoProperties->Gamma.ValidFlags));
|
|
}
|
|
|
|
DBG_PRT((" ColorEnable:"));
|
|
DBG_PRT((" Available: %d", pVideoProperties->ColorEnable.bUsed));
|
|
|
|
if (pVideoProperties->ColorEnable.bUsed)
|
|
{
|
|
DBG_PRT((" Current Value: %d", pVideoProperties->ColorEnable.lCurrentValue));
|
|
DBG_PRT((" Current Flag: %d", pVideoProperties->ColorEnable.CurrentFlag));
|
|
DBG_PRT((" Min Value: %d", pVideoProperties->ColorEnable.lMinValue));
|
|
DBG_PRT((" Max Value: %d", pVideoProperties->ColorEnable.lMaxValue));
|
|
DBG_PRT((" Default Value: %d", pVideoProperties->ColorEnable.lDefaultValue));
|
|
DBG_PRT((" Increment: %d", pVideoProperties->ColorEnable.lIncrement));
|
|
DBG_PRT((" Valid Flags: %d", pVideoProperties->ColorEnable.ValidFlags));
|
|
}
|
|
|
|
DBG_PRT((" WhiteBalance:"));
|
|
DBG_PRT((" Available: %d", pVideoProperties->WhiteBalance.bUsed));
|
|
|
|
if (pVideoProperties->WhiteBalance.bUsed)
|
|
{
|
|
DBG_PRT((" Current Value: %d", pVideoProperties->WhiteBalance.lCurrentValue));
|
|
DBG_PRT((" Current Flag: %d", pVideoProperties->WhiteBalance.CurrentFlag));
|
|
DBG_PRT((" Min Value: %d", pVideoProperties->WhiteBalance.lMinValue));
|
|
DBG_PRT((" Max Value: %d", pVideoProperties->WhiteBalance.lMaxValue));
|
|
DBG_PRT((" Default Value: %d", pVideoProperties->WhiteBalance.lDefaultValue));
|
|
DBG_PRT((" Increment: %d", pVideoProperties->WhiteBalance.lIncrement));
|
|
DBG_PRT((" Valid Flags: %d", pVideoProperties->WhiteBalance.ValidFlags));
|
|
}
|
|
|
|
DBG_PRT((" BacklightCompensation:"));
|
|
DBG_PRT((" Available: %d", pVideoProperties->BacklightCompensation.bUsed));
|
|
|
|
if (pVideoProperties->BacklightCompensation.bUsed)
|
|
{
|
|
DBG_PRT((" Current Value: %d", pVideoProperties->BacklightCompensation.lCurrentValue));
|
|
DBG_PRT((" Current Flag: %d", pVideoProperties->BacklightCompensation.CurrentFlag));
|
|
DBG_PRT((" Min Value: %d", pVideoProperties->BacklightCompensation.lMinValue));
|
|
DBG_PRT((" Max Value: %d", pVideoProperties->BacklightCompensation.lMaxValue));
|
|
DBG_PRT((" Default Value: %d", pVideoProperties->BacklightCompensation.lDefaultValue));
|
|
DBG_PRT((" Increment: %d", pVideoProperties->BacklightCompensation.lIncrement));
|
|
DBG_PRT((" Valid Flags: %d", pVideoProperties->BacklightCompensation.ValidFlags));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DBG_PRT(("Picture Attributes: Not Available"));
|
|
}
|
|
|
|
if (pVideoProperties->bCameraAttributesUsed)
|
|
{
|
|
DBG_PRT(("Camera Attributes: Available"));
|
|
|
|
DBG_PRT((" Pan:"));
|
|
DBG_PRT((" Available: %d", pVideoProperties->Pan.bUsed));
|
|
|
|
if (pVideoProperties->Pan.bUsed)
|
|
{
|
|
DBG_PRT((" Current Value: %d", pVideoProperties->Pan.lCurrentValue));
|
|
DBG_PRT((" Current Flag: %d", pVideoProperties->Pan.CurrentFlag));
|
|
DBG_PRT((" Min Value: %d", pVideoProperties->Pan.lMinValue));
|
|
DBG_PRT((" Max Value: %d", pVideoProperties->Pan.lMaxValue));
|
|
DBG_PRT((" Default Value: %d", pVideoProperties->Pan.lDefaultValue));
|
|
DBG_PRT((" Increment: %d", pVideoProperties->Pan.lIncrement));
|
|
DBG_PRT((" Valid Flags: %d", pVideoProperties->Pan.ValidFlags));
|
|
}
|
|
|
|
DBG_PRT((" Tilt:"));
|
|
DBG_PRT((" Available: %d", pVideoProperties->Tilt.bUsed));
|
|
|
|
if (pVideoProperties->Tilt.bUsed)
|
|
{
|
|
DBG_PRT((" Current Value: %d", pVideoProperties->Tilt.lCurrentValue));
|
|
DBG_PRT((" Current Flag: %d", pVideoProperties->Tilt.CurrentFlag));
|
|
DBG_PRT((" Min Value: %d", pVideoProperties->Tilt.lMinValue));
|
|
DBG_PRT((" Max Value: %d", pVideoProperties->Tilt.lMaxValue));
|
|
DBG_PRT((" Default Value: %d", pVideoProperties->Tilt.lDefaultValue));
|
|
DBG_PRT((" Increment: %d", pVideoProperties->Tilt.lIncrement));
|
|
DBG_PRT((" Valid Flags: %d", pVideoProperties->Tilt.ValidFlags));
|
|
}
|
|
|
|
DBG_PRT((" Roll:"));
|
|
DBG_PRT((" Available: %d", pVideoProperties->Roll.bUsed));
|
|
|
|
if (pVideoProperties->Roll.bUsed)
|
|
{
|
|
DBG_PRT((" Current Value: %d", pVideoProperties->Roll.lCurrentValue));
|
|
DBG_PRT((" Current Flag: %d", pVideoProperties->Roll.CurrentFlag));
|
|
DBG_PRT((" Min Value: %d", pVideoProperties->Roll.lMinValue));
|
|
DBG_PRT((" Max Value: %d", pVideoProperties->Roll.lMaxValue));
|
|
DBG_PRT((" Default Value: %d", pVideoProperties->Roll.lDefaultValue));
|
|
DBG_PRT((" Increment: %d", pVideoProperties->Roll.lIncrement));
|
|
DBG_PRT((" Valid Flags: %d", pVideoProperties->Roll.ValidFlags));
|
|
}
|
|
|
|
DBG_PRT((" Zoom:"));
|
|
DBG_PRT((" Available: %d", pVideoProperties->Zoom.bUsed));
|
|
|
|
if (pVideoProperties->Zoom.bUsed)
|
|
{
|
|
DBG_PRT((" Current Value: %d", pVideoProperties->Zoom.lCurrentValue));
|
|
DBG_PRT((" Current Flag: %d", pVideoProperties->Zoom.CurrentFlag));
|
|
DBG_PRT((" Min Value: %d", pVideoProperties->Zoom.lMinValue));
|
|
DBG_PRT((" Max Value: %d", pVideoProperties->Zoom.lMaxValue));
|
|
DBG_PRT((" Default Value: %d", pVideoProperties->Zoom.lDefaultValue));
|
|
DBG_PRT((" Increment: %d", pVideoProperties->Zoom.lIncrement));
|
|
DBG_PRT((" Valid Flags: %d", pVideoProperties->Zoom.ValidFlags));
|
|
}
|
|
|
|
DBG_PRT((" Exposure:"));
|
|
DBG_PRT((" Available: %d", pVideoProperties->Exposure.bUsed));
|
|
|
|
if (pVideoProperties->Exposure.bUsed)
|
|
{
|
|
DBG_PRT((" Current Value: %d", pVideoProperties->Exposure.lCurrentValue));
|
|
DBG_PRT((" Current Flag: %d", pVideoProperties->Exposure.CurrentFlag));
|
|
DBG_PRT((" Min Value: %d", pVideoProperties->Exposure.lMinValue));
|
|
DBG_PRT((" Max Value: %d", pVideoProperties->Exposure.lMaxValue));
|
|
DBG_PRT((" Default Value: %d", pVideoProperties->Exposure.lDefaultValue));
|
|
DBG_PRT((" Increment: %d", pVideoProperties->Exposure.lIncrement));
|
|
DBG_PRT((" Valid Flags: %d", pVideoProperties->Exposure.ValidFlags));
|
|
}
|
|
|
|
DBG_PRT((" Iris:"));
|
|
DBG_PRT((" Available: %d", pVideoProperties->Iris.bUsed));
|
|
|
|
if (pVideoProperties->Iris.bUsed)
|
|
{
|
|
DBG_PRT((" Current Value: %d", pVideoProperties->Iris.lCurrentValue));
|
|
DBG_PRT((" Current Flag: %d", pVideoProperties->Iris.CurrentFlag));
|
|
DBG_PRT((" Min Value: %d", pVideoProperties->Iris.lMinValue));
|
|
DBG_PRT((" Max Value: %d", pVideoProperties->Iris.lMaxValue));
|
|
DBG_PRT((" Default Value: %d", pVideoProperties->Iris.lDefaultValue));
|
|
DBG_PRT((" Increment: %d", pVideoProperties->Iris.lIncrement));
|
|
DBG_PRT((" Valid Flags: %d", pVideoProperties->Iris.ValidFlags));
|
|
}
|
|
|
|
DBG_PRT((" Focus:"));
|
|
DBG_PRT((" Available: %d", pVideoProperties->Focus.bUsed));
|
|
|
|
if (pVideoProperties->Focus.bUsed)
|
|
{
|
|
DBG_PRT((" Current Value: %d", pVideoProperties->Focus.lCurrentValue));
|
|
DBG_PRT((" Current Flag: %d", pVideoProperties->Focus.CurrentFlag));
|
|
DBG_PRT((" Min Value: %d", pVideoProperties->Focus.lMinValue));
|
|
DBG_PRT((" Max Value: %d", pVideoProperties->Focus.lMaxValue));
|
|
DBG_PRT((" Default Value: %d", pVideoProperties->Focus.lDefaultValue));
|
|
DBG_PRT((" Increment: %d", pVideoProperties->Focus.lIncrement));
|
|
DBG_PRT((" Valid Flags: %d", pVideoProperties->Focus.ValidFlags));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DBG_PRT(("Camera Attributes: Not Available"));
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
///////////////////////////////
|
|
// DumpCaptureMoniker
|
|
//
|
|
// Static Fn
|
|
//
|
|
void CDShowUtil::DumpCaptureMoniker(IMoniker *pCaptureDeviceMoniker)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CComPtr<IPropertyBag> pPropertyBag;
|
|
|
|
if (pCaptureDeviceMoniker == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
//
|
|
// Get property storage for this DS device so we can get it's
|
|
// device id...
|
|
//
|
|
|
|
hr = pCaptureDeviceMoniker->BindToStorage(0,
|
|
0,
|
|
IID_IPropertyBag,
|
|
(void **)&pPropertyBag);
|
|
}
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
CSimpleString strTemp;
|
|
|
|
DBG_TRC(("Dumping Moniker information for Capture Device"));
|
|
|
|
GetDeviceProperty(pPropertyBag, L"FriendlyName", &strTemp);
|
|
|
|
DBG_PRT(("DShow: FriendlyName = %ls", strTemp.String()));
|
|
|
|
GetDeviceProperty(pPropertyBag, L"CLSID", &strTemp);
|
|
|
|
DBG_PRT(("DShow: CLSID = %ls", strTemp.String()));
|
|
|
|
hr = GetDeviceProperty(pPropertyBag, L"DevicePath", &strTemp);
|
|
|
|
DBG_PRT(("DShow: DevicePath = %ls", strTemp.String()));
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
///////////////////////////////
|
|
// MyDumpGraph
|
|
//
|
|
// Static Fn
|
|
//
|
|
void CDShowUtil::MyDumpGraph(LPCTSTR Description,
|
|
IGraphBuilder *pGraphBuilder)
|
|
{
|
|
if (pGraphBuilder == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (Description)
|
|
{
|
|
DBG_TRC(("%S", Description));
|
|
}
|
|
else
|
|
{
|
|
DBG_TRC(("*** Dumping Filter Graph ***"));
|
|
}
|
|
|
|
//
|
|
// Enum all the filters
|
|
//
|
|
|
|
CComPtr<IEnumFilters> pEnum;
|
|
UINT uiNumFilters = 0;
|
|
|
|
if ((pGraphBuilder) && (pGraphBuilder->EnumFilters(&pEnum) == S_OK))
|
|
{
|
|
pEnum->Reset();
|
|
CComPtr<IBaseFilter> pFilter;
|
|
|
|
while (S_OK == pEnum->Next(1, &pFilter, NULL))
|
|
{
|
|
++uiNumFilters;
|
|
MyDumpFilter(pFilter);
|
|
pFilter = NULL;
|
|
}
|
|
|
|
if (uiNumFilters == 0)
|
|
{
|
|
DBG_TRC(("*** No Filters in Graph ***"));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
///////////////////////////////
|
|
// MyDumpFilter
|
|
//
|
|
// Static Fn
|
|
//
|
|
void CDShowUtil::MyDumpFilter(IBaseFilter * pFilter)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
FILTER_INFO FilterInfo;
|
|
CLSID clsid;
|
|
|
|
if (pFilter == NULL)
|
|
{
|
|
DBG_TRC(("Invalid IBaseFilter interface pointer in MyDumpFilter"));
|
|
|
|
return;
|
|
}
|
|
|
|
FilterInfo.pGraph = NULL;
|
|
|
|
hr = pFilter->QueryFilterInfo(&FilterInfo);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pFilter->GetClassID(&clsid);
|
|
}
|
|
else
|
|
{
|
|
DBG_TRC(("Unable to get filter info"));
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
WCHAR wszGUID[127 + 1] = {0};
|
|
|
|
GUIDToString(clsid, wszGUID, sizeof(wszGUID)/sizeof(WCHAR));
|
|
|
|
DBG_PRT(("Filter Name: '%S', GUID: '%S'",
|
|
FilterInfo.achName,
|
|
wszGUID));
|
|
|
|
if (FilterInfo.pGraph)
|
|
{
|
|
FilterInfo.pGraph->Release();
|
|
FilterInfo.pGraph = NULL;
|
|
}
|
|
|
|
MyDumpAllPins(pFilter);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
///////////////////////////////
|
|
// MyDumpAllPins
|
|
//
|
|
// Static Fn
|
|
//
|
|
void CDShowUtil::MyDumpAllPins(IBaseFilter *const pFilter)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CComPtr<IPin> pPin = NULL;
|
|
ULONG ulCount = 0;
|
|
CComPtr<IEnumPins> pEnumPins = NULL;
|
|
|
|
hr = const_cast<IBaseFilter*>(pFilter)->EnumPins(&pEnumPins);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
while ((SUCCEEDED(pEnumPins->Next(1, &pPin, &ulCount))) &&
|
|
(ulCount > 0))
|
|
{
|
|
MyDumpPin(pPin);
|
|
pPin = NULL;
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
///////////////////////////////
|
|
// MyDumpPin
|
|
//
|
|
// Static Fn
|
|
//
|
|
void CDShowUtil::MyDumpPin(IPin* pPin)
|
|
{
|
|
if (pPin == NULL)
|
|
{
|
|
DBG_TRC(("Invalid IPin pointer in MyDumpPinInfo"));
|
|
return;
|
|
}
|
|
|
|
LPWSTR pin_id1 = NULL;
|
|
LPWSTR pin_id2 = NULL;
|
|
PIN_INFO pin_info1 = {0};
|
|
PIN_INFO pin_info2 = {0};
|
|
|
|
const IPin *p_connected_to = NULL;
|
|
|
|
// get the pin info for this pin.
|
|
const_cast<IPin*>(pPin)->QueryPinInfo(&pin_info1);
|
|
const_cast<IPin*>(pPin)->QueryId(&pin_id1);
|
|
|
|
(const_cast<IPin*>(pPin))->ConnectedTo(
|
|
const_cast<IPin**>(&p_connected_to));
|
|
|
|
if (p_connected_to)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
FILTER_INFO filter_info = {0};
|
|
|
|
const_cast<IPin*>(p_connected_to)->QueryPinInfo(&pin_info2);
|
|
const_cast<IPin*>(p_connected_to)->QueryId(&pin_id2);
|
|
|
|
if (pin_info2.pFilter)
|
|
{
|
|
hr = pin_info2.pFilter->QueryFilterInfo(&filter_info);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (filter_info.pGraph)
|
|
{
|
|
filter_info.pGraph->Release();
|
|
filter_info.pGraph = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (pin_info2.pFilter)
|
|
{
|
|
pin_info2.pFilter->Release();
|
|
pin_info2.pFilter = NULL;
|
|
}
|
|
|
|
const_cast<IPin*>(p_connected_to)->Release();
|
|
|
|
if (pin_info1.dir == PINDIR_OUTPUT)
|
|
{
|
|
DBG_PRT((" Pin: '%S', PinID: '%S' --> "
|
|
"Filter: '%S', Pin: '%S', PinID: '%S'",
|
|
pin_info1.achName,
|
|
pin_id1,
|
|
filter_info.achName,
|
|
pin_info2.achName,
|
|
pin_id2));
|
|
}
|
|
else
|
|
{
|
|
DBG_PRT((" Pin: '%S', PinID: '%S' <-- "
|
|
"Filter: '%S', Pin: '%S', PinID: '%S'",
|
|
pin_info1.achName,
|
|
pin_id1,
|
|
filter_info.achName,
|
|
pin_info2.achName,
|
|
pin_id2));
|
|
}
|
|
|
|
// if pin_id2 is NULL, then CoTaskMemFree is a no-op
|
|
CoTaskMemFree(pin_id2);
|
|
}
|
|
else
|
|
{
|
|
if (pin_info1.dir == PINDIR_OUTPUT)
|
|
{
|
|
DBG_PRT((" Pin: '%S', PinID: '%S' --> Not Connected",
|
|
pin_info1.achName,
|
|
pin_id1));
|
|
}
|
|
else
|
|
{
|
|
DBG_PRT((" Pin: '%S', PinID: '%S' <-- Not Connected",
|
|
pin_info1.achName,
|
|
pin_id1));
|
|
}
|
|
}
|
|
|
|
// if pin_id1 is NULL, then CoTaskMemFree is a no-op
|
|
CoTaskMemFree(pin_id1);
|
|
|
|
if (pin_info1.pFilter)
|
|
{
|
|
pin_info1.pFilter->Release();
|
|
pin_info1.pFilter = NULL;
|
|
}
|
|
|
|
return;
|
|
}
|