如何解决Directshow 虚拟相机中的模糊桌面捕获输出
我正在尝试创建 Directshow 虚拟相机来捕获桌面。
为了创建虚拟相机,我使用了现有的 https://github.com/roman380/tmhare.mvps.org-vcam
为了添加桌面捕获而不是随机数据,我得到了 Microsofts Push Source Filters Sample
桌面捕获推送源过滤器的确切源代码位于
https://github.com/roman380/Windows-classic-samples/blob/master/Samples/Win7Samples/multimedia/directshow/filters/pushsource/PushSourceDesktop.cpp
我正在初始化 output pin 的 Media Type 构造函数是
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);
// 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);
是
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;
}
我在 google meet 上试过这个虚拟摄像头,它工作正常,显示我的桌面但视频质量很差
这个模糊视频的原因是什么,我该如何解决?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。