⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 capture.cpp

📁 一个外国人写的人脸检测程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:

#include "stdafx.h"
#include "capture.h"
#include "samplegrab.h"



//
// Global Data
//
enum PLAYSTATE {Stopped, Paused, Running, Init};

DWORD g_dwGraphRegister = 0;

IVideoWindow  * g_pVW = NULL;
IMediaControl * g_pMC = NULL;
IMediaEventEx * g_pME = NULL;
IGraphBuilder * g_pGraph = NULL;
ICaptureGraphBuilder2 * g_pCapture = NULL;
PLAYSTATE g_psCurrent = Stopped;

//
// Functions
//
void Msg(TCHAR *szFormat, ...);

HRESULT FindCaptureDevice(IBaseFilter** ppSrcFilter, unsigned int devIndex = 1);

HRESULT GetInterfaces(HWND hWnd);
void CloseInterfaces(void);
HRESULT SetupVideoWindow(HWND hWnd);
void ResizeVideoWindow(HWND hWnd);
HRESULT AddGraphToRot(IUnknown *pUnkGraph, DWORD *pdwRegister);
void RemoveGraphFromRot(DWORD pdwRegister);



void vcGetCaptureDevices(CComboBox& adaptersBox)
{
        adaptersBox.ResetContent();

// Create the System Device Enumerator.
        HRESULT hr;
        ICreateDevEnum *pSysDevEnum = NULL;
        hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
                              IID_ICreateDevEnum, (void **) & pSysDevEnum);
        if (FAILED(hr)) {
                Msg(TEXT("CoCreateInstance() hr=0x%x"), hr);
                return;
        }

// Obtain a class enumerator for the video compressor category.
        IEnumMoniker *pEnumCat = NULL;
        hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumCat, 0);

        if (hr == S_OK) {
                // Enumerate the monikers.
                IMoniker *pMoniker = NULL;
                ULONG cFetched;
                while (pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK) {
                        IPropertyBag *pPropBag;
                        hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag,
                                                     (void **) & pPropBag);
                        if (SUCCEEDED(hr)) {
                                // To retrieve the filter's friendly name, do the following:
                                VARIANT varName;
                                VariantInit(&varName);
                                hr = pPropBag->Read(L"FriendlyName", &varName, 0);
                                if (SUCCEEDED(hr)) {
                                        adaptersBox.AddString(varName.bstrVal);
                                }
                                VariantClear(&varName);

                                // To create an instance of the filter, do the following:
                                IBaseFilter *pFilter;
                                hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter,
                                                            (void **) & pFilter);
                                // Now add the filter to the graph.
                                //Remember to release pFilter later.
                                pPropBag->Release();
                        }
                        pMoniker->Release();
                }
                pEnumCat->Release();
        }
        pSysDevEnum->Release();

        adaptersBox.SetCurSel(0);
}

HRESULT vcCaptureVideo(HWND msgWindow, HWND prvWindow, unsigned int devIndex)
{
        if (devIndex == 0)
                devIndex = 1;

        HRESULT hr;
        IBaseFilter *pSrcFilter = NULL;

        // Get DirectShow interfaces
        hr = GetInterfaces(msgWindow);
        if (FAILED(hr)) {
                Msg(TEXT("Failed to get video interfaces!  hr=0x%x"), hr);
                return hr;
        }

        // Attach the filter graph to the capture graph
        hr = g_pCapture->SetFiltergraph(g_pGraph);
        if (FAILED(hr)) {
                Msg(TEXT("Failed to set capture filter graph!  hr=0x%x"), hr);
                return hr;
        }

        // Use the system device enumerator and class enumerator to find
        // a video capture/preview device, such as a desktop USB video camera.
        hr = FindCaptureDevice(&pSrcFilter);
        if (FAILED(hr)) {
                // Don't display a message because FindCaptureDevice will handle it
                return hr;
        }


        // Add Capture filter to our graph.
        hr = g_pGraph->AddFilter(pSrcFilter, L"Video Capture");
        if (FAILED(hr)) {
                Msg(TEXT("Couldn't add the capture filter to the graph!  hr=0x%x\r\n\r\n")
                    TEXT("If you have a working video capture device, please make sure\r\n")
                    TEXT("that it is connected and is not being used by another application.\r\n\r\n")
                    TEXT("The sample will now close."), hr);
                pSrcFilter->Release();
                return hr;
        }

        hr = sgAddSampleGrabber(g_pGraph);
        if (FAILED(hr)) {
                Msg(TEXT("Couldn't add the SampleGrabber filter to the graph!  hr=0x%x"), hr);
                return hr;
        }
        hr = sgSetSampleGrabberMediaType();
        if (FAILED(hr)) {
                Msg(TEXT("Couldn't set the SampleGrabber media type!  hr=0x%x"), hr);
                return hr;
        }
        IBaseFilter* pGrabber = sgGetSampleGrabber();


        // Render the preview pin on the video capture filter
        // Use this instead of g_pGraph->RenderFile
        hr = g_pCapture->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,
                                      pSrcFilter, pGrabber/*NULL*/, NULL);
        if (FAILED(hr)) {
                Msg(TEXT("Couldn't render the video capture stream.  hr=0x%x\r\n")
                    TEXT("The capture device may already be in use by another application.\r\n\r\n")
                    TEXT("The sample will now close."), hr);
                pSrcFilter->Release();
                return hr;
        }

        hr = sgGetSampleGrabberMediaType();

        // Now that the filter has been added to the graph and we have
        // rendered its stream, we can release this reference to the filter.
        pSrcFilter->Release();

        // Set video window style and position
        hr = SetupVideoWindow(prvWindow);
        if (FAILED(hr)) {
                Msg(TEXT("Couldn't initialize video window!  hr=0x%x"), hr);
                return hr;
        }

