简体   繁体   English

如何使用DirectShow和网络摄像头预览图像

[英]How to use DirectShow and webcam to preview an image

I'm trying to use C++ and DirectShow to display my webcam... but I'm having some troubles. 我正在尝试使用C ++和DirectShow来显示我的网络摄像头...但是我遇到了一些麻烦。 The following code gives me a segmentation fault on: 以下代码为我提供了分段错误:

m_pDF->EnumPins(&pinEnum);

my cpp code: 我的cpp代码:

#include <tchar.h>
#include <strsafe.h>
#include <dshow.h>
#include <atlbase.h>
#include <d3d9.h>
#include <vmr9.h>

#pragma comment(lib,"Strmiids.lib")

#define SAFE_RELEASE(x) { if (x) x->Release(); x = NULL; }

HRESULT EnumerateDevices(REFGUID category, IEnumMoniker **ppEnum)
{
    // Create the System Device Enumerator.
    ICreateDevEnum *pDevEnum;   // Video and Audio interface object
    HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pDevEnum)); // Creates the system device enumerator

    if (SUCCEEDED(hr))
    {
        // Create an enumerator for the category.
        hr = pDevEnum->CreateClassEnumerator(category, ppEnum, 0);  // Enumeration of 'category' objects
        if (hr == S_FALSE)
        {
            hr = VFW_E_NOT_FOUND;  // The category is empty. Treat as an error.
        }
        pDevEnum->Release(); // Deletes Enumeration object
    }
    return hr;
}

void main(void)
{
    IGraphBuilder *pGraph = NULL;
    IMediaControl *pControl = NULL; // contains methods for stopping and starting the graph
    IMediaEvent   *pEvent = NULL;   // methods for getting events from the Filter Graph Manager

    IPin *m_pCamOutPin;
    IBaseFilter *m_pDF=NULL;
    IMoniker *pM;
    IEnumMoniker *pEnum; // Enumerator object

    // Initialize the COM library.
    HRESULT hr = CoInitialize(NULL);
    if (FAILED(hr))
    {
        printf("ERROR - Could not initialize COM library");
        return;
    }

    // Create the filter graph manager and query for interfaces.
    hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, 
                        IID_IGraphBuilder, (void **)&pGraph);
    if (FAILED(hr))
    {
        printf("ERROR - Could not create the Filter Graph Manager.");
        return;
    }

    // Bind
    hr = EnumerateDevices(CLSID_VideoInputDeviceCategory, &pEnum);
    pEnum->Next(1, &pM, NULL);
    pM->BindToObject(0, 0, IID_IBaseFilter, (void**)m_pDF);
    pM->Release();

    hr=pGraph->AddFilter(m_pDF, L"Video Capture");

    CComPtr<IEnumPins> pinEnum;
    m_pDF->EnumPins(&pinEnum);

    hr = pinEnum->Reset();
    hr = pinEnum->Next(1, &m_pCamOutPin, NULL); 

    if (FAILED(hr))
    return;

    // control
    hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
    hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);

    // Build the graph. IMPORTANT: Change this string to a file on your system.
    hr = pGraph->Render(m_pCamOutPin);
    if (SUCCEEDED(hr))
    {
        // Run the graph.
        hr = pControl->Run();
        if (SUCCEEDED(hr))
        {
            // Wait for completion.
            long evCode;
            pEvent->WaitForCompletion(INFINITE, &evCode);

            // Note: Do not use INFINITE in a real application, because it
            // can block indefinitely.
        }
    }
    SAFE_RELEASE(pControl);
    SAFE_RELEASE(pEvent);
    SAFE_RELEASE(pGraph);
    CoUninitialize();
}

Any ideas on what am I doing wrong and what do I have to do to get this to work? 关于我在做什么错以及如何使它正常工作有什么想法?

m_pDF is a pointer to IBaseFilter: m_pDF是指向IBaseFilter的指针:

IBaseFilter *m_pDF=NULL;

BindToObject last parameter is a pointer to a pointer. BindToObject最后一个参数是指向指针的指针。 Which means this functioncall is wrong: 这意味着此函数调用是错误的:

pM->BindToObject(0, 0, IID_IBaseFilter, (void**)m_pDF);

Instead you need to pass the address of m_pDF to get a pointer to a pointer: 相反,您需要传递m_pDF的地址来获取指向指针的指针:

pM->BindToObject(0, 0, IID_IBaseFilter, (void**)&m_pDF);

It is not a problem to cast IBaseFilter** to void** , but you can't cast IBaseFilter* to void** . IBaseFilter**void**没问题,但是您不能将IBaseFilter*void**

The crash should be related m_pDF , it not be a valid pointer. 崩溃应该与m_pDF有关,它不是有效的指针。

you should add check for pM->BindToObject(0, 0, IID_IBaseFilter, (void**)m_pDF); 您应该添加检查pM->BindToObject(0, 0, IID_IBaseFilter, (void**)m_pDF); to know that m_pDF is initialize sucess or not. 知道m_pDF是否初始化成功。

and you should also check hr=pGraph->AddFilter(m_pDF, L"Video Capture"); 并且您还应该检查hr=pGraph->AddFilter(m_pDF, L"Video Capture"); hr is ok or not. hr没事。

if fail, you can get the error code know the reason. 如果失败,您可以获取错误代码并了解原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM