Blurry desktop capture output in Directshow Virtual camera

181 views Asked by At

I am trying to create Directshow virtaul camera to capture desktop.
For creating virtual camera I used existing https://github.com/roman380/tmhare.mvps.org-vcam
For adding desktop capturing instead of random data I took help from Microsofts Push Source Filters Sample

Exact source code for Desktop capturing Push source Filter is at
https://github.com/roman380/Windows-classic-samples/blob/master/Samples/Win7Samples/multimedia/directshow/filters/pushsource/PushSourceDesktop.cpp

My output pin constructor which is initializing Media Type is

CVCamStream::CVCamStream(HRESULT *phr, CVCam *pParent, LPCWSTR pPinName) :
    CSourceStream(NAME("Virtual Cam"),phr, pParent, pPinName),
    m_pParent(pParent),
    m_iFrameNumber(0),
    m_rtFrameLength(FPS_5), // Capture and display desktop 5 times per second
    m_nCurrentBitDepth(32)
{
    // Set the default media type to higest quality
    GetMediaType(0, &m_mt);

    // Get the device context of the main display
    HDC hDC;
    hDC = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);

    // Get the dimensions of the main desktop window
    m_rScreen.left = m_rScreen.top = 0;
    m_rScreen.right = GetDeviceCaps(hDC, HORZRES);
    m_rScreen.bottom = GetDeviceCaps(hDC, VERTRES);

    // Save dimensions for later use in FillBuffer()
    m_iImageWidth = m_rScreen.right - m_rScreen.left;
    m_iImageHeight = m_rScreen.bottom - m_rScreen.top;

    // Release the device context
    DeleteDC(hDC);
}

HRESULT GetMediaType(int iPosition, CMediaType *pmt); is

HRESULT CVCamStream::GetMediaType(int iPosition, CMediaType *pmt)
{
    CheckPointer(pmt, E_POINTER);
    CAutoLock cAutoLock(m_pFilter->pStateLock());

    if (iPosition < 0)
        return E_INVALIDARG;

    // Have we run off the end of types?
    if (iPosition > 4)
        return VFW_S_NO_MORE_ITEMS;

    VIDEOINFO* pvi = (VIDEOINFO*)pmt->AllocFormatBuffer(sizeof(VIDEOINFO));
    if (NULL == pvi)
        return(E_OUTOFMEMORY);

    // Initialize the VideoInfo structure before configuring its members
    ZeroMemory(pvi, sizeof(VIDEOINFO));

    switch (iPosition)
    {
    case 0:
    {
        // Return our highest quality 32bit format

        // Since we use RGB888 (the default for 32 bit), there is
        // no reason to use BI_BITFIELDS to specify the RGB
        // masks. Also, not everything supports BI_BITFIELDS
        pvi->bmiHeader.biCompression = BI_RGB;
        pvi->bmiHeader.biBitCount = 32;
        break;
    }

    case 1:
    {   // Return our 24bit format
        pvi->bmiHeader.biCompression = BI_RGB;
        pvi->bmiHeader.biBitCount = 24;
        break;
    }

    case 2:
    {
        // 16 bit per pixel RGB565

        // Place the RGB masks as the first 3 doublewords in the palette area
        for (int i = 0; i < 3; i++)
            pvi->TrueColorInfo.dwBitMasks[i] = bits565[i];

        pvi->bmiHeader.biCompression = BI_BITFIELDS;
        pvi->bmiHeader.biBitCount = 16;
        break;
    }

    case 3:
    {   // 16 bits per pixel RGB555

        // Place the RGB masks as the first 3 doublewords in the palette area
        for (int i = 0; i < 3; i++)
            pvi->TrueColorInfo.dwBitMasks[i] = bits555[i];

        pvi->bmiHeader.biCompression = BI_BITFIELDS;
        pvi->bmiHeader.biBitCount = 16;
        break;
    }

    case 4:
    {   // 8 bit palettised

        pvi->bmiHeader.biCompression = BI_RGB;
        pvi->bmiHeader.biBitCount = 8;
        pvi->bmiHeader.biClrUsed = iPALETTE_COLORS;
        break;
    }
    }

    // Adjust the parameters common to all formats
    pvi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    pvi->bmiHeader.biWidth = m_iImageWidth;
    pvi->bmiHeader.biHeight = m_iImageHeight;
    pvi->bmiHeader.biPlanes = 1;
    pvi->bmiHeader.biSizeImage = GetBitmapSize(&pvi->bmiHeader);
    pvi->bmiHeader.biClrImportant = 0;

    SetRectEmpty(&(pvi->rcSource)); // we want the whole image area rendered.
    SetRectEmpty(&(pvi->rcTarget)); // no particular destination rectangle

    pmt->SetType(&MEDIATYPE_Video);
    pmt->SetFormatType(&FORMAT_VideoInfo);
    pmt->SetTemporalCompression(FALSE);

    // Work out the GUID for the subtype from the header info.
    const GUID SubTypeGUID = GetBitmapSubtype(&pvi->bmiHeader);
    pmt->SetSubtype(&SubTypeGUID);
    pmt->SetSampleSize(pvi->bmiHeader.biSizeImage);

    return NOERROR;
}

I tried this virtual camera on google meet and its working fine, its showing my desktop but video quality is very poor

enter image description here

What is reason of this blur video and How can I fix this?

0

There are 0 answers