Windows Media Foundation:IMFCaptureEngine::TakePhoto-采样等待时间过长 我在我的C++应用中使用Window Media基金会来拍摄照片。 我的问题是等待取样的时间太长

Windows Media Foundation:IMFCaptureEngine::TakePhoto-采样等待时间过长 我在我的C++应用中使用Window Media基金会来拍摄照片。 我的问题是等待取样的时间太长,c++,winapi,image-processing,video,ms-media-foundation,C++,Winapi,Image Processing,Video,Ms Media Foundation,拍照的算法: 配置预览(帧大小,例如640 x 480) 开始预览 用户向teke photo调用请求 调用我的方法ConfigurePhoto(帧大小,例如2560 x 1920) 调用IMFCaptureEngine::TakePhoto 要接收照片应用程序,请使用实现接口IMFCaptureEngineOnSampleCallback的my类。 它等待调用HRESULT STDMETHODCALLTYPE CaptureEngineSampleCB::OnSample(IMFSample*

拍照的算法:

  • 配置预览(帧大小,例如640 x 480)
  • 开始预览
  • 用户向teke photo调用请求
  • 调用我的方法ConfigurePhoto(帧大小,例如2560 x 1920)
  • 调用IMFCaptureEngine::TakePhoto
  • 要接收照片应用程序,请使用实现接口IMFCaptureEngineOnSampleCallback的my类。 它等待调用HRESULT STDMETHODCALLTYPE CaptureEngineSampleCB::OnSample(IMFSample*pSample)

    我有一个问题,等待步骤6的时间太长了。 有时我只等一秒钟,但有时我只等几分钟。 此时预览中的图像看起来被卡住了

    有没有可能缩短等候时间? 有人知道我做错了什么吗? 捕捉照片的更好方法是什么

  • 下面是一些代码

    HRESULT CaptureDevice::ConfigurePhoto(INT resolutionId, ConfigurationType configureType)
    {
        HRESULT hr = S_OK;
    
        {
            IMFCaptureSink *pSink = NULL;
            IMFMediaSink *p = NULL;
            UINT32 width, height;
    
            // Get a pointer to the photo sink.
            HRESULT hr = m_pEngine->GetSink(MF_CAPTURE_ENGINE_SINK_TYPE_PHOTO, &pSink);
            if (SUCCEEDED(hr))
            {
                IMFCapturePhotoSink *pPhoto = NULL;
                hr = pSink->QueryInterface(IID_PPV_ARGS(&pPhoto));
                if (SUCCEEDED(hr))
                {
                    IMFCaptureSource *pSource;
    
                    hr = m_pEngine->GetSource(&pSource);
                    if (SUCCEEDED(hr))
                    {
                        IMFMediaType *pMediaType = 0;
                        hr = pSource->GetAvailableDeviceMediaType((DWORD)MF_CAPTURE_ENGINE_PREFERRED_SOURCE_STREAM_FOR_PHOTO, resolutionId, &pMediaType);
                        if (SUCCEEDED(hr))
                        {
                            LogMediaType(pMediaType);
                            hr = pSource->SetCurrentDeviceMediaType((DWORD)MF_CAPTURE_ENGINE_PREFERRED_SOURCE_STREAM_FOR_PHOTO, pMediaType);
                            if (SUCCEEDED(hr))
                            {
                                if (WaitForMediaTypeChange())
                                {
                                    IMFMediaType *pMediaType = 0;
                                    //Utils::SafeRelease(&pMediaType);
                                    hr = pSource->GetCurrentDeviceMediaType((DWORD)MF_CAPTURE_ENGINE_PREFERRED_SOURCE_STREAM_FOR_PHOTO, &pMediaType);
                                    if (SUCCEEDED(hr))
                                    {
                                        hr = MFGetAttributeSize(pMediaType, MF_MT_FRAME_SIZE, &width, &height);
    
                                        IMFMediaType *pPhotoMediaType = 0;
                                        LONG bufferStride = 0;
    
                                        //Configure the photo format
                                        hr = Utils::CreateSnapshotMediaTypeForCB(pMediaType, &pPhotoMediaType, bufferStride);
    
                                        if (SUCCEEDED(hr))
                                        {
                                            //LogMediaType(pPhotoMediaType);
    
                                            if (SUCCEEDED(hr))
                                            {
                                                hr = pPhoto->RemoveAllStreams();
                                                if (SUCCEEDED(hr))
                                                {
    
                                                    DWORD dwSinkStreamIndex;
                                                    // Try to connect the first still image stream to the photo sink
                                                    hr = pPhoto->AddStream((DWORD)MF_CAPTURE_ENGINE_PREFERRED_SOURCE_STREAM_FOR_PHOTO, pPhotoMediaType, NULL, &dwSinkStreamIndex);
                                                    if (SUCCEEDED(hr))
                                                    {
    
                                                        hr = pPhoto->SetSampleCallback(m_pSampleCallback);
    
                                                        if (SUCCEEDED(hr))
                                                        {
                                                            hr = pPhoto->Prepare();
                                                            if (SUCCEEDED(hr))
                                                            {
                                                                if (!WaitForCaptureSinkPrepare())
                                                                {
                                                                    hr = E_FAIL;
                                                                }
    
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                            Utils::SafeRelease(&pPhotoMediaType);
    
                                        }
    
                                    }
                                    Utils::SafeRelease(&pMediaType);
    
                                }
                                else
                                {
                                    hr = E_FAIL;
                                }
                            }
                            Utils::SafeRelease(&pMediaType);
                        }
                        Utils::SafeRelease(&pSource);
                    }
                    Utils::SafeRelease(&pPhoto);
                }
                Utils::SafeRelease(&pSink);
            }
    
            /* ... other action */
        }
        return hr;
    }
    
    
    
     HRESULT CaptureDevice::CreatePreview(INT previewRresolutionId, HWND hWnd, BOOL mirror)
    {
        HRESULT hr = S_OK;
        DWORD dwSinkStreamIndex = 0;
        UINT32 w, h;
        LONG lStride = 0;
    
        if (m_pPreview == NULL)
        {
            IMFCaptureSink *pSink = NULL;
    
            hr = m_pEngine->GetSink(MF_CAPTURE_ENGINE_SINK_TYPE_PREVIEW, &pSink);
            if (SUCCEEDED(hr))
            {
                hr = pSink->QueryInterface(IID_PPV_ARGS(&m_pPreview));
                if (SUCCEEDED(hr))
                {
                    //if (m_useDirect3D)
                    {
                        hr = m_pPreview->SetMirrorState(mirror);
                        m_previewWnd = PreviewWindow::CreatePreviewWindow(*this, hWnd);
                        hr = m_pPreview->SetRenderHandle(m_previewWnd);
                    }
    
                    if (SUCCEEDED(hr))
                    {
                        IMFCaptureSource* pSource = NULL;
    
                        hr = m_pEngine->GetSource(&pSource);
                        if (SUCCEEDED(hr))
                        {
                            IMFMediaType *pMediaType = NULL;
    
                            // Configure the video format for the preview sink.
                            hr = pSource->GetAvailableDeviceMediaType((DWORD)MF_CAPTURE_ENGINE_PREFERRED_SOURCE_STREAM_FOR_VIDEO_PREVIEW, previewRresolutionId, &pMediaType);
                            if (SUCCEEDED(hr))
                            {
                                LogMediaType(pMediaType);
                                //hr = Utils::SetDefaultStride(pMediaType, &lStride);
                                hr = pSource->SetCurrentDeviceMediaType((DWORD)MF_CAPTURE_ENGINE_PREFERRED_SOURCE_STREAM_FOR_VIDEO_PREVIEW, pMediaType);
                                if (SUCCEEDED(hr))
                                {
                                    WaitForMediaTypeChange();
    
                                    IMFMediaType *pMediaType2 = NULL;
                                    hr = Utils::CloneVideoMediaType(pMediaType, MFVideoFormat_RGB24, &pMediaType2);
                                    if (SUCCEEDED(hr))
                                    {
                                        hr = pMediaType2->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
                                        if (SUCCEEDED(hr))
                                        {
    
                                            // Connect the video stream to the preview sink.
                                            hr = m_pPreview->AddStream((DWORD)MF_CAPTURE_ENGINE_PREFERRED_SOURCE_STREAM_FOR_VIDEO_PREVIEW, pMediaType2, NULL, &dwSinkStreamIndex);
    
                                        }
                                    }
    
                                    Utils::SafeRelease(&pMediaType2);
                                }
                            }
                            Utils::SafeRelease(&pMediaType);
                        }
                        Utils::SafeRelease(&pSource);
                    }
                }
            }
            Utils::SafeRelease(&pSink);
    
            if (FAILED(hr))
            {
                Utils::SafeRelease(&m_pPreview);
            }
        }
    
        return hr;
    }
    
    预览流的属性:

    MF_MT_FRAME_SIZE    640 x 480
    MF_MT_AVG_BITRATE    110592000
    MF_MT_MAJOR_TYPE    MFMediaType_Video
    MF_MT_DEFAULT_STRIDE    640
    MF_MT_AM_FORMAT_TYPE    {05589F80-C356-11CE-BF01-00AA0055595A}
    MF_MT_FIXED_SIZE_SAMPLES    1
    MF_MT_FRAME_RATE    30000 x 1001
    MF_MT_PIXEL_ASPECT_RATIO    1 x 1
    MF_MT_ALL_SAMPLES_INDEPENDENT    1
    MF_MT_FRAME_RATE_RANGE_MIN    30000 x 1001
    MF_MT_SAMPLE_SIZE    460800
    MF_MT_INTERLACE_MODE    2
    MF_MT_FRAME_RATE_RANGE_MAX    30000 x 1001
    MF_MT_SUBTYPE    MFVideoFormat_NV12
    

    captionSource->GetAvailableDeviceMediaType((DWORD)MF_CAPTURE_ENGINE_PREFERRED_SOURCE_STREAM_FOR_VIDEO_PREVIEW, mediaTypeIndex /* chosen by user index 0*/, &pMediaType);
    
    captionSource->GetAvailableDeviceMediaType( (DWORD)MF_CAPTURE_ENGINE_PREFERRED_SOURCE_STREAM_FOR_PHOTO, mediaTypeIndex /* chosen by user index 16*/, &pMediaType);
    
    图像流的属性:

    MF_MT_FRAME_SIZE    2560 x 1920
    MF_MT_MAJOR_TYPE    MFMediaType_Image
    MF_MT_AM_FORMAT_TYPE    {692FA379-D3E8-4651-B5B4-0B94B013EEAF}
    MF_MT_ALL_SAMPLES_INDEPENDENT    1
    MF_MT_SUBTYPE    {19E4A5AA-5662-4FC5-A0C0-1758028E1057}
    

    captionSource->GetAvailableDeviceMediaType((DWORD)MF_CAPTURE_ENGINE_PREFERRED_SOURCE_STREAM_FOR_VIDEO_PREVIEW, mediaTypeIndex /* chosen by user index 0*/, &pMediaType);
    
    captionSource->GetAvailableDeviceMediaType( (DWORD)MF_CAPTURE_ENGINE_PREFERRED_SOURCE_STREAM_FOR_PHOTO, mediaTypeIndex /* chosen by user index 16*/, &pMediaType);