2017-08-30 222 views
3

我有一個圖端點是SampleGrabber其中我使用回調函數獲取所有幀的未壓縮數據。ISampleGrabberFilter一次一個步驟的步驟

在我的頂級界面代碼中,我希望有一個函數ReadNextFrame()它獲取圖中下一幀的數據(直到它到達文件末尾)。

性能方面的錯誤實現是將nextFrameIndex傳遞給grabberCB類,以指定此時我想要的幀。所以我的回調函數會跳過所有其他幀,只會選擇一個我想要的。這是昂貴的,因爲圖必須遍歷整個文件來拾取單個幀數據。

我注意到有一個IVideoFrameStep接口,這是理想的我想要的。但似乎這個接口不與樣品採集卡兼容,它的文件說:實現微軟 下精確到幀的追求的DirectShow必須實現AM_KSPROPSETID_FrameStep屬性集, 這是在配合使用IVideoFrameStep

解碼器接口。

我試着將它連接到我的圖形,但IVideoFrameStep :: CanStep()函數返回給我假的意思是我無法用樣品採集卡使用。

所以我的問題是:有沒有一種簡單和性能方面很好的解決方案,所以我可以有我的圖表,以保持目前的狀態,然後做出一個機架前用樣品採集卡得到的數據?

回答

2

您發現IVideoFrameStep有一定要求的工作和它背後的想法是,整個過濾器圖確實狀態轉換,運行,暫停播放恰好是一幀。

要使用樣品採集卡可以實現更簡單的方法,它沒有任何特殊要求由一個得到所有幀一次。

  1. 讓你的過濾器圖表運行;這將是有意義的,從圖中刪除時鐘 - 看到IMediaFilter::SetSyncSource(NULL)
  2. 有在感興趣位置的樣品採集卡與SampleCB回調
  3. 一旦你有你SampleCB執行,做你的數據的事情,表明幀可用性更高運行圖級別的代碼
  4. 雖然裏面SampleCB和#3以上操作後,不從方法返回,而是陷入等待一個事件,這是表明你已經準備好繼續
  5. 高層次的應用代碼將處理一幀,並設置從#4的事件上面允許SampleCB退出並進一步努力獲得新框架;用上面#3重複的新框架。

也就是說,你SampleCB等待被鎖定整個管道保持其狀態所需的時間,讓你在方便的步伐幀處理框架。

僞的SampleCB代碼是(帶手動設置/復位事件):

data m_Data; 
event m_DataAvailability; 
event m_NextFrameRequest; 

void SampleCB(Frame) 
{ 
    m_Data = Frame.GetData(); 
    m_DataAvailability.Set(); 
    m_NextFrameRequest.WaitFor(); // Sleeping here until signaled to continue 
    m_NextFrameRequest.Reset(); 
} 

data ReadNextFrame() 
{ 
    m_DataAvailability.WaitFor(); 
    data Data = m_Data; 
    m_DataAvailability.Reset(); // Current data processed, we need next portion 
    m_NextFrameRequest.Set(); // Indicate that we allow next callback call 
    return Data; // Make captured frame available 
} 
+0

感謝您的評論,羅馬。你所建議的想法似乎是非常好的,並且工作起來,但從設計角度看,我不能那樣做。問題是我的函數ReadNextFrame()應該在單個函數調用中完成並返回一個值。如果我在SampleCB代碼中等待事件,這意味着它將成爲活動線程,並且我的函數將無法完成。 – mbaros

+0

您的頂級'ReadNextFrame'可能會等待'SampleCB'設置的事件。一旦同步,'ReadNextFrame'將複製回調準備的數據,並設置另一個事件釋放回調等待並繼續獲取下一幀。 'ReadNextFrame'又有一個數據副本返回給調用者。 –

+0

能否請你解釋一下如何做#4有點詳細?非常感謝你。 – mbaros