directshow报0x80004002的错误

vs2008+directshow开发中执行到hr = m_pDeviceFilter->QueryInterface(IID_IAMVideoControl,(LPVOID *)&m_pAMVideoControl)这里会报0x80004002的错误,完整代码如下,有哪位大神知道是什么问题吗?

img

img

img


bool __fastcall DirectShowHandler::Open(DirectShowHandler_OpenParam * pParam)
{
    if (m_bOpen)//如果设备打开状态,则直接返回
    {
        return false;
    }

    if (pParam == NULL)//没有传递打开对象参数,直接返回
    {
        return false;
    }

    //初始化DirectShowHandler_OpenParam类对象参数
    HRESULT hr;
    HWND hWnd = m_hWnd = pParam->m_hWnd;//null 父窗口句柄初始化?

    m_iDeviceIndex = pParam->m_iDeviceIndex;//设备索引 想要open的设备号(第1台的话0。以后1,2,…)
    m_bUseExternalTrigger = pParam->m_bUseExternalTrigger;//是否使用外部触发

    m_pContext = pParam->m_pContext;    // 2010.6.28 add by Shiba

    // 2012.07.25 nemo add
    m_iImageWidth    = pParam->m_iImageWidth;//图像宽
    m_iImageHeight    = pParam->m_iImageHeight;//图像高


    // 曗懌忣曬乯塸扨岅偺擔杮岅栿
    //   Enumerate : 楍嫇丄堦棗
    //   Moniker   : 偁偩柤
    ICreateDevEnum *pCreateDevEnum = NULL;
    IEnumMoniker *pEnumMoniker = NULL;
    IMoniker *pMoniker = NULL;
    IAMStreamConfig * pConfig = NULL;

    AM_MEDIA_TYPE am_media_type;//构建AM_MEDIA_TYPE(媒体类型)结构体对象  https://blog.csdn.net/xuqiang918/article/details/8565470
    ZeroMemory(&am_media_type, sizeof(am_media_type));//初始化

    ULONG nFetched = 0;

    try {
//        DWORD dwDirectXVersion;
//        TCHAR szDirectXVersion[256];
//
//        hr = GetDXVersion(&dwDirectXVersion, szDirectXVersion, sizeof(szDirectXVersion));
//        if (FAILED(hr))
//        {
//            SHOW_ERROR(hWnd, hr);
//            throw;
//        }
//
//        if (dwDirectXVersion < 0x00080000)
//        {
//            char szBuf[256];
//            sprintf(szBuf, "DirectX Version is old.\n\nDirectX Version : %s\n\nInstall DirectX8 or later.",
//                szDirectXVersion);
//            MessageBox(hWnd, szBuf, "DirectShowHandler", MB_OK | MB_ICONSTOP);
//            return false;
//        }

        // FilterGraph傪惗惉 创建filter graph manager
        hr = CoCreateInstance(
            CLSID_FilterGraph,
            NULL,
            CLSCTX_INPROC,
            IID_IGraphBuilder,
            (LPVOID *)&m_pGraphBuilder
            );
        if (FAILED(hr))
        {
            SHOW_ERROR(hWnd, hr);
            throw "CoCreateInstance() failed.";
        }

        //
        // SampleGrabber弨旛
        //

        // SampleGrabber(Filter)傪惗惉 创建SampleGrabber fliter
        hr = CoCreateInstance(
            CLSID_SampleGrabber,
            NULL,
            CLSCTX_INPROC,
            IID_IBaseFilter,
            (LPVOID *)&m_pSampleGrabberFilter);
        if (FAILED(hr))
        {
            SHOW_ERROR(hWnd, hr);
            throw "CoCreateInstance() failed.";
        }

        // Filter偐傜ISampleGrabber僀儞僞乕僼僃乕僗傪庢摼偟傑偡  获取ISampleGrabber接口,用于设置回调等相关信息
        hr = m_pSampleGrabberFilter->QueryInterface(
            IID_ISampleGrabber,
            (LPVOID *)&m_pSampleGrabber
            );
        if (FAILED(hr))
        {
            SHOW_ERROR(hWnd, hr);
            throw "QueryInterface() failed.";
        }

        // SampleGrabber傪愙懕偡傞僼僅乕儅僢僩傪巜掕丅
        // 偙偙偑億僀儞僩偱偡丅
        // 偙偙偺巜掕偺巇曽偵傛傝SampleGrabber偺憓擖売強傪
        // 寛掕偱偒傑偡丅偙偺僒儞僾儖偺傛偆側巜掕傪偡傞偲
        // 夋柺弌椡偺悺慜偱僒儞僾儖傪庢摼偱偒傑偡丅
          // SampleGrabberを接続するフォーマットを指定。指定连接SampleGrabber的格式。
        // ここがポイントです。 /这里是重点。
        // ここの指定の仕方によりSampleGrabberの挿入箇所を 根据这里的指定方法可以决定插入SampleGrabber的位置。像这个样本那样的指定的话在画面输出前能取得样本。
        // 決定できます。このサンプルのような指定をすると
        // 画面出力の寸前でサンプルを取得できます。
        ZeroMemory(&am_media_type, sizeof(am_media_type));
        am_media_type.majortype = MEDIATYPE_Video;//主类型-视频类型
        am_media_type.subtype = MEDIASUBTYPE_RGB24;//子类型-rgb24
        am_media_type.formattype = FORMAT_VideoInfo;//内存块的格式
        hr = m_pSampleGrabber->SetMediaType(&am_media_type);//指定示例抓取器输入引脚上连接的媒体类型
        if (FAILED(hr))
        {
            SHOW_ERROR(hWnd, hr);
            throw "SetMediaType() failed.";
        }

        // Graph偵SampleGrabber Filter傪捛壛 在Graph中添加SampleGrabber Filter
        hr = m_pGraphBuilder->AddFilter(
            m_pSampleGrabberFilter,
            L"Sample Grabber"
            );
        if (FAILED(hr))
        {
            SHOW_ERROR(hWnd, hr);
            throw "AddFilter() failed.";
        }

        //
        // 僉儍僾僠儍梡僨僶僀僗庢摼
        //

        // CaptureGraphBuilder2偲偄偆僉儍僾僠儍梡GraphBuilder傪惗惉偡傞 //创建Capture Graph Builder.  这个接口提供了一些方法用来构建和控制捕捉graph。
        hr = CoCreateInstance(
            CLSID_CaptureGraphBuilder2,
            NULL,
            CLSCTX_INPROC,
            IID_ICaptureGraphBuilder2,
            (LPVOID *)&m_pCaptureGraphBuilder2
            );
        if (FAILED(hr))
        {
            SHOW_ERROR(hWnd, hr);
            throw "CoCreateInstance() failed.";
        }

        // FilterGraph傪僙僢僩偡傞 设置FilterGraph  //Initialize the Capture Graph Builder
        hr = m_pCaptureGraphBuilder2->SetFiltergraph(m_pGraphBuilder);
        if (FAILED(hr))
        {
            SHOW_ERROR(hWnd, hr);
            throw "SetFiltergraph() failed.";
        }

        // MediaControl僀儞僞乕僼僃乕僗庢摼 // IMediaControl接口,用来控制流媒体在Filter Graph中的流动,例如流媒体的启动和停止;
        hr = m_pGraphBuilder->QueryInterface(
            IID_IMediaControl,
            (LPVOID *)&m_pMediaControl
            );
        if (FAILED(hr))
        {
            SHOW_ERROR(hWnd, hr);
            throw "QueryInterface() failed.";
        }

        // 僨僶僀僗傪楍嫇偡傞偨傔偺CreateDevEnum傪惗惉 创建设备枚举com对象
        hr = CoCreateInstance(
            CLSID_SystemDeviceEnum,
            NULL,
            CLSCTX_INPROC_SERVER,
            IID_ICreateDevEnum,
            (PVOID *)&pCreateDevEnum
            );
        if (FAILED(hr))
        {
            SHOW_ERROR(hWnd, hr);
            throw "CoCreateInstance() failed.";
        }

        // VideoInputDevice傪楍嫇偡傞偨傔偺EnumMoniker傪惗惉 创建视频采集设备枚举com对象
        hr = pCreateDevEnum->CreateClassEnumerator(
            CLSID_VideoInputDeviceCategory,
            &pEnumMoniker,
            0
            );
        if (FAILED(hr))
        {
            SHOW_ERROR(hWnd, hr);
            throw "CreateClassEnumerator() failed.";
        }

        if (pEnumMoniker == NULL)
        {
            // 愙懕偝傟偨塮憸擖椡僨僶僀僗偑堦偮傕柍偄応崌偵偼偙偺if暥偵擖傝傑偡  如果没有任何连接的视频输入设备,就进入if语句。
            MessageBox(NULL, "Capture Device not found.", "DirectShowHandler", MB_OK | MB_ICONSTOP);
            throw "Capture Device not found.";
        }

        // EnumMoniker傪Reset偡傞
        // Reset偡傞偲丄愭摢偐傜悢偊側偍偟傑偡  Reset EnumMonikerReset的话,从开头开始重新数
        hr = pEnumMoniker->Reset();
        if (FAILED(hr))
        {
            SHOW_ERROR(hWnd, hr);
            throw "Reset() failed.";
        }

        // 嵟弶偺Moniker傪庢摼 //获得第一个Moniker(姓名)
        for (int iDev = 0; iDev <= m_iDeviceIndex; iDev++)
        {
            hr = pEnumMoniker->Next(//Next 以检索枚举中的每个名字对象
                1,
                &pMoniker,
                &nFetched
                );
            if (FAILED(hr))
            {
                SHOW_ERROR(hWnd, hr);
                throw "Next() failed.";
            }
        }

        {
            IPropertyBag *pPropertyBag;
            //TCHAR szDevName[256];

            // IPropertyBag偵bind偡傞  BindToStorage之后就可以访问设备标识的属性集了  BindToStorage 以检索其关联的属性包
            hr = pMoniker->BindToStorage(
                0,
                0,
                IID_IPropertyBag,
                (LPVOID *)&pPropertyBag
                );
            if (FAILED(hr))
            {
                SHOW_ERROR(hWnd, hr);
                throw "BindToStorage() failed.";
            }

            // Friendly name傪庢摼偡傞偨傔偺擖傟暔  获得Friendly name的容器
            VARIANT varFriendlyName;
            varFriendlyName.vt = VT_BSTR;

            // FriendlyName傪庢摼  获得FriendlyName
            hr = pPropertyBag->Read(L"FriendlyName", &varFriendlyName, 0);
            if (FAILED(hr))
            {
                SHOW_ERROR(hWnd, hr);
                throw "Read() failed.";
            }

            // 庢摼偟偨FriendlyName傪僐僺乕
            #ifdef UNICODE
            // 擮偺偨傔UNICODE偺帪偺僐乕僪
            _tcscpy(devname, varFriendlyName.bstrVal);
            #else
            // 摿偵壗傕偟側偗傟偽丄UNICODE偱偼側偔丄偙偪傜偵側傞偼偢偱偡
            WideCharToMultiByte(CP_ACP, 0, varFriendlyName.bstrVal, -1, m_szDeviceName, sizeof(m_szDeviceName), 0, 0);
            #endif

    //        // 寢壥傪昞帵
    //        LabelDevice->Caption = AnsiString().sprintf("Device: %s", szDevName);

            // 帒尮傪夝曻 释放资源
            VariantClear(&varFriendlyName);

            // 帒尮傪夝曻 释放资源
            pPropertyBag->Release();
        }

        // Monkier傪Filter偵Bind偡傞 将(设备)Monkier Bind到Filter 创建了设备过滤器
        hr = pMoniker->BindToObject(
            0,
            0,
            IID_IBaseFilter,
            (void**)&m_pDeviceFilter
            );
        if (FAILED(hr))
        {
            SHOW_ERROR(hWnd, hr);
            throw "BindToObject() failed.";
        }

        // 偙偺帪揰偱Monkier宯丄Enumerate宯偼梡嵪傒
        if (pMoniker != NULL) pMoniker->Release();
        if (pEnumMoniker != NULL) pEnumMoniker->Release();
        if (pCreateDevEnum != NULL) pCreateDevEnum->Release();

        // FilterGraph偵僨僶僀僗僼傿儖僞傪捛壛偡傞 在FilterGraph中添加设备过滤器
        hr = m_pGraphBuilder->AddFilter(
            m_pDeviceFilter,
            L"Device Filter"
            );
        if (FAILED(hr))
        {
            SHOW_ERROR(hWnd, hr);
            throw "AddFilter() failed.";
        }
        
        int wh_Index = 0;
        if (1)
        {
            // get the IAMStreamConfig interface so that we can set the resolution  获取IAMStreamConfig接口,以便我们可以设置分辨率
            hr = m_pCaptureGraphBuilder2->FindInterface(//查询摄像头支持格式的接口
                &PIN_CATEGORY_CAPTURE,
                &MEDIATYPE_Video,
                m_pDeviceFilter,
                IID_IAMStreamConfig,
                (LPVOID *)&pConfig
                );
            if (FAILED(hr))
            {
                SHOW_ERROR(hWnd, hr);
                throw "FindInterface() failed.";
            }

            int iCount = 0;
            int iSize = 0;
            // get the number of different resolutions possible 获得可能的不同分辨率的数量 一个是媒体类型的数量,二是属性所需结构的大小
            hr = pConfig->GetNumberOfCapabilities(&iCount, &iSize);//获得设备所支持的媒体类型的数量
            if (FAILED(hr))
            {
                SHOW_ERROR(hWnd, hr);
                throw "GetNumberOfCapabilities() failed.";
            }

            if (iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS))//这个方法是用于视频和音频
            {
                for (int iIndex = 0; iIndex < iCount; iIndex++)
                {
                    VIDEO_STREAM_CONFIG_CAPS scc;
                    AM_MEDIA_TYPE *pmtConfig;
                    // make sure we can set the capture format to the resolution we want  //确保我们可以设置捕获格式为我们想要的分辨率
                    hr = pConfig->GetStreamCaps(iIndex, &pmtConfig, (BYTE*)&scc);//来枚举媒体类型
                    if (SUCCEEDED(hr))
                    {

                        VIDEOINFOHEADER *pVideoInfoHeader = (VIDEOINFOHEADER *)pmtConfig->pbFormat;// 指向内存块的指针

                        if (pmtConfig->formattype == FORMAT_VideoInfo)
                        {

                            TCHAR szBuf[4096];
                            sprintf(szBuf,
                                "rcSource : (%d, %d, %d, %d)\n"
                                "rcTarget : (%d, %d, %d, %d)\n"
                                "dwBitRate : %u(bit/sec)\n"
                                "dwBitErrorRate : %u(bit error/sec)\n"
                                "AvgTimePerFrame : %Lu(unit/100ns)\n"
                                "bmiHeader.biSize : %d\n"
                                "bmiHeader.biWidth : %d\n"
                                "bmiHeader.biHeight : %d\n"
                                "bmiHeader.biPlanes : %d\n"
                                "bmiHeader.biBitCount : %d\n"
                                "bmiHeader.biCompression : %d\n"
                                "bmiHeader.biSizeImage : %d\n"
                                "bmiHeader.biXPelsPerMeter : %d\n"
                                "bmiHeader.biYPelsPerMeter : %d\n"
                                "bmiHeader.biClrUsed : %d\n"
                                "bmiHeader.biClrImportant : %d\n",
                                pVideoInfoHeader->rcSource.left,
                                pVideoInfoHeader->rcSource.top,
                                pVideoInfoHeader->rcSource.right,
                                pVideoInfoHeader->rcSource.bottom,
                                pVideoInfoHeader->rcTarget.left,
                                pVideoInfoHeader->rcTarget.top,
                                pVideoInfoHeader->rcTarget.right,
                                pVideoInfoHeader->rcTarget.bottom,
                                pVideoInfoHeader->dwBitRate,
                                pVideoInfoHeader->dwBitErrorRate,
                                pVideoInfoHeader->AvgTimePerFrame,
                                pVideoInfoHeader->bmiHeader.biSize,
                                pVideoInfoHeader->bmiHeader.biWidth,
                                pVideoInfoHeader->bmiHeader.biHeight,
                                pVideoInfoHeader->bmiHeader.biPlanes,
                                pVideoInfoHeader->bmiHeader.biBitCount,
                                pVideoInfoHeader->bmiHeader.biCompression,
                                pVideoInfoHeader->bmiHeader.biSizeImage,
                                pVideoInfoHeader->bmiHeader.biXPelsPerMeter,
                                pVideoInfoHeader->bmiHeader.biYPelsPerMeter,
                                pVideoInfoHeader->bmiHeader.biClrUsed,
                                pVideoInfoHeader->bmiHeader.biClrImportant
                                );

                            // MessageBox(hWnd, szBuf, "VideoInfoHeader", MB_OK | MB_ICONINFORMATION);
                        }
                        
                        if((pVideoInfoHeader->bmiHeader.biWidth == m_iImageWidth) &&
                            (pVideoInfoHeader->bmiHeader.biHeight == m_iImageHeight)){
                            wh_Index  = iIndex;
                        }

                        // That resolution is available, now we set the capture format to the resolution we want.
                        //pConfig->SetFormat(pmtConfig);

                        MyDeleteMediaType(pmtConfig);//构体本身释放
                    }
                }
            }
        }

        
        // 夝憸搙愝掕 解析度设定
        hr = m_pCaptureGraphBuilder2->FindInterface(//查询摄像头支持格式接口
            &PIN_CATEGORY_CAPTURE,
            &MEDIATYPE_Video,
            m_pDeviceFilter,
            IID_IAMStreamConfig,
            (LPVOID *)&pConfig
            );
        if (FAILED(hr))
        {
            SHOW_ERROR(hWnd, hr);
            throw "FindInterface() failed.";
        }

        VIDEO_STREAM_CONFIG_CAPS scc;
        AM_MEDIA_TYPE *pmtConfig;
        // make sure we can set the capture format to the resolution we want  确保我们可以将捕获格式设置为我们想要的分辨率
        hr = pConfig->GetStreamCaps(wh_Index, &pmtConfig, (BYTE*)&scc);////来枚举媒体类型
        if (SUCCEEDED(hr))
        {

            VIDEOINFOHEADER *pVideoInfoHeader = (VIDEOINFOHEADER *)pmtConfig->pbFormat;
            pVideoInfoHeader->bmiHeader.biWidth = m_iImageWidth;
            pVideoInfoHeader->bmiHeader.biHeight = m_iImageHeight;
            
            pConfig->SetFormat(pmtConfig);

            //MyDeleteMediaType(pmtConfig);
        }

        //
        // Preview偺偨傔偺VideoRenderer傪梡堄偟傑偡 准备一个Preview的VideoRenderer。
        //
        hr = CoCreateInstance(
            CLSID_VideoRenderer,
            NULL,
            CLSCTX_INPROC_SERVER,
            IID_IBaseFilter,
            (LPVOID *)&m_pVideoRenderer
            );
        if (FAILED(hr))
        {
            SHOW_ERROR(hWnd, hr);
            throw "CoCreateInstance() failed.";
        }

        hr = m_pGraphBuilder->AddFilter(m_pVideoRenderer, L"Video Renderer");
        if (FAILED(hr))
        {
            SHOW_ERROR(hWnd, hr);
            throw "AddFilter() failed.";
        }

        // Graph傪惗惉偡傞
        // SampleGrabber傪娫偵擖傟偰丄
        // Renderer偲偟偰偼VideoRenderer傪棙梡偟傑偡
        hr = m_pCaptureGraphBuilder2->RenderStream(
            &PIN_CATEGORY_PREVIEW,  // [in] 僺儞 僇僥僑儕傪巜掕偡傞丄僺儞 僾儘僷僥傿 僙僢僩偺 AMPROPERTY_PIN_CATEGORY 峔憿懱偺儊儞僶傊偺億僀儞僞丅
            NULL,                   // [in] 弌椡僺儞偺儊僨傿傾 僞僀僾傪巜掕偡傞儊僕儍乕 僞僀僾 GUID 傊偺億僀儞僞丅
            m_pDeviceFilter,        // [in] 愙懕偺愭摢僼傿儖僞傊偺億僀儞僞偐丄傑偨偼弌椡僺儞傊偺億僀儞僞傪巜掕偡傞丅
            m_pSampleGrabberFilter, // [in] 埑弅僼傿儖僞側偳拞娫僼傿儖僞偺 IBaseFilter 僀儞僞乕僼僃僀僗傊偺億僀儞僞丅NULL 傕壜丅
            m_pVideoRenderer        // [in] 儗儞僟儔傗 Mux 僼傿儖僞側偳丄僔儞僋 僼傿儖僞偺 IBaseFilter 僀儞僞乕僼僃僀僗傊偺億僀儞僞丅
            );
        if (FAILED(hr))
        {
            SHOW_ERROR(hWnd, hr);
            throw "RenderStream() failed.";
        }

        // 奜晹僩儕僈巊偆応崌
        // ********************************************************************** 
        //2010.8.23 奜晹僩儕僈傪巊傢側偄応崌傕丄巊傢側偄愝掕傪峴偆昁梫偑偁傞丂幠
        //if (m_bUseExternalTrigger)
        //{
        //    hr = m_pDeviceFilter->QueryInterface(
        //        IID_IAMVideoControl,
        //        (LPVOID *)&m_pAMVideoControl
        //        );
        //    if (FAILED(hr))
     //       {
        //        SHOW_ERROR(hWnd, hr);
        //        throw "QueryInterface() failed.";
     //       }
        //    else
        //    {
        //        hr = m_pCaptureGraphBuilder2->FindPin(
        //            m_pDeviceFilter,
        //            PINDIR_OUTPUT,
        //            &PIN_CATEGORY_CAPTURE,
        //            &MEDIATYPE_Video,
        //            FALSE,
        //            0,
        //            &m_pGrabberPin
        //            );
        //        if (FAILED(hr))
        //        {
        //            SHOW_ERROR(hWnd, hr);
        //            throw "FindPin() failed.";
        //        }
        //        else
        //        {
        //            long caps = 0;
        //            hr = m_pAMVideoControl->GetCaps(
        //                m_pGrabberPin,
        //                &caps
        //                );
        //            if ((caps & VideoControlFlag_ExternalTriggerEnable) == 0)
        //            {
        //                MessageBox(m_hWnd, "External Trigger is not supported.\nPlease check if appropriate device driver installed correctly.\n\nNote:http://www.theimagingsource.com/downloads/icwdmuvccamtis.en_US.zip", __FUNCTION__, MB_OK | MB_ICONSTOP);
        //            }
        //            else
        //            {
        //                hr = m_pAMVideoControl->SetMode(
        //                    m_pGrabberPin,
        //                    VideoControlFlag_ExternalTriggerEnable
        //                    );
        //                if (FAILED(hr))
        //                {
        //                    SHOW_ERROR(hWnd, hr);
        //                    throw "SetMode() failed.";
        //                }
        //            }
        //        }
        //    }
        //}
#if 0    // [AP3]
    /* ChipAVI梡偺僇儊儔偱僒億乕僩偟偰側偄婡擻傪僐儊儞僩 2011.04.22 I.Ohno
    */
#endif
        hr = m_pDeviceFilter->QueryInterface(
            IID_IAMVideoControl,
            (LPVOID *)&m_pAMVideoControl
            );//相机控制接口
        if (FAILED(hr))
        {
            SHOW_ERROR(hWnd, hr);
            throw "QueryInterface() failed.";
        }
        else
        {
            hr = m_pCaptureGraphBuilder2->FindPin(//寻找设备filter的pin口
                m_pDeviceFilter,
                PINDIR_OUTPUT,
                &PIN_CATEGORY_CAPTURE,
                &MEDIATYPE_Video,
                FALSE,
                0,
                &m_pGrabberPin
                );
            if (FAILED(hr))
            {
                SHOW_ERROR(hWnd, hr);
                throw "FindPin() failed.";
            }
            else
            {//判断是否可以使用外部触发
                long caps = 0;
                hr = m_pAMVideoControl->GetCaps(//得到基础硬件的功能
                    m_pGrabberPin,
                    &caps
                    );
                if ((caps & VideoControlFlag_ExternalTriggerEnable) == 0)
                {
                    MessageBox(m_hWnd, "External Trigger is not supported.\nPlease check if appropriate device driver installed correctly.\n\nNote:http://www.theimagingsource.com/downloads/icwdmuvccamtis.en_US.zip", __FUNCTION__, MB_OK | MB_ICONSTOP);
                }
                else
                {
                    long mode = m_bUseExternalTrigger ? VideoControlFlag_ExternalTriggerEnable : 0;
                    hr = m_pAMVideoControl->SetMode(
                        m_pGrabberPin,
                        mode
                        );
                    if (FAILED(hr))
                    {
                        SHOW_ERROR(hWnd, hr);
                        throw "SetMode() failed.";
                    }
                }
            }
        }
        // ********************************************************************** 

#if 0    // [AP3]
        // 2010.7.20 業岝帪娫愝掕偺堊捛壛丂幠
        hr = m_pDeviceFilter->QueryInterface(
            IID_IAMCameraControl,
            (LPVOID *)&m_pIAMCameraControl
            );
        if (FAILED(hr))
        {
            SHOW_ERROR(hWnd, hr);
            throw "QueryInterface() failed.";
        }
*/
#endif
        //
        // 僐乕儖僶僢僋娭悢傪愝掕  设置回调函数 0:samplecb   1:buffercb//接收指向sample缓冲区的指针的回调方法。
        //
        hr = m_pSampleGrabber->SetCallback((ISampleGrabberCB *)m_pSampleGrabberCB, 1);
        if (FAILED(hr))
        {
            SHOW_ERROR(hWnd, hr);
            throw "SetCallback() failed.";
        }

        //
        // SampleGrabber偐傜忣曬傪庢摼
        //

        // 愙懕忣曬庢摼丅
        // 偙偺張棟偼RenderFile偵傛傝Graph偑峔惉偝傟偨屻偵   连接信息取得。这个处理需要在图形由RenderFile组成之后进行。
        // 峴偆昁梫偑偁傝傑偡丅
        hr = m_pSampleGrabber->GetConnectedMediaType(&am_media_type);//检索连接在Sample Grabber的输入引脚上的MediaType
        if (FAILED(hr))
        {
            SHOW_ERROR(hWnd, hr);
            throw "GetConnectedMediaType() failed.";
        }

        VIDEOINFOHEADER *pVideoInfoHeader = (VIDEOINFOHEADER *)am_media_type.pbFormat;

        // 僼儗乕儉僶僢僼傽妋曐 //帧缓冲器确保
        m_iWidth  = pVideoInfoHeader->bmiHeader.biWidth;
        m_iHeight = pVideoInfoHeader->bmiHeader.biHeight;

        m_OneFrameBufSize = am_media_type.lSampleSize;
        m_iFrameBufNum = pParam->m_iFrameBufNum;
        size_t TotalBufSize = m_OneFrameBufSize * m_iFrameBufNum;

        // 2010.9.14 弶夞偵儊儌儕妋曐丂僨僗僩儔僋僞偱奐曻丂幠
        //m_pFrameBuf = (BYTE *)VirtualAlloc(NULL, TotalBufSize, MEM_COMMIT, PAGE_READWRITE);
        if (m_pFrameBuf == NULL) {//整个帧缓冲器的开头
            m_pFrameBuf = (BYTE *)VirtualAlloc(NULL, TotalBufSize, MEM_COMMIT, PAGE_READWRITE);//分配内存
        }

        if (m_pFrameBuf == NULL)
        {
            char szMsg[256];
            sprintf(szMsg, "VirtualAlloc() failed.\n\n"
                "required memory:%dbytes\n"
                "Width:%d Height:%d OneFrameBufSize:%d FrameBufNum:%d\n"
                "Source Code Line Number:%d",
                TotalBufSize,
                m_iWidth, m_iHeight, m_OneFrameBufSize, m_iFrameBufNum,
                __LINE__
                );
            MessageBox(hWnd, szMsg, "DirectShowHandler", MB_OK | MB_ICONSTOP);
            throw "VirtualAlloc() failed.";
        }

        // 夋憸乮塮憸乯偺暆偲崅偝傪昞帵
        // 僒儞僾儖傪傢偐傝傗偡偔偡傞偨傔偵昞帵偟偰偄傞偩偗側偺偱丄
        // 昁偢昁梫偲偄偆傢偗偱偼偁傝傑偣傫丅
    //  printf(
    //        "size = %dx%d\n",
    //      pVideoInfoHeader->bmiHeader.biWidth,
    //      pVideoInfoHeader->bmiHeader.biHeight
    //        );

        // 僨乕僞僒僀僘傪昞帵
        // 偙傟傕愢柧偺偨傔偵昞帵偟偰偄傑偡丅
    //  printf(
    //        "sample size = %d\n",
    //      am_media_type.lSampleSize
    //        );

        hr = m_pGraphBuilder->QueryInterface(
            IID_IVideoWindow,
            (LPVOID *)&m_pVideoWindow
            );
        if (FAILED(hr))
        {
            SHOW_ERROR(hWnd, hr);
            throw "QueryInterface() failed.";
        }

        hr = m_pVideoWindow->put_Owner((OAHWND)hWnd);
        if (FAILED(hr))
        {
            SHOW_ERROR(hWnd, hr);
            throw "put_Owner() failed.";
        }

        hr = m_pVideoWindow->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS);
        if (FAILED(hr))
        {
            SHOW_ERROR(hWnd, hr);
            throw "put_WindowStyle() failed.";
        }
        hr = m_pVideoWindow->SetWindowPosition(
            pParam->m_rcClient.left,
            pParam->m_rcClient.top,
            pParam->m_rcClient.right - pParam->m_rcClient.left,
            pParam->m_rcClient.bottom - pParam->m_rcClient.top
            );
        if (FAILED(hr))
        {
            SHOW_ERROR(hWnd, hr);
            throw "SetWindowPosition() failed.";
        }

        hr = m_pVideoWindow->SetWindowForeground(OATRUE);
        if (FAILED(hr))
        {
            SHOW_ERROR(hWnd, hr);
            throw "SetWindowForeground() failed.";
        }

        hr = m_pVideoWindow->put_Visible(OATRUE);
        if (FAILED(hr))
        {
            SHOW_ERROR(hWnd, hr);
            throw "put_Visible() failed.";
        }

        MyFreeMediaType(am_media_type);
    }
    catch (...)
    {
        if (m_pFrameBuf != NULL)
        {
            VirtualFree(m_pFrameBuf, 0, MEM_RELEASE);
            m_pFrameBuf = NULL;
        }
        if (pMoniker != NULL) pMoniker->Release();
        if (pEnumMoniker != NULL) pEnumMoniker->Release();
        if (pCreateDevEnum != NULL) pCreateDevEnum->Release();
        if (pConfig != NULL) pConfig->Release();

        MyFreeMediaType(am_media_type);

        // 僐乕儖僶僢僋娭悢傪夝彍
        if (m_pSampleGrabber != NULL)
        {
            m_pSampleGrabber->SetCallback(NULL, 1);
        }

        if (m_pVideoWindow != NULL)
        {
            m_pVideoWindow->Release();
            m_pVideoWindow = NULL;
        }
        if (m_pVideoRenderer != NULL)
        {
            m_pVideoRenderer->Release();
            m_pVideoRenderer = NULL;
        }
        if (m_pGrabberPin != NULL)
        {
            m_pGrabberPin->Release();
            m_pGrabberPin = NULL;
        }
        if (m_pAMVideoControl != NULL)
        {
            m_pAMVideoControl->Release();
            m_pAMVideoControl = NULL;
        }
        // 2010.7.20 業岝帪娫愝掕偺堊捛壛丂幠
        if (m_pIAMCameraControl != NULL) {
            m_pIAMCameraControl->Release();
            m_pIAMCameraControl = NULL;
        }
        if (m_pDeviceFilter != NULL)
        {
            m_pDeviceFilter->Release();
            m_pDeviceFilter = NULL;
        }
        if (m_pMediaControl != NULL)
        {
            m_pMediaControl->Release();
            m_pMediaControl = NULL;
        }
        if (m_pCaptureGraphBuilder2 != NULL)
        {
            m_pCaptureGraphBuilder2->Release();
            m_pCaptureGraphBuilder2 = NULL;
        }
        if (m_pSampleGrabber != NULL)
        {
            m_pSampleGrabber->Release();
            m_pSampleGrabber = NULL;
        }
        if (m_pSampleGrabberFilter != NULL)
        {
            m_pSampleGrabberFilter->Release();
            m_pSampleGrabberFilter = NULL;
        }
        if (m_pGraphBuilder != NULL)
        {
            m_pGraphBuilder->Release();
            m_pGraphBuilder = NULL;
        }

        ZeroMemory(m_szDeviceName, sizeof(m_szDeviceName));
        m_iWidth  = 0;
        m_iHeight = 0;
        m_OneFrameBufSize = 0;
        m_iFrameBufNum = 0;
        m_hWnd = NULL;

        return false;
    }

    m_bOpen = true;

    return true;
}