#ifdef REGISTER_FILTERGRAPH
        // Add our graph to the running object table, which will allow
        // the GraphEdit application to "spy" on our graph
        hr = AddGraphToRot(g_pGraph, &g_dwGraphRegister);
        if (FAILED(hr)) {
                Msg(TEXT("Failed to register filter graph with ROT!  hr=0x%x"), hr);
                g_dwGraphRegister = 0;
        }
#endif

        // Start previewing video data
        hr = g_pMC->Run();
        if (FAILED(hr)) {
                Msg(TEXT("Couldn't run the graph!  hr=0x%x"), hr);
                return hr;
        }

        // Remember current state
        g_psCurrent = Running;

        return S_OK;
}

void vcStopCaptureVideo()
{
        sgCloseSampleGrabber();
        CloseInterfaces();
}

HRESULT FindCaptureDevice(IBaseFilter** ppSrcFilter, unsigned int devIndex)
{
        HRESULT hr = S_OK;
        IBaseFilter* pSrc = NULL;
        IMoniker* pMoniker = NULL;
        ICreateDevEnum* pDevEnum = NULL;
        IEnumMoniker* pClassEnum = NULL;

        if (!ppSrcFilter) {
                return E_POINTER;
        }

        // Create the system device enumerator
        hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
                              IID_ICreateDevEnum, (void **) & pDevEnum);
        if (FAILED(hr)) {
                Msg(TEXT("Couldn't create system enumerator!  hr=0x%x"), hr);
        }

        // Create an enumerator for the video capture devices

        if (SUCCEEDED(hr)) {
                hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pClassEnum, 0);
                if (FAILED(hr)) {
                        Msg(TEXT("Couldn't create class enumerator!  hr=0x%x"), hr);
                }
        }

        if (SUCCEEDED(hr)) {
                // If there are no enumerators for the requested type, then
                // CreateClassEnumerator will succeed, but pClassEnum will be NULL.
                if (pClassEnum == NULL) {
                        MessageBox(NULL, TEXT("No video capture device was detected.\r\n\r\n")
                                   TEXT("This sample requires a video capture device, such as a USB WebCam,\r\n")
                                   TEXT("to be installed and working properly.  The sample will now close."),
                                   TEXT("No Video Capture Hardware"), MB_OK | MB_ICONINFORMATION);
                        hr = E_FAIL;
                }
        }

        // Find the [devIndex] video capture device on the device list.
        // Note that if the Next() call succeeds but there are no monikers,
        // it will return S_FALSE (which is not a failure).  Therefore, we
        // check that the return code is S_OK instead of using SUCCEEDED() macro.

        if (SUCCEEDED(hr)) {
                for (unsigned int i = 0; i < devIndex; i++) {
                        hr = pClassEnum->Next(1, &pMoniker, NULL);
                        if (hr == S_FALSE) {
                                Msg(TEXT("Unable to access video capture device!"));
                                hr = E_FAIL;
                                break;
                        }
                }
        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -