VS2010 C++学习(5):基于DirectShow视频预览录像程序
MFC+DirectShow摄像头简单视频浏览
MFC+DirectShow摄像头简单视频浏览1 安装摄像头驱动2 引用DirectShow库,包含DirectShow头文件#pragma comment(lib,"Strmiids.lib")#pragma comment(lib,"quartz.lib")#include "dshow.h"3 初始化com环境::CoInitialize(NULL);4 定义一个过滤器引脚查询函数,并实现之定义IPin *findpin(IBaseFilter *pFilter,PIN_DIRECTION dir);实现,假定工程为MFC Dialog Based类型,主对话框类为VDlg IPin *VDlg::findpin(IBaseFilter *pFilter,PIN_DIRECTION dir) {IEnumPins *pEnumPins=NULL;IPin *pRetPin=NULL;PIN_DIRECTION pDir;pFilter->EnumPins(&pEnumPins);while(pEnumPins->Next(1,&pRetPin,NULL)==S_OK){pRectPin->QueryDirection(&pDir);if(pDir==dir){return pRetPin;}}return 0;}5 预览实现void VDlg::vPreview(){ICaptureGraphBuilder *pBuilder=NULL;::CoCreateInstance(CLSID_CaptureGraphBuilder2,NULL,CLSCTX_INPROC_SERV ER,IID_ICaptureGraphBuilder2,(void **)&pBuilder);::CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,IID_IG raphBuilder,(void **)&pGraph);pBuilder->SetFiltergraph(pGraph);ICreateDevEnum *pDevEnum=NULL;IEnumMoniker *pClsEnum=NULL;::CoCreateInstance(CLSID_SystemDeviceEnum,NULL,CLSCTX_INPROC,IID_ICre ateDevEnum,(void **)&pDevEnum);pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pClsE num,0);if(pClsEnum->Next(1,&pMoniker,NULL)==S_OK){pMoniker->BindToObject(0,0,IID_IBaseFilter,(void **)&pSrc);pMoniker->Release();}pClsEnum->Release();pGraph->AddFilter(pSrc,L"AVI");::CoCreateInstance(CLSID_VideoRenderer,NULL,CLSCTX_ALL,IID_IBaseFi lter,(void **)&pPreview);if(pPreview){pGraph->AddFilter(pPreview,L"PREVIEW");IPin *pPinOut,*pPinIn;pPinOut=findpin(pSrc,PINDIR_OUTPUT);pPinIn=findpin(pPreview,PINDIR_INPUT);pGraph->ConnectDirect(pPinOut,pPinIn,0);IVideoWindow *pWnd=NULL;pPreview->QueryInterface(IID_IVideowindow,(void **)&pWnd);if(pWnd){long ws;pWnd->put_Owner((long)m_hWnd);pWnd->get_WindowStyle(&ws);ws=ws &~ WS_CAPTION;ws=ws &~WS_DLGFRAME;ws=ws & WS_CHILD;pWnd->put_WindowStyle(ws);CRect rc;this->GetClientRect(rc);pWnd->put_Lef(5);pWnd->put_Top(5);pWnd->put_Width(rc.Width()-5); pWnd->put_Height(rc.Height()-5); }pMediaCtrl->Run();}}。
基于DirectShow的客户端实时视频流回放技术
d, t ) e r lr  ̄ fe 等。过滤器通过向文件读写、 ei 修改数据和显示数据到输 出设备上来操作流媒体。为了完成整个 任务 。 必须要将所有的过滤器 F t 连接起来 , 3 ir l e 这 种过滤器组成了过滤器图表结构 , 如图 I 所示。
Die th w r cS o
术, 避开了复杂的视频流解压算法 , 具有较好的通用性和可移植性。
1 Drc hw 简 介 i t o eS
M ic hw的设计 目 SD eSo rt 标是: 隔离数据传输 、 硬件兼容、 流同步等底层处理, 使客户能够轻轻松松地创建 W n w 应用平台上的多媒体应用程序[。它对媒体数据的处理采用流媒体( uie a t ) i os d ¨ M l d 咖 的方式, t is m 在应用 中大大的减少了编程的复杂程度, 同时又可以自 动协商从数据源到应用的转换 , 口 流接 提供了统一的、 可以预测 的数据存取的控制方法, 这样应用程序在播放媒体数据时不需要考虑它最初的来源和格式。
V I 2 . o. 8N 1 o
Ma .2 o r 06
基 于 Drc hw的客户 端 i to eS 实 时视频 流 回放 技 术
刘 琼 , 慧灿 周
( 湖南文理学院 计算机科学系 。 湖南 常德 450 ) 103
摘
要: 介绍 了Dr t o 术的原理并 以 M E i c hw技 eS P G一1视频流解 码回放为例 , 详细说 明了 Ft Gah的构建 与实现方法。 ir r l e p 文献标识码 : A 文章编号 :6 1 2 120 )1 0 1 3 17 —03 (060 —06 —0
维普资讯
在过滤器图表结构中, 源过滤器用来从数据源劳敢数据 , 并将数据传送到过滤器 图表中, 这里的数据
利用DirectShow实现视频文件播放
DirectShow 媒体文件回放总结收藏作者:Inkick1.概述DirectShow中媒体文件回放的过程也就是一个为媒体文件选择相应所需的Filter、构建Filter Graph、并对Filter Graph的状态进行维持、控制的过程。
这里所说的媒体文件,不仅仅是指音频、视频文件,同时也包括bmp、jpeg、gif等图形图像格式以及midi等数字化音乐序列。
因此,使用DirectShow进行媒体文件的回放需要经过以下的步骤:2.构建Filter GraphFilter Graph为Filter提供了一个容器,一个构建完整的Filter Graph也就是一个完整的Filter 连路,这个连路对于程序是透明的,可控制的。
而对于每一个媒体文件来说,Filter Graph 与媒体文件存在着对应的关系。
也就是说,一个Filter Graph只能实现一个(种)文件的回放。
在DirectShow中,Filter Graph是由接口对象IGraphBuilder实现的,我们可以调用Win32 API 函数CoCreateInstance()建立一个实体。
Filter Graph实体建立之后并不具有任何的Filter,因此不具有任何实际用途。
因此我们需要连接需要的Filter来完成FilterGraph的构建。
智能连接这个术语覆盖了一系列Filter Graph Manager用于构建所有或部份filter graph的算法。
任何时候,当Filter Graph Manager需要添加filter来完成graph时,它大致做以下几件事情:如果有一个filter存在于graph中,而且这个filter有至少一个没有连接的input pin,Filter Graph Manager试着去试用这个filter。
否则,Filter Graph Manager在已注册的filter中寻找连接时可以接受合适的媒体类型的filter。
基于Directshow的视频缩放的技术措施
基于Directshow的视频缩放的技术措施本文从网络收集而来,上传到平台为了帮到更多的人,如果您需要使用本文档,请点击下载按钮下载本文档(有偿下载),另外祝您生活愉快,工作顺利,万事如意!在日常学习工作中经常会对各种视频文件进行分析,比如视频的剪切、缩放等,但是对于这些操作可能会用到专业的视频分析卡等硬件的支持。
针对硬件价值较高,微软提供了一套基于COM的流媒体处理开发包DirectShow。
在DirectShow中提供了完整的视频分析处理接口DES,负责对各类视频进行分析处理。
通过DES、Filter Graph可以对视频进行缩放处理,使视频的缩放脱离硬件的直接支持,适合于个人PC 机上的视频处理。
本文主要分析了3中视频缩放的方法,通过这些方法可以进一步加快视频缩放的速度和效率。
1 Directshow简介利用Directshow对视频进行缩放处理,必须对Directshow的架构,DES(Directshow Editing Services)以及Filter Graph Manager等知识有所了解。
Directshow的体系结构Directshow本质上就是基于COM组建的流媒体开发包,它为我们用户提供了一整套完整的视频处理接口。
该体系结构大致可分为3层:用户应用层、Directshow接口层、底部设备层。
Filter以及Filter Graph ManagerFilter其实就是一种叫做过滤器的COM组件,一共有三种类型的Filter:Source Filter、Transforill Filter、Rendering Filter。
它们都包含一个或多个Pin,Source Filter负责视频的采集,输入等;Transform Filter负责对视频进行格式转换、传输等;Rendering Filter负责视频文件的渲染,输出。
由于每一个Filter都有Pin针,我们可以根据不同的任务、需求,将各种Filter利用Pin针连接起来,就构成了一个Filter Graph。
基于DirectShow的视频采集和传播系统
基于DirectShow的数字视频采集与传输系统内容摘要:本文简单介绍了DirectShow技术,研究了利用DirectShow实现视频采集、压缩和网络传输技术。
并利用第三方提供的编解码器实现了MPEG-4视频数据的网络传输系统,在该系统中利用RTP 协议进行视频数据传输,同时实现了远端帧率的控制。
1 引言近年来,随着国民经济的发展,社会各个部门对于视频监视系统的需求越来越多。
但目前的很多监视系统都跟具体的硬件相关,必须要具体的采集卡的支持才能实现。
所以有必要开发一种具有通用性的视频监视系统,用普通的摄像头就能实现视频的采集。
基于DirectShow的开发能很灵活地控制音视频的效果,所以选择DirectShow这种可扩展性好的技术做开发对以后的应用升级很有帮助。
此外,为了实现流媒体传输控制的策略,流媒体的传输和回放也是应解决的问题之一。
由Microsoft提供的DirectShow技术基于组件对象模型技术,支持宽松的格式变化,提供高品质的多媒体流回放。
利用它可以在普通微机中实现流媒体的客户端处理,并可以提高系统的通用性和可扩展性。
对于视频数据的传输,压缩率是一个必须考虑到的因素。
MPEG-4是由ISO和IEC的MPEG组制定的一个关于活动图像和声音的编码国际标准。
它在基于内容的交互性、压缩率、通用访问能力等方面提供了一系列新的或改进的功能。
MPEG-4视频在提供较好的图像质量的同时拥有较高的压缩率,适合于作为传输的图像压缩标准。
2相关技术2.1 DirectShow技术简介DirectShow是Microsoft为开发高性能多媒体应用而开发的底层应用程序接口(API),它是DirectX家族的核心成员之一。
DirectShow自身是通过一种系统内置的或程序员开发的过滤器(Filter)来控制和处理多媒体数据的体系结构。
该体系结构定义了如何处理和控制过滤器内部及相互之间的多媒体数据流。
每个过滤器都有输入或输出针(Pin), 或两者都有。
基于DirectShow视频及图片捕获软件的开发
基于DirectShow视频及图片捕获软件的开发我们知道目前很多工业相机的图像数据采集都是基于DirectShow的,常见的有映美精等。
DirectShow是微软公司提供的一套在Windows平台上进行流媒体处理的开发包,与DirectX开发包一起发布。
DirectShow为多媒体流的捕捉和回放提供了强有力的支持。
运用DirectShow,我们可以很方便地从支持WDM驱动模型的采集卡上捕获数据,并且进行相应的后期处理乃至存储到文件中。
它广泛地支持各种媒体格式,包括Asf、Mpeg、Avi、Dv、Mp3、Wave等等,使得多媒体数据的回放变得轻而易举。
另外,DirectShow还集成了DirectX其它部分(比如DirectDraw、DirectSound)的技术,直接支持DVD的播放,视频的非线性编辑,以及与数字摄像机的数据交换。
更值得一提的是,DirectShow提供的是一种开放式的开发环境,我们可以根据自己的需要定制自己的组件。
笔者使用visual studio 2005 来开发了基于DirectShow的视频捕获软件,并用开发的软件对映美精相机进行了测试。
本软件不但可以实现对相机的视频捕获,而且还可以抓取图像帧。
软件运行时自动搜索所连接的相机,预览后可以对相机参数进行设置。
下面是软件的主界面。
预览视频后可以对视频格式和图像参数进行设置。
开始预览时,捕获的视频是黑白的,我们将颜色空间设置为UYVY即可捕获彩色视频。
下面是捕获的一帧图像,图像质量虽然没有映美精自带的软件效果好,但已经实现了所需各项基本功能,接下来的工作将会进一步提高软件性能。
另外我们还可以捕获视频,点击“捕获视频”按钮,输入要保持的文件名,注意要以.avi后缀结尾,点确定就开始捕获视频。
从我们开发的软件可以看到,映美精的相机能够很好的支持DirectShow的驱动,我们的软件对映美精相机的识别是如此的容易。
接下来我们将继续开发基于其它驱动的图像捕获软件,为最终实现在一个软件中识别各种相机而努力。
基于DirectShow的多摄像头视频采集
基于DirectShow的多摄像头视频采集1.为什么使用DirectShow笔者使用的是两个USB摄像头,单摄像头视频采集使用OpenCV的VideoCapture类没有问题,但是双摄像头就有问题,一个正常,另外一个采集不到信息,显示一片灰色。
网上有种解决方法是逆序打开摄像头,结果两个窗口是可以采集到视频信息,但是竟然是同一个摄像头的视频信息,无奈的只能使用DirectShow采集多摄像头视频信息。
先看看什么是DirectShow:DirectShow 是 DirectX 的组件之一, DirectX 软件开发包是 Microsoft 提供的一套在 Windows平台上开发高性能图形、声音、输入、输出和网络游戏的编程接口。
这其中,DirectShow提供了应用程序从适当的硬件中捕捉和预览音、视频的能力。
数据源包括: VCR、 Camera、 TV Tuner、 Microphone 或其他的数据源。
应用程序可以立刻显示捕捉的数据(预览),或是保存到一个文件中。
摄像头采集信息常用的软件AMCap就是基于DirectShow SDK编写的。
查阅一下官方文档,感觉好难的样子,难道要新学一门“快过时”的技术吗?幸好于仕琪老师写了一个CCameraDS类,可直接返回IplImage,使用方便。
2.在VS2010中配置DirectShow并采集双目摄像头视频下载DirectShow相关文件,我已经共享在百度云盘,点击下载。
解压以后copy到D:\opencv里(放在这里为了管理方便)在解决资源管理器中的项目名称处右键\属性\配置属性\VC++目录,引用目录中添加DirectShow的include文件夹,我添加的是D:\opencv\DirectShow\Include在引用目录下面有一个库目录,添加DirectShow的Lib文件夹,我添加的是D:\opencv\DirectShow\Lib;下载CCameraDS类相关文件,点击下载。
基于VC++与DirectShow的视频监控及其实验平台
1 引言
为 了满 足银行 、 通 、 交 电力 、 民小 区等要 害部 门和 居 社会领 域 的安 防需要 ,视频 监控技 术得 到迅速发 展 、 普 及。 早期 的监控 主要 由摄像机 、 视频矩 阵、 监视器 、 录像机 组成 , 过视频 线 、 通 控制 电缆 连接 , 只适用 于小范 围 内的
. Dr t W工作原 理 e h 上进行媒体 流处 理的多媒体 开发 包, Drc 开发包一 21 i cSo 与 i t eX 图 1显示 了 DrcSo i t w的 体 系结 构 图 ,ic hw e h Dr t o eS 起发 布。 是微软公司推 出的新一代基 于 C M组件对象模 O
收 稿 日期 :0 70 —0修 回 日期 :0 7 0— 8 20 — 7 1; 20 — 7 2 作 者简 介 : 彭海 云(9 2 )女 , 师 , 究方 向: 17 一 , 讲 研 计算机 应用 研 究。
Acv Mo i t e ve i C 0 口
应 用 程序
工
MC  ̄ E I ]
控件
t
V
监控。 随着数字 视频压 缩编码 技术的 日益成熟 、 多媒体计 算机性能的提高和 网络带 宽的增大 ,使 多媒体数据 的远 程传 输变成可能 ,这些 多媒 体数据具有 图像清晰 、可记
具有代 码量少 、 通用性 强 、 时性好 的特 点 , 实 来进 行实 时 的视频监控 。
I体 端 媒 源
媒 目端 体 的
图 1 Di cS o 的 体 系结 图 r thw e
C#DirectShow预览摄像头并截图
C#DirectShow预览摄像头并截图C# DirectShow预览摄像头并截图,供⼤家参考,具体内容如下本事例通过Windows DirectX Filtergraph ⼀些列管道将电脑所接⼊视频采集设备的视频流播放到制定区域,通过ISampleGrabberCB接⼝的BufferCB回调函数截取图⽚。
⽤此⽅法预览图像cpu占⽤率极低,⽐其其他事件绑定并逐帧显⽰图像性能更佳。
UI布局:代码如下:using System;using System.Drawing;using System.Windows.Forms;using DirectShowLib;using System.Runtime.InteropServices;using Types;using System.Drawing.Imaging;namespace Test{public partial class FormDirect : Form, ISampleGrabberCB{private int _previewWidth = 640;private int _previewHeight = 480;private int _previewStride = 0;private int _previewFPS = 30;private volatile bool isGrab = false;IVideoWindow videoWindow = null;IMediaControl mediaControl = null;IFilterGraph2 graphBuilder = null;ICaptureGraphBuilder2 captureGraphBuilder = null;DsROTEntry rot = null;public FormDirect(){InitializeComponent();}private void button2_Click(object sender, EventArgs e){//截图isGrab = true;}private void button3_Click(object sender, EventArgs e){string button_text = button3.Text;if (button_text.Equals("Start Webcam")){button3.Text = "Stop Webcam";StartCamera();}else{button3.Text = "Start Webcam";StopCamera();}}private void StartCamera(){DsDevice[] devices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);if (devices.Length == 0){MessageBox.Show("No USB webcam connected");button3.Text = "Start Webcam";return;}else{CaptureVideo(devices[0]);}}private void StopCamera(){button3.Text = "Start Webcam";CloseInterfaces();}public void CaptureVideo(DsDevice device){pictureBox1.Image = null;int hr = 0;IBaseFilter sourceFilter = null;ISampleGrabber sampleGrabber = null;try{// Get DirectShow interfacesGetInterfaces();// Attach the filter graph to the capture graphhr = this.captureGraphBuilder.SetFiltergraph(this.graphBuilder);DsError.ThrowExceptionForHR(hr);// Use the system device enumerator and class enumerator to find// a video capture/preview device, such as a desktop USB video camera.sourceFilter = SelectCaptureDevice(device);// Add Capture filter to graph.hr = this.graphBuilder.AddFilter(sourceFilter, "Video Capture");DsError.ThrowExceptionForHR(hr);// Initialize SampleGrabber.sampleGrabber = new SampleGrabber() as ISampleGrabber;// Configure SampleGrabber. Add preview callback.ConfigureSampleGrabber(sampleGrabber);// Add SampleGrabber to graph.hr = this.graphBuilder.AddFilter(sampleGrabber as IBaseFilter, "Frame Callback");DsError.ThrowExceptionForHR(hr);// Configure preview settings.SetConfigParams(this.captureGraphBuilder, sourceFilter, _previewFPS, _previewWidth, _previewHeight);// Render the previewhr = this.captureGraphBuilder.RenderStream(PinCategory.Preview, MediaType.Video, sourceFilter, (sampleGrabber as IBaseFilter),null);DsError.ThrowExceptionForHR(hr);SaveSizeInfo(sampleGrabber);// Set video window style and positionSetupVideoWindow();// Add our graph to the running object table, which will allow// the GraphEdit application to "spy" on our graphrot = new DsROTEntry(this.graphBuilder);// Start previewing video datahr = this.mediaControl.Run();DsError.ThrowExceptionForHR(hr);}catch{MessageBox.Show("An unrecoverable error has occurred.");}finally{if (sourceFilter != null){Marshal.ReleaseComObject(sourceFilter);sourceFilter = null;}if (sampleGrabber != null){Marshal.ReleaseComObject(sampleGrabber);sampleGrabber = null;}}}public void CaptureVideo(){pictureBox1.Image = null;int hr = 0;IBaseFilter sourceFilter = null;ISampleGrabber sampleGrabber = null;try{// Get DirectShow interfacesGetInterfaces();// Attach the filter graph to the capture graphhr = this.captureGraphBuilder.SetFiltergraph(this.graphBuilder);DsError.ThrowExceptionForHR(hr);// Use the system device enumerator and class enumerator to find// a video capture/preview device, such as a desktop USB video camera.sourceFilter = FindCaptureDevice();// Add Capture filter to graph.hr = this.graphBuilder.AddFilter(sourceFilter, "Video Capture");DsError.ThrowExceptionForHR(hr);// Initialize SampleGrabber.sampleGrabber = new SampleGrabber() as ISampleGrabber;// Configure SampleGrabber. Add preview callback.ConfigureSampleGrabber(sampleGrabber);// Add SampleGrabber to graph.hr = this.graphBuilder.AddFilter(sampleGrabber as IBaseFilter, "Frame Callback");DsError.ThrowExceptionForHR(hr);// Configure preview settings.SetConfigParams(this.captureGraphBuilder, sourceFilter, _previewFPS, _previewWidth, _previewHeight);// Render the previewhr = this.captureGraphBuilder.RenderStream(PinCategory.Preview, MediaType.Video, sourceFilter, (sampleGrabber as IBaseFilter),null); DsError.ThrowExceptionForHR(hr);SaveSizeInfo(sampleGrabber);// Set video window style and positionSetupVideoWindow();// Add our graph to the running object table, which will allow// the GraphEdit application to "spy" on our graphrot = new DsROTEntry(this.graphBuilder);// Start previewing video datahr = this.mediaControl.Run();DsError.ThrowExceptionForHR(hr);catch{MessageBox.Show("An unrecoverable error has occurred.");}finally{if (sourceFilter != null){Marshal.ReleaseComObject(sourceFilter);sourceFilter = null;}if (sampleGrabber != null){Marshal.ReleaseComObject(sampleGrabber);sampleGrabber = null;}}}public IBaseFilter SelectCaptureDevice(DsDevice device){object source = null;Guid iid = typeof(IBaseFilter).GUID;device.Mon.BindToObject(null, null, ref iid, out source);return (IBaseFilter)source;}public IBaseFilter FindCaptureDevice(){int hr = 0;#if USING_NET11UCOMIEnumMoniker classEnum = null;UCOMIMoniker[] moniker = new UCOMIMoniker[1];#elseIEnumMoniker classEnum = null;IMoniker[] moniker = new IMoniker[1];#endifobject source = null;// Create the system device enumeratorICreateDevEnum devEnum = (ICreateDevEnum)new CreateDevEnum();// Create an enumerator for the video capture deviceshr = devEnum.CreateClassEnumerator(FilterCategory.VideoInputDevice, out classEnum, 0);DsError.ThrowExceptionForHR(hr);// The device enumerator is no more neededMarshal.ReleaseComObject(devEnum);// If there are no enumerators for the requested type, then// CreateClassEnumerator will succeed, but classEnum will be NULL.if (classEnum == null){throw new ApplicationException("No video capture device was detected.\r\n\r\n" +"This sample requires a video capture device, such as a USB WebCam,\r\n" + "to be installed and working properly. The sample will now close.");}// Use the first video capture device on the device list.// Note that if the Next() call succeeds but there are no monikers,// it will return 1 (S_FALSE) (which is not a failure). Therefore, we// check that the return code is 0 (S_OK).#if USING_NET11int i;if (classEnum.Next (moniker.Length, moniker, IntPtr.Zero) == 0)#elseif (classEnum.Next(moniker.Length, moniker, IntPtr.Zero) == 0)#endif{// Bind Moniker to a filter objectGuid iid = typeof(IBaseFilter).GUID;moniker[0].BindToObject(null, null, ref iid, out source);}else{throw new ApplicationException("Unable to access video capture device!");}// Release COM objectsMarshal.ReleaseComObject(moniker[0]);Marshal.ReleaseComObject(classEnum);// An exception is thrown if cast failreturn (IBaseFilter)source;public void GetInterfaces(){int hr = 0;// An exception is thrown if cast failthis.graphBuilder = (IFilterGraph2)new FilterGraph();this.captureGraphBuilder = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();this.mediaControl = (IMediaControl)this.graphBuilder;this.videoWindow = (IVideoWindow)this.graphBuilder;DsError.ThrowExceptionForHR(hr);}public void CloseInterfaces(){if (mediaControl != null){int hr = mediaControl.StopWhenReady();DsError.ThrowExceptionForHR(hr);}if (videoWindow != null){videoWindow.put_Visible(OABool.False);videoWindow.put_Owner(IntPtr.Zero);}// Remove filter graph from the running object table.if (rot != null){rot.Dispose();rot = null;}// Release DirectShow interfaces.Marshal.ReleaseComObject(this.mediaControl); this.mediaControl = null;Marshal.ReleaseComObject(this.videoWindow); this.videoWindow = null;Marshal.ReleaseComObject(this.graphBuilder); this.graphBuilder = null;Marshal.ReleaseComObject(this.captureGraphBuilder); this.captureGraphBuilder = null;}public void SetupVideoWindow(){int hr = 0;// Set the video window to be a child of the PictureBoxhr = this.videoWindow.put_Owner(pictureBox1.Handle);DsError.ThrowExceptionForHR(hr);hr = this.videoWindow.put_WindowStyle(WindowStyle.Child);DsError.ThrowExceptionForHR(hr);// Make the video window visible, now that it is properly positionedhr = this.videoWindow.put_Visible(OABool.True);DsError.ThrowExceptionForHR(hr);// Set the video positionRectangle rc = pictureBox1.ClientRectangle;hr = videoWindow.SetWindowPosition(0, 0, _previewWidth, _previewHeight);DsError.ThrowExceptionForHR(hr);}private void SetConfigParams(ICaptureGraphBuilder2 capGraph, IBaseFilter capFilter, int iFrameRate, int iWidth, int iHeight) {int hr;object config;AMMediaType mediaType;// Find the stream config interfacehr = capGraph.FindInterface(PinCategory.Capture, MediaType.Video, capFilter, typeof(IAMStreamConfig).GUID, out config);IAMStreamConfig videoStreamConfig = config as IAMStreamConfig;if (videoStreamConfig == null){throw new Exception("Failed to get IAMStreamConfig");}// Get the existing format blockhr = videoStreamConfig.GetFormat(out mediaType);DsError.ThrowExceptionForHR(hr);// copy out the videoinfoheaderVideoInfoHeader videoInfoHeader = new VideoInfoHeader();Marshal.PtrToStructure(mediaType.formatPtr, videoInfoHeader);// if overriding the framerate, set the frame rateif (iFrameRate > 0){videoInfoHeader.AvgTimePerFrame = 10000000 / iFrameRate;}// if overriding the width, set the widthif (iWidth > 0){videoInfoHeader.BmiHeader.Width = iWidth;}// if overriding the Height, set the Heightif (iHeight > 0){videoInfoHeader.BmiHeader.Height = iHeight;}// Copy the media structure backMarshal.StructureToPtr(videoInfoHeader, mediaType.formatPtr, false);// Set the new formathr = videoStreamConfig.SetFormat(mediaType);DsError.ThrowExceptionForHR(hr);DsUtils.FreeAMMediaType(mediaType);mediaType = null;}private void SaveSizeInfo(ISampleGrabber sampleGrabber){int hr;// Get the media type from the SampleGrabberAMMediaType media = new AMMediaType();hr = sampleGrabber.GetConnectedMediaType(media);DsError.ThrowExceptionForHR(hr);if ((media.formatType != FormatType.VideoInfo) || (media.formatPtr == IntPtr.Zero)){throw new NotSupportedException("Unknown Grabber Media Format");}// Grab the size infoVideoInfoHeader videoInfoHeader = (VideoInfoHeader)Marshal.PtrToStructure(media.formatPtr, typeof(VideoInfoHeader)); _previewStride = _previewWidth * (videoInfoHeader.BmiHeader.BitCount / 8);DsUtils.FreeAMMediaType(media);media = null;}private void ConfigureSampleGrabber(ISampleGrabber sampleGrabber){AMMediaType media;int hr;// Set the media type to Video/RBG24media = new AMMediaType();media.majorType = MediaType.Video;media.subType = MediaSubType.RGB24;media.formatType = FormatType.VideoInfo;hr = sampleGrabber.SetMediaType(media);DsError.ThrowExceptionForHR(hr);DsUtils.FreeAMMediaType(media);media = null;hr = sampleGrabber.SetCallback(this, 1);DsError.ThrowExceptionForHR(hr);}public int BufferCB(double SampleTime, IntPtr pBuffer, int BufferLen){if (isGrab){Bitmap v = new Bitmap(_previewWidth, _previewHeight, _previewStride,PixelFormat.Format24bppRgb, pBuffer);//v.RotateFlip(RotateFlipType.Rotate180FlipX);v.RotateFlip(RotateFlipType.Rotate90FlipX);this.BeginInvoke((MethodInvoker)delegate{pictureBox2.BackgroundImage = v;isGrab = false;});}return 0;}public int SampleCB(double SampleTime, IMediaSample pSample){//throw new NotImplementedException();return 0;}}}以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
基于DirectShow框架的视频监控系统
产品设计与实现监控系统的发展经历了几个阶段,在20世纪90年代初以前,主要是以模拟设备为主的闭路电视监控系统,称为第一代模拟监控系统。
20世纪90年代中期,随着计算机处理能力的提高和视频技术的发展,人们利用计算机的高速数据处理能力进行视频的采集和处理,利用显示器的高分辨率实现图像的多画面显示,从而大大提高了图像质量。
这种基于PC机的多媒体主控台系统,称为第二代数字化本地视频监控系统。
随后,数字视频压缩编码技术日益成熟,多媒体计算机性能不断提高,网络带宽逐步增大,视频监控步入了全数字化的网络时代,称为第三代远程视频监控系统。
第三代视频监控系统以网络为依托,以数字视频的压缩、传输、存储和播放为核心,以智能实用的图像分析为特色,引发了视频监控的技术革命。
它不仅符合社会信息化的发展趋势,而且代表了监控行业的发展方向。
目前,比较好的多媒体开发和视频处理应用程序的技术是微软提出的DirectShow。
Direct-Show是微软公司提供的一套开发包,它与Di-rectX开发包一起发布,是一套在Windows操作平台上处理各种格式的媒体文件的回放、音视频采集等多媒体应用的编程接口,DirectShow给出了一种全新的多媒体数据处理模型,并封装了采集、压缩和解压缩等一系列算法,为视频监控、视频会议等多媒体应用系统的开发提供了良好的平台。
针对远程视频监控的特点,在VisualC++环境下,笔者运用DirectShow框架和IP组播技术,实现了基于MPEG-4格式的网络视频监控系统的开发。
DirectShow是基于COM技术的,有着较强的编程规范和重用性。
运用DirectShow,可以方便地从采集设备上捕获数据,并且进行相应的后期处理乃至存储到文件中。
它广泛地支持各种媒体格式,包括ASF、MPEG、AVI、DV、MP3和WAVE等,使得多媒体数据的回放变得轻而易举。
另外,DirectShow还集成了DirectX其他部分(比如DirectDraw、DirectSound)的技术,直接支持DVD的播放,视频的非线性编辑,以及与数字摄像机的数据交换。
基于DirectShow视频播放器
DirectShow是微软公司提供的一套在Windows平台上进行流媒体处理的开发包,与DirectX开发包一起发布。
DirectShow为多媒体的捕捉和回放提供了强有力的支持。
运用DirectShow我们可以很方便地从支持WDM驱动模型的采集卡上捕获数据,并且进行相应的后期处理乃至存储到文件中。
它广泛地支持各种媒体格式,包括Asf、Mpeg、Avi、Dv、Mp3、Wave等等,使得多媒体数据的回放变得轻而易举。
另外,DirectShow还集成了DirectX其它部分(比如DirectDraw、DirectSound)的技术,直接支持DVD播放,视频的非线性编辑,以及与数据摄像机的交换换。
更值得一提的是,DirectShow提供的是一种开放式的开发环境,我们可以根据自己的需要定制自己的组件。
(引)入门DirectShow使用一种叫做Filter Graph的模型来管理整个数据流的处理过程,参与数据流处理的各个功能模块称做Filter,各个Filter在Filter Graph 中按一定的顺序连成一条流水线协调工作,完成一些相对独立的功能,如Filter 可以完成如下的一些功能:●读文件●从视频设备中获取视频●对视频流进行解码●将数据送往声卡或显卡每个Filter都有输入端和输出端,例如一个MPEG-1解码Filter它的输入是MPEG编码的流数据,它的输出端是一解码过的流数据。
DirectShow正是通过将不同的Filter连接在一起完成特定的功能的,我们将这些Filter的连接叫做Filter Graph,如下图A给出是播放AVI的Filter Graph:图A 播放AVI文件的Graph Filter图上图中每个模块分别代表了不同的Filter,媒体文件Filter从硬盘读取AVI 文件,AVI分离Filter将文件分离为音频流和视频流,AVI解码Filter对视频流进行解码并送往Video表现Filter,由后者将各帧在显示器上显示,默认的DirectSound设备用DirectSound将音频流输出。
基于DirectShow的P2P网络视频采集传输与播放系统
软件技术课程设计实验报告基于 DirectShow 的 P2P 网络视频采集、传输与播放系统)一. 概述DirectShow 是一个windows 平台上的流媒体框架,提供了高质量的多媒体流采集和回放功能。
它支持多种多样的媒体文件格式,包括ASF、MPEG、AVI、MP3 和WAV 文件。
同时DirectShow 支持使用WDM 驱动或早期的VFW 驱动来进行多媒体流的采集。
DirectShow 整合了其它的DirectX 技术,能自动地侦测并使用可利用的音视频硬件加速,也能支持没有硬件加速的系统。
DirectShow 大大简化了媒体回放、格式转换和采集工作。
但与此同时,它也为用户自定义的解决方案提供了底层流控制框架,从而使用户可以自行创建支持新的文件格式或其它用途的DirectShow 组件。
DirectShow 的主要功能是提供对多媒体流的捉捕与回放。
这种多媒体流既可以来自本地磁盘文件,也可以来自网络上的远程服务器。
也就是说,它提供了一种“在线播放”的功能,在远程数据尚未完全传输到本地机器上的同时,本地应用程序可不必等待数据完全传输完毕再进行播放,可以一边传输,一边播放。
这就为网络化的视频采集数据的实时解码显示提供一个方便的开发平台。
点对点技术(peer-to-peer ,简称P2P)又称对等互联网络技术,是一种网络新技术,依赖网络中参与者的计算能力和带宽,而不是把依赖都聚集在较少的几台服务器上。
P2P 网络通常用于通过连接来连接节点。
这类网络可以用于多种用途,各种文件共享软件已经得到了广泛的使用。
P2P 技术也被使用在类似VoIP 等实时媒体业务的数据通信中。
二. 需求分析2.1 开发要求1. 熟悉、掌握vs2010 开发工具,以及DirectShow SDK9.0 软件开发包。
2. 熟悉了解Socket 网络编程;3. 开发基于DirectShow 的应用软件,要求能够完成P2P 的网络视频采集、视频传输、视频播放的功能。
基于DirectShow的多媒体播放器设计与实现(含源文件)
编号毕业设计(论文)基于DirectShow的多媒体播放器设计与实现目录摘要 (I)Abstract (II)1 绪论 (1)1.1 课题研究的背景与意义 (1)1.2 课题国内外研究现状 (1)1.3 可行性分析 (2)1.3.1 技术可行性分析 (2)1.3.2 经济可行性分析 (2)1.3.3 管理可行性分析 (2)1.4 论文的主要内容及章节安排 (3)2 相关平台及开发技术简介 (3)2.1 Microsoft Visual C++ 2010概述 (3)2.1.1 MicosoftVisual C++ 2010特点 (3)2.1.2 MFC概述 (4)2.2 ADO访问数据库技术概述 (4)2.2.1 OLE DB和ADO简介 (4)2.2.2 ADO主要对象介绍 (5)2.2.3 VC++中使用ADO进行数据库开发的基本流程 (5)2.3 DirectShow核心技术 (5)2.3.1 DirectShow整体架构 (5)2.3.2 COM组件 (6)2.3.3 Filter概述及连接 (6)2.3.4 滤波器链表管理器 (7)2.3.5 滤波器链表中数据传输 (7)2.3.6 事件通知机制 (8)2.4 Skin++皮肤库概述 (9)2.4.1 Skin++简介 (9)2.4.2 Skin++特性 (9)3 系统需求分析 (9)3.1 系统业务需求 (9)3.2 系统数据需求 (10)3.3 功能需求 (10)3.4 非功能需求 (10)3.4.1 适应性 (10)3.4.2 安全性 (10)3.4.3 可靠性 (11)3.4.4 可扩充性 (11)3.4.5 可维护性 (11)3.4.6 可移植性 (11)4 多媒体播放器的设计 (11)4.1 系统功能设计 (11)4.1.1 媒体文件添加(数据输入) (11)4.1.2 媒体文件存储和显示(数据存储及显示) (12)4.1.3 媒体文件播放及控制(数据流传输、控制及输出) (12)4.2 系统结构设计 (12)4.3 系统数据库设计 (13)4.4 播放器滤波器链表结构设计 (13)4.5 DirectShow智能连接 (13)4.5.1 智能连接概述 (13)4.5.2 智能连接的实现 (14)5 多媒体播放器的实现 (14)5.1 基于DirectShow播放器的实现 (14)5.1.1 初始化COM (14)5.1.2 创建滤波器链表管理器 (15)5.1.3 智能连接建立滤波器链表 (15)5.2 DirectShow接口实现 (15)5.3 媒体文件信息存储实现 (15)5.3.1 数据库存储 (16)5.3.2 链表存储 (16)5.3.3 List列表显示 (17)5.4 播放控制功能的实现 (18)5.4.1 定位 (18)5.4.2 播放 (19)5.4.3 暂停、停止 (19)5.4.4 全屏 (19)5.4.5 截图 (20)5.4.6 静音控制 (20)5.4.7 速率控制 (21)5.4.8 上一个和下一个 (21)5.4.9 查找 (22)5.4.10 删除 (22)5.4.11 排行榜 (23)5.4.12 播放模式设置 (24)5.4.13 帮助 (24)5.4.14捕获本地摄像头 (25)5.5 歌词关联实现 (26)5.5.1 歌词构造原理概述 (26)5.5.2 获取歌词方法及过程 (27)5.5.3 遇到难点和问题 (27)5.6 用户管理功能实现 (28)5.6.1 用户注册 (28)5.6.2 用户登录 (29)5.6.3 用户使用系统整体流程 (29)5.7 播放JPG格式图片实现 (30)5.7.1 JPG格式图片缩放实现 (30)5.7.2 JPG格式图片的显示 (30)6 测试多媒体播放器实例及结论 (31)6.1 测试环境设计 (31)6.1.1 软件环境 (31)6.1.2 硬件环境 (32)6.2 测试用例设计 (32)6.3 测试结果分析 (33)6.3.1 多媒体播放器的主题界面 (33)6.3.2 多媒体播放器测试结果记录 (34)6.4 测试结论 (35)结束语 (35)致谢...................................................................................................... 错误!未定义书签。
VS2010 C 学习(5):基于DirectShow视频预览录像程序
VS2010 C++学习(5):基于DirectShow的视频预览录像程序学习VC++编制的基于DirectShow视频捕获程序,主要练习基于DirectShow程序的应用。
一、主要内容:1.基于DirectShow视频预览;2.基于DirectShow视频录像;二、设计实现:(一)、安装DirectShow首先我们安装DirectShow SDK,由于现在directShow没有和direcxtx一起发布,而是和windows sdk 打包发布了,可以到官网下载最新的windows sdk 开发包。
一个可用的下载地址为/07/hh/DXSDK_Feb10.rar 然后安装好windows SDK。
安装完DirectShow SDK的目录为C:\Program Files\Microsoft SDKs\Windows\v7.1\Samples\multimedia\directshow。
(二)、开发环境配置开发环境的配置主要有两个工作要做:一是在使用Directshow SDK开发自己的程序时需要的DirectShow的有关静态库的配置,二是visual C++开发环境的配置。
1)生成DirectShow SDK开发库使用DirectShow SDK开发用户自己的程序需要几个静态链接库:quartz.lib、strmbasd.lib、STRMBASE.lib和strmiids.lib。
中间两个lib需要用户自己编译生成,而其他两个微软已经提供。
下表列出了使用DirectShow SDK开发程序所有要使用的库。
2)更改添加的include内容:C:\Program Files\MicrosoftSDKs\Windows\v7.1\Samples\multimedia\directshow\baseclasses;C:\Program Files\Microsoft SDKs\Windows\v7.1\Include;添加过程如下。
基于directshow的视频播放器设计与实现
基于directshow的视频播放器设计与实现作者:伍开胜罗宇刘斌来源:《科技视界》 2015年第31期伍开胜罗宇刘斌(西华师范大学计算机学院,四川南充 637000)【摘要】设计并实现了一款基于Directshow的视频播放器,在资源占用上较占优势。
给出了Directshow利用Filter和Filter Graph播放视频的步骤。
之后给出了媒体播放器的基本模块,最后给出了播放器几个功能的具体实现并对比同类软件进行了性能测试。
【关键词】Directshow;Filter;FilterGraph0 引言随着信息技术的发展,多媒体播放器迎来新的挑战。
在多媒体应用技术中,对多媒体大量的数据传输、高效的数据处理、音视频流的同步、媒体流的格式转换,一直是需要解决的主要问题,怎样使流媒体的处理变得简单而富有成效逐渐成为了焦点问题。
而选择一种合适的应用方案,将事半功倍。
本文以微软的Visual C++作为开发工具,以Directshow为框架设计一个能播放RMVB,MP4,AVI等常见格式的播放器。
1 DirectShow概述在DirectShow中,一个应用程序必须实例化一个或者多个过滤器,并将它们连接起来.所有这些过滤器和它们之间的连接被称为过滤器图表(FilterGraph)。
应用程序通过过滤器图表管理器(Filter Graph Manager)来创建相应的Filter Graph.其中,Filter Graph Manager也是个COM组件,它为应用程序提供了建立Filter Graph的各种方法,控制着FilterGraph的运行。
2 Filter和Filter GraphDirectShow是基于模块化,每个功能模块都采取COM组件方式,称为过滤器(Filter)。
Directshow提供了一部分标准的过滤器可直接使用,开发者也可开发自己的功能Filter来扩展Directshow的应用。
下面用一个简单的小例子来说明如何使用Filter来播放一个格式为AVI的视频文件。
Visual C++编程实现摄像头视频捕捉
Visual C++编程实现摄像头视频捕捉摘要:本文主要讲述用Directshow进行视频捕捉(捕捉静态图像)的编程思路,并提供针对摄像头编程的一个视频捕捉类CcaptureVideo和一个示例。
前言DirectShow是微软公司提供的一套在Windows平台上进行流媒体处理的开发包,与DirectX开发包一起发布。
DirectShow为多媒体流的捕捉和回放提供了强有力的支持。
用DirectShow开发应用程序,我们可以很方便地从支持WDM 驱动模型的采集卡上捕获数据,并且进行相应的后期处理乃至存储到文件中。
DirectShow是基于COM的,为了编写DirectShow应用程序,需要了解COM客户程序编写的基础知识。
DirectShow提供了大量的接口,但在编程中发现还是不够方便,如果能构建一个视频捕捉类把常用的一些动作封装起来,那么就更方便了。
编程思路为了更加容易建立视频捕捉应用程序,DirectShow提供了一个叫做Capture Graph Builder的对象,Capture Graph Builder提供IcaptureGraphBuilder2接口,该接口可以建立和控制Capture Graph。
建立视频捕捉程序,必须首先获取并初始化IcaptureGraphBuilder2接口,然后选择一个适当的视频捕捉设备。
选择好设备后,为该设备创建Capture filter,然后调用AddFilter把Capture filter添加到Filter Graph。
如果仅仅希望用摄像头来进行实时监控的话,只需要在上面的基础上调用ICaptureGraphBuilder2::RenderStream就可以了:DirectShow提供了一个捕捉静态图像的方法:使用Sample Grabber filter。
依次按照以下三个步骤就可以了:第一步, 定义一个类实现Sample Grabber的回调接口IsampleGrabberCB:第二步、调用RenderStream依次把Still pin、Sample Grabber和系统默认Renderer Filter连接起来。
基于DirectShow的视频播放程序的开发
基于DirectShow的视频播放程序的开发
高勇;阙大顺
【期刊名称】《交通信息与安全》
【年(卷),期】2003(021)006
【摘要】采用VC、VB等可视化编程工具,开发一个具有视频播放功能的程序也要花费程序员的大量时间.DirectShow是微软Windows平台SDK中DirectX的重要组成部分,它基于COM技术.用它来开发视频播放软件,具有快捷、代码量少和程序稳健的特点.本文介绍用DirectShow开发视频播放软件的基本步骤,和它所附带的重要工具GraphEdit,并以实例加以说明.
【总页数】4页(P87-90)
【作者】高勇;阙大顺
【作者单位】武汉理工大学,武汉,430063;武汉理工大学,武汉,430063
【正文语种】中文
【中图分类】TN94
【相关文献】
1.基于DirectShow实现多路视频播放控制 [J], 许众威;钱小红
2.利用VC++实现基于DirectShow的视频播放器开发 [J], 赵炯;陈力
3.基于DirectShow的视频播放器设计 [J], 张胜芳
4.基于DirectShow的视频播放器设计 [J], 张胜芳
5.基于directshow的视频播放器设计与实现 [J], 伍开胜;罗宇;刘斌
因版权原因,仅展示原文概要,查看原文内容请购买。
VC实现DirectShow全屏播放视频
VC实现DirectShow全屏播放视频C/C++转载 2010-05-23 23:13:01 阅读27 评论0 字号:大中小订阅有些正在尝试自己编制游戏的朋友可能会碰到这样一个问题:游戏要播放片头动画,可是如何全屏播放动画呢?用媒体播放机控件?这是最简单的方法,可是好多功能都用不上,不免觉得有些浪费。
而用vfw之类的多媒体库又太麻烦。
怎么办呢?其实微软不但提供了DirectX这样的便于游戏开发的SDK,还提供了基于其上的DirectX Media SDK。
这套SDK可以帮助你简化多媒体开发,而又充分利用DirectX的高性能。
使用起来很简单,功能也很强大,它可以自己识别流的格式,连 mpeg2都不放过!下面我以实例来说明如何调用DirectShow来全屏播放视频:首先,需要在工程中包含如下头文件:这些头文件提供了必要的数据结构和方法声明。
其次,我们可以将程序的整个流程分为3个步骤:1、建立DirectDraw表面(Surface)。
2、从文件中提取视频流(可能还有音频)。
3、在DirectDraw上表面播放视频流。
必要的变量:IMultiMediaStream接口是DirectShow中最高等级的接口对象,可以包含一个或多个多媒体对象。
这些多媒体对象可以是不同类型的,比如音频,视频等等。
下面大家将会看到。
在初始化方法中加入如下代码:HRESULT Init(){......pDD=NULL;pPrimarySurface=NULL;pMMStream=NULL;ZeroMemmory(ddsd,sizeof(ddsd));HRESULT r;//初始化COMCoInitialize(NULL);//初始化DirectDrawr=InitDDraw();return r;}由于DirectShow是基于COM的所以要用CoInitialize初始化COM,该方法很简单,只有一个参数且必须是NULL。
基于VS2010的c#实现摄像 录像 抓拍(代码)
using System;using System.Collections.Generic;using ponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using System.Threading;using System.Runtime.InteropServices; //DllImport所在的名字空间namespace WindowsFormsApplication1{public partial class Form1 : Form{public Form1(){InitializeComponent();}public class VideoAPI{[DllImport("avicap32.dll")]public static extern IntPtr capCreateCaptureWindowA(byte[] lpszWindowName, int dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, int nID);[DllImport("avicap32.dll")]public static extern bool capGetDriverDescriptionA(short wDriver, byte[] lpszName, int cbName, byte[] lpszVer, int cbVer);[DllImport("User32.dll")]public static extern bool SendMessage(IntPtr hWnd, int wMsg, bool wParam, int lParam);[DllImport("User32.dll")]public static extern bool SendMessage(IntPtr hWnd, int wMsg, short wParam, int lParam);//[DllImport("Kernel32.dll")]// public static extern bool CloseHandle(HANDLE hObject);// public static extern IntPtr CloseHandle(IntPtr hObject);[DllImport("kernel32", EntryPoint = "CloseHandle")]public static extern IntPtr CloseHandle(IntPtr hObject);public const int WM_USER = 0x400;public const int WS_CHILD = 0x40000000;public const int WS_VISIBLE = 0x10000000;public const int SWP_NOMOVE = 0x2;public const int SWP_NOZORDER = 0x4;public const int WM_CAP_DRIVER_CONNECT = WM_USER + 10;public const int WM_CAP_DRIVER_DISCONNECT = WM_USER + 11;public const int WM_CAP_SET_CALLBACK_FRAME = WM_USER + 5;public const int WM_CAP_SET_PREVIEW = WM_USER + 50;public const int WM_CAP_SET_PREVIEWRATE = WM_USER + 52;public const int WM_CAP_SET_VIDEOFORMAT = WM_USER + 45;public const int WM_CAP_START = WM_USER;public const int WM_CAP_SAVEDIB = WM_CAP_START + 25;public const int WM_CAP_SEQUENCE = WM_CAP_START + 62;public const int WM_CAP_STOP = WM_CAP_START + 68;public const int WM_CAP_FILE_SET_CAPTURE_FILEA = WM_CAP_START + 20;}public class cVideo{private IntPtr lwndC;private IntPtr mControlPtr;private int mWidth;private int mHeight;public cVideo(IntPtr handle, int width, int height){mControlPtr = handle;mWidth = width;mHeight = height;}public void StartWebCam() //链接摄像头{byte[] lpszName = new byte[100];byte[] lpszVer = new byte[100];VideoAPI.capGetDriverDescriptionA(0, lpszName, 100, lpszVer, 100);this.lwndC = VideoAPI.capCreateCaptureWindowA(lpszName, VideoAPI.WS_CHILD | VideoAPI.WS_VISIBLE, 0, 0, mWidth, mHeight, mControlPtr, 0);if (VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_DRIVER_CONNECT, 0, 0)){VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_SET_PREVIEWRATE, 100, 0);VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_SET_PREVIEW, true, 0);}}public void CloseWebcam() //断开摄像头{VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_DRIVER_DISCONNECT, 0, 0);VideoAPI.CloseHandle(lwndC); //关闭进程}public void StarKinescope(string path) //开始录像{IntPtr hBmp = Marshal.StringToHGlobalAnsi(path);VideoAPI.SendMessage(lwndC,VideoAPI.WM_CAP_FILE_SET_CAPTURE_FILEA, 0, hBmp.ToInt32());VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_SEQUENCE, 0, 0);}public void StopKinescope() //停止录像{Application.DoEvents();VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_STOP, 0, 0);}public void GrabImage(IntPtr hWndC, string path) //抓拍{IntPtr hBmp = Marshal.StringToHGlobalAnsi(path);VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_SAVEDIB, 0, hBmp.ToInt32());}}cVideo video = null;private void button1_Click_1(object sender, EventArgs e){button1.Enabled = false;button2.Enabled = true;button3.Enabled = true;video = new cVideo(pictureBox1.Handle, pictureBox1.Width, pictureBox1.Height);//video.CloseWebcam();//thread IsBackground = true;video.StartWebCam();this.MaximizeBox = true;}private void button2_Click_1(object sender, EventArgs e){button1.Enabled = false;button3.Enabled = true;video.StarKinescope(@"d:\" + DateTime.Today.Month.ToString() + DateTime.Today.Day.ToString() + DateTime.Now.Hour.ToString() + DateTime.Now.Minute.ToString() + DateTime.Now.Second.ToString() + ".avi");//video.StarKinescope(@"d:\lx1.avi");}private void button4_Click_1(object sender, EventArgs e){Application.Exit();}private void button3_Click_1(object sender, EventArgs e){button2.Enabled = true;button3.Enabled = false;video.StopKinescope();}private void Form1_Load(object sender, EventArgs e){button1.Enabled = true;button2.Enabled = false;button3.Enabled = false;button4.Enabled = true;}private void button5_Click(object sender, EventArgs e){button1.Enabled = true;button2.Enabled = false;button3.Enabled = false;button4.Enabled = true;video.CloseWebcam();}}}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
VS2010C++学习(5):基于DirectShow的视频预览录像程序学习VC++编制的基于DirectShow视频捕获程序,主要练习基于DirectShow程序的应用。
一、主要内容:1.基于DirectShow视频预览;2.基于DirectShow视频录像;二、设计实现:(一)、安装DirectShow首先我们安装DirectShow SDK,由于现在directShow没有和direcxtx一起发布,而是和windows sdk打包发布了,可以到官网下载最新的windows sdk开发包。
一个可用的下载地址为/07/hh/DXSDK_Feb10.rar 然后安装好windows SDK。
安装完DirectShow SDK的目录为C:\Program Files\Microsoft SDKs\Windows\v7.1\Samples\multimedia\directshow。
(二)、开发环境配置开发环境的配置主要有两个工作要做:一是在使用Directshow SDK开发自己的程序时需要的DirectShow的有关静态库的配置,二是visual C++开发环境的配置。
1)生成DirectShow SDK开发库使用DirectShow SDK开发用户自己的程序需要几个静态链接库:quartz.lib、strmbasd.lib、STRMBASE.lib和strmiids.lib。
中间两个lib需要用户自己编译生成,而其他两个微软已经提供。
下表列出了使用DirectShow SDK开发程序所有要使用的库。
2)更改添加的include内容:C:\Program Files\MicrosoftSDKs\Windows\v7.1\Samples\multimedia\directshow\baseclasses;C:\Program Files\Microsoft SDKs\Windows\v7.1\Include;添加过程如下。
选择“Ex005属性”→“选项”→“VC++目录”→“包含目录”,将上面的2个Include内容添加进去。
3)更改添加lib路径要添加的lib内容:C:\Program Files\MicrosoftSDKs\Windows\v7.1\Samples\multimedia\directshow\baseclasses\Debug;C:\Program Files\Microsoft SDKs\Windows\v7.1\Lib;添加过程和Include内容相似,选择“Ex005属性”→“选项”→“VC++目录”→“库文件”选项。
4)添加链接库支持C:\Program Files\MicrosoftSDKs\Windows\v7.1\Samples\multimedia\directshow\baseclasses\Debug;C:\Program Files\Microsoft SDKs\Windows\v7.1\Lib;5)小贴士DirectShow中的例子,在编译的过程中经常会出现这样的错误:Error1error C2061:syntax error:identifier'CAMSchedule'c:/program files/microsoftsdks/windows/v6.0/samples/multimedia/directshow/baseclasses/refclock.h80这主要是因为在不同SDK的目录里包含了多个schedule.h file和refclock.h因此需要在“Ex005属性”→“选项”→“VC++目录”→“包含目录”中调整include的顺序,将samples/multimedia/directshow/baseclasses放到其他的sdk之前即可(三)、DirectShow视频采集方案流媒体处理技术以其复杂性和技术性一直受到人们的关注。
随着网络技术的不断发展,流媒体在网络上得到了广泛地应用。
如何能够简单、有效地进行流媒体处理,已成为一个焦点问题。
为此,Microsoft推出了DirectShow,DirectShow 是Microsoft推出的基于Windows平台的流媒体处理开发包,它与DirectX一起发布。
DirectShow对流媒体的捕捉、回放提供了强大的支持。
1)DirectShow系统结构分析DirectShow主要由过滤器(Filter Graph)图表构成。
过滤图表中包含了各种Filter,这些Filter能够按一定顺序连接在一起,构成一条流水线。
从功能的角度划分,Filter大体可以分为3类,●Source Filters;主要负责获取数据,可以是一个文件、一个采集卡、声卡或数码相机等。
●Transform Filters;负责数据的转换、传输。
例如各种码器、解码器等。
●Rendering Filters。
负责数据的最终去向,例如将数据传送到声卡、显卡或存储为文件。
在开发DirectShow应用程序时,通常需要设计一个过滤图表(Filter Graph),向过滤图表中添加相应的过滤器,最后连接过滤器的引脚就完成了功能的设计。
例如,实现一个简单的视频预览功能,需要向过滤图表中添加一个视频捕捉源过滤器和一个Video Renderer过滤器,将视频捕捉源过滤器的输出引脚与Video Renderer过滤器的输入引脚相连就可以了。
而在程序中只需要按照设计过滤图表的捕捉添加过滤器并连接过滤器引脚就可以了。
在连接过滤器引脚时需要注意:只能是输出过滤器引脚与输入过滤器引脚相连,两个输出过滤器或两个输入过滤器引脚是不能相连的。
2)Filter图表设计为了方便用户设计过滤图表,DirectX提供了一个Graph Edit工具。
位于C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\graphedt.exe。
点击运行。
演示如何使用Graph Edit工具设计过滤图表,过滤图表的功能是实现视频的预览功能。
具体步骤如下:(1)单击“Graph/Insert Filters”菜单项打开“添加过滤器”窗口,选择一个视频捕捉源过滤器。
选择“Video Renderer”最终去向过滤器,连接,如图1。
图2宽屏haali视频分离器单击工具栏中的“>”按钮运行过滤图表,将显示一个视频预览窗口。
3)枚举系统设备使用Graph Edit工具,用户可以非常方便地获得与某一系统设备相关的过滤器。
但是,在程序中该如何获得这些过滤器呢?用户可以采用枚举的方式列举系统中安装的设备。
以列举系统中的视频捕捉设备为例,(1)首先定义一个设备列举接口ICreateDevEnum的一个指针;(2)调用CoCreateInstance方法创建ICreateDevEnum实例。
(3)然后定义一个列举监视器IEnumMoniker的一个指针;(4)调用ICreateDevEnum实例的CreateClassEnumerator方法创建IEnumMoniker实例。
(5)最后以循环的方式调用IEnumMoniker实例的Next方法遍历系统设备;(6)调用IEnumMoniker实例的BindToObject方法将系统设备绑定到过滤器上。
在上面的描述中,ICreateDevEnum实例的CreateClassEnumerator方法的第一个参数确定枚举的系统设备。
例如,第一个参数为CLSID_VideoInputDeviceCategory,表示将要枚举系统中的视频捕捉卡,为CLSID_VideoCompressorCategory,表示枚举系统中的视频压缩器。
下面的代码演示了如何枚举系统中的视频捕捉卡。
//枚举视频设备;值=CLSID_VideoInputDeviceCategory//音频设备的值=CLSID_AudioInputDeviceCategory;ICreateDevEnum*pDevEnum=NULL;CoCreateInstance(CLSID_SystemDeviceEnum,NULL,CLSCTX_INPROC,IID_ICreateDevEnum,(void**)&pDevEnum);IEnumMoniker*pClassEnum=NULL;pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pClassEnum,0);ULONG cFetched;while(pClassEnum->Next(1,&pMoniker,&cFetched)==S_OK){pMoniker->BindToObject(0,0,IID_IBaseFilter,(void**)&pSrc);pMoniker->Release();break;}pClassEnum->Release();而下面的代码则用于判断系统中是否安装了指定的视频压缩器。
ICreateDevEnum*pDevEnum=NULL;CoCreateInstance(CLSID_SystemDeviceEnum,NULL,CLSCTX_INPROC,IID_ICreateDevEnum,(void**)&pDevEnum);IEnumMoniker*pClassEnum=NULL;//列举视频压缩设备;值=CLSID_VideoCompressorCategorypDevEnum->CreateClassEnumerator(CLSID_VideoCompressorCategory,&pClassEnum,0);while(pClassEnum->Next(1,&pMoniker,&cFetched)==S_OK){IPropertyBag*pProp=NULL;pMoniker->BindToStorage(0,0,IID_IPropertyBag,(void**)&pProp);VARIANT varName;varName.vt=VT_BSTR;pProp->Read(L"FriendlyName",&varName,0);CString str=varName.bstrVal;if(str.Find("Microsoft Video1",0)!=-1){pMoniker->BindToObject(0,0,IID_IBaseFilter,(void**)&pCompress);pMoniker->Release();break;}VariantClear(&varName);}pClassEnum->Release();4)查找Filter Pin过滤器引脚每一个过滤器(Filter)至少应有一个引脚(Pin),或者是输入引脚或者是输出引脚。