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; 
}