2012-01-26 17 views
0

我有一个directshow过滤器,用于使用下面的代码捕获屏幕。DirectShow在捕捉过程中调整大小

首先,我得使用窗口矩形

EnumWindows 

这给了我LPRECT

HDC   hMemDC; 
HBITMAP  hBitmap, hOldBitmap; 
int   nX, nY, nX2, nY2; 
int   nWidth, nHeight; 

if (IsRectEmpty(lpRect)) 
    return NULL; 

hMemDC = CreateCompatibleDC(hScrDC); 

nX = lpRect->left; 
nY = lpRect->top; 
nX2 = lpRect->right; 
nY2 = lpRect->bottom; 

nWidth = nX2 - nX; 
nHeight = nY2 - nY; 

hBitmap = CreateCompatibleBitmap(hScrDC, nWidth, nHeight); 

hOldBitmap = (HBITMAP) SelectObject(hMemDC, hBitmap); 

BitBlt(hMemDC, 0, 0, nWidth, nHeight, hScrDC, nX, nY, SRCCOPY); 

hBitmap = (HBITMAP) SelectObject(hMemDC, hOldBitmap); 

GetDIBits(hScrDC, hRawBitmap, 0, nHeightScanLines, pData, pHeader, DIB_RGB_COLORS);  

DeleteDC(hMemDC); 

问题是,当我调整我试图捕获的窗口,它应该是这样的enter image description here

然而它像这样结束 enter image description here

我有一种感觉,这是由于图像宽度的像素数量,但我不确定如何调整directshow过滤器的输出宽度和高度?

+0

您可以分享实际调整大小的代码和执行渲染的代码吗?某处看起来“俯仰”变量被忽略。 – selbie

+0

上面的代码是我用来做渲染的(在FillBuffer方法中)。对于调整大小,我实际上只是将lpRect更改为窗口的矩形。 – kiwijus

+0

没错,但你如何将这些位保存到文件和/或渲染到屏幕?我怀疑你的问题在那里。 – selbie

回答

0

您遇到的效果是您的缓冲区与您的过滤器在其针脚连接上的媒体类型不匹配。通常,如果滤波器(引脚)不正确地处理扩展视频步幅变化,如Handling Format Changes from the Video Renderer中所述,会发生这种情况。

更有可能在你的情况下,但是你正在失去尝试调整大小的正确媒体类型。您的代码实际上并未进行任何大小调整,并且您可能希望调整大小以使填充的缓冲区最终与连接上的媒体类型不匹配。

+0

因此,为了做一些调整大小,我应该创建一个新的BITMAPINFO和VIDEOINFOHEADER并设置一个新的AM_MEDIA_TYPE? – kiwijus

+0

您的滤镜与输出引脚上的某种媒体类型相连。您将分别为'FillBuffer',以匹配此媒体类型。如果你只改变一些RECT,没有人会为你调整有效载荷数据的大小。因此,第一件事是你的缓冲区必须与媒体类型一致(直接影响你的效果)。接下来是如果您需要调整大小,发布更多细节的时间以及您希望如何完成。 –

+0

啊,好吧!当我正在跟踪的窗口被调整大小时,我试图调整缓冲区大小 – kiwijus

0

当过滤器提供尺寸不同于协商的视频样本时,可能会发生此问题。

如果过滤器应该只捕获窗口内容而不裁剪或填充并且窗口大小发生变化,则应该使用下游过滤器重新协商媒体格式。文章Dynamic Format Changes描述了不同的解决方案。另请参阅Custom DirectShow Source Filter - Dynamic Resolution Change

+0

所以我会正确添加ReceiveConnection功能到我的directshow过滤器? – kiwijus

+0

是的,如果你需要增加缓冲区大小。有关更多信息,请参见[在DirectShow中处理动态格式更改](http://stackoverflow.com/questions/6124609/handling-dynamic-format-changes-in-directshow)。虽然这可能比使用QueryAccept方法更加昂贵。 –

相关问题