directshow 为什么1394视频采集卡卡都是320*240

您现在的位置:&&>>&&>>&正文
专业高清音视频采集卡主流驱动模式:WDM驱动
作者:九视视频网 来源:www.xiangb.com 发表时间:
九视电子专业音视频采集卡支持标准的Directshow进行开发,除了采用标准的WDM驱动,支持标准的Directshow进行开发的T200AE高清外,还有微软AVStream标准驱动开发的T620E 高清两路DVI/VGA/HDMI音视频采集卡
  现在专业音视频开发中视频采集卡涉及在Windows的不同版本上开发的驱动程序,主流是支持Windows DirectShow Interface由VFW和WDM驱动的采集卡; 不过在大陆,由厂商自己开发的驱动程序来驱动的采集卡,也是比较常见的,九视目前推出的专业级高清音视频,其采用的大多是WDM驱动(必须要满足提供n种被要求的特性(如电源管理、即插即用)才被称为WDM驱动。),并且自带的驱动程序支持DirectShow Interface,这样只要支持DirectShow 标准的软件就能直接进行应用;并且专业级视频采集卡都提供自己的二次开发SDK,如果要做二次开发,都可以直接使用专用接口函数,这样在应用上是非常方便的。
  WDM简介: Win32 Driver Model Win32驱动程序模型
  WDM(Win32 Driver Model),即Win32驱动程序模型,是Microsoft力推的全新驱动程序模式,旨在通过提供一种灵活的方式来简化驱动程序的开发,在实现对新硬件支持的基础上减少并降低所必须开发的驱动程序的数量和复杂性。
  除了通用的平台服务和扩展外,WDM还实现了一个模块化的、分层次类型的微型驱动程序结构。类型驱动程序实现了支持通用总线、协议或设备类所需的功能性接口。类型驱动程序的一般特性是为逻辑设备的命令设置、协议和代码重用所需的总线接口实现标准化提供必要的条件。
  WDM将成为21世纪主流的驱动模式
  WDM对标准类接口的支持减少了Windows 95和Windows NT所需的设备驱动程序的数量和复杂性。Windows 2000也引入了WDM驱动程序构架。虽然WDM目前实际应用还不多,但是相信在不久的将来,在Windows平台上,WDM将成为21世纪主流的驱动模式。
  WDM特性:动态构造WDM驱动程序堆栈是实现即插即用设备支持的关键
  模块化的WDM体系结构中灵活统一的接口,使操作系统可以动态地配置不同的驱动程序模块来支持特定的设备。一个典型的驱动程序堆栈由通用设备、协议及特定协议和特定总线的微型驱动程序联接的总线类驱动程序构成。动态构造WDM驱动程序堆栈是实现即插即用设备支持的关键。
  WDM 流媒体应用程序
  对于流媒体应用程序,WDM在核心态提供了快速反应的接口来处理I/O流。WDM的流接口是通过标准的WDM类接口提供出的。
  WDM支持USB、IEEE 1394、ACPI等全新的硬件标准
  WDM支持USB、IEEE 1394、ACPI等全新的硬件标准。而且以往在两个平台上同时运行时需要编写两个截然不同的驱动程序,现在只需要编写一个WDM驱动程序就可以了。
  九视将致力于为高清的开拓和耕耘,九视专业音视频采集卡支持标准的Directshow进行开发,除了采用标准的WDM驱动,支持标准的Directshow进行开发的T200AE高清外,还有微软AVStream标准驱动开发的<FONT color=#ffE 高清两路DVI/VGA/HDMI音视频采集卡,兼容使用DirectShow接口的各种音视频采集软件和使用DirectSound接口的音频采集软件。
  总体来说,九视系列视频采集卡其功能是非常全面的,兼容性是非常广泛的。像九视T200AE高清VGA采集卡、、、等都是提供自己的SDK,供二次开发用。如果您需要了解更多详情的知识,都可以随时咨询我们在线技术客服,或者来电进行垂询,咨询热线:010--高清采集卡_百度百科