管理员cmd执行:

regsvr32 C:\Windows\system32\kswdmcap.ax
regsvr32 C:\Windows\syswow64\kswdmcap.ax

错误代码0x80004002表示"E_NOINTERFACE",意味着接口不可用或未实现。

在执行QueryInterface时,发生了接口不匹配的错误。这可能是由以下几个原因导致的:

检查接口是否正确。确保IID_IAMVideoControl指定的接口确实存在,并且与m_pDeviceFilter的类型匹配。

检查m_pDeviceFilter是否已成功实例化。在执行QueryInterface之前,确保m_pDeviceFilter已经正确地创建和初始化。

确保在执行QueryInterface之前,已经通过调用CoInitialize或者CoInitializeEx来进行了COM的初始化。

确保m_pDeviceFilter支持IAMVideoControl接口。可以通过调用m_pDeviceFilter->QueryInterface来查询其他接口,以确认它支持所需的接口。

如果上述步骤都没有解决问题,还可以尝试以下方法:

检查操作系统和DirectShow版本的兼容性。确保你的操作系统和DirectShow版本与你使用的开发环境和库版本相匹配。

检查相关的依赖项。某些接口可能依赖于其他组件或库。确保所有依赖项都已正确安装和配置。

查找文档和示例代码。查看官方文档和相关示例代码,了解如何正确使用该接口和相关的DirectShow组件。

