Exemple #1
0
VideoSourceWin::VideoSourceWin(int w, int h)
    : VideoSource(w, h)
{
    HRESULT hr;
    VIDEOINFOHEADER *pVid;

    g2g = PR_FALSE;
    width = w;
    height = h;
    
    hr = CoInitialize(0);
    if (FAILED(hr)) return;

    InitAllQeditTypeLibGUIDs();

    hr = CoCreateInstance(
        CLSID_FilterGraph, NULL, CLSCTX_INPROC,
        IID_IGraphBuilder, (void **) &pGraph
    );
    if (FAILED(hr)) return;

    hr = CoCreateInstance(
        CLSID_CaptureGraphBuilder2 , NULL, CLSCTX_INPROC,
        IID_ICaptureGraphBuilder2, (void **) &pCapture
    );
    if (FAILED(hr)) return;

    hr = pGraph->QueryInterface(IID_IMediaControl, (LPVOID *) &pMC);
    if (FAILED(hr)) return;
    hr = pCapture->SetFiltergraph(pGraph);
    if (FAILED(hr)) return;

    hr = GetDefaultInputDevice(&pSrcFilter);
    if (FAILED(hr)) return;

    /* Add capture device to graph */
    hr = pGraph->AddFilter(pSrcFilter, L"Video Capture");
    if (FAILED(hr)) {
        pSrcFilter->Release();
        return;
    }

    /* Create SampleGrabber */
    hr = CoCreateInstance(
        CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER,
        IID_PPV_ARGS(&pGrabberF)
    );
    if (FAILED(hr)) {
        pSrcFilter->Release();
        return;
    }
    hr = pGrabberF->QueryInterface(IID_ISampleGrabber, (void**)&pGrabber);
    if (FAILED(hr)) {
        pSrcFilter->Release();
        return;
    }

    /* Create Null Renderer (required sink by ISampleGrabber) */
    hr = CoCreateInstance(
        CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER,
        IID_IBaseFilter, (void **)&pNullF
    );
    if (FAILED(hr)) {
        pSrcFilter->Release();
        return;
    }

    /* Get default media type values and set what we need */
    hr = pCapture->FindInterface(
        &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, pSrcFilter,
        IID_IAMStreamConfig, (void**)&pConfig
    );
    if (FAILED(hr)) {
        pSrcFilter->Release();
        return;
    }

    hr = pConfig->GetFormat(&pMT);

    /* We play it safe and request RGB32 always because that's what majority
     * of webcams seem to support
     */
    pMT->majortype = MEDIATYPE_Video;
    pMT->formattype = FORMAT_VideoInfo;
    pMT->subtype = MEDIASUBTYPE_ARGB32;
    pVid = reinterpret_cast<VIDEOINFOHEADER*>(pMT->pbFormat);
    pVid->bmiHeader.biWidth = width;
    pVid->bmiHeader.biHeight = height;

    /* Set frame rates */
    fps_n = NANOSECONDS;
    fps_d = (PRUint32)pVid->AvgTimePerFrame;

    pConfig->SetFormat(pMT);
    pGrabber->SetMediaType(pMT);
    _DeleteMediaType(pMT);

    /* Instance initialized properly */
    SAFE_RELEASE(pConfig);
    g2g = PR_TRUE;
    m_refCount = 0;
}
HRESULT DSCaptureDevice::setFormat(const DSFormat& format)
{
    HRESULT hr;
    IAMStreamConfig* streamConfig = NULL;

    /* get the right interface to change capture settings */
    hr
        = m_captureGraphBuilder->FindInterface(
                &PIN_CATEGORY_CAPTURE,
                &MEDIATYPE_Video,
                m_srcFilter,
                IID_IAMStreamConfig,
                (void**) &streamConfig);
    if(SUCCEEDED(hr))
    {
        int nb = 0;
        int size = 0;
        AM_MEDIA_TYPE* mediaType = NULL;
        size_t bitCount = 0;

        hr = streamConfig->GetNumberOfCapabilities(&nb, &size);
        if (SUCCEEDED(hr) && nb)
        {
            BYTE* scc = new BYTE[size];

            if (scc)
            {
                DWORD pixfmt = format.pixelFormat;

                for (int i = 0 ; i < nb ; i++)
                {
                    AM_MEDIA_TYPE* mt;

                    if (streamConfig->GetStreamCaps(i, &mt, scc) == S_OK)
                    {
                        VIDEOINFOHEADER* hdr = (VIDEOINFOHEADER*) mt->pbFormat;

                        if (hdr
                                && (mt->subtype.Data1 == pixfmt)
                                && ((long) format.height
                                        == hdr->bmiHeader.biHeight)
                                && ((long) format.width
                                        == hdr->bmiHeader.biWidth))
                        {
                            mediaType = mt;
                            if ((pixfmt == MEDIASUBTYPE_ARGB32.Data1)
                                    || (pixfmt == MEDIASUBTYPE_RGB32.Data1))
                                bitCount = 32;
                            else if (pixfmt == MEDIASUBTYPE_RGB24.Data1)
                                bitCount = 24;
                            else
                                bitCount = hdr->bmiHeader.biBitCount;
                            break;
                        }
                        else
                            _DeleteMediaType(mt);
                    }
                }

                delete[] scc;
            }
            else
                hr = E_OUTOFMEMORY;
        }

        if (mediaType)
        {
            hr = streamConfig->SetFormat(mediaType);
            if (SUCCEEDED(hr))
            {
                m_bitPerPixel = bitCount;
                m_format = format;
                m_format.mediaType = mediaType->subtype;
            }
            _DeleteMediaType(mediaType);
        }
        else if (SUCCEEDED(hr))
            hr = E_FAIL;

        streamConfig->Release();
    }

    return hr;
}