清除历史记录关闭
声明:百科词条人人可编辑,词条创建和修改均免费,绝不存在官方及代理商付费代编,请勿上当受骗。
高清采集卡
高清是一种标准。英文为“High Definition”,意思是“高分辨率”。我们常说的的高清,有四个含义:高清电视,高清设备,高清格式,高清电影等。
高清采集卡简介
高清是一种标准。英文为“High Definition”,意思是“高分辨率”。我们常说的的高清,有四个含义:高清电视,高清设备,高清格式,高清电影等。高清采集卡分辨率达到1080P(分辨率),就能称为高清了。
是一种高清晰电视信号格式,“1080”表示垂直方向有1080条水平扫描线,“i”表示采用交错式扫描视频显示方式(interlaced scan)。1080i先扫描单数的垂直画面,再扫描双数的垂直画面,故只需要1080P一半的带宽,但是碰到高速移动的物体时,物体周围就有晃动现象。早期的高清析度电视都是这种规格。
高清采1080P是一种视频显示格式,是美国电影电视工程师协会(SMPTE)制定的最高等级高清数字电视的格式标准,是数字电影成像技术和计算机技术的完美融合。其格式由于高清视频数据传输量巨大,所以需要有新的压缩算法。高清视频格式,主要有:H.264、WMA-HD、MPEG2-TS、MPEG4和VC-1等。其中,H.264格式目前最为流行。所以,再购买高清采集卡或者显卡的时候,一定搞清楚,设备是否支持H.264。比如T300E两路VGA采集卡不支持高清显示,T200AE高清采集卡支持高清显示。
高清视频是从1080i到720p再到1080p ,分辨率为p/60Hz,行频为45kHz 。1080p转换为720p的图像则更加简单,只需要在每三个像素行中去掉一行,每三个像素列中去掉一列,1080p的三分之二正好是720p。
高清采集卡高清采集卡标准
高清采集卡具有高稳定性、多功能、兼容性广等特点。是专为视频会议、远程监控、网络教学、视频直播、大屏幕显示、医疗系统、军事雷达等高清流媒体领域推出的高清视频采集卡。采用高清接口——HDMI、分量等实时采集各种相应的视频信号源,支持480p、720p, 1080i、和1080p等高清分辨率,兼容各种视频操作编辑件,使整个多媒体系统画质高、成本低、功耗低、性能稳定、功能全面等优势。
高清采集卡工作原理
高清采集卡工作原理是由模拟信号经过A/D采样后转换为数字信号,通过FPGA写入SDRAM作为缓存,再经FPGA从SDRAM中将采集压缩的数据读出通过PCI总线传输到上位机,由上位机对数据进行传输等处理。信号实时进行采集支持声音的同步录制,显示画面可以任意拉伸或全屏,录制后格式为avi,保证适应各类播放器播放,录制后期可以进行非线编,删除或添加相关内容,显示画面颜色和清晰度可调,录制帧率和码率可调。
经过高速PCI总线能够直接采集图象到显存或主机系统内存,此外不仅可以使图象直接采集到,实现单屏工作方式,而且可以利用PC机内存的可扩展性,实现所需数量的序列图象逐帧连续采集,进行序列图象处理分析。如果将一台PC机数据在另一台PC上显示以及采集信号,传统的方法是将信号通过视频转换器变成视频信号,再通过视频采集卡在另一台PC机上显示采集。视频采集就是将视频源的模拟信号通过处理转变成数字信号(即0和1),并将这些数字信息存储在电脑硬盘上的过程。这种模拟/数字转变是通过视频采集卡上的采集芯片进行的。首先PC机发一个开始采集命令并等中断,然后采集卡会探测场同步开始,然后启动采集一张图片(根据行场消隐及大小),采集结束后通过PCI中断通知pc机,而PC机收到些中断后,马上启动DMA读取采集卡的数据(只需要准备好内存地址和所读大小即可),读取完毕即完成一次采集。由视频采集芯片将模拟信号转换成数字信号,然后传至板卡自带的临时存储器中,再由卡上自带视频压缩芯片执行压缩算法,将庞大的视频信号压缩变小,最后这些压缩后的直接或通过PCI桥芯片进入PCI,存储到硬盘。
高清采集卡高清采集
电视信号传输中传输视频信号的一种接口类型,把视频信号的亮度信息和色彩信息分开来,这样视频信号包括了分开传输的一路亮度信号和两路色差信号,因而避免了信号之间的串扰,与复合电视信号(亮度信号与色彩信号复合传输)和S端子相比有更高的图像质量。分量接口的颜色是红、绿、蓝!分量接口也可以叫做色差口。
高清采集卡高清VGA接口
对于采集VGA信号,传统的方式有两种:
(1) 将VGA转换为视频进行处理,但这样会大幅度降低画面质vga量; (2) 或是采取软件抓屏的方式对电脑画面进行采集,但这样必须安装特定软件才实现,影响性能且只能安装于PC系统,对于雷达或是专用设备无能为力。
VGA高清采集卡能直接采集VGA信号,可以把输入的VGA视频信号实时采集压缩,并能立即在一台显示 器上同时显示另外一台甚至多台设备的VGA数据,不用增加额外的设备。不同于PCI采集卡,不用担心CPU消耗过度问题,不用担心音视频信号不同步,不必担心信号采集效果、速度、质量,也不用担心起信号采集卡的兼容性、扩展性,最新的广播级视频采集卡,PCI-E视频采集卡—T200AE 高清VGA采集卡,单卡实现同时采集1路VGA信号,2路视频信号,1路音频信号,音视频信号的同步,实时采集。支持所有视频采集、编辑、直播软件,兼容成熟电脑硬件。T200AE 音视频高清VGA采集卡可以直接兼容及替换流行的采集卡,同三维最新高清VGA采集卡中的T200AE 高清VGA采集卡使用了最先进的VGA图像采集压缩模块。可采集高速的RGB图像信号,并利用高效的JPEG数字图像压缩技术,实现对不同分辨率、不同刷新率图像的压缩。所采集图像质量完全忠实于源信号,实时采集效果具有高分辨率、高清晰度、高保真的特点。
T200AE 高清VGA采集卡,根据专业用户需求改进的一个全新PCI-E VGA视频录播采集卡,可支持一机多卡,卡上不但提供一路VGA信号,在具有两路视频信号输入同时,加入了一路音频输入,支持所有视频采集、编辑、直播软件。支持标准的DIRECT SHOW API进行开发,无需二次开发;根据不同客户的需求,亦可提供二次开发SDK。同时可以任意组合输入信号,录播软件可支持任意6路信号输入,需要增加可以定制开发。
高清采集卡高清DVI接口
T100E高清DVI采集卡是非常成熟的一款专业级DVI数字信号采集卡,其可以采集1080P高清DVI信号,采用了PCI-E高速传输接口,通过DVI数字接口传输,可以得到无损的全分辨率高清无压缩视频采集。该款DVI视频采集卡集合了众多优点于一身,高清采集卡上不但提供一路DVI数字信号采集,还提供带有VGA视频信号输入(采集中只能选择一路)。支持一机多卡,可和其它流媒体采集卡配合使用,并兼容各种Directshow标准开发的视频软件,可以在微软Amcap、Media Encoder,Real公司Real Producer等各种常用使用软件下使用。支持Windows 2000/ XP/2003/Vista等操作系统。免费提供DSHOW驱动和SDK开发包,方便用户较快地集成到现有的系统中。可广泛应用于录播产品、医疗图像处理、雷达信号数据采集、多屏显示等各个领域。
高清采集卡高清HDMI接口
HDMI,高清晰度多媒体接口(英文:High Definition Multimedia Interface)是一种全数位化影像和声音传送接口,
可以传送无压缩的音频信号及视频信号。HDMI接口芯片功耗的大大降低,在与HDTV相连接时,显著延长HD视频的播放时间。
HDMI可用于机顶盒、DVD播放机、个人电脑、电视游乐器、综合扩大机、数位音响与电视机。HDMI可以同时传送音频和影音信号,由于音频和视频信号采用同一条电缆,大大简化了系统的安装。
分量色差接口:
分量接口的颜色是红、绿、蓝! 分量接口也可以叫做色差口 HDMI、分量采集卡是现在视频行业中技术最先进的一款综合采集卡。
1080i高清HDMI采集卡
高性能高清视频采集编辑卡 影音工场高性能高清视频采集编辑卡,内置HDMI、色差、AV、SV等输入接口,最高支持1080i(隔行扫描)全高清输入早期的高清析度电视都是这种规格。支持市面上大部份TV游戏设备的各种格式输入、支持各种高清摄像机的实现采集。
HDMI版本:
HDMI自推出以来,已经从1.0版本、1.1版本、1.2版本、1.2a版本发展到1.3版。与以前的版本相比,HDMI 1.3版拥有更大的带宽,由原先的4.96Gbps倍增至10.2Gbps,能够传输更高流量的高清节目;HDMI 1.3版支持的色数也更高,HDMI 1.1及1.2版仅能支持到24bit色深,1.3版HDMI接口则是大幅扩充至30-bit、36-bit以及48-bit(RGB或YCbCr);HDMI 1.3版还加入了对多轨高流量的无压缩音源或非失真压缩音源(如Dolby TrueHD和DTS-HD Master Audio)的支持。也就是说,如果接口和线材都是HDMI 1.3版的,那么就可以传输更高码率、更高色数、拥有更好音质的高清影视节目。
产品描述:
高性能高清视频采集编辑卡,内置HDMI、色差、AV、SV等输入接口,最高支持1080i(隔行扫描)全高清输入。达到极佳高清视频采集效果,满足各种录播、会议视频传输、高清视频监控等的需求,并可用于婚庆,教育,企业,中小电视台等专业高质量的视频采集编辑。
多种数字图像和数字降噪技术;
视频输入可使用PAL、NTSC制式;
色度引擎自动增强功能;
自动检测输入信号的格式和模式;
自适应静态检测和抖动检测;
全功能遥控操作,OSD显示,非常方便;
强大的反锯齿显示优化和平滑处理技术,能创造出高清晰度影像效果;
具有运动自适应隔行处理、数字缩放和行场频变化功能;
支持输入格式:480i、480p、576i、576p、720p、1080i
系统需求:
n CPU: Intel core2 2.4GHz or faster
n Memory: 1G Mb or above
n With PCI-E interface
n PCI sound card or main board built-in sound card
n Operation System: WINDOWS XP SP2, WINDOWS 2003, VISTA
产品应用:
丰富的高清到高品质模拟输入接口
l提供HDMI、1080i模拟分量、S-Video及复合视频输入接口采集
lPCI- E 1X通道
l支持格式: p/24 p /25 p /30 p /50i/59.94i/60i、720 50p/59.94p/60p,NTSC/PAL、S-Video
真正10Bit和8Bit实时全分辨率高清无压缩音视频录制
可以确保从高清素材输出生成的高清节目完全保留了原始的图像质量。让CPU从视频解压缩的工作中解脱出来,采集视频的渲染的速度也更快了
支持标准微软DirectShow架构及支持流媒体采集
(如Adobe Flash Media Live Encoder,微软Media Encoder,AMCap 等视频软件)
更多色彩空间
lHDMI的色位更深,色深越大,就能表现越多数量的不同颜色,从而可以表现更为细腻的色彩渐变效果,采样率达到4:2:2, 其色彩分辨率是基于Firewire(火线)的DV和HDV等视频标准的两倍,因此您的视频会更加清晰逼真。
l色彩精度支持: YUV 4:2:2 10 bit
l色彩空间支持: YUV 4:2:2
支持一机多卡视频采集切换
特别适用与特技展台等多角度视频采集
视、音频精确同步
对每一帧精确采集的严格要求,让您可以享受到真正的数字视频、音频采集,实现完美视、音频同步
高清采集卡功能特性
1、高清采集卡性能:Hz,RGB24:4x85Hz,RGB24:x85Hz, RGB24: 80fps
2 、 高清高精度HDMI图像采集卡支持“一机多卡”工作方式,可实现多通道实时采集,可以随音切换画面。
3、高清高精度信号采集卡接口方面,开放参数配置窗口,方便用户对图像的亮度、对比度、压缩比、帧率及图像位置进行调整,满足客户对图像质量的各种需求,亮度、对比度、色度、饱和度以及画面 大小比例,均可调节(a/d之前);
4、适合于进行专业的音视频、图像分析采集卡提供win2000/xp系统下的开发库,支持vc、vb、delphi等开发环镜,全力提供源自专业厂家的技术支援服务。底层程序稳定,功能丰富、开发简便、便于程序移植。件兼容性能好,工作稳定可靠。可在兼容机、原装机/工控机上良好地稳定工作。
高清采集卡应用范围
高清采集卡适合于进行专业的高清音视频、图像分析、处理工作,可广泛应用于显微成像、医学影像、智能交通、分析测量、生物医学、机器视觉、工业图象分析,以及其它多种高精度图像处理分析领域。
高清采集卡可应用到工业检测、工业测量、智能交通、医学影像、工业监控、仪器仪表、机器视觉、网络直播,录播系统,VOD点播,远程教育培训,安全监视、交通收费、图像采集以及其它多种图像采集处理分析,视讯会议系统中且提供免费的网络和电话技术支持指导和维护。
一、屏幕监控
如果要对某显示器显示的内容监控,——例如工业自动化领域,可以用VGA高清采集卡或采集盒采集这个显示器显示的内容,实时传输给监控者,也可保存下来,供事后查看。
二、屏幕直播
A、直播视频会议的屏幕,给更多的没机会参加视频会议的人观看;
B、利用VGA采集卡或采集盒做屏幕直播,比其它直播方式的画面清晰很多。
C、教学领域,可以用来直播教师计算机的屏幕,实现多媒体教学,或者远程教学。
三、处理特殊视频格式
用高清采集卡或采集盒配合流媒体编码软件,实时采集、编码成流媒体格式,放到流媒体服务器上供大家点播。有些视频文件,文件格式是开发公司自定的,其它公司软件不能直接对其处理,例如教学课件、3D动画文件,等等。些视频文件太大,不适合携带、传输、演示,例如3D动画文件,那么可以用T200AE-VGA采集卡或采集盒配合流媒体编码软件,编码成体积很小的流媒体格式用VGA采集卡或采集盒将其采集成未压缩文件AVI形式,进行编辑。
四、安检X光机、雷达图像信号、VDR纪录仪、医疗X光机、CT机、胃肠机等。
五、VGA相机、VGA摄像机等VGA信号、RGB信号输出设备的图像采集和处理
高清采集卡高清采集卡SDK
软件开发套件(Software Development Kit, 即 SDK),一般来说是透过像Visual Basic 和Visual C++等程序语言作为软件开发的一套工具组。基本上SDK包含了VC的动态链接库(DLL )、VB和Delphi的OCX控件以及更为详细的技术支持文件。开发者可使用SDK来开发DirectShow软件架构的应用程序,提升微软Windows平台上的多媒体影音撷取与播放的质量。
另外,SDK还包括应用程序接口(Application Programming Interface, API),它提供使用接口方便软件开发者呼叫常用程序模块,亦即软件开发者不用写程序代码也能快速且有效率地创造窗体、指令钮和目录选单。
有SDK能提供哪些功能
1. 先进图像优化技术
(1) 进阶去交错功能(2)可调整亮度/ 对比/彩度/饱和度 (不适用于HDMI )(3)降低影像分辨率
2. 支持1080i 高画质影像
3. 可在影片上迭加图片或文字
4. 可在影片上加入时间戳记
5. 连续或反向屏幕采集
高清采集卡流媒体
高清采集卡用的最多的一项功能是流媒体采集.流媒体是指在网络中使用流式传输技术的连续时基媒体,如音频、视频或多媒体文件。而流式传输技术就是把连续的声音和图像信息经过压缩处理后放到网站服务器上,让用户一边下载一边收听观看,而不需要等待整个文件下载到自己的机器后才可以观看的网络传输技术,一般支持directshow框架的高清采集卡就能初步的支持流媒体采集卡。
.百度百科.&#91;引用日期&#93;
.同三维.&#91;引用日期&#93;
清除历史记录关闭天创恒达TC-4000SDI Pro DirectShow 高清采集卡
产品特性:.
4路SDI高清信号同时采集。.
每路输入视频信号可达p@60 Hz。.
可采集SDI中的潜入音频信号。.
微软AVStream标准驱动,可支持大部分Windows上的多媒体视频软件或流媒体软件。高级特性: · 高性能DMA传输功能。 · 自动输入视频格式侦测,自动视频有效区域侦测,自动采集相位调节。 · 手工设定有效画面区域功能,可用于画面的剪裁和对特殊输入信号时序的支持。 · 多阶画面缩放功能,具有三种针对画面宽高比的缩放模式。 · 支持垂直滤波和运动自适应去隔行功能。 · 硬件色彩转换,可输出RGB24,RGB32,YUY2,UYVY,I420色彩格式。 · 支持色彩调节功能,可调节画面的对比度、亮度、色彩饱和度、色相、Gamma;并可单独调节R,G,B三色的亮度、对比度。 · 画面水平、垂直反转功能。 · 一机多卡,各卡同时采集,并具有独立的设置选项。 · 固件可升级。产品规格:请注意: 1. 实际输出帧率受PCI-Express 接口传输带宽限制,可能低于设定值。本文为作者分享,影视工业网鼓励从业者分享原创内容,影视工业网不会对原创文章作任何编辑!如作者有特别标注,请按作者说明转载,如无说明,则转载此文章须经得作者同意,并请附上出处(影视工业网)及本页链接。原文链接 http://107cine.com/stream/63584/
你需要登录才可以回帖
作者:个人VIP会员[北京]
人气:393790
作者的其它文章
扫一扫,即可添加影视工业网为微信好友.
还可添加微信账号:Ilove107cine QQ号
加我们为微信好友
今日热销产品
【京公网安备16号】圆刚 V1A8 视频采集卡
支持两路复合视频输入和一路S-Video输入,支持720x576(PAL)
您当前的位置:
> 圆刚 V1A8 视频采集卡 支持两路复合视频输入和一路S-Video输入,支持720x576(PAL)
圆刚 V1A8 视频采集卡 支持两路复合视频输入和一路S-Video输入,支持720x576(PAL)
发货地址:广东深圳
信息编号:
产品价格:296.00 元/片
商家相关产品:
商家产品分类
“圆刚 V1A8 视频采集卡 支持两路复合视频输入和一路S-Video输入,支持720x576(PAL)”详细信息
产品规格:
产品数量:
5000.00 片
包装说明:
价格说明:
查看人数:
本页链接:
http://info.b2b168.com/s168-.html
V1A8 视频采集卡,现在很多朋友选择C725代替 SDK2000. SDK2500 SDK3000E,
圆刚PCI视频采集卡是一款高品质9位A/D处理PCI图像采集卡。支持两路复合视频输入和一路S-Video输入,支持720x576(PAL)清晰度录像。
圆刚PCI视频采集卡能于所有基于微软DirectShow开发的第三方软件兼容。
圆刚PCI视频采集卡采用高品质PHILIPS 7130芯片,32位真彩色,采样频率更高,使采集图像画质更为清晰、稳定、艳丽且流畅,运动图像软件处理不拉毛、不拉丝、不托影。
圆刚PCI视频采集卡性能价格比高、兼容性好,广泛应用于视频会议、安全监视、交通收费、图像采集以及其它多种图像采集处理分析领域。
【标准输入输出,良好的硬件兼容性】
输入方式:复合视频,S-Video输入,标准PAL、NTSC、SECAM制彩色视频信号输入
输出方式:PCI
芯 片:采用PHILIPS SAA7130HL芯片
硬件完成输入图像的比例缩放(SCALE)、裁剪(CLIP);输入图像的大小、位置可灵活设置
支持计算机内容与采集图像同屏显示的工作方式
【强大的图像处理和采集功能】
支持色调及色彩对比调整,32位真彩色 支持色度空间变换:YUY2(4:2:2), UYVY(4:2:2) ,YVU9(4:1:0),YV12(4:1:1), RGB 24 ,RGB 32等多种图像显示和存储格式
全屏幕采集,图像采集大分辨率:720×576 (PAL) 640×480 (NTSC)另有多种 分辨率可供选择
(如Adobe Flash Media Live Encoder,微软Media Encoder,AMCap 等视频软件)
动态/静态影像截取功能
>> 支持单场、单帧、连续场、连续帧的采集方式
>> 单场、单帧采集:BMP及JPG格式
>> 连续场、连续帧的采集:BMP、JPG、AVI(PAL: 25 fps, NTSC: 30 fps)、Image Buffer格式
音频过滤捕捉 X
系统支持 WinXP, Vista, Win7
文本叠加 O
输入 复合视频
分辨率 NTSC & PAL & SECAM: 160*120 / 176*144 / 240*180 / 240*176 / 320*240 / 352*240 / 352*288 / 640*240 / 640*288 / 640*480 / 704*576 / 720*240 / 720*288 / 720*480 / 720*576
视频捕捉 采集视频到文件:AVI
采集视频到缓冲:AVI
(PAL: 25 fps, NTSC: 30 fps)
Deinterlace O
图像自动比例缩放 O
软件 1.圆刚附赠软件Aver MediaCenter
2.支持标准的DIRECT SHOW API进行开发的第三方软件(MS Media Encoder/GraphEdit/AMCap)
支持多卡使用 O
画面捕捉 采集图像到文件:BMP/JPG
采集图像到缓冲:BMP
Pixel Formats RGB32
Pixel Formats YUY2(4:2:2)
UYVY(4:2:2)
YVU9(4:1:0)
YV12(4:1:1)
亮度/对比/色相/彩色/锐利度调整 O
PAL & NTSC & SECAM
PHILIPS SAA7130HL
Petium III 450 以上
操作系统: Windows XP/Vista Win7
界面: PCI2.1 插槽
声音输入需经声卡
8MB 显存容量的AGP 绘图卡
PCI视频采集卡
欢迎来到深圳市联信宏富科技有限公司网站,我公司位于经济发达,交通发达,人口密集的中国经济中心城市—深圳。 具体地址是深圳市华强北赛格广场,负责人是张先生。
联系电话是3,联系手机是,
主要经营公司在:北京,湖南郑州,山西太原圆刚四川成都等地成立办事处,并且在陕西西安天津四川重庆东北沈阳广东广州河北石家庄山东济南安徽合肥湖北武汉黑龙江哈尔滨江苏南京云南昆明代理长春设有经销商。圆刚在南宁,湖南长沙,新疆乌鲁木齐,南昌圆刚视频采集,西藏呼和浩特,山西银川,福建福州,甘肃兰州,成都,贵州贵阳,浙江杭州,广西,上海多地与视频会议和医疗采集有着良好的合作,并且协助和参与当地视频采集卡报价和招标。。
单位注册资金单位注册资金人民币 100 万元以下。
“圆刚 V1A8 视频采集卡 支持两路复合视频输入和一路S-Video输入,支持720x576(PAL)”相关的客户留言
我要给“圆刚 V1A8 视频采集卡 支持两路复合视频输入和一路S-Video输入,支持720x576(PAL)”留言
“圆刚 V1A8 视频采集卡 支持两路复合视频输入和一路S-Video输入,支持720x576(PAL)”联系方式
深圳市联信宏富科技有限公司
(市场部)
地址:深圳市华强北赛格广场
邮编:518000
网址:http://laixiaojun007.cn.b2b168.com/
“圆刚 V1A8 视频采集卡 支持两路复合视频输入和一路S-Video输入,支持720x576(PAL)”相关产品,你也可查看该供应商更多
粤ICP备号 - Copyright (C) 2004 -
B2b168.com All Rights Reserved&&&&File Source(Async) filter从硬盘中读取avi文件;AVI Splitter filter分析文件并将其分解成两个流:一个压缩的视频流和一个音频流;AVI Decompressor filter将视频帧解码,Video Renderer
filter将解码后的视频帧通过DirectDraw或GDI显示出来;Default DirectSound Device filter使用DirectSound播放音频流。
&&&&应用程序没有必要对这些数据流进行管理,而是通过一个叫Filter
Graph Manager这个上层组件来控制这些filter。应用程序调用上层API如"Run"(通过graph移动数据)或"Stop"(停止移动数据)。如果你需要对数据流作更多的操作,你可以通过COM接口直接进入filter。Filter
Graph Manager同样也输出事件通知给应用程序。
&&&&Filter Graph的另一个用途是将filter连在一起创建一个filter graph。
&&&&编写一个DirectShow应用程序大体需要三个步骤:
&&&&1.创建一个Filter Graph Manager的实例
&&&&2.使用Filter Graph Manager创建一个filter graph,此时,需要已经具备所有必需的filter。
&&&&3.使用Filter Graph Manager控制filter graph和通过这些filter的流,在这个过程中,应用程序会收到Filter Graph Manager发送的事件。
&&&&完成这些后,应用程序需发布这个Filter Graph
Manager和所有的filter。
2.3. 播放一个文件
&&&&这一章以本节这个有趣的例子来结束,这个例子是一个播放音频或视频文件的简单控制台程序。程序只有寥寥数行,但却展示了DirectShow编程的强大能力。
&&&&正如上一节所讲的创建DirectShow应用程序的三个步骤,第一步,首先,需要调用CoInitialize来作初始化,然后调用CoCreateInstance创建Filter Graph Manager:
HRESULT hr = CoInitialize(NULL);
&&&&if (FAILED(hr))
IGraphBuilder *pG
&&&&HRESULT hr = CoCreateInstance(CLSID_FilterGraph,
&&& CLSCTX_INPROC_SERVER,
IID_IGraphBuilder, (void **)&pGraph);
&&&&如上所示,类标识符(CLSID)是CLSID_FilterGraph。Filter Graph Manager由进程内DLL(in-process DLL)提供,因此参数3,dwClsContext的值为CLSCTX_INPROC_SERVER。由于DirectShow运行自由线程模式(free-threading model),所以你同样可以使用COINIT_MULTITHREADED参数来调用CoInitializeEx。
&&&&第二步是创建filter graph,调用CoCreateInstance得到的IGraphBuilder接口包含了大部分创建filter graph的方法。在这个例子中还需要另外两个接口:IMediaControl和IMediaEvent。
&&&&IMediaControl控制数据流,它包含开启和停止graph的方法;IMediaEvent包含从Filter Graph Manager获取事件的方法,在这个例子中,这个接口用来得到回放结束事件。
&&&&所有这些接口由Filter Graph Manager提供,使用得到的IGraphBuiler接口指针来查询得到。
&&&&IMediaControl *pC
&&&&IMediaEvent&& *pE
&&&&hr = pGraph-&QueryInterface(IID_IMediaControl,
(void **)&pControl);
&&&&hr = pGraph-&QueryInterface(IID_IMediaEvent, (void
**)&pEvent);
&&&&现在你可以创建filter
graph了,对于文件回放只需要一个简单的调用:
pGraph-&RenderFile(L"C:\\\\Example.avi", NULL);
&&&&IGraphBuilder::RenderFile方法创建了一个能够播放指定文件的filter graph,事实上,原本需要做的一些如创建filter实例及将这些filter连接起来的工作,都由这个方法自动完成了,如果是视频文件,这个filter
graph看起来应该是这个样子:
&&&&[file source]-&[如果是缩格式,这里是个解码器]-&[Video Renderer]
&&&&要开始回放,调用IMediaControl::Run方法:
&&&&&&hr =
pControl-&Run();
&&&&当filter graph运行时,数据经过各个filter最后回放为视频或音频。回放发生在一个单独的线程中。你可以通过调用IMediaEvent::WaitForCompletion方法来等待回放的结束:
&&&&&&long evCode = 0;
&&&&pEvent-&WaitForCompletion(INFINITE, &evCode);
&&&&这个方法在播放期间被阻塞,直至播放结束或超时。
&&&&当应用程序结束时,需要释放接口指针并关闭COM库:
&&&&pControl-&Release();
&&&&pEvent-&Release();
&&&&pGraph-&Release();
&&&&CoUninitialize();
&&&&下面是这个例子的完整代码:
#include &dshow.h&
void main(void)
&&&&IGraphBuilder *pGraph = NULL;
&&&&IMediaControl *pControl = NULL;
&&&&IMediaEvent&& *pEvent = NULL;
&&&&// Initialize the COM library.
&&&&HRESULT hr = CoInitialize(NULL);
&&&&if (FAILED(hr))
&&&&&&&&printf("ERROR - Could
not initialize COM library");
&&&&// Create the filter graph manager and query for
interfaces.
&&&&hr = CoCreateInstance(CLSID_FilterGraph, NULL,
CLSCTX_INPROC_SERVER,&
&&&&&&&&&&&&&&&&&&&&&&&&IID_IGraphBuilder,
(void **)&pGraph);
&&&&if (FAILED(hr))
&&&&&&&&printf("ERROR - Could
not create the Filter Graph Manager.");
&&&&hr = pGraph-&QueryInterface(IID_IMediaControl,
(void **)&pControl);
&&&&hr = pGraph-&QueryInterface(IID_IMediaEvent, (void
**)&pEvent);
&&&&// Build the graph. IMPORTANT: Change this
string to a file on your system.
pGraph-&RenderFile(L"C:\\\\Example.avi", NULL);
&&&&if (SUCCEEDED(hr))
&&&&&&&&// Run the graph.
&&&&&&&&hr = pControl-&Run();
&&&&&&&&if (SUCCEEDED(hr))
&&&&&&&&&&&&//
Wait for completion.
&&&&&&&&&&&&long
&&&&&&&&&&&&pEvent-&WaitForCompletion(INFINITE,
&&&&&&&&&&&&//
Note: Do not use INFINITE in a real application, because it
&&&&&&&&&&&&//
can block indefinitely.
&&&&pControl-&Release();
&&&&pEvent-&Release();
&&&&pGraph-&Release();
&&&&CoUninitialize();
3. 关于DirectShow
3.1. DirectShow体系概述
&&&&多媒体的难题
&&&&处理多媒体有几个主要的难题:
&&&&*多媒体流包含了巨大的数据量,而这些数据都必须非常快地被处理
&&&&*音频和视频必须同步,因此它们必须在同一时间开始或停止,并以同一速率播放
&&&&*数据可能来自很多的源,如本地文件、网络、电视广播和视频摄像机
&&&&*数据有各种各样的格式,如AVI、ASF、MPEG和DV
&&&&*程序员无法预知最终用户使用什么样的硬件设备
&&&&DirectShow的解决方案
&&&&DirectShow被设计成用来解决所有这些难题,它主要的设计目的就是通过将复杂的数据转输、硬件的多样性和同步问题从应用程序中独立出来,从而简化在windows平台上数字媒体应用程序的开发任务。
&&&&要实现数据高效地被处理,需要流化音视频数据,而DirectShow会尽可能地使用DirectDraw和DirectSound,从而高效地将数据送到用户的声音和图形设备中进行播放。同步则是通过在媒体数据中加入时间戳来实现。而DirectShow模块化的架构,使其可以轻松操纵变化多端的源、格式和硬件设备,在这样的架构里,应用程序只需组合和匹配多个filter来实现功能。
&&&&DirectShow提供的filter支持基于WDM的采集和调谐设备,也支持早先的VFW采集卡和为ACM和VCM接口编写的编码器。
&&&&下图显示了应用程序、DirectShow组件和DirectShow支持的硬件和软件组件之间的关系:
&&&&如图,DirectShow将应用程序与众多复杂的设备隔离开来,通信和控制这些设备均出DirectShow的filter来完成。DirectShow同样为某种文件格式提供与之对应的编解码器。
3.2. Filter Graph和它的组件
&&&&这一节描述了DirectShow的主要组件,为DirectShow应用程序和DirectShow Filter开发者提供一个介绍。应用程序开发者可以忽略掉很多底层部分,但是,了解底层对于理解DirectShow架构还是很有帮助的。
3.2.1. 关于DirectShow Filter
&&&&DirectShow使用一个模块化的架构,每个处理过程都由一个叫做filter的COM对象来实现。DirectShow为应用程序提供了一系列标准的filter,开发者也可以编写自己的filter来扩展DirectShow的功能。下面是播放一个AVI文件的各个步骤:
&&&&*从文件中读取数据并转成字节流(File Source
&&&&*检查AVI头,分析字节流并将它们分离成视频和音频(AVI Aplitter filter)
&&&&*将视频解码(不同的解码filter,取决于不同的压缩格式)
&&&&*将视频显示出来(Video Renderer filter)
&&&&*将音频送入声卡(Default DirectSound
Device filter)
&&&&如图所示,每个filter与一个或多个其它的filter相连,其中的连接点也是一个COM对象,称作Pin,filter使用Pin将数据从一个filter转移到另一个,图中的箭头指示了数据流动的方向。在DirectShow中,这一系列连接在一起的filter称作filter graph。
&&&&Filter可能处于有三种不同的状态:运行、停止和暂停状态。filter在运行状态时处理数据,停止状态时停止处理数据,暂停状态则是表示就绪,可以开始进入运行状态。除了极个别的情况,一个filter Graph中的所有filter通常都处理同一个状态下,因此,filter graph也可以称其处于运行、停止、暂停状态。
&&&&Filter可以被分成几个大的种类:
&&&&*source filter&- filter graph的数据源,这些数据可以来自文件、网络、摄像头或任何其它东西。每一个source filter操纵不同类型的数据源。
&&&&*transform filter&- 接收数据,处理数据并将它送入下一个filter。编码filter和解码filter都属于这个种类。
&&&&*Renderer filter&- 处于filter链的未端,接受数据并将其展现给用户。比如,一个视频renderer在显示器上绘制视频图像;一个音频renderer将音频数据送入声卡;一个写文件filter(file-writer filter)将数据存盘。
&&&&*splitter filter&- 分析输入的数据流并将其分解成两路或多路,比如,AVI splitter分析字节流并将其分解成视频流和音频流。
&&&&*mux filter&- 将多路输入流合并成一路。比如,AVI Mux正好与AVI splitter做相反的工作,它将视频和音频流合成为一个AVI格式的字节流。
&&&&以上的分类并不是绝对的,比如,ASF Reader Filter同时充当了source filter和splitter filter的角色。
&&&&所有的DirectShow filter都提供IBaseFilter接口,所有的Pin也都提供IPin接口。DirectShow也定义了许多其它的接口以实现特定的功能。
3.2.2. 关于Filter Graph Manager
&&&&Filter Graph Manager是一个用以控制filter graph中的filter的COM对象。它提供了许多功能,包括:
&&&&*协调filter之间的状态变化
&&&&*建立参考时钟(reference clock)
&&&&*将事件返回给应用程序
&&&&*提供应用程序建立filter graph的方法
&&&&这里先简单地描述一个这些功能。
&&&&状态变化:filter们的状态变化必须遵照一个特定的次序,因此,应用程序不能将状态变化的命令直接发给filter,而是将一个简单的命令发给filter graph manager,由它来将命令分发给各个filter。定位命令同样使用这种方式,应用程序发送一个定位命令给filter
graph manager,由它来分发。
&&&&参考时钟:在filter graph中的所有filter都使用一个相同的时钟,称为参考时钟(reference clock)。参考时钟保证了所有流的同步。一个视频帧或一段音频样本被播放的时间钞称作呈现时间(presentation time)。呈现时间精确地相对于参考时钟。Filter
Graph Manager通常选择的参考时钟是声卡参考时钟或系统时钟。
&&&&Graph事件:filter
graph manager使用一个消息队列来通知应用程序发生在filter graph中的事件。
&&&&Graph-buliding 方法:filter graph manager提供给应用程序将filter加入到filter graph中的方法,以及将filter与filter连接或断开连接的方法。
&&&&Filter graph manager不提供操纵在filter之间流动数据的功能,这个功能由filter通过pin连接在一个单独的线程中自行完成。
3.2.3. 关于媒体类型(Media Type)
&&&&因为DirectShow是模块化的,因此需要有一个在filter graph各个点之间描述格式的方法。比如说,AVI回放,数据输入时是一个RIFF块的流,然后被分解成视频和音频流。视频流由一个个可能被压缩的视频帧组成,解压后,视频流又变成了一系列未压缩的位图。音频与视频类似。
&&&&Media Type:DirectShow怎样来描述格式&&&&Media
Type是描述数字媒体格式的常用方式。当两个filter连接时,它们需要协商决定同一个Media Type。Media Type标识了从上一个filter递交到下一个filter或物理层的数据流格式。如果两个filter对Media Type不能协商一致,则不能连接。
&&&&对于某些应用程序,你不必去关心Media type,比如文件回放,DirectShow做了所有有关它的事情。
&&&&Media type使用AM_MEDIA_TYPE结构体来定义,这个结构体包含了以下内容:
&&&&*Major type:主类型,是一个GUID,定义了数据的整体类型,包括了:视频、音频、未分析的字节流、MIDI等。
&&&&*Subtype:子类型,另一个GUID,进一步定义了数据格式。比如,如果主类型是视频,则子类型可以是RGB-24、RGB-32、UYVY等格式,如果主类型是音频,则可能是PCM或MPEG-1 payload等。子类型提供了比主类型更多的内容,但仍未提供完整的格式定义,比如,子类型没有定义图像尺寸和帧率,这些都将在Format block中被定义。
&&&&*Format block:格式块,定义了具体的格式。格式块是AM_MEDIA_TYPE结构体中一个单独被分配的内存空间,pbFormat成员指向这块内存空间。因为不同的格式会有不同的格式描述,所以pbFormat成员的类型是void*。比如,PCM音频使用WAVEFORMATEX结构体,视频使用不同的结构体包括:VIDEOINFOHEADER和VIDEOINFOHEADER2。formattype成员是一个GUID,指定了格式块包含了哪种结构体,每一种格式的结构体都被分配了GUID。cbFormat成员定义了格式式块的长度。
&&&&当格式块被定义时,主类型和子类型包含的信息就显得有点多余了。其实,主类型和子类型为识别格式提供了一个便利的方法,比方说,你可以指定一个普通的24位RGB格式(MEDIASUBTYPE_RGB24),而不需去关心VIDEOINFOHEADER结构体中诸如图像尺寸和帧率这些信息。
&&&&下面是一个filter检查媒体类型的例子:
HRESULT CheckMediaType(AM_MEDIA_TYPE *pmt)
&&&&if (pmt == NULL) return E_POINTER;
&&&&// 检查主类型,我们需要的是视频
&&&&if (pmt-&majortype != MEDIATYPE_Video)
&&&&&&&&return
VFW_E_INVALIDMEDIATYPE;
&&&&// 检查子类型,我们需要的是24-bit RGB.
&&&&if (pmt-&subtype != MEDIASUBTYPE_RGB24)
&&&&&&&&return
VFW_E_INVALIDMEDIATYPE;
&&&&// 检查format type和格式块的大小.
&&&&if ((pmt-&formattype == FORMAT_VideoInfo)
&&&&&&&& (pmt-&cbFormat &=
sizeof(VIDEOINFOHEADER) &&
&&&&&&&& (pmt-&pbFormat != NULL))
&&&&&&&&// 现在可以安全地将格式块指针指向正确的结构体。
&&&&&&&&VIDEOINFOHEADER *pVIH =
(VIDEOINFOHEADER*)pmt-&pbF
&&&&&&&&// 检查pVIH
(未展示). 如果正确,返回S_OK.
&&&&&&&&return S_OK;
&&&&return VFW_E_INVALIDMEDIATYPE;
&&&&AM_MEDIA_TYPE结构体还包含了一些任选项,用来提供附加的信息,filter不需要这些信息:
&&&&*ISampleSize,如果这个字段非零,表示这是每个sample的尺寸,如果是零,则表示sample的尺寸会改变。
&&&&*bFixdSizeSamples,如果这个布尔类型的标记是TRUE,表示ISampleSize有效,否则,你可以忽略ISampleSize。
&&&&*bTemporalCompression,如果这个布尔类型的标记是FALSE,表示所有帧都是关键帧。
3.2.4. 关于媒体样本(Media Sample)和分配器(Allocator)
&&&&Filter通过Pin与Pin之间的连接来递交数据,数据从一个filter的输出Pin转移到另一个filter的输入Pin,除了个别情况,实现这种功能通常的方法是调用输入Pin上的IMemInputPin::Receive方法。
&&&&依靠filter,媒体数据的内存空间可以通过多个途径来分配:在堆上、在DirectDraw表面(surface)、在共享GDI内存或使用其它的分配机制。这个负责分配内存空间的对象称为分配器(Allocator),是一个暴露IMemAllocator接口的COM对象。
&&&&当两个Pin相连时,其中的一个Pin必须提供一个分配器。DirectShow定义了一个方法调用序列来决定到底由哪个Pin来提供分配器。Pin还负责协商分配器创建的缓冲数和每个缓冲的尺寸。
&&&&在数据流开始之前,分配器创建了一个缓冲池。在数据流动过程中,上游filter在缓冲中填入数据并递送给下游filter,但是,上游filter递送给下游filter的并不是原始的缓冲区指针,而是一个称为媒体样本(Media Sample)的COM对象,它由分配器创建并用来管理缓冲区,暴露IMediaSample接口。一个媒体样本包含:
&&&&*指向下层缓冲区的指针
&&&&*时间戳
&&&&*各种标记
&&&&*可选的媒体类型
&&&&时间戳定义了呈现时间(presentation time),用以让renderer filter确定播放的合适时机。各种标记可以用来指示很多事情,比如,数据在上一个sample后是否被打段过(如重新定位、掉帧)等。媒体类型为流中间改变数据格式提供了途径,通常,没有媒体类型的sample,被认为从上一个sample以来数据格式没有被改变过。
&&&&当filter使用一个缓冲时,它保存了sample上的参考计数。分配器使用参考计数来决定什么时候可以重用这个缓冲,这防止了一个filter在写一个缓冲时另一个filter还在使用这个缓冲,除非所有的filter都释放了这个缓冲,否则sample不会将其返回给分配器的缓冲池。
3.2.5. 硬件如何参与Filter Graph
&&&&这一节描述了DirectShow如何与音频和视频硬件交互。
&&&&&外壳filter(Wrapper Filter)
&&&&所有的DirectShow filter都是用户模式的软件组件。为了使象视频采集卡这样的内核模式的硬件驱动加入到filter graph中,必须使其象用户模式的filter那样。DirectShow提供外壳filter来完成这个功能,这类filter包括:Audio Capture filter、VFW Capture filter、TV Tuner filter、TV Audio filter和Analog Video Crossbar filter。DirectShow也提供一个叫KsProxy的filter,它可以实现任何类型的WDM流驱动。硬件商通过提供一个Ksproxy plug-in来扩展KsProxy,以使其支持自己的功能,ksproxy plug-in是一个被KsProxy聚合的COM对象。
&&&&外壳filter通过暴露COM接口来实现设备的功能。应用程序使用这些接口将信息传递给filter,filter再把这些COM调用转化为设备驱动调用,将信息传递到内核模式下的设备中去,然后返回结果给应用程序。TV Tuner、TV Audio、Analog
Video Crossbar和KsProxy filter都通过IKsPropertySet接口来支持驱动的自定义属性,VFW Capture
filter和Audio Capture filter不支持这种方式。
&&&&外壳filter使应用程序可以象控制其它directshow filter一样来控制设备,filter已经封装了与内核驱动通信的细节。
&&&&Video for Windows Devices
&&&&VFW Capture filter支持早期的VFW采集卡,当一个设备加入到目标系统中支后,它可以被directshow使用系统设备枚举器(System Device Enumerator)发现并加入到filter graph中去。
&&&&音频采集(Audio Capture)和混音设备(声卡)(Mixing Device/Sound Card)
&&&&较新的声卡都有麦克风等设备的插口,而且大多数这类声卡都有板级的混频能力,可单独控制每一个连接设备的音量及高低音。在directshow中,声卡的输入和混频设备被Audio Capture filter封装。每个声卡都能被系统设备枚举器发现。要查看你的系统中的所有声卡,只需打开GraphEdit,从Audio Capture Sources一类中选择即可,每个在这个类里的filter都是一个单独的Audio Capture filter。
WDM流设备&&&&较新的硬解码设备和采集卡都遵照WDM规范。这些设备和比VFW设备更强大的功能,以及可以应用于多种系统(winxp,winNT,win2000,win98/me)。WDM视频采集卡支持许多VFW所没有的功能,包括枚举采集的格式、编程控制视频参数(如对比度、亮度)、编程选择输入端和电视调谐支持。
&&&&为了支持WDM流设备,directshow提供了KsProxy filter(ksproxy.ax)。KsProxy被称为“瑞士军刀",因为它可以做很多不同的事情。filter上pin的数量,以及COM接口的数量,取决于底层驱动的能力。KsProxy不以"KsProxy"这个名字显示在filter graph中,而是使用一个已在注册表中登记的设备名称。要查看你系统中的WDM设备,可以运行GraphEdit然后从WDM Streaming这个类别中选择。即使你的系统中只有一块WDM卡,这块卡也可能包含多个设备,而每一个设备都表现为一个filter,每个filter是实际意义上的KsProxy。
&&&&应用程序使用系统设备枚举器在系统中寻找WDM设备moniker,然后调用moniker的BindToObject来实例化。因为KsProxy能够表现所有类型的WDM设备,因此它必须通过询问驱动来决定哪些属性是驱动所支持的。属性集是一组数据结构的集合,被WDM设备使用,也被诸如MPEG2软解码filter这样的用户模式filter使用。KsProxy通过暴露COM接口来配置自己,硬件商则通过提供插件来扩展KsProxy,插件暴露硬件商自定义的一些接口,用以实现特殊的功能。所有这些细节对于应用程序来说都是不可见的,应用程序通过KsProxy控制设备就象控制其它的DirectShow filter一样。
&&&&内核流
&&&&WDM设备支持内核流,在内核流中数据在内核模式下被彻底流化而永远不需要切换到用户模式下去,从而避免了在内核模式和用户模式之间切换的巨大开销,内核流允许高的比特率而不消耗CPU的时间。基于WDM的filter能够使用内核流将多媒体数据一个硬件设备送入到另一个中去,既可以是在同一块卡中也可以在不同的卡中,而不需要将数据拷入系统主存。
&&&&从应用程序的视点来看,数据好象是从一个用户模式的filter传到另一个中去,但是实际上,数据根本就没有传到用户模式下过,而是可能支接从内核模式的设备中传到下一个中去直至被呈现(render)在显卡上。某些情况,比如采集视频到一个文件中去,在某些点上需要将数据从内核模式传入到用户模式,但是,仍然没有必要将数据拷贝到内存的一个新位置中去。
&&&&应用程序开发者通常只需了解一个内核流的背景知识而不需要深究它的细节。
3.3. 构建Filter Graph
3.3.1. 用于构建Graph的组件
&&&&DirectShow提供了一系列用于构建filter
graph的组件,包括:
&&&&*Filter Graph Manager。这个对象用于控制filter graph,支持IGraphBuilder、IMediaControl和IMediaEventEx等许多接口。所有的directshow应用程序都需要在某些地方用到这个对象,虽然在有些情况下,是其它的对象为应用程序创建了filter graph manager。
&&&&*Capture Graph Builder。这个对象为构建filter graph提供附加的方法。它最初是为构建提供视频采集的graph而设计的(这正是它的名字由来),但是对于构建许多另外类型的filter graph也是很有用的。它支持ICaptureGraphBuilder2接口。
&&&&*Filter Mapper和System Device Enumerator。这些对象用于查找在系统中注册的或代表硬件驱动的filter。
&&&&*DVD Graph Builder。这个对象构建用以回放和导航DVD的filter graph。它支持IDvdGraphBuilder接口。基于脚本的应用程序能够使用MSWebDVD ActiveX控件来控制DVD回放。
&&&&*Video Control。WinXP提供这个ActiveX控件,用于操纵directshow中的数据和模拟电视。
&&&&智能连接(Intelligent Connect)
&&&&智能连接这个术语覆盖了一系列Filter Graph
Manager用于构建所有或部份filter graph的算法。任何时候,当Filter Graph Manager需要添加filter来完成graph时,它大致做以下几件事情:
&&&&1.如果有一个filter存在于graph中,而且这个filter有至少一个没有连接的input pin,Filter Graph Manager试着去试用这个filter。
&&&&2.否则,Filter Graph Manager在已注册的filter中寻找连接时可以接受合适的媒体类型的filter。每一个filter都注册有一个Merit值,这个值用以标记哪个filter最容易被Filter Graph Manager选中来完成graph。Filter Graph Manager按Merit值的顺序来选择filter,Merit值越大,被选中的机会越大。对于每种流类型(如音频、视频、MIDI),默认的renderer具有一个很高的Merit值,解码器同样是,专用filter具有低Merit值。
&&&&如果Filter Graph Manager因选择的filter不合适而被困,它会返回来尝试另外的filter组合。
3.3.2 Grap构建概述
&&&&创建一个filter graph,从创建一个Filter Graph Manager实例开始:
&&&& IGraphBuilder* pIGB;
&&&& HRESULT hr = CoCreateInstance(CLSID_FilterGraph,
&&&& NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder,(void
**)&pIGB);
&&&&&Filter Graph Manager支持下列Graph构建方法:
&&&&*IFilterGraph::ConnectDirect,在两个pin之间进行直接连接,如果连接失败,则返回失败
&&&&*IFilterGraph::Connect,连接两个Pin,如果可能的话,直接连接它们,否则,在中间加入其它的filter来完成连接。
&&&&*IGraphBuilder::Render,从某个输出Pin处开始完成余下的graph构建。该方法会自动在输出pin后面添加必须的filter,直到renderer
filter为止。
&&&&*IGraphBuilder::RenderFile,构建一个完整的文件回放graph。
&&&&*IGraphBuilder::AddFilter,将一个filter添加到graph中。它不连接filter,并且在调用此方法前,filter必须已经被创建。创建filter可以是用CoCreateInstance方法或使用Filter Mapper或系统设备枚举器(System Device Enumerator)。
&&&&这些方法提供了三种构建graph的途径:
&&&&1.filter graph manager构建整个graph
&&&&2.filter graph manager构建部分graph
&&&&3.应用程序构建整个graph
&&&&Filter Graph Manager构建整个graph
&&&&如果你仅仅是想回放一个已知格式的文件,如AVI、MPEG、WAV或MP3,使用RenderFile方法。
&&&&RenderFile方法首先寻找注册在系统中能分析源文件的filter,它使用协议名(如http://),文件扩展名或文件的头几个字节来决定选择哪一个源filter。
&&&&Filter Graph Manager使用一个迭代过程来完成余下的graph构建。在这个迭代过程中,它逐个列出filter的输出pin上支持的媒体类型,并搜索哪个已注册的filter的输入Pin接受该媒体类型。它使用一系列的规则来缩小filter的范围并排定优先顺序:
&&&&*filter类别(category)标识的filter的一般功能
&&&&*媒体类型描述filter能在接受或能输出哪种数据类型
&&&&*merit值决定filter被尝试的次序。如果两个filter具有相同的filter类别并且同时支持相同的输入类型,Filter Graph Manager选择merit值大的那一个。一些filter故意给出一个小merit值是因为它是为特殊用途设计的,仅能由应用程序来将其添加到graph。
&&&&Filter Graph Manager使用Filter
Mapper对象来搜索已注册的filter。
&&&&每个filter被添加时,filter graph manager试着将其与前一个filter的输出pin连接。它们协商决定他们是否能连接,如果能,哪一种媒体类型被用来连接。如果新filter不能连接,filter graph manager丢弃它并尝试别一个,这个过程一直继续到每个流都被render为止。
&&&Filter Graph Manager构建部分graph
&&&&如果不仅仅是播放一个文件,那么你的应用程序就必须做一些graph的构建工作。比如,一个视频采集应用程序必须先选择一个source filter并将其添加到graph中去。如果你需要将数据写入到一个AVI文件中,你必须添加一个AVI Mux和File Write filter。不过,也经常有可能让filter graph
manager来完成整个graph,比如,你可以通过Render方法来render一个pin进行预览。
&&&&应用程序构建整个graph
&&&&在某些场合,你的应用程序需要添加和连接每个filter来构建graph。在这种情况下,你很可能明确地知道哪些filter需要加到graph中去。使用这种方式,应用程序通过调用AddFilter方法添加每个filter,然后枚举filter上的pin,调用Connect或ConnectDirect来连接它们。
3.3.3. 智能连接
&&&&智能连接是filter graph manager用以构建filter graph的机制。它包含了一系列相关的用以选择filter和将它们添加到graph中去的算法。作为应用程序开发者,你并不需要很具体地了解智能连接的细节。如果你在构建某个filter graph时遇到问题并希望能解决它,或者你正在编写你自己的filter并希望它能自动地被graph构建,请阅读这一节。
&&&&智能连接涉及以下IGraphBuilder方法:
&&&&*IGraphBuilder::Render
&&&&*IGraphBuilder::AddSourceFilter
&&&&*IGraphBuilder::RenderFile
&&&&*IGraphBuilder::Connect
&&&&Render方法构建一部分graph,它从一个尚未连接的输出pin开始顺着数据流的方向往下,添加必要的filter,起始的那个filter必须已被添加到了graph中。Render方法每一步都搜索一个能够连接到前一个filter的filter,如果新连接上的filter有多个输出pin,数据流能自动分流,搜索直到每个流都被renderer为止。如果Render方法搜索到的filter无法使用,它会返回去尝试另一个filter。
&&&&要连接每一个输出pin,Render方法做以下工作:
&&&&1.如果pin支持IStreamBuilder接口,Filter Graph Manager让pin的IStreamBuilder::Render方法来完成整过程。通过暴露这个接口,pin承担了构建graph剩余部分的全部工作。但是,只有很少数的filter支持此接口。
&&&&2.Filter Graph Manager尝试使用任何在缓存中的filter。在智能连接的整个过程中,filter graph manager可以在早期将filter缓存起来。
&&&&3.如果filter graph包含了任何有未连接的输入pin的filter,filter
graph manager会将其当作下一个filter来尝试连接。你可以通过在调用Render之前添加特定的filter来强制让Render方法来尝试这个filter。
&&&&4.最后,filter graph manager使用IFilterMapper2::EnumMatchingFilters方法在所有注册的filter中寻找,依据已注册的媒体类型列表来逐个试着匹配输出pin的各个媒体类型(按优先级高低排列)。
&&&&每个已注册的filter都有一个merit值,这是一个用来表示filter优先级的数字,最大优先级越高,EnumMatchingFilters方法返回的filter集依据merit值来排列,直至最小的merit值MERIT_DO_NOT_USE+1,它忽略merit为MERIT_DO_NOT_USR或更小的filter。filter也通过GUID来归类,类别本身也有merit值,EnumMatchingFilters方法忽略任何merit值为MERIT_DO_NOT_USE或更小的类别,即使在那个类别中的filter有较高的merit值。
&&&&总结一下,Render方法以下列步骤尝试filter
&&&&1.使用IStreamBuilder
&&&&2.尝试被缓存的filter
&&&&3.尝试已添加在graph中的filter
&&&&4.在已注册的filter中寻找
&&&&AddSourceFilter方法添加一个能render特定文件的source filter。首先,它依据协议名(如Http://)、文件扩展名、或文件头在已注册的filter中寻找匹配的那个。如果此方法定位到了一个合适的source filter,它便立刻创建一个这个filter的实例,并将其添加到graph中,然后调用filter的IFileSourceFilter::Load方法。
&&&&RenderFile方法依据一个文件名来构建一个默认的回放graph,在其内部,RenderFile方法调用AddSourceFilter来定位source filter,并且用Render来构建Graph的余下部分。
&&&&Connect方法将输出pin连接到输入pin上去,这个方法自动添加必要的中间filter到graph中去,使用在Render方法中描述的那一系列算法:
&&&&1.使用IStreamBuilder
&&&&2.尝试被缓存的filter
&&&&3.尝试已添加在graph中的filter
&&&&4.在已注册的filter中寻找
3.4. Filter Graph中的数据流
&&&&这一节主要描述媒体数据是如何在filter graph中流动的。如果你只是为了编写DirectShow应用程序,你不需要知道这些细节,当然,知道这些细节对于编写directshow应用程序仍然是有帮助的。但是如果你要编写directshow filter,那么你就必须掌握这部分知识了。
3.4.1. DirectShow数据流概述
&&&&在这一部分先粗略地描述一下DirectShow中数据流是如何工作的。
&&&&数据首先是被保存在缓冲区里的,在缓冲区里,它们仅仅是一个字节数组。每一个缓冲区被一个称作媒体样本(media sample)的COM对象所包容,media sample提供IMediaSample接口。media sample由另一个称作分配器(allocator)的COM对象创建,allocator提供IMemAllocator接口。每一个pin连接都指定有一个allocator,当然,两个或多个pin连接也可以共享几个allocator。
&&&&每一个allocator都创建一个media sample池,并为每个sample分配缓冲区。一旦一个filter需要一个缓冲区来填充数据,它就调用方法来请求一个sample。只要allocator有一个sample还没有被任何filter使用,GetBuffer方法就立即返回一个sample的指针。如果allocator所有的sample已经被用完,这个方法就阻塞在那里,直到有一个sample变成可用的了。GetBuffer返回一个sample后,filter就将数据写入到sample的缓冲区中去,并在sample上设置适当的标记(如时间戳),然后将它递交到下一个filter去。
&&&&当一个renderer filter接收到了一个sample时,renderer filter检查时间戳,并将sample先保存起来,直到filter graph的参考时钟指示这个sample的数据可以被render了。当filter将数据render后,它就将sample释放掉,此时sample并不立即回到allocator的sample池中去,除非这个sample上的参考计数已经变为0,表示所有的filter都已释放这个sample。
&&&&上游的filter可能在renderer之前运行,这就意味着,上游的filter填充缓冲的速度可能快于renderer销毁它们。但是尽管如此,samples也并无必要更早地被render,因为renderer将一直保存它们直到适当的时机去render,并且,上游filter也不会意外地将这些samples的缓冲覆盖掉,因为GetSample方法只会返回那些没有被使用的sample。上游filter可以提前使用的sample的数量取决于allocator分配池中的sample的数量。
&&&&前面的图表只显示了一个allocator,但是通常的情况下,每个流中都会有多个allocator。因此,当renderer释放了一个sample时,它会产生一个级联效应。如下图所示,一个decoder保存了一个视频压缩帧,它正在等待renderer释放一个sample,而parser
filter也正在decoder去释放一个sample。&&&&
&&&&当renderer释放了一个sample后,decoder完成尚未完成的GetBuffer调用。然后decoder便可以对压缩的视频帧进行解码并释放它保存的sample,从而使parser完成它的GetBuffer调用。
3.4.2. 传输协议(Transports)
&&&&为了使媒体数据能在filter graph中流动,Directshow filter必须能支持多个协议中的一个,这些协议被称作传输协议(transports)。当两个filter连接后,它们必须支持同一个传输协议,否则,它们将不能交换数据。通常,一个传输协议要求某个pin支持一个特定的接口,当两个filter连接时,另一个pin来调用这个pin的这个接口。
&&&&大多数的directshow filter在主存中保存媒体数据,并且通过pin连接向另一个filter递交数据,这种类型的传输协议被称作本地内存传输协议(local memory transport)。尽管这类传输协议在directshow中应用最普遍,但并非所有的filter都使用它。例如,某些filter通过硬件途径来传递数据,使用pin仅仅是为了传递控制信息,如IOverlay接口。
&&&&DirectShow为本地内存传输协议定义了两种机制,推(push)模式和拉(pull)模式。在推模式中,source filter产生数据,并将其递交给下游的filter,下游的filter被动地接收数据并处理它们,再将数据传递给它的下游filter。在拉模式中,source filter与一个parser filter连接,parser filter向source filter请求数据,source filter回应请求并传递数据。推模式使用接口,而拉模式使用接口。
&&&&推模式比拉模式应用更广泛。
3.4.3. 媒体样本(sample)和分配器(allocator)
&&&&当一个pin向另一个pin传递媒体数据时,它并不是直接传递一个内存缓冲区的指针,而是传递一个COM对象的指针,这个COM对象管理着内存缓冲,被称为媒体样本(media sample),暴露接口。接收方pin通过调用IMediaSample接口的方法来访问内存缓冲,如,和。
&&&&sample总是从输出pin到输入pin向下传输。在推模式中,输出pin通过在输入pin上调用IMemInputPin::Receive方法来传递一个sample。输入pin或者在Receive方法内部同步地处理数据,或者另开一个工作线程进行异步处理。如果输入pin需要等待资源,允许在Receive中阻塞。
&&&&另一个用来管理媒体样本的COM对象,被称作分配器(allocator),它暴露接口。一旦一个filter需要一个空闲的媒体样本,它调用方法来获得sample的指针。每一个pin连接都共享一个allocator,当两个pin连接时,它们协商决定哪个filter来提供allocator。pin可以设置allocator的属性,比如缓冲的数量和每个缓冲的大小。
&&&&下图显示了allocator、media sample和filter的关系:
&&&&媒体样本参考计数(Media
Sample Reference Counts)
&&&&一个allocator创建的是一个拥有有限个sample的sample池。在某一时刻,有些sample正在被使用,有些则可被GetBuffer方法使用。allocator使用参考计数来跟踪sample,GetBuffer方法返回的sample参考计数为1,如果参考计数变为0,sample就可以返回到allocator的sample池中去了,这样它就可以再次被GetBuffer方法使用。在参考计数大于0期间,sample是不能被GetBuffer使用的。如果每个从属于allocator的sample都在被使用,则GetBuffer方法会被阻塞直至有sample可以被使用。
&&&&举个例子,假设一个输入pin接收到一个sample。如果它同步地在Receive方法内部处理它,sample的参考计数不增加,当Receive返回时,输出pin释放这个sample,参考计数归0,sample就返回到sample池中去了。另一种情况,如果输入pin异步地处理sample,它就在Receive方法返回前将sample的参考计数加1,此时参考计数变为2。当输出pin释放这个sample时,参考计数变为1,sample不能返回到sample池中去,直到异步处理的工作线程完成工作,调用Release释放这个sample,参考计数变为0时,它才可以返回到sample池中去。
&&&&当一个pin接收到一个sample,它可以将数据拷贝到另一个sample中去,或者修改原始的sample并将其传递到下一个filter中去。一个sample可能在整个graph长度内被传递,每个filter都依次调用AddRef和Release。因而,输出pin在调用Receive后一定不能重复使用同一个sample,因为下游的filter可能正在使用这个sample。输出pin只能调用GetBuffer来获得新的sample。
&&&&这个机制减少了总的内存分配过程,因为filter可以重复使用同样的缓冲。它同样防止了数据在被处理前意外地被覆盖写入。
&&&&当filter处理数据后数据量会变大(如解码数据),一个filter可以为输入pin和输出pin分配不同的allocator。如果输出数据并不比输入数据量要大,filter可以用替换的方式来处理数据而不用将其拷贝到新的sample中去,在这种情况下,两个或多个pin连接共享一个allocator。
&&&&提交(Commit)和反提交(Decommit)分配器
&&&&当一个filter首次创建一个allocator时,allocator并不为其分配内存缓冲,此时如果调用GetBuffer方法的话会失败。当流开始流动时,输出pin调用来提交allocator,从而为其分配内存。此时pin可以调用GetBuffer了。
&&&&当流停止时,pin调用来反提交allocator,在allocator被再次提交前所有后来的GetBuffer调用都将失败,同样,如果有阻塞的正在等待sample的GetBuffer调用,也将立即返回失败信息。Decommit方法是否释放内存取决于实现方式,如CMemAllocator类直至析构时才释放内存。
3.4.4. filter状态
&&&&filter有三种可能的状态:停止(stopped),就绪(paused)和运行(running)。就绪状态的目的是为了让graph提前做准备以便在run命令下达时可以立即响应。Filter Graph Manager控制所有的状态转换。当一个应用程序调用,或时,Filter Graph
Manager在所有filter上调用相应的IMediaFilter方法。在停止状态和运行状态之间转换时总是要经过就绪状态,即如果应用程序在一个处于停止状态的graph上调用Run时,Filter
Graph Manager在运行它之前先将其转为pause状态。
&&&&对于大多数filter来说,运行状态和就绪状态是等同的。看下面的这个graph:
&&&&Source & Transform & Renderer
&&&&假设这个source filter不是一个实时采集源,当source filter就绪时,它创建一个线程来尽可能快地产生新数据并写入到media
sample中去。线程通过在transform filter的输入pin上调用IMemInputPin方法将sample“推”到下游filter。transform filter在source filter的线程中接收数据,它可能也使用一个工作线程赤将sample传递给renderer,但是在通常情况下,它在同一个线程中传递它们。如renderer处理就绪状态下,它等待接收sample,当它接收到一个时,它或阻塞或保存那个sample,如果这是一个Video renderer,则它将sample显示为一个静态的图片,只在必要的时候刷新它。
&&&&此时,流已经准备充分去被render,如果graph仍然处理就绪状态下,sample会在每一个sample后堆积,直至每个filter都被阻塞在Receive或GetBuffer下。没有数据会被丢失。一旦source线程的阻塞被解除时,它只是简单地从阻塞点那里进行恢复。
&&&&source filter和transform filter忽略从就绪状态转到运行状态——它们仅仅是尽可能快地继续处理数据。但是当renderer运行时,它就要开始render sample了。首先,它render在就绪状态下保存的那个sample,接着,每接收到一个新的sample,它计算这个sample的呈现时间,renderer保存每个sample直至到了它们的呈现时间再render它们。在等待合适的呈现时间时,它或者阻塞在Receive方法上,或者在一个工作线程中接收数据并将其放入队列中去。renderer的上一个filter不关心这些问题。
&&&&实时源(live source),如采集设备,是通常情况中的一个例外。在实时源中,不适合提前准备数据。应用程序可能将graph置于就绪状态下,然后等很长时间才再运行它。graph不应该再render就绪期间的sample,因此,一个实时源在就绪状态时不产生新的sample。要将这种情况通知给filter graph manager,source filter的IMediaFilter::GetState方法返回VFW_S_CANT_CUE。这个返回值表示filter已切换到就绪状态下,即使renderer还没有收到任何数据。
&&&&当一个filter停止时,它不再接收任何传递给它的数据。source filter关闭它们的流线程,别的filter关闭所有它们创建的工作线程。pin反提交(decommit)它们的allocator。
&&&&状态转换
&&&&filter graph manager按从下游filter到上游filter的次序来完成所有的状态转换,从renderer开始逐个向上直至source filter,这个次序是必要的,可以防止数据丢失或graph死锁。最重要状态转换是就绪状态和停止状态间的转换:
&&&&*停止状态到就绪状态:当每一个filter被置为就绪态时,它便准备好从上一个filter接收sample。source
filter是最后一个被置为就绪态的filter,它创建数据流线程并开始传递sample。因为所有下游filter都处于就绪状态,所以没有一个filter会拒绝接收sample。当graph中所有的renderer都接收到一个sample后,filter graph manager才彻底完成状态转换工作(实时源除外)。
&&&&*就绪状态到停止状态:当一个filter停止时,它释放了所有它保存的sample,就将解除所有上游filter调用GetBuffer时的阻塞。如果filter正在Receive方法中等待数据,则它停止等待并从Receive中返回,从而解除阻塞。因而,此时当filter graph manager再去将上游filter转换为停止状态时,它已经不再阻塞于GetBuffer和Receive,从而可以响应停止命令。上游filter在得到停止命令前可能会传递下一些过时的sample,但下游filter不再接收它们,因为此时下游filter已处于停止状态了。
3.4.5. 拉模式
&&&&在IMemInputPin接口中,上游filter决定哪些数据要被发送,然后将数据推到下游filter中去。但是在某些情况下,拉模式会更加合适。在拉模式中,只有当下游filter从上游filter中请求数据时,数据才被传递下去,数据流动由下游filter发起。这种类型的连接使用接口。
&&&&典型的拉模式应用是文件回放。比如,在一个AVI回放graph中,Async File Source filter完成一般的文件读操作并将数据作为字节流传递下去,没有什么格式信息。AVI Splitter filter读取AVI头并将数据流分解成视频和音频sample。AVI Splitter比Async
File Source filter更能决定它们需要哪些数据,因此需用IAsyncReader接口来代替IMemInputPin接口。
&&&&要从输出pin请求数据,输入pin调用下面方法中的一个:
&&&&*IAsyncReader::Request
&&&&*IAsyncReader::SyncRead
&&&&*IAsyncReader::SyncReadAligned
&&&&第一个方法是异步的,支持多重读操作。其余的是同步的。
&&&&理论上,任一个filter都能支持IAsyncReader,但是实际上,它仅仅在连接有一个parser filter的source filter上使用。分析器(parser)非常象一个推模式的source filter,当它就绪时,它创建一个数据流线程,从IAsyncReader连接中拉数据并将其推到下一游filter中去。它的输出pin使用IMemInputPin,graph余下的部分使用标准的推模式。
3.5 DirectShow中的事件通告
&&&&这一节主要描述在directshow filter graph中事件是怎样发生的,以及应用程序如何接收事件通告并响应它们。
3.5.1 概述
&&&&一个filter通过发送一个事件通来通知filter graph manager某个事件已经发生。这些事件可以是一些预知的事件比如流结束事件,也可以是一些异常如render流时失败。一部分事件由filter graph manager自己处理,另一部分则由应用程序来处理。如果filter graph manager不处理某个事件,那么这个事件会被放入到队列中去。filter
graph也可以通过队列将自己的事件发送给应用程序。
&&&&应用程序从队列中接收事件并根据其类型来响应它们。DirectShow中的事件通告类似于windows的消息队列机制。应用程序可以让filter graph manager取消对指定的事件类型的默认操作,而是将它们放入事件队列由应用程序来处理它们。
&&&&由于这样的机制,使我们能做到:
&&&& *filter graph manager与应用程序的对话
&&&& *filter可以即和应用程序也和filter graph manager对话
&&&& *由应用程序来决定处理事件的复杂度。
3.5.2 从队列中取事件
&&&&Filter Graph Manager暴露3个支持事件通知的接口:
&&&& *IMediaEventSink 包含filter发送事件的方法
&&&& *IMediaEvent 包含应用程序取事件的方法
&&&& *IMediaEventEx 继承扩展IMediaEvent接口
&&&&filter通过在filter graph manager上调用IMediaEventSink::Notify方法来发送事件通告,一个事件通知由一个表示事件类型的事件号,和两个DWORD类型用以放置附加信息的参数组成。按事件号的不同,这两个参数可以是指针、返回值、参考时间或者其它信息。完整的事件号和参数列表,参见Event Notification codes()。
&&&&要从事件队列中取事件,应用程序需要在filter graph
manager上调用IMediaEvent::GetEvent事件。这个方法一直阻塞到取到事件或超时。一旦队列中有了事件,这个方法就返回事件号和两个事件参数。在调用GetEvent后,应用程序应该总是调用IMediaEvent::FreeEventParams方法来释放与事件参数相关的所有资源。比如,一个参数可能是由filter graph分配的BSTR值。
&&&&下面的代码是一个如何从队列中取事件的框架:
long evCode, param1, param2;
&&while (hr = pEvent-&GetEvent(&evCode, &param1,
&param2, 0), SUCCEEDED(hr))
&&&&&&tch(evCode)&
&&&&&&&&&&// Call
application-defined functions for each&
&&&&&&&&&&// type of event
that you want to handle.
&&&&&&hr = pEvent-&FreeEventParams(evCode,
param1, param2);
&&要重置filter graph manager默认的事件处理过程,调用IMediaEvent::CancelDefaultHandling方法,用事件号做参数。你可以通过调用IMediaEvent::RestoreDefaultHandling方法来恢复某个事件的处理过程。如果filter graph对某个事件号没有默认处理过程,则调用上面两个方法不产生任何影响。
3.5.3 当事件发生时
&&&&要处理DirectShow事件,应用程序需要一个方法来知道事件何时正等待在队列中。Filter Graph Manager提供两种方法:
&&&&*窗口通告:一旦有事件发生,Filter Graph
Manager就发送一个用户自定义窗口消息来通知应用程序窗口
&&&&*事件信号:如果有DirectShow事件在队列中,filter graph manager就触发一个windows事件,如果队列为空,则reset这个事件。
&&&&应用程序可以使用任何一种方法,但通常窗口通告方法相对比较简单。
&&&窗口通告:
&&&&要设置窗口通告,调用IMediaEventEx::SetNotifyWindow方法并指定一个私有消息,私有消息可以是从WM_APP到0xBFFF的任一个。一旦filter
graph manager把一个新的事件通告放入队列中,它便发送这个消息给指定的窗口。应用程序从窗口的消息循环中来响应这个消息。
&&&&下面是如何设置通知窗口的例子:
#define WM_GRAPHNOTIFY WM_APP + 1&& //
Private message.
&&pEvent-&SetNotifyWindow((OAHWND)g_hwnd, WM_GRAPHNOTIFY, 0);
&&消息是一个普通的windows消息,并且独立于DirectShow消息通告队列被发送。使用这种方法的好处是大部分应用程序拥有一个消息循环,因此,要知道DirectShow事件何时发生便无需做额外的工作了。
&&下面是一段如何响应通告消息的框架代码:
LRESULT CALLBACK WindowProc( HWND hwnd, UINT msg, UINT
wParam, LONG lParam)
&&&&&&tch (msg)
&&&&&&&&&&case
WM_GRAPHNOTIFY:
&&&&&&&&&&&&&&HandleEvent();&&//
Application-defined function.
&&&&&&&&&&&&&&
&&&&&&&&&&// Handle other
Windows messages here too.
&&&&&&return (DefWindowProc(hwnd, msg, wParam,
&&&&&&因为事件通告与消息循环均为异步进行的,因此在应用程序响应事件时队列中可以会有多个事件。而当事件变为非法时,它们会从队列中被清除掉。所以在你的事件处理代码中,调用GetEvent直至返回一个表示队列已空的失败代号。
&&&&在释放IMediaEventEx指针前,请以NULL作参数调用SetNotifyWindow方法来取消事件通告。并且在你的事件处理代码中,在调用GetEvent前检查IMediaEventEx指针是否合法。这些步骤可以防止在释放IMediaEventEx指针后应用程序继续接收事件通告的错误。
&&&&事件信号:
&&&&Filter Graph Manager建立一个反映事件队列状态的手工重设事件(manual-reset event)。如果队列中包含有未处理的事件通告,Filter Graph
Manager就会发信号给手工重设事件。如果队列是空的,则调用IMediaEvent::GetEvent方法会重设(reset)事件。应用程序可以通过这个事件来确定队列的状态。
&&&&注意:此处的术语可能被混淆。手工重设事件是由windows的CreateEvent函数创建的一种事件类型,它与由DirectShow定义的事件无关。
&&&&调用IMediaEvent::GetEventHandle方法得到手工重设事件的句柄,调用一个函数如WaitForMultipleObjects来等待发送给手工重设事件的信号。一旦收到信号,就可以调用IMediaEvent::GetEvent来接收DirectShow事件了。
&&&&下面的代码举例说明了这种方法。在取得事件句柄后,在100毫秒时间间隔内等待发送给手工重设事件的信号,如果有信号发来,它调用GetEvent然后在windows控制台上打印出事件号和事件参数,循环在EC_COMPLETE事件发生后结束,这标志着回放结束。
&&HANDLE&&hE&
&&long&&&&evCode, param1, param2;
&&BOOLEAN bDone = FALSE;
&&HRESULT hr = S_OK;
&&hr = pEvent-&GetEventHandle((OAEVENT*)&hEvent);
&&if (FAILED(hr)
&&&&&&/* Insert failure-handling code here. */
&&while(!bDone)&
&&&&&&if (WAIT_OBJECT_0 ==
WaitForSingleObject(hEvent, 100))
&&&&&&&&&&while (hr =
pEvent-&GetEvent(&evCode, &param1, &param2, 0),
SUCCEEDED(hr))&
&&&&&&&&&&{
&&&&&&&&&&&&&&printf("Event
code: %#04x\\n Params: %d, %d\\n", evCode, param1, param2);
&&&&&&&&&&&&&&pEvent-&FreeEventParams(evCode,
param1, param2);
&&&&&&&&&&&&&&bDone
= (EC_COMPLETE == evCode);
&&&&&&&&&&}
&&&&因为Filter Graph会在适当的时候自动重设事件,因此你的应用程序应当不去作重设工作。同时,当你释放filter graph时,filter graph会关闭事件句柄,因此在这之后你就不能再使用事件句柄了。
3.6. DirectShow中的时间和时钟
&&&&这一节主要概述DirectShow体系中时间和时钟。
3.6.1. 参考时钟
&&&&Filter Graph Manager的一个功能,能够以同一个时钟来同步所有在graph中的filter,称作参考时钟(reference clock)。
&&&&任何暴露了IReferenceClock接口的对象都能够作为一个参考时钟来使用。参考时钟可以由一个DirectShow filter来提供,例如可以直接使用硬件时钟的audio
renderer。另外,Filter Graph Manager也能使用系统时间来作参考时钟。
&&&&名义上,一个参考时钟以千万分之一秒的精度来度量时间,但是实际上的精度不会这么高。要取得参考时钟的当前时间,调用IReferenceClock::GetTime方法。由于时钟的基准时间,即时钟开始时的时间计数,是依赖于具体的实现的,因此GetTime的返回值不反映绝对时间,只反映相对于graph开始时的相对时间。
&&&&虽然参考时钟的精度是变化的,但是GetTime的返回值却保证是单调递增的,换句话说,也就是参考时钟的时间是不会回退的。如果参考时钟的时间是由硬件源产生的,而硬件时钟回退了(比如,有一个调节器调节了时钟),GetTime依然返回最晚的那个时间只到硬件时钟追上它。要知道更多的内容可以参考CBaseReferenceClock类()。
&&&&&&&&当Graph运行时,Filter Graph Manager会自动选择参考时钟,选择参考时钟的规则如下:
&&&&*如果应用程序指定了一个时钟,则使用这个时钟;
&&&&*如果Graph包含了一个支持IReferenceClock的活动源filter(即推模式源filter),则使用这个filter;
&&&&*如果Graph未包含任何支持IReferenceClock的推模式源filter,使用任何一个支持IReferenceClock接口的filter,选择的次序是从Renderer filter开始依次向上。已连接的filter优先于未连接的filter被选。(如果这个graph会render一个音频流,则这个规则通常就会选择audio renderer filter来作为参考时钟)
&&&&*如果没有filter支持合适的时钟,则使用系统参考时钟。
&&&&应用程序可以在Filter Graph Manager上调用IMediaFilter::SetSyncSource方法来选择时钟,只有在由于你有一个特殊原因想要选择自己的时钟时才需要这么做。
&&&&想要让Filter Graph Manager不使用任何参考时钟,可以调用SetSyncSource,参数为NULL。比如,你需要尽可能快地来处理sample时,就可以这么做。要恢复黑认的参考时钟,在Filter Graph
Manager上调用IFilterGraph::SetDefaultSyncSource方法。
&&&&当参考时钟发生变化时,Filter Graph Manager会通知每一个filter调用它的IMediaFilter::SetSyncSource方法,应用程序无需调用filter的这个方法。
3.6.2. 时钟时间
&&&&DirectShow定义了两种相关时间:参考时间(reference time)和流时间(stream time)
&&&&*参考时间是一个绝对时间,由参考时钟返回
&&&&*流时间是一个相对于graph最后开始时的相对时间
&&&& ·当graph处于运行态时,流时间等于参考时间减去起始时间
&&&& ·当graph处于暂停态时,流时间停留在暂停的那一刻
&&&& ·在重新定位后,流时间被重设为0
&&&& ·当graph处于停止态时,流时间无意义
&&&&如果一个媒体样本有一个时间戳t,表示这个在流时间为t时被render,正因为这个原因,因此流时间也被叫做呈现时间(presentation time)。
&&&&当应用程序调用IMediaControl::Run运行graph时,Filter Graph Manager调用每个filter的IMediaFilter::Run。为了补偿消耗在运行每个filter的时间总和,Filter Graph Manager会略微晚一点来定义起始时间。
3.6.3. 时间戳
&&&&时间戳定义了媒体样本的起始和结束时间。时间戳有时被称作呈现时间(presentation time)。在阅读余下的文章时,一个必须记住的要点是并非所有的媒体格式都以相同的方式来使用时间戳。举个例子,并不是所有MPEG样本都被打上了时间戳,在MPEG Filter Graph中,时间戳在被解码前并非应用在每个帧上。
&&&&当一个renderer filter接收到一个样本时,它以时间戳为基准来确定render时间。如果样本来晚了,或者这个样本没有时间戳,那个filter就立刻render它,否则,filter就等在那直到合适的时机。(通过IReferenceClock::AdviseTime方法来等待样本的render时间)
&&&&源filter和语法解析filte使用下列原则,在它们处理的样本上设置合适的时间戳:
&&&&*文件回放:第一个样本被打上起始时间戳,为0,后面的时间戳由样本长度和回放速率来决定,这些都由文件格式来决定。分析文件的filter负责计算出合适的时间戳。例子见()
&&&&*音视频采集:每个样本都被打上一个起始时间戳,这个时间戳与当它被捕获时的Stream time相同。应注意以下几点:
&&&& ·从预览pin(Preview Pin)出来的样本没有时间戳。因为图像处理的延时,一个打上采集时间的视频帧总是会迟一点到达视频renderer。这会导致在进行质量控制时,renderer会丢弃部分视频帧。关于质量控制,参见()
&&&& ·音频采集:音频采集filter使用它自己的缓冲集,而并非使用音频驱动程序的。音频驱动以固定的时间间隔来填充采集filter的缓冲。这个时间间隔由驱动决定,通常不超过10毫秒。在音频样本上的时间戳反映的是驱动填充采集filter时的时间,因此会有偏差,尤其是当应用程序使用一个很小的缓冲区时。不过,媒体时间可以精确地反映缓冲区中音频样本的数量。
&&&&*混合filter(Mux filter):依赖于输出格式,一个mux filter可能需要由它来产生时间戳,也可能不需要。举个例子,AVI文件格式使用固定的帧率而没有时间戳,因此AVI Mux filter假设那些样本在近似正确的时间内到达。如果样本没有在合适的时间间隔内到达,AVI Mux filter会插入}

我要回帖

更多关于 直播为什么要用采集卡 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信