0

スペース ボタンを押したときにキャプチャされたストリームの画像を取得するために、Microsoft の SDK Direct Show サンプルから入手できる既存の AmCap アプリケーションを変更しようとしています。以下は、スペースキーダウンを処理しているポイントです。

        case WM_KEYDOWN:
        if((GetAsyncKeyState(VK_ESCAPE) & 0x01) && gcap.fCapturing)
        {
            StopCapture();
            if(gcap.fWantPreview)
            {
                BuildPreviewGraph();
                StartPreview();
            }
        }
        else if ((GetAsyncKeyState(VK_SPACE) & 0x01))
        {
            IMediaControl *pMC = NULL;
            HRESULT hr = gcap.pFg->QueryInterface(IID_IMediaControl, (void **)&pMC);

            if (SUCCEEDED(hr)){
                hr=pMC->Pause();
                if (SUCCEEDED(hr)){
                    CaptureImage(TEXT("C:\\output.bmp"));
                    pMC->Run();
                    pMC->Release();
                }else
                    ErrMsg(TEXT("Failed to pause stream!  hr=0x%x"), hr);
            }
            else
                ErrMsg(TEXT("Cannot grab image"));
        }
        break;

以下は、CaptureImage 関数の内容です。

HRESULT hr;

SmartPtr<IBasicVideo> pWC;

// If we got here, gcap.pVW is not NULL 
ASSERT(gcap.pVW != NULL);
hr = gcap.pVW->QueryInterface(IID_IBasicVideo, (void**)&pWC);

if (pWC)
{
    long bufSize;
    long *lpCurrImage = NULL;
    pWC->GetCurrentImage(&bufSize, NULL);

    lpCurrImage = (long *)malloc(bufSize);
    //

    // Read the current video frame into a byte buffer.  The information
    // will be returned in a packed Windows DIB and will be allocated
    // by the VMR.
    hr = pWC->GetCurrentImage(&bufSize, lpCurrImage);
    if (SUCCEEDED(hr))
    {
        HANDLE fh;
        BITMAPFILEHEADER bmphdr;
        BITMAPINFOHEADER bmpinfo;
        DWORD nWritten;

        memset(&bmphdr, 0, sizeof(bmphdr));
        memset(&bmpinfo, 0, sizeof(bmpinfo));

        bmphdr.bfType = ('M' << 8) | 'B';
        bmphdr.bfSize = sizeof(bmphdr) + sizeof(bmpinfo) + bufSize;
        bmphdr.bfOffBits = sizeof(bmphdr) + sizeof(bmpinfo);

        bmpinfo.biSize = sizeof(bmpinfo);
        bmpinfo.biWidth = 640;
        bmpinfo.biHeight = 480;
        bmpinfo.biPlanes = 1;
        bmpinfo.biBitCount = 32;

        fh = CreateFile(TEXT("C:\\Users\\mike\\Desktop\\output.bmp"),
            GENERIC_WRITE, 0, NULL,
            CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
        WriteFile(fh, &bmphdr, sizeof(bmphdr), &nWritten, NULL);
        WriteFile(fh, &bmpinfo, sizeof(bmpinfo), &nWritten, NULL);
        WriteFile(fh, lpCurrImage, bufSize, &nWritten, NULL);
        CloseHandle(fh);

        ErrMsg(TEXT("Captured current image to %s"),  szFile);
        return TRUE;
    }
    else
    {
        ErrMsg(TEXT("Failed to capture image!  hr=0x%x"), hr);
        return FALSE;
    }
}

return FALSE;

問題は、アプリを実行しようとすると、GetCurrentImage 関数が呼び出されているときに HRESULT (0x8000ffff) エラーが発生することです。

一方、VS デバッガーを使用してアプリを実行すると、コードは問題なく動作します。

問題がタイミングの問題であると想定して、ストリーム pMC->Pause() の直後に Sleep を追加しようとしましたが、うまくいきませんでした。

どんなアイデアでも非常に役立ちます!

前もって感謝します。

4

0 に答える 0