2013-05-15 31 views
0

如何使用智能T恤過濾器將視頻流從網絡攝像頭呈現到文件? 所以我想補充SmartTee過濾器,並得到類似的東西:SmartTee過濾器並保存到文件

Capture filter 
     | 
    SmartTee filter 
    |   | 
capture  preview 
    |   | 
Mux filter GrabFilter 
    |   | 
FileWriter VideoRenderer 

所以這是引黃捕獲過濾器和智能三通:

// Get capture filter 
srcFilter = FindCaptureDevice(); 

// Add Capture filter to our graph. 
graph.AddFilter(srcFilter, "Video Capture"); 

//Add smartTee filter to graph 
smartTeeFilter = (IBaseFilter)new SmartTee(); 
graph.AddFilter(smartTeeFilter, "Smart Tee"); 

IPin outPin = GetPin(PinDirection.Output, srcFilter); 
IPin inPin = GetPin(PinDirection.Input, smartTeeFilter); 
graph.Connect(outPin, inPin); 

這是與採集和渲染(以防萬一)連接:

sampGrabber = new SampleGrabber() as ISampleGrabber; 
baseGrabFilter = sampGrabber as IBaseFilter; 
graph.AddFilter(baseGrabFilter, "Grabber"); 

IPin sourcePin, grabPin; 
sourcePin = GetPin(PinDirection.Output, smartTeeFilter); 
grabPin = GetPin(PinDirection.Input, baseGrabFilter);   
graph.Connect(sourcePin, grabPin); 

graph.Render(GetPin(PinDirection.Output, baseGrabFilter)); 

這就是我在保存文件部分中的全部內容:

IBaseFilter mux; 
IFileSinkFilter sink; 

capture.SetOutputFileName(
    MediaSubType.Avi,  // Specifies AVI for the target file. 
    path,     // File name. 
    out mux,    // Receives a pointer to the mux. 
    out sink);    // (Optional) Receives a pointer to the file sink. 

sink.SetFileName(path, null); 

IPin outPin = DsFindPin.ByDirection(smartTeeFilter, PinDirection.Output, 1); 
IPin inPin = GetPin(PinDirection.Input, mux); 
graph.Connect(outPin, inPin); 

control.Run(); 

它沒有拋出異常。只需創建大小爲64Kb的文件。我保存到文件代碼有什麼問題?

已添加。 我看看CapWMV例子,並在那裏保存是這樣的:

IFileSinkFilter sink = null; 
IBaseFilter fileWriterFilter = null; 
capture = (ICaptureGraphBuilder2) new CaptureGraphBuilder2(); 
capture.SetFiltergraph(graph); 
int hr = capture.SetOutputFileName(MediaSubType.Avi, path, out fileWriterFilter, out sink); 
DsError.ThrowExceptionForHR(hr); 

hr = capture.RenderStream(null, null, smartTeeFilter, null, fileWriterFilter); 
DsError.ThrowExceptionForHR(hr); 

hr = control.Run(); 
DsError.ThrowExceptionForHR(hr); 

我再次得到64 KB的文件,並沒有別的。我的錯誤在哪裏?

+0

哈爾我GUYZ,我卡住了。這只是保存到文件。沒有智能發球臺,它是兩行代碼。它不會很複雜。 – WatTheCat

回答

1

頂部的拓撲結構是正確的。

但是,您的代碼與您的代碼不匹配:您連接了多路複用器輸入,然後您連接Run。沒有代碼存在或顯示爲連接多路複用器輸出,這是強制性的。

接下來的事情是,由於智能連接自動提供過濾器,您的實際拓撲結構可能與預期不同,因此您還需要通過枚舉過濾器或publishing to ROT and viewing with external tool來查看此過濾器。

如果你有機會看看真正拓撲結構,你或許會立即抓住問題:

IPin sourcePin, grabPin; 
sourcePin = GetPin(PinDirection.Output, smartTeeFilter); 
grabPin = GetPin(PinDirection.Input, baseGrabFilter);   
graph.Connect(sourcePin, grabPin); 

您正在連接第一個搶到輸出引腳樣品採集卡和預覽視頻渲染器。然而,index zero output pin is Capture

捕捉引腳輸出引腳0,預覽引腳輸出引腳1

所以你寫預覽(永恆)媒體採樣到一個文件,它不是因此您需要正確連接三通輸出引腳 - 以便將三通的捕捉輸出連接到多路複用器/寫入器支路。

+0

哦,對,多路複用器和文件編寫器之間沒有任何關係。現在我明白了,我不知道該怎麼做。所以它讓我變得愚蠢的問題:如何連接多路複用器和文件編寫器? – WatTheCat

+0

獲取引腳並對它們執行'graph.Connect',就像連接其他對一樣。 –

+0

是的,但是我應該使用'sink'作爲'IBaseFiler'還是別的? – WatTheCat