videocapture

您所在的位置:网站首页 视骏hevc解码器 videocapture

videocapture

2023-10-24 09:53| 来源: 网络整理| 查看: 265

DirectShow框架简介

DirectShow框架是多媒体播放框架上一个非常经典的框架,现在已经十多年了,在Windows平台上依然无法替代,非常值得去学习研究。个人觉得从设计模式的角度上看,directshow框架的灵活性、复用性、可维护性、可拓展性这些方面做得非常不错,也是它经久不衰历久弥新的一个原因,现在的很多第三方的decoder和filter都基于directshow框架开发,可以很灵活的移植到directshow视频框架中,例如视骏开发的HEVC/H.265解码器,都可以直接挂载在directshow框架中进行视频解码。

图形化理解DirectShow

推荐一款工具GraphStudio,了解DirectShow框架必备工具,软件截图如下: [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vywGjHIE-1626603489412)(http://of6x0sb2r.bkt.clouddn.com/graphstudio.png-WaterMark)] 我们点击Graph可以插入我们在电脑系统中注册的Filter Render,默认情况下,我们将播放的视频加到GraphStudio中,会自动生成directshow的整个播放流程,然后就可以播放视频了。一般的播放效果流程如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ONNktbzr-1626603489414)(http://of6x0sb2r.bkt.clouddn.com/direcshow%E6%B5%81%E7%A8%8B%E5%9B%BE.png-WaterMark)]

GraphStudio会自动采用系统默认的一套Filter和Render,如果安装了K-Lite Codec Pack,就可以修改系统默认的这一套,如下图: [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DTTu8ava-1626603489415)(http://of6x0sb2r.bkt.clouddn.com/K_Lite_kit.png-WaterMark)] 我们想测试我们自己的Filter和Render,都可以自定义插入,下面就以DirectShow中植入视骏的HEVC解码器为例子,了解DirecShow的整个播放流程,如下图所示: [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MavdR37W-1626603489417)(http://of6x0sb2r.bkt.clouddn.com/HEVCDecoder.png-WaterMark)]

DirectShow播放HEVC视频

可以参考雷老师关于DirectShow的介绍, 地址:http://blog.csdn.net/leixiaohua1020/article/details/42372419 播放的流程如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3lWHsY1N-1626603489418)(http://of6x0sb2r.bkt.clouddn.com/directshowplay.png-WaterMark)]

整个播放我们可以抽象出三个步骤:

Created with Raphaël 2.3.0 注册Filter和Render 链接Filter和Render 执行播放RenderFile

注册:播放HEVC视频需要的Strongene Mpeg-4 Demultiplexor,Lentoid HEVC Decoder,Video Renderer链接:相当于上面GraphStudio图中的链接箭头播放:将视频导入播放链路中,开始播放注册Filter和Render解码器属性

首先获取到这些Filter的Object name、CLSID、Filename和FilePath [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qhTGvbDM-1626603489418)(http://of6x0sb2r.bkt.clouddn.com/filterInfo.png-WaterMark)] 如果已经将filter注册进Windows的系统中,就只需要用到Object Name,为了避免重新注册导致冲突;

//Name:File Source (Async.) {E436EBB5-524F-11CE-9F53-0020AF0BA770} /** Windows自带File Source (Async.),dll路径:C:\Windows\SysWOW64\quartz.dll CLSID = */ //MP4 Splitter {61F47056-E400-43D3-AF1E-AB7DFFD4C4AD} Name: Strongene Mpeg-4 Demultiplexor static const GUID CLSID_MP4Splitter = {0x61f47056,0xe400,0x43d3,{0xaf,0x1e,0xab,0x7d,0xff,0xd4,0xc4,0xad}}; //h265-HEVC Decoder {658C5E1C-58E1-43CA-9D10-13735D465576} Name:Lentoid HEVC Decoder static const GUID CLSID_HEVCDecoder = {0x658C5E1C,0x58E1,0x43CA,{0x9D,0x10,0x13,0x73,0x5D,0x46,0x55,0x76}}; //Name:Video Mixing Renderer {B87BEB7B-8D29-423F-AE4D-6582C10175AC} /** Windows自带VideoRenderer,dll路径:C:\Windows\SysWOW64\quartz.dll */声明DirectShow播放需要的类和变量IGraphBuilder * mGraph;//创建一个Filter Graph Manager组件 IMediaControl * mMediaControl;//提供控制过滤器图表中多媒体数据流的方法,包括运行、暂停和停止 IMediaEventEx * mEvent;//继承自IMediaEvent接口,处理过滤器图表的事件 IBasicVideo * mBasicVideo;//用于设置视频特性,如视频显示的目的区域和源区域 IBasicAudio * mBasicAudio;//用于控制音频流的音量和平衡 IVideoWindow * mVideoWindow;//定义一个视频窗口的控制对象 IMediaSeeking * mSeeking;//提供搜索数据流位置和设置播放速率的方法 IBaseFilter *m_pSourceFilter = NULL; IBaseFilter *m_pSplitter = NULL; IBaseFilter *m_pSplitter = NULL; IBaseFilter *m_pVideoHEVCDecoder = NULL; IBaseFilter *m_pVideoRender = NULL; DWORD mObjectTableEntry = 0;注册Filter:加载解码器并获取DllGetClassObject指针,loadFilter()bool loadFilter(LPCSTR chAx) { //加载Filter所在的dll文件 m_hInst = ::LoadLibrary(chAx); if (NULL == m_hInst) { return false; } //获取DllGetClassObject函数指针 m_pDllGetClassObject = ( DLL_GET_CLASS_OBJECT )::GetProcAddress(m_hInst, "DllGetClassObject"); if (NULL == m_pDllGetClassObject) { return false; } return true; }动态创建解码器对象,createFilter()bool createFilter(GUID clId, IBaseFilter** pBaseFilter) { if (NULL == m_pDllGetClassObject) { return false; } //获取类工厂接口 IClassFactory *p_IClassFactory = NULL; if (FAILED( m_pDllGetClassObject(clId, IID_IClassFactory, (void **)&p_IClassFactory) )) { return false; } //创建与类厂相关联的COM对象(Filter),并获取其IBaseFilter接口 p_IClassFactory->CreateInstance(NULL, IID_IBaseFilter, (void **)pBaseFilter); p_IClassFactory->Release(); p_IClassFactory = NULL; if ((NULL == pBaseFilter) || (NULL == *pBaseFilter)) { return false; } return true; }申明一个方法函数InitRegister(),bool InitRegister() { mGraph=NULL; mMediaControl=NULL; mEvent=NULL; mBasicVideo=NULL; mBasicAudio=NULL; mVideoWindow=NULL; mSeeking=NULL; if(!mGraph) { //建立 filter graph manager HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,IID_IGraphBuilder, (void **)&mGraph); if(mGraph != NULL) { LPCSTR splitterDll, HEVCDecoderDll; LPCWSTR splitterName, HEVCDecoderName; GUID splitterGuid, HEVCDecoderGuid; //Source Filter hr = CoCreateInstance(CLSID_AsyncReader, NULL, CLSCTX_INPROC,IID_IBaseFilter, (void **)&m_pSourceFilter); if(hr == S_OK) { mGraph->AddFilter(m_pSourceFilter, L"File Source Filter"); } else { cout Release(); cout Next(1, &pPin, NULL) == S_OK) { PIN_DIRECTION ThisPinDir; pPin->QueryDirection(&ThisPinDir); if (ThisPinDir == PinDir) //如果out/in类型符合 { nIndex ++; IPin *pTmp = NULL; hr = pPin->ConnectedTo(&pTmp); if (SUCCEEDED(hr)) //如果已经被连接 { pTmp->Release(); } else { pPin->EnumMediaTypes(&pType); pType->Next(1, &pMType, 0); if(myMajortype == pMType->majortype) //类型匹配 { pEnum->Release(); pType->Release(); *ppPin = pPin; pPin->Release(); return S_OK; } pType->Release(); } } pPin->Release(); } pEnum->Release(); cout Connect(ppinOut, ppinIn))) { cout


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3