组件注册的问题,IID_IAMVideoControl错误显示0x80004002不支持此接口 ,检查组件是否正确注册。

你是要采集摄像头吗,建议不要抄网上别人博客代码,大多质量不行。

可以抄微软官方示例代码
https://github.com/microsoft/Windows-classic-samples
这里面的
Win7Samples\multimedia\directshow\capture\playcap
Win7Samples\multimedia\mediafoundation\SimpleCapture
这两个都是摄像头采集播放示例

0x80004002是一个常见的COM错误代码,表示没有找到所请求的接口。意味着你的程序使用了一个不兼容或不正确的接口,或者你的系统缺少某些组件或更新


0×80004002错误代码意思:是指电脑在执行整和检查时发现错误,因此载入预设的系统设定值。解决的方法:
1、首先在电脑上使用组合快捷键win键+r键打开运行窗口。
2、在运行窗口中输入“regsvr32 Softpub.dll”回车确认进入下一步操作。
3、重复第二步,重新打开运行窗口,在运行窗口中输入“regsvr32 Wintrust.dll”回车确认进入下一步操作
4、重复第二步,再次打开运行窗口,在运行窗口中输入“regsvr32 Initpki.dll”回车确认,点击确定即可

根据提供的代码和错误信息,错误代码0x80004002表示“未找到接口”。这通常意味着在尝试调用QueryInterface函数时,指定的接口IID_IAMVideoControl没有被找到或不存在。

解决此问题的一种可能方法是检查是否正确加载了DirectShow库,以便能够访问所需的接口。您可以确保包含dshow.h头文件并链接到正确的库文件。

此外,还应确保您正在使用的DirectShow版本与开发环境(VS2008)兼容。有时,不同版本之间的接口版本差异可能导致接口未找到的错误。

最后,还应检查m_pDeviceFilter指针是否初始化和分配了正确的设备过滤器。