線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:3168
推到 Plurk!
推到 Facebook!

(已結案) 使用 SampleGrabber 的 Onbuffer Event 記憶體釋放的問題

缺席
daldal
高階會員


發表:6
回覆:102
積分:226
註冊:2007-06-18

發送簡訊給我
#1 引用回覆 回覆 發表時間:2007-06-18 17:23:30 IP:61.219.xxx.xxx 訂閱
不好意思,小弟第一次發言

如有缺漏或是不足的地方,請多多指教


用DirectShow將CCD裝置畫面擷取到電腦顯示的方式有VideoWindow & SampleGrabber 兩種

目前我是用SampleGrabber裡面的OnBuffer Event來取代Timer作持續的抓圖

可是測試的時候遇到一個狀況

OnBuffer Event 啟動以後會不斷的吃記憶體而沒辦法釋放,請問這樣是正常的嗎?

目前我是在Filter , FilterGraph , SampleGrabber 加上了 FreeOnRelease

結果沒有變化





而使用Timer定時去GetBitmap並不會持續吃記憶體

請問有沒有方法使用 OnBuffer Event 來GetBitmap的狀況下釋放記憶體?


PS: 在 OnBuffer Evenet 以及 Timer 中用的都是 GetBitmap() 來取得影像至Img元件
編輯記錄
daldal 重新編輯於 2008-03-11 20:19:57, 註解 更改成結案‧
daldal
高階會員


發表:6
回覆:102
積分:226
註冊:2007-06-18

發送簡訊給我
#2 引用回覆 回覆 發表時間:2007-06-19 19:02:23 IP:59.112.xxx.xxx 訂閱
目前試的結果是這樣

如果一次只連結一個 Filter,FilterGraph,SampleGrabber
OnBuffer Event 的功能是正常的

但若是同時使用兩組以上的 Filter,FilterGraph,SampleGrabber
OnBuffer Event 會在切換的中間不斷的堆疊記憶體 (不知道這樣敘述是否有誤@@)
而造成無法正常釋放

可是看不懂 DSPack 的Pas語言 後面的嘗試不知道要如何下手
有人能提供一些其他找出問題的方向嗎,感謝萬分~
psp67101
一般會員


發表:5
回覆:10
積分:3
註冊:2005-05-06

發送簡訊給我
#3 引用回覆 回覆 發表時間:2007-11-12 16:42:25 IP:220.128.xxx.xxx 訂閱
請問妳有SampleGrabber的範例程式給我參考嗎
擷取CCD的影像部分
謝謝
===================引 用 daldal 文 章===================
不好意思,小弟第一次發言
如有缺漏或是不足的地方,請多多指教

用DirectShow將CCD裝置畫面擷取到電腦顯示的方式有VideoWindow & SampleGrabber 兩種
目前我是用SampleGrabber裡面的OnBuffer Event來取代Timer作持續的抓圖
可是測試的時候遇到一個狀況
OnBuffer Event 啟動以後會不斷的吃記憶體而沒辦法釋放,請問這樣是正常的嗎?
目前我是在Filter , FilterGraph , SampleGrabber 加上了 FreeOnRelease
結果沒有變化


而使用Timer定時去GetBitmap並不會持續吃記憶體
請問有沒有方法使用 OnBuffer Event 來GetBitmap的狀況下釋放記憶體?

PS: 在 OnBuffer Evenet 以及 Timer 中用的都是 GetBitmap() 來取得影像至Img元件
daldal
高階會員


發表:6
回覆:102
積分:226
註冊:2007-06-18

發送簡訊給我
#4 引用回覆 回覆 發表時間:2008-03-11 19:51:59 IP:220.130.xxx.xxx 訂閱
抽空看了DSPACK的Source Code
裡面SampleGrabber的OnBuffer Event是利用Thread去抓取圖片
所以如果直接用顯示影像Timage->Picture->Bitmap去抓取的話
有一定機率(視你的CPU、WebCam處理而定)會造成Thread端無法釋放記憶體
因為此時你的Application正在Invalidate中

所以改成用Assign賦予圖片DIB到Timage->Picture->Bitmap,
速度會慢一些(因為此時TImage會等待Assign動作完畢)
然後Invalidate才會觸發重繪
但是至少記憶體就可以正常釋放了。

PS 以上說法也可能有錯,因為DSPACK Code有很多地方還是看不太懂@@
daldal
高階會員


發表:6
回覆:102
積分:226
註冊:2007-06-18

發送簡訊給我
#5 引用回覆 回覆 發表時間:2008-03-11 19:55:50 IP:220.130.xxx.xxx 訂閱

===================引 用 psp67101 文 章===================
請問妳有SampleGrabber的範例程式給我參考嗎
擷取CCD的影像部分
謝謝


在Dspack的/Sample/BCB目錄下有可以Compile的CCD影像擷取範例
記得要改Include路徑,就可以了
daldal
高階會員


發表:6
回覆:102
積分:226
註冊:2007-06-18

發送簡訊給我
#6 引用回覆 回覆 發表時間:2010-02-11 17:38:59 IP:61.219.xxx.xxx 訂閱
這幾天在閱讀 MSDN 上的 DirectShow reference

看到了ISampleGrabberCB::BufferCB Method 中有這麼一行
Note This method receives a pointer to the original sample data, not a copy.
The original documentation incorrectly stated that pBuffer contains a copy of the data.

然後加上ISampleGrabberCB::SampleCB Method 中的備註有提到
If the sample is a DirectDraw surface, the surface is locked during the callback. The Win16 lock (also called Win16Mutex) might be locked as well. Both of these locks create the potential for deadlock. If the callback thread waits for a thread that is trying to call a DirectDraw API, it can cause deadlock. In addition, if the Win16 lock is being held, deadlock can result if the callback holds a critical section or waits for another thread to complete any activity. Therefore, the callback should not perform any actions with the potential to block, such as holding a critical section or waiting on another thread. Also, do not call any GDI or USER32.DLL APIs that might cause a window to move. For more information about the Win16 lock, see Knowledge Base article Q125867, Understanding Win16Mutex.
所以答案就揭曉啦
因為Thread事件發生時,我把他搬移到Bitmap元件中
Bitmap寫入後會去呼叫 GDI 的 drawdib 去進行 paint 動作
而這些動作會導致記憶體釋放的時候
被鎖定住而無法動作
所以就一直堆啊堆啊.....T_T
以上

系統時間:2024-05-02 2:12:10
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!