2012-01-26 16 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方法更加昂貴。 –

相關問題