Windows 上的原生多媒體解決方案 MF 探索


  Media Foundation是windows上原生的多媒體C++庫。之前windows上的原生工具是Directshow,據說是基於filter的一個框架,我對此暫時不太瞭解,不予評判兩者區別。我的理解,只要是是視頻和音頻相關處理的win應用,都能夠應用MF封裝好的方法來組合調用,比如媒體播放器,媒體轉換器,流媒體生成器等。

  使用MF解決攝像頭驅動的關鍵,在於攝像頭被看作一個媒體源,而不是EMGU裏面的一個capture.由於是一個源,我可以使用MF對於源的數據封裝,使用對MF進行直接的訪問。只需要創建一個攝像頭源,並且設置信號的屬性類型,就能拿到vedio對象。

  微軟提供了一個可視化工具來模擬了這個編程過程:TopoEdit.exe.利用TopoEdit工具,即使我不知道我的攝像頭輸出信號是什麼參數,我都能夠通過連線和調試來找到能夠驅動攝像頭的合適參數,用於後面的編程過程,非常的方便。

  對於新框架,第一件事情就是參考官方例程。MF來自於windows SDK,但是我無路如何都找不到裏面的歷程。終於,在github中有好心人分享了整個例程包:

https://github.com/sipsorcery/mediafoundationsamples

  例程包裏MFWebCamRtp MFWebCamToFile MFWebCamToH264Buffer都和攝像頭相關。後面兩個都需要在TopoEdit中找到攝像頭的子類型MFVideoFormat_YUY2並修改相應的代碼,纔可以正常運行。

  wKioL1cMvlOyFO4QAACxUCNRB_A159.png

  對於MFWebCamRtp,其.vcxproj就是丟失的,無法在VS2013中加載。好在其源代碼可以看到。裏面寫明瞭其流媒體服務的實現,是使用了live555框架。

  live555本身是跨平臺的類庫文件,但是其live media server提供了win環境下的流媒體實現。其二進制exe程序可以將文件夾下的任何視頻文件轉換成爲VLC可以播放的流媒體文件。不過代碼本身是C++代碼,而且編譯方法需要導入Live555的類庫;好在找到了SkySeraph大神的分享博客。按照其步驟走到生成Lib一步的時候,nmake總是編譯報錯。好在他分享了生成後的Lib文件和整個VS項目。他甚至更新了VS2013版本的,真實令人欽佩的分享着。

  藉着這次完整的項目,我實現了編譯,確保了live555本身沒有問題。然後我的工作,就是還原MFWebCamRtp歷程,利用SkySeraph大神編譯好的live555庫,我將文本打開的MFWebCamRtp拷貝去新的cpp文件,並且修改成爲攝像頭的類型,反覆的解決編譯器和鏈接器報錯問題:

  1. using namespace System 報錯,必須在項目屬性中選擇CLR編譯環境纔可以起作用。

  2. Error 217 error LNK2019: unresolved external symbol ___WSAFDIsSet@8 referenced in function "protected: virtual void __thiscall BasicTaskScheduler::SingleStep(unsigned int)" (?SingleStep@BasicTaskScheduler@@MAEXI@Z)

    一開始我以爲是BasicTaskScheduler::SingleStep(unsigned int)沒定義,反覆的引用BasicTaskScheduler所在的liver555庫BasicUsageEnvironment,沒法解決問題,後來仔細看從才發現沒有定義的是前面的___WSAFDIsSet出了問題。後來在互聯網上發現是ws2_32.lib沒有引用,增加 #pragma comment(lib, "ws2_32.lib")就解決了問題。

     編譯通過後,程序打開了攝像頭,程序在把視頻片段壓入緩存的時候,報出了內存損壞無法訪問錯誤:

wKiom1cMxrrSrLn7AABAf_ttqkU977.png

  這次對於MF生成攝像頭流媒體的探索,就暫停在了這個錯誤上。另外,在體驗了各種面嚮對象語言之後,還是覺得C++的結構指針感覺爽快 :)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章