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

📄 amcap.cpp

📁 s<erzydfgh e45uzehsrtubxsrgj
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    // you don't want the audio.

    if( !gcap.fMPEG2 )
    {
        hr = gcap.pBuilder->RenderStream(&PIN_CATEGORY_CAPTURE,
                                         &MEDIATYPE_Interleaved,
                                         gcap.pVCap, NULL, gcap.pRender);
        if(hr != NOERROR)
        {
            hr = gcap.pBuilder->RenderStream(&PIN_CATEGORY_CAPTURE,
                                             &MEDIATYPE_Video,
                                             gcap.pVCap, NULL, gcap.pRender);
            if(hr != NOERROR)
            {
                ErrMsg(TEXT("Cannot render video capture stream"));
                goto SetupCaptureFail;
            }
        }

        if(gcap.fWantPreview)
        {
            hr = gcap.pBuilder->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Interleaved,
                                            gcap.pVCap, NULL, NULL);
            if(hr == VFW_S_NOPREVIEWPIN)
            {
                // preview was faked up for us using the (only) capture pin
                gcap.fPreviewFaked = TRUE;
            }
            else if(hr != S_OK)
            {
                hr = gcap.pBuilder->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,
                                                 gcap.pVCap, NULL, NULL);
                if(hr == VFW_S_NOPREVIEWPIN)
                {
                    // preview was faked up for us using the (only) capture pin
                    gcap.fPreviewFaked = TRUE;
                }
                else if(hr != S_OK)
                {
                    ErrMsg(TEXT("Cannot render video preview stream"));
                    goto SetupCaptureFail;
                }
            }
        }
    }
    else
    {
        SmartPtr< IBaseFilter > sink;
        if( &gcap.pSink )
        {
            gcap.pSink->QueryInterface( IID_IBaseFilter, reinterpret_cast<void **>( &sink ) );
        }

        hr = gcap.pBuilder->RenderStream(NULL,
                                         &MEDIATYPE_Stream,
                                         gcap.pVCap, NULL, sink);
    }

    //
    // Render the audio capture pin?
    //

    if(!gcap.fMPEG2 && gcap.fCapAudio)
    {
        hr = gcap.pBuilder->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Audio,
                                         gcap.pACap, NULL, gcap.pRender);
        if(hr != NOERROR)
        {
            ErrMsg(TEXT("Cannot render audio capture stream"));
            goto SetupCaptureFail;
        }
    }

    //
    // Render the closed captioning pin? It could be a CC or a VBI category pin,
    // depending on the capture driver
    //

    if(!gcap.fMPEG2  && gcap.fCapCC)
    {
        hr = gcap.pBuilder->RenderStream(&PIN_CATEGORY_CC, NULL,
                                         gcap.pVCap, NULL, gcap.pRender);
        if(hr != NOERROR)
        {
            hr = gcap.pBuilder->RenderStream(&PIN_CATEGORY_VBI, NULL,
                                             gcap.pVCap, NULL, gcap.pRender);
            if(hr != NOERROR)
            {
                ErrMsg(TEXT("Cannot render closed captioning"));
                // so what? goto SetupCaptureFail;
            }
        }
        // To preview and capture VBI at the same time, we can call this twice
        if(gcap.fWantPreview)
        {
            hr = gcap.pBuilder->RenderStream(&PIN_CATEGORY_VBI, NULL,
                                             gcap.pVCap, NULL, NULL);
        }
    }

    //
    // Get the preview window to be a child of our app's window
    //

    // This will find the IVideoWindow interface on the renderer.  It is
    // important to ask the filtergraph for this interface... do NOT use
    // ICaptureGraphBuilder2::FindInterface, because the filtergraph needs to
    // know we own the window so it can give us display changed messages, etc.

    if(!gcap.fMPEG2 && gcap.fWantPreview)
    {
        hr = gcap.pFg->QueryInterface(IID_IVideoWindow, (void **)&gcap.pVW);
        if(hr != NOERROR && gcap.fWantPreview)
        {
            ErrMsg(TEXT("This graph cannot preview"));
        }
        else if(hr == NOERROR)
        {
            RECT rc;
            gcap.pVW->put_Owner((OAHWND)ghwndApp);    // We own the window now
            gcap.pVW->put_WindowStyle(WS_CHILD);    // you are now a child

            // give the preview window all our space but where the status bar is
            GetClientRect(ghwndApp, &rc);
            cyBorder = GetSystemMetrics(SM_CYBORDER);
            cy = statusGetHeight() + cyBorder;
            rc.bottom -= cy;

            gcap.pVW->SetWindowPosition(0, 0, rc.right, rc.bottom); // be this big
            gcap.pVW->put_Visible(OATRUE);
        }
    }

    // now tell it what frame rate to capture at.  Just find the format it
    // is capturing with, and leave everything alone but change the frame rate
    if( !gcap.fMPEG2 )
    {
        hr = gcap.fUseFrameRate ? E_FAIL : NOERROR;
        if(gcap.pVSC && gcap.fUseFrameRate)
        {
            hr = gcap.pVSC->GetFormat(&pmt);

            // DV capture does not use a VIDEOINFOHEADER
            if(hr == NOERROR)
            {
                if(pmt->formattype == FORMAT_VideoInfo)
                {
                    VIDEOINFOHEADER *pvi = (VIDEOINFOHEADER *)pmt->pbFormat;
                    pvi->AvgTimePerFrame = (LONGLONG)(10000000 / gcap.FrameRate);
                    hr = gcap.pVSC->SetFormat(pmt);
                }
                DeleteMediaType(pmt);
            }
        }
        if(hr != NOERROR)
            ErrMsg(TEXT("Cannot set frame rate for capture"));
    }

    // now ask the filtergraph to tell us when something is completed or aborted
    // (EC_COMPLETE, EC_USERABORT, EC_ERRORABORT).  This is how we will find out
    // if the disk gets full while capturing
    hr = gcap.pFg->QueryInterface(IID_IMediaEventEx, (void **)&gcap.pME);
    if(hr == NOERROR)
    {
        gcap.pME->SetNotifyWindow((OAHWND)ghwndApp, WM_FGNOTIFY, 0);
    }

    // potential debug output - what the graph looks like
    // DumpGraph(gcap.pFg, 1);

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

    // All done.
    gcap.fCaptureGraphBuilt = TRUE;
    return TRUE;

