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++的结构指针感觉爽快 :)