www.pudn.com > Face3DModel.zip > VideoCamera.cpp
// VideoCamera.cpp: implementation of the CVideoCamera class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Face3DModel.h"
#include "VideoCamera.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CVideoCamera::CVideoCamera() : m_pVW(NULL)
, m_fConnect(FALSE)
{
}
CVideoCamera::~CVideoCamera()
{
if (m_fConnect)
{
Disconnect();
}
}
BOOL CVideoCamera::Connect()
{
HRESULT hr;
CComBSTR bstrName("Yht USB PC Camera");
hr = GetMyCaptureDevice(&m_pSrc, bstrName);
if (FAILED(hr))
{
return FALSE;
}
// Create the filter graph.
hr = m_pGraph.CoCreateInstance(CLSID_FilterGraph);
// Create the capture graph builder.
hr = m_pBuilder.CoCreateInstance(CLSID_CaptureGraphBuilder2);
m_pBuilder->SetFiltergraph(m_pGraph);
hr = m_pGraph->AddFilter(m_pSrc, L"Capture");
// Set default width & height required
IAMStreamConfig * pVSC = NULL;
hr = m_pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE,
&MEDIATYPE_Video, m_pSrc,
IID_IAMStreamConfig, (void **)&pVSC);
if (SUCCEEDED(hr))
{
AM_MEDIA_TYPE *pmt;
// get format being used NOW
hr = pVSC->GetFormat(&pmt);
if (hr == NOERROR)
{
if (pmt->formattype == FORMAT_VideoInfo)
{
HEADER(pmt->pbFormat)->biWidth = 640;
HEADER(pmt->pbFormat)->biHeight = 480;
pVSC->SetFormat(pmt);
}
DeleteMediaType(pmt);
}
pVSC->Release();
}
hr = m_pSample.CoCreateInstance(CLSID_SampleGrabber);
hr = m_pSample->QueryInterface(IID_ISampleGrabber,
reinterpret_cast(&m_pSampleGrabber));
hr = m_pGraph->AddFilter(m_pSample, L"SampleGrabber");
AM_MEDIA_TYPE mt;
ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
mt.majortype = MEDIATYPE_Video;
mt.subtype = MEDIASUBTYPE_RGB24;
hr = m_pSampleGrabber->SetMediaType(&mt);
m_pSampleGrabber->SetOneShot(FALSE);
m_pSampleGrabber->SetBufferSamples(TRUE);
hr = m_pBuilder->RenderStream(
&PIN_CATEGORY_PREVIEW, // Pin category
&MEDIATYPE_Video, // Media type
m_pSrc, // Capture filter
m_pSample, // Sample filter
NULL // Default renderer
);
hr = m_pGraph->QueryInterface(IID_IVideoWindow, (void **)&m_pVW);
// Run the graph.
REFERENCE_TIME rtStop = MAXLONGLONG;//10 * ONE_SECOND;
hr = m_pBuilder->ControlStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,
m_pSrc, NULL, &rtStop, 0, 0);
if (FAILED(hr))
{
Disconnect();
return FALSE;
}
m_fConnect = TRUE;
return m_fConnect;
}
BOOL CVideoCamera::Disconnect()
{
if (m_pVW != NULL)
{
m_pVW->get_Owner(NULL);
m_pVW->put_Visible(OAFALSE);
m_pVW->Release();
m_pVW = NULL;
}
m_pSampleGrabber.Release();
m_pSrc.Release();
m_pSample.Release();
m_pGraph.Release();
m_pBuilder.Release();
m_fConnect = FALSE;
return TRUE;
}
BOOL CVideoCamera::IsConnect()
{
return m_fConnect;
}
BOOL CVideoCamera::GetSize(long *pWidth, long *pHeight)
{
HRESULT hr = S_OK;
IAMStreamConfig * pVSC = NULL;
hr = m_pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE,
&MEDIATYPE_Video, m_pSrc,
IID_IAMStreamConfig, (void **)&pVSC);
if (SUCCEEDED(hr))
{
AM_MEDIA_TYPE *pmt;
// get format being used NOW
hr = pVSC->GetFormat(&pmt);
if (hr == NOERROR)
{
if (pmt->formattype == FORMAT_VideoInfo)
{
*pWidth = HEADER(pmt->pbFormat)->biWidth;
*pHeight = HEADER(pmt->pbFormat)->biHeight;
}
else
{
hr = E_FAIL;
}
DeleteMediaType(pmt);
}
pVSC->Release();
}
return SUCCEEDED(hr);
}
BOOL CVideoCamera::SetVideoWindow(HWND hWnd, long x, long y, long width, long height)
{
HRESULT hr = S_OK;
if (SUCCEEDED(hr))
{
hr = m_pVW->put_Visible(FALSE);
}
if (SUCCEEDED(hr))
{
hr = m_pVW->put_Owner((OAHWND)hWnd);
}
if (SUCCEEDED(hr))
{
hr = m_pVW->put_WindowStyle(WS_CHILD);
}
if (SUCCEEDED(hr))
{
hr = m_pVW->SetWindowPosition(x, y, width, height); // be this big
}
if (SUCCEEDED(hr))
{
hr = m_pVW->put_Visible(OATRUE);
}
return SUCCEEDED(hr);
}
BOOL CVideoCamera::Run()
{
CComQIPtr pControl(m_pGraph);
return SUCCEEDED(pControl->Run());
}
BOOL CVideoCamera::Pause()
{
CComQIPtr pControl(m_pGraph);
return SUCCEEDED(pControl->Pause());
}
BOOL CVideoCamera::Stop()
{
CComQIPtr pControl(m_pGraph);
return SUCCEEDED(pControl->Stop());
}
LONG CVideoCamera::GetState()
{
CComQIPtr pControl(m_pGraph);
OAFilterState filterState;
if (SUCCEEDED(pControl->GetState(50, &filterState)))
{
return filterState;
}
return State_Stopped;
}
BOOL CVideoCamera::GetCurrentBuffer(long * pBufferSize, long *pBuffer)
{
return SUCCEEDED(m_pSampleGrabber->GetCurrentBuffer(pBufferSize, pBuffer));
}
void CVideoCamera::OnCameraVideoSource()
{
HRESULT hr;
IAMStreamConfig *pSC;
hr = m_pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE,
&MEDIATYPE_Interleaved, m_pSrc.p,
IID_IAMStreamConfig, (void **)&pSC);
if(hr != NOERROR)
hr = m_pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE,
&MEDIATYPE_Video, m_pSrc.p,
IID_IAMStreamConfig, (void **)&pSC);
ISpecifyPropertyPages *pSpec;
CAUUID cauuid;
hr = pSC->QueryInterface(IID_ISpecifyPropertyPages,
(void **)&pSpec);
if(hr == S_OK)
{
hr = pSpec->GetPages(&cauuid);
hr = OleCreatePropertyFrame(AfxGetMainWnd()->GetSafeHwnd(), 30, 30, NULL, 1,
(IUnknown **)&pSC, cauuid.cElems,
(GUID *)cauuid.pElems, 0, 0, NULL);
CoTaskMemFree(cauuid.pElems);
pSpec->Release();
}
pSC->Release();
}
void CVideoCamera::OnCameraVideoFormat()
{
HRESULT hr;
ISpecifyPropertyPages *pSpec;
CAUUID cauuid;
hr = m_pSrc->QueryInterface(IID_ISpecifyPropertyPages,
(void **)&pSpec);
if(hr == S_OK)
{
hr = pSpec->GetPages(&cauuid);
hr = OleCreatePropertyFrame(AfxGetMainWnd()->GetSafeHwnd(), 30, 30, NULL, 1,
(IUnknown **)&m_pSrc.p, cauuid.cElems,
(GUID *)cauuid.pElems, 0, 0, NULL);
CoTaskMemFree(cauuid.pElems);
pSpec->Release();
}
}
HRESULT CVideoCamera::GetMyCaptureDevice(IBaseFilter **pF, BSTR bstrName)
{
HRESULT hr = E_FAIL;
CComPtr pFilter;
CComPtr pSysDevEnum;
CComPtr pEnumCat = NULL;
// Create the System Device Enumerator.
hr = pSysDevEnum.CoCreateInstance(CLSID_SystemDeviceEnum);
// Obtain a class enumerator for the video compressor category.
if (SUCCEEDED(hr))
{
hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumCat, 0);
if (pEnumCat == NULL)
{
hr = E_FAIL;
}
}
if (SUCCEEDED(hr))
{
// Enumerate the monikers.
CComPtr pMoniker;
ULONG cFetched;
while(pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK)
{
CComPtr pProp;
pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pProp);
VARIANT varName;
VariantInit(&varName); // Try to match the friendly name.
hr = pProp->Read(L"FriendlyName", &varName, 0);
if (SUCCEEDED(hr))
{
hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pFilter);
//&& (wcscmp(bstrName, varName.bstrVal) == 0)
break;
}
VariantClear(&varName);
pMoniker = NULL; // Release for the next loop.
}
*pF = pFilter;
if (*pF != NULL)
{
(*pF)->AddRef(); // Add ref on the way out.
}
}
return hr;
}