SetupCaptureFail:
    TearDownGraph();
    return FALSE;
}



// build the preview graph!
//
// !!! PLEASE NOTE !!!  Some new WDM devices have totally separate capture
// and preview settings.  An application that wishes to preview and then
// capture may have to set the preview pin format using IAMStreamConfig on the
// preview pin, and then again on the capture pin to capture with that format.
// In this sample app, there is a separate page to set the settings on the
// capture pin and one for the preview pin.  To avoid the user
// having to enter the same settings in 2 dialog boxes, an app can have its own
// UI for choosing a format (the possible formats can be enumerated using
// IAMStreamConfig) and then the app can programmatically call IAMStreamConfig
// to set the format on both pins.
//
BOOL BuildPreviewGraph()
{
    int cy, cyBorder;
    HRESULT hr;
    AM_MEDIA_TYPE *pmt;

    // we have one already
    if(gcap.fPreviewGraphBuilt)
        return TRUE;

    // No rebuilding while we're running
    if(gcap.fCapturing || gcap.fPreviewing)
        return FALSE;

    // We don't have the necessary capture filters
    if(gcap.pVCap == NULL)
        return FALSE;
    if(gcap.pACap == NULL && gcap.fCapAudio)
        return FALSE;

    // we already have another graph built... tear down the old one
    if(gcap.fCaptureGraphBuilt)
        TearDownGraph();

    //
    // Render the preview pin - even if there is not preview pin, the capture
    // graph builder will use a smart tee filter and provide a preview.
    //
    // !!! what about latency/buffer issues?

    // NOTE that we try to render the interleaved pin before the video pin, because
    // if BOTH exist, it's a DV filter and the only way to get the audio is to use
    // the interleaved pin.  Using the Video pin on a DV filter is only useful if
    // you don't want the audio.

    if( gcap.fMPEG2 )
    {
        hr = gcap.pBuilder->RenderStream(&PIN_CATEGORY_PREVIEW,
                                         &MEDIATYPE_Stream, gcap.pVCap, NULL, NULL);
        if( FAILED( hr ) )
        {
            ErrMsg(TEXT("Cannot build MPEG2 preview graph!"));
        }

    }
    else
    {
        hr = gcap.pBuilder->RenderStream(&PIN_CATEGORY_PREVIEW,
                                         &MEDIATYPE_Interleaved, gcap.pVCap, NULL, NULL);
        if(hr == VFW_S_NOPREVIEWPIN)
        {
            // preview was faked up for us using the (only) capture pin
            gcap.fPreviewFaked = TRUE;
        }
        else if(hr != S_OK)
        {
            // maybe it's DV?
            hr = gcap.pBuilder->RenderStream(&PIN_CATEGORY_PREVIEW,
                                             &MEDIATYPE_Video, gcap.pVCap, NULL, NULL);
            if(hr == VFW_S_NOPREVIEWPIN)
            {
                // preview was faked up for us using the (only) capture pin
                gcap.fPreviewFaked = TRUE;
            }
            else if(hr != S_OK)
            {
                ErrMsg(TEXT("This graph cannot preview!"));
                gcap.fPreviewGraphBuilt = FALSE;
                return FALSE;
            }
        }

        //
        // Render the closed captioning pin? It could be a CC or a VBI category pin,
        // depending on the capture driver
        //

        if(gcap.fCapCC)
        {
            hr = gcap.pBuilder->RenderStream(&PIN_CATEGORY_CC, NULL,
                                             gcap.pVCap, NULL, NULL);
            if(hr != NOERROR)
            {
                hr = gcap.pBuilder->RenderStream(&PIN_CATEGORY_VBI, NULL,
                                                 gcap.pVCap, NULL, NULL);
                if(hr != NOERROR)
                {
                    ErrMsg(TEXT("Cannot render closed captioning"));
                }
            }
        }
    }

    //
    // Get the preview window to be a child of our app's window
    //

    // This will find the IVideoWindow interface on the renderer.  It is
    // important to ask the filtergraph for this interface... do NOT use
    // ICaptureGraphBuilder2::FindInterface, because the filtergraph needs to
    // know we own the window so it can give us display changed messages, etc.

    hr = gcap.pFg->QueryInterface(IID_IVideoWindow, (void **)&gcap.pVW);
    if(hr != NOERROR)
    {
        ErrMsg(TEXT("This graph cannot preview properly"));
    }
    else
    {
        //Find out if this is a DV stream
        AM_MEDIA_TYPE * pmtDV;

        if(gcap.pVSC && SUCCEEDED(gcap.pVSC->GetFormat(&pmtDV)))
        {
            if(pmtDV->formattype == FORMAT_DvInfo)
            {
                // in this case we want to set the size of the parent window to that of
                // current DV resolution.
                // We get that resolution from the IVideoWindow.
                SmartPtr<IBasicVideo> pBV;

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

                if(SUCCEEDED(hr))
                {
                    HRESULT hr1, hr2;
                    long lWidth, lHeight;

                    hr1 = pBV->get_VideoHeight(&lHeight);
                    hr2 = pBV->get_VideoWidth(&lWidth);
                    if(SUCCEEDED(hr1) && SUCCEEDED(hr2))
                    {
                        ResizeWindow(lWidth, abs(lHeight));
                    }
                }
            }
        }

        RECT rc;
        gcap.pVW->put_Owner((OAHWND)ghwndApp);    // We own the window now
        gcap.pVW->put_WindowStyle(WS_CHILD);    // you are now a child

        // give the preview window all our space but where the status bar is
        GetClientRect(ghwndApp, &rc);
        cyBorder = GetSystemMetrics(SM_CYBORDER);
        cy = statusGetHeight() + cyBorder;
        rc.bottom -= cy;

        gcap.pVW->SetWindowPosition(0, 0, rc.right, rc.bottom); // be this big
        gcap.pVW->put_Visible(OATRUE);
    }

    // now tell it what frame rate to capture at.  Just find the format it
    // is capturi

⌨️ 快捷键说明

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