如何使用DirectShow驱动H264/H265格式输出的UVC摄像头

免责声明:仅供研究讨论,未经确认,内容与提供之源码,严禁商用!!!

先提一些题外话,在微软关于DirectShow的官网上有如下说明:

https://docs.microsoft.com/zh-cn/windows/win32/directshow/directshow

所以我这里去Windows官网下载Sdk,从中获取新版的DirectShow,但microsoft似乎对DirectShow后续改动其实并没有特别多,

https://developer.microsoft.com/en-us/windows/downloads/sdk-archive

因为目前我用的系统是Win7,所以我暂时下载的如下版本的SDk。

安装完成后,我这里在C:\Program Files\Microsoft SDKs\Windows\v7.1\Samples\multimedia\directshow中有directshow相关的SDK包。

 

回归正题,通常DirectShow原始SDK包没有自带驱动H264/H265流格式摄像头的filter。

但是通过查找Github上的开源项目libde265(https://github.com/strukturag/libde265),在其README.md说明中可以翻看到如下一段。

Libde265 has been integrated into these applications:

 

- gstreamer plugin, [source](https://github.com/strukturag/gstreamer-libde265), [binary packages](https://launchpad.net/~strukturag/+archive/libde265).

 

- VLC plugin [source](https://github.com/strukturag/vlc-libde265), [binary packages](https://launchpad.net/~strukturag/+archive/libde265).

 

- Windows DirectShow filters, https://github.com/strukturag/LAVFilters/releases

 

- ffmpeg fork, https://github.com/farindk/ffmpeg

 

- ffmpeg decoder [source](https://github.com/strukturag/libde265-ffmpeg)

 

- libde265.js JavaScript decoder [source](https://github.com/strukturag/libde265.js), [demo](https://strukturag.github.io/libde265.js/).

 

由上,我们可以直接下载上述DirectShow的第三方filter导入即可拿来解码H265码流,由于目前小编手头还没有H265格式输出的UVC摄像头,现以H264为例。

介绍如何导入新的Filter,以及如何使用第三方filter完成解码操作。这里我将采用sourceforge上的另一个开源Filter(http://hax264.sourceforge.net/)项目,箭头处可进入下载页面下载相关开源的源码和Release包。

下载好Hax264_setup_1_0_0.exe后,安装,你将会得到以下文件。

 

接下来我们要做的是注册组件,filter实际就是COM组件,可使用命令行注册,这里由于上述路径中有空格,我将其移到了D盘,此外运行cmd.exe时,要以管理员身份运行,如下:

补充一点,以上注册组件的这个步骤要特别注意,这个路径一旦确定以后,里面的库等资源就不要移动到别的地方去了,否则,会导致运行我们的解码程序时找不到资源模块,这不但会导致你的程序Crash,在使用GraphEdit添加Filter时,也会提示找不到模块。

接下来打开DirectShow的GraphEdit.exe可以发现在枚举系统的DirectShow Filters时,多了我们刚刚注册的Filter,如下:

接下来,由于我的摄像头有多个输出pin及多种输出格式,我配置我的UVC摄像头输出格式为H264-1080P输出,如下图:

在H264 DS Filter上右击配置属性,我们有两种输出格式可以配置如下:

以上已经可以点亮摄像头,接下来,我们通过代码去实现上述Com连接,并取样图像。

首先我们在代码中创建该Filter时,需要一个唯一ID,我们可以通过在Insert Filter页面查看:

该处后面的ID中即有我们需要的ID,于是可新增定义如下:

 

#define MYDEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \

    EXTERN_C const GUID DECLSPEC_SELECTANY name \

    = { l, w1, w2, { b1, b2,  b3,  b4,  b5,  b6,  b7,  b8 } }

 

// 43FC6785-8E56-4ED6-9CCC-9F3556AC9D24        

MYDEFINE_GUID(CLSID_H264DS,0x43FC6785, 0x8E56, 0x4ED6, 0x9C, 0xCC, 0x9F, 0x35, 0x56, 0xAC, 0x9D, 0x24);

 

// H.264 compressed video stream

// 34363248-0000-0010-8000-00AA00389B71  'H264' == MEDIASUBTYPE_H264

MYDEFINE_GUID(MEDIASUBTYPE_H264,0x34363248, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);

 

// 创建H264解码接口

IBaseFilter *m_pH264Filter;

    hrCoCreateInstance(CLSID_H264DS,0,CLSCTX_INPROC,IID_IBaseFilter,

(void**)&m_pH264Filter);//声明第二个filter

    if(hr == S_FALSE) return hr;

 

//添加H264 Filter到Graph中

    hr = m_pGraphFilter->AddFilter(m_pH264Filter,L"H264 DS Filter"); 

    if (hr == S_FALSEreturn hr

 

这里上传了一个我编写的示例程序资源:

https://download.csdn.net/download/tanjiaqi2554/11691879

以上资源可驱动点亮该格式输出的UVC摄像头,编译的时候需要正确设置你的DirectShow的包含头文件目录路径和库路径,如下:

以上可能报错,如果是7.0A版本以后的DirectShow可能缺少Qedit.h,没关系【它在老版本9.0中是有的】,这个文件我也单独上传了,直接复制到DirectShow头文件目录下即可,如下:

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值