directshow vmr9抓屏能否生成flv

=====如何用DirectShow抓屏啊!=====
[问题点数:50分,结帖人ablewindy]
=====如何用DirectShow抓屏啊!=====
[问题点数:50分,结帖人ablewindy]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
2005年12月 专题开发/技术/项目大版内专家分月排行榜第二
相关帖子推荐:
2005年12月 专题开发/技术/项目大版内专家分月排行榜第二
2006年4月 总版技术专家分月排行榜第一
2006年3月 总版技术专家分月排行榜第三
本帖子已过去太久远了,不再提供回复功能。&回复: 高效屏幕录制
&回复: 高效屏幕录制
有相关的优秀的开源的软件?
&回复: 高效屏幕录制
&回复: 高效屏幕录制
jiangsheng : 你好,前一段时间我研究了一下VNC的源代码,发现现在最好的截屏方法是Mirror Driver,ultravnc就是用了这种技术,可是它的这部分代码并没有公开。我搜索到有一个有一个Winvncdrv也实现了这个功能,但是网上提 供的网址不能够访问了。不知道你是否有这方面编程经验或者源代码。 我的邮箱地址是,希望能够得到你的回复。
&回复: 高效屏幕录制
经验没有,不过WindowsDDK里面好像有Mirror Driver的例子
&回复: 高效屏幕录制
请教,如果做一个远程遥控软件,截取屏幕用哪种方法比较好?
&回复: 高效屏幕录制
你说: 某些使用DirectX等技术的程序可能无法录制,例如大多数游戏和媒体播放器 请问: 对于使用了DirectX的游戏来说,有没有办法录制?
&re: 高效屏幕录制
唉, 近段时间我被win32下的屏幕录制和屏幕广播弄得焦头烂额, 不知道大家可否交流一下这方面的经验, 这段时间里我分析了RealVNC的源码:包括VNCHook,WinVNC的屏幕截取方法,双缓冲管理方法和VNCViewer的刷写方法, 另 外,看了这篇文章后,我又看了一遍,MIRROR Driver的源码(这东西微软没有更新win 2k 的DDK和win2003 的DDK的都是一样的),对两种屏幕录制的方法(像VNC哪样在用户模式下的屏幕截取,和像一般商业的教学软件里的,在内核模式下的屏幕截取)大致了解, 但是无法结合两种方法的优点~~~~。 针对这两种屏幕录制,我有以下感觉: VNC-like:VNC很巧妙地利用了 Win32下的消息机制,通过系统钩子的通知和GDI引擎的位传送(BitBlt)在 DibSection上完成屏幕截取,并且通过双倍桢缓冲机制减少传送像素数据所需的网络带宽,VNC能做成这样,确实是很让我惊讶,但是,在 RealVNC自己写的WinVNC里面,我觉得,Win32的消息机制会造成屏幕截取的较大延迟,而且使用了BitBlt来截屏,照样是截取不了 DirectX或电影的画面,另外,在用户模式下,VNC的内存容量、带宽的占用是很大的(在bpp下,需要3 X
bytes约等于4~5M的空间,另外还有3条线程在协调工作) Mirror-Driver-like:Mirror Driver的好处是可以直接利用硬件,达到用户模式下让人难以企及的“实时”,然而,在内核模式下却好像难以利用VNC哪种钩子带来的好处(CPU占用 率低,因为需要历遍的像素数量少得多),最大的问题还是在于我不知道怎样把内核模式里面的数据怎样带到用户模式中去(因为要发送到网络上~~~~~~~) shit~~~ GetCurrentImage(...)好像可以把DirectX的图像也截取下来,不知道能不能替代BitBlt来完成所有的屏幕截呢~~~~~~~? 希望能与正在从事这方面开发的程序员交流一下
&re: 高效屏幕录制
VNC很大的,代码我也没看全 可以去看文档,有问题去邮件列表问
&re: 高效屏幕录制
请问:用什么方式可以达到高帧率,低消耗呢?我看到一个软件捕捉屏幕的速度远高于vnc而其cpu开销只有vnc的1/3。高手可否告知其使用的是什么捕捉屏幕的方法?
&re: 高效屏幕录制
那可能是从设备驱动层抓的图
&re: 高效屏幕录制
因为要做屏幕广播,所以也在研究了一点屏幕抓图,我看的源码是 UltraVNC 说点经验及问题: (1)两者差别 驱动方式(推模式)Mirror Driver: 优点:占用CPU资源少(1-5%),速度快。实时性高。 缺点:a. window 2000/xp/2003支持,98不支持。 b. 装完驱动需重新启动方能使用。 HOOK方式(拉模式)HOOK: 优点:系统支持广泛,装后不需要重启就能使用。 缺点:占用CPU资源大。 解决方法:两种都开发,window 2000/xp/2003系统采用驱动方动,其它系统使 用HOOK方式。 (2)问题 1)我已提取出了VNC中的驱动方式抓屏方法。 但在分析HOOK方式时,发现没有HOOK DLL也可以抓屏,而且CPU占有率也不是很高。怀疑是用全屏的方式定时抓的。 2)双缓冲管理方法是什么意思?有朋友可以解释一下吗? 我的MSN:,有从事这方面开发的程序员交流一下
&re: 高效屏幕录制
双缓冲或者多缓冲的技术去看看DirectShow的pin的采样数据区分配算法
&[Tech] 高效屏幕录制
Ping Back来自:blog.csdn.net
&re: 高效屏幕录制
呵呵,大家闹的好热闹。我这个菜鸟看的好高兴
&re: 高效屏幕录制
mirror中怎么得到Video buffer的地址?
&re: 高效屏幕录制
希望与从事VNC开发的人一起研究 下
&re: 高效屏幕录制
请问VNC不能捕获WINDOWS MEDIA PLAYER REALPLAY 播放的视频,大家最近采用什么来截屏啊,用DIRECTSHOW能不能捕获啊,我用directdraw捕获也捕获不到,windows media player 播放的视频,捕获结果就是屏幕+黑屏(播放的视频)
&re: 高效屏幕录制
to softworm,是不是在故弄玄虚呀,mirror driver的源码能看出什么名堂来,你能否说说看,比如Applications如何通过GDI或者是其他方式取得屏幕图像数据的。
&re: 高效屏幕录制
我有一个程序是通过一个service来调用,利用GETDC抓屏幕,在登录进系统时抓屏幕没有问题,但一旦注销或者锁定用户状态时,就抓出黑屏,怎么回事呢?请指教!该service已经设置为交互操作了 msn:
&re: 高效屏幕录制
注销或者锁定用户状态时系统切换到了另一个桌面。
&re: 高效屏幕录制
呵呵 这个东西 的确具有吸引力 我研究了近2年 可以用n中方法去实现!
&re: 高效屏幕录制
我用bitblt来截屏,鼠标会闪烁, 如果用DirectX截屏,是否可以避免鼠标会闪烁?
&re: 高效屏幕录制
双缓冲可以避免闪烁
&re: 高效屏幕录制
swordxie是用什么方法抓屏啊? 是不是DirectX的效率最高啊?
&re: 高效屏幕录制
看了您的blog《高效屏幕录制》和评论,觉得很有收获。其中您有一句话“注销或者锁定用户状态时系统切换到了另一个桌面。 ”。我想知道在这种状态下如何截屏?希望您能给一个方法或者思路,谢谢了。 我的邮箱:
&re: 高效屏幕录制
其实可以直接用winvnc中间的那两个文件,*.sys & *.dll, winvnc源码中封装了对他们的调用。可以看看源码。 况且搞一个mirror也没有什么了不起。
&re: 高效屏幕录制
to softworm : Mirror 怎么可以直接利用硬件呢?
&re: 高效屏幕录制
可以使用openinputdesktop获得当前活动的桌面来截屏。具体代码可以i参考vnc的源代码。
&re: 高效屏幕录制
好像WinVNC/TightVNC也截不了金山词霸的取词窗口
&re: 高效屏幕录制
屏幕捕获,可以只采用BITBLT的方式,在网络情况好的情况下,可以达到每秒15帧左右,主要是因为GETDIBS这个函数花费了太多的时间(大约30-50ms一帧)有谁有方法取代这个函数吗???
&re: 高效屏幕录制
屏幕捕获,可以只采用BITBLT的方式,在网络情况好的情况下,可以达到每秒15帧左右,主要是因为GETDIBS这个函数花费了太多的时间(大约30-50ms一帧)有谁有方法取代这个函数吗??? 读取数据我用的是读显存缓冲区,内存COPY
&re: 高效屏幕录制
我想问一下用GDI来抓屏的效率高,还是用DirectX来抓屏的效率高?
&re: 高效屏幕录制
GDI32 DirectX is much slower
&re: 高效屏幕录制
不知道那里可以找到VNC的代码文档,干看代码的话很痛苦啊~~
&re: 高效屏幕录制
花了几天时间硬着头皮分析了realvnc的代码(初学者,刚拿到代码的时候都不知道程序流程是什么样的,汗),主要是想把其中屏幕截取的部分拿出来单独 做个屏幕录取的功能。程序别别扭扭地有个模样了,这时候我发现调用BitBlt函数的时候鼠标会闪烁,晕,回头看vnc运行的情况,发现vnc server端的主机鼠标也会闪,不过不是特别明显。有两个问题想不通,一是display那部分的代码我几乎没改,直接拿来用,为什么好像我的闪得厉害 些(错觉??);二是如何能避免鼠标闪烁?看到有同志说是用双缓冲,不懂,只知道双缓冲往屏幕上贴图的时候用,不知道截屏也要用。唉,看了别人的代码,就 知道自己有多少水水了。不过,整个vnc代码基本被我看懂了,呵呵,收获啊,网上居然没有初学者文档,没有人写一份么?
&re: 高效屏幕录制
小弟毕业设计做的就是这个,要求低CPU使用率,现在就遇到上面说的GetDIBits()函数CPU使用率过高的情况。 发现网上的屏幕广播的软件这方面做的很不错,基本上都用了虚拟显卡Mirror的。不知哪里有这个Mirror的使用方法介绍,或者如果有直接读取显存的方法还望不吝赐教。
&re: 高效屏幕录制
今天看了一下,发现高CPU使用率的是BitBlt(),不是GetDIBits(),现在只期望直接读显存了
&re: 高效屏幕录制
又用directdraw直接读显存试了一下,发现大部分的CPU都用在memcpy()从显存复制数据上了,对此我非常不解,用memcpy()复制同 样大小的非显存的内存数据CPU使用率只有一点点,而且写入同样大小的内存数据到显存,CPU使用率也不是很高,不知为何唯独复制出来的如此耗费CPU
&re: 高效屏幕录制
不知Mirror Driver的原理是什么,是截屏的时候是根据画面变化复制一部分的变化区数据吗?那是不是和HOOK差不多了,为什么上面的说一者CPU使用率低,一者CPU使用率高啊?希望哪位提点一下,小弟没有源码
&re: 高效屏幕录制
关于Bitblt耗时的问题, 其实是硬件结构决定的, 并不是Bitblt慢。 Bitblt的优化做的非常的精良,有兴趣的可以参考一下MSDN中的光栅操作码的介绍。 针对与截取屏幕,我以前在非常古老的计算机上作过测试, DELPHI + GDI 和 VC + DirectX的速度相近,甚至前者还略略胜出些。 所以说, 在这个方面, DirectX并无优势可言。
&re: 高效屏幕录制
使用Bitblt拷贝屏幕内容, 其数据需要从显存传输到内存,经过低速繁忙的总线,自然比从内存到内存的数据拷贝慢得多。 不过现在AGP(4x, 8x)的广泛使用以及pcix的开始, 这个瓶颈正在逐步的消失。 显存=&内存 vs 内存=&内存 对于老式机器来说(低速agp,甚至是pci),差别至少是一个数量级,甚至是两个。 对于当前的流行机器来说,应该在5倍以内。可以预见,如果pcix应用起来, 有一天从显存拷贝数据比从内存拷贝快也不是没有可能。
&re: 高效屏幕录制
针对 显存 =〉内存 的瓶颈, 我还有个听起来很悖论的猜测:那就是某些低档的集成主板或者显卡,处于节省成本的原因,划分了一部分的系统内存当成显存来用。 如果结构合理的话,这个瓶颈就自然消失了。
&re: 高效屏幕录制
请问楼上,如果是显存=〉内存存在瓶颈以至于速度慢,那么为什么内存=〉显存速度就快呢?而且Mirror Driver的也总要有个显存=〉内存的步骤吧,所以我觉得速度慢不完全是这个原因。 它应该还经过了些别的步骤吧,问题是用什么可以绕过这些步骤。
&re: 高效屏幕录制
很好,那么该怎么录制呢
&re: 高效屏幕录制
//snk 这样可以映射显存,要在内核模式下运行,取得显卡的HANDLER首先,EngDeviceIOControl要自己从导入表中算出来,效果并没有想像的好,读写显存慢的很 int MapVideoMemory(){ DWORD NumR static BOOL bFirst=TRUE; VIDEO_MEMORY videoMemory = {0}; VIDEO_MEMORY_INFORMATION videoMemoryInformation = {0}; if(globalDrv && funcList.EngDeviceIoControl && bFirst){ DbgPrint("MapVideoMemory"); __try{ VIDEO_MODE_INFORMATION modeI funcList.EngDeviceIoControl(globalDrv,IOCTL_VIDEO_QUERY_CURRENT_MODE,NULL, 0,&modeInformation,sizeof(VIDEO_MODE_INFORMATION),&NumRet); DbgPrint("stride %d",modeInformation.ScreenStride); DbgPrint("bitmap width %d VisScreenWidth %d",modeInformation.VideoMemoryBitmapWidth, modeInformation.VisScreenWidth); DbgPrint("NumberRedBits %d NumberGreenBits %d NumberBlueBits %d",modeInformation.NumberRedBits ,modeInformation.NumberGreenBits,modeInformation.NumberBlueBits); DbgPrint("RedMask %d GreenMask %d BlueMask %d 0x%x",modeInformation.RedMask ,modeInformation.GreenMask,modeInformation.BlueMask,modeInformation.AttributeFlags); funcList.EngDeviceIoControl(globalDrv,IOCTL_VIDEO_MAP_VIDEO_MEMORY,&videoMemory, sizeof(VIDEO_MEMORY),&videoMemoryInformation,sizeof(VIDEO_MEMORY_INFORMATION),&NumRet); bFirst=FALSE; uFramebufferLength=videoMemoryInformation.FrameBufferL if(videoMemoryInformation.FrameBufferLength&videoMemoryInformation.VideoRamLength){ uFramebufferLength=videoMemoryInformation.VideoRamL } pGVideo=(char*)videoMemoryInformation.FrameBufferB DbgPrint("FrameBufferBase 0x%x FrameBufferLength 0x%x VideoRamBase 0x%x VideoRamLength 0x%x", pGVideo,uFramebufferLength,videoMemoryInformation.VideoRamBase, videoMemoryInformation.VideoRamLength); } __except(EXCEPTION_EXECUTE_HANDLER){ DbgPrint("Catch Error When MapVideoMemory"); } } CreateVideoShareMemory(); return 0; }
&re: 高效屏幕录制
我下了一个VNC的代码 可是服务器端编译有错,有一个文件找不到,想自己写程序调用VNC的驱动,可是头都看大了就是调用不成功。 那位大虾有调用VNC Mirror Driver 的例子,请帮赐教。不胜感激。我的邮箱:
&re: 高效屏幕录制
Cannot open include file: 'aclui.h': No such file or directory 这个文件找不到,请问是什么原因 ?请多多指教。我的邮箱:
&re: 高效屏幕录制
用钱买也可以商量
&re: 高效屏幕录制
&re: 高效屏幕录制
一个问题请教: 象HyperSnap那样的抓图软件截图方式很多, 其中包括扩展活动窗口截图 和 滚屏截图, 用扩展活动窗口截图方式截图时, 能设置要截取的窗口的宽和高的像素大小(可以大于屏幕的像素大小),然后截取该窗口完整的图像, 怎样编程实现呢??? 另, snapit这种软件能进行DOS截屏, 又怎样编程实现呢?
&re: 高效屏幕录制
各位高手: 象HyperSnap那样的抓图软件截图方式很多, 其中包括扩展活动窗口截图 和 滚屏截图, 用扩展活动窗口方式截图时, 能设置要截取的活动窗口的宽和高的像素大小(可以大于屏幕的像素大小),并能截取该窗口完整的图像,怎样编程实现啊??? 另, 像snapit那样的抓图软件能进行DOS截屏, 又怎样编程实现呢???我想大概分以下两种情况来分析 1. 在Windows Vista, Windows XP, Windows 2000 Professional, Windows NT Workstation, Windows Me, Windows 98, or Windows 95上运行的DOS窗口时, 如何获取DOS窗口的句柄, 因为一旦获取窗口的句柄, 就能轻松编程截取该窗口的图像.在Windows XP及其后的Windows平台, 有GetConsoleWindow函数获取DOS窗口的句柄, 而Windows 98, Windows 95却没有, 怎样才能在上述所有平台上获取DOS窗口的句柄呢?? 在全屏DOS窗口下, 情况是否相同呢?? 2. 在纯DOS环境下, 怎样做到按一下某个按键, 自动在后台启动指定的程序并能截取当前DOS屏幕的图像??(如果指定的程序已经启动, 则截取当前DOS屏幕的图像), 再按一下另一个键, 则退出指定的程序, 上述如何编程实现啊???
&re: 高效屏幕录制
我也很奇怪,显存 =〉内存很慢,直接写显存似乎很快。 另外我也有GDI方式的屏幕捕获,效果比mirror也差不太多。 另外还有直接HOOK 显卡驱动的方式,这种方式效率应该是最高的,我还没有完全做好。
&re: 高效屏幕录制
Cannot open include file: 'aclui.h': No such file or directory 这个文件找不到,请问是什么原因 ?请多多指教。我的邮箱:
添加sdk,应该就可以了吧
&re: 高效屏幕录制
我最近在写一个类似REALVNC的东西,实现了最简单的抓屏和鼠标/键盘操作,做完后才发现了频繁BitBlt非常之消耗CPU的问题.简直气炸了.如 果用我自已的笔记本(迅驰1.5,ATI9700显卡)做SERVER的话,CPU只占30~40%,但如果用我公司的烂机器跑SERVER的话(P4, 烂2D显卡,4M显存那种),CPU跑到80~99%,真是太慢啦,查来查去原来就是这个BitBlt,而且更奇怪的是,我把这部分代码提出来,在另一个 程式里跑,也只有40~50%啊,真是怪死了.
&re: 高效屏幕录制
最近我也需要写截屏方面的代码,我用GDI方式截屏时,截不下鼠标和播放的视频,是不是用DirectShow方式就可以了呢?另外读显存是不是能够把鼠标和视频都截下来呢?有没有读显存的资料呢?
&re: 高效屏幕录制
各位大侠可否提供一个vnc的源码下载?找的头都晕了
&re: 高效屏幕录制
谁把WinVnc的代码改成Delphi的了,这样参与研究的人一定多很多,C++我不懂,我正用Delphi搞这个。
&re: 高效屏幕录制
我的邮箱llbbg_.cn
&re: 高效屏幕录制
请问有哪位高手解决了“VNC不能捕获WINDOWS MEDIA PLAYER REALPLAY 播放的视频”问题了?或者哪位知道如何用directdraw直接从显存中读取(屏幕)数据?麻烦给小妹一份例子程序的源码,在此先谢过了:)
&re: 高效屏幕录制
啊,忘了附上email了:-p
QQ: 望指导,盼回复
&re: 高效屏幕录制
to snk 和所有热心人, EngDeviceIoControl(globalDrv,IOCTL_VIDEO_QUERY_CURRENT_MODE,NULL,..) 函数中 globalDrv怎么获得?
&re: 高效屏幕录制
忘了问: 显存基址开始存放的数据是RGB值吗,具体格式是不是 0xbbggrr?
&re: 高效屏幕录制
有没有软件实现屏幕实时25桢录制的办法? 先谢谢了...
&re: 高效屏幕录制
请问一下VNC是用的TCP还是UDP啊? 如果用UDP也可以实现的话,那我也研究研究。
&回复: 高效屏幕录制
Cannot open include file: 'aclui.h': No such file or directory 我的出现了这个问题!请高手指点一下!怎么解决呢 MSN:
&回复: 高效屏幕录制
delphi等等都可以用
&回复: 高效屏幕录制
厉害,想请教各位
&回复: 高效屏幕录制
直接memcpy显存 显然很慢 内存到内存快得多 问题在于这是显存和内存的数据复制 想BitBlt和memcpy都是不符合性能要求的 另 显卡驱动不是IRP驱动的 IRP模型比较慢一点
&回复: 高效屏幕录制
用.net 可不可以做啊,我不会VC这些
&回复: 高效屏幕录制
&回复: 高效屏幕录制
看看我做的
有GDI和DRIVER2种。
&回复: 高效屏幕录制
to roger:先把你做的基于realvnc的源码拿来研究一下好吗?
&回复: 高效屏幕录制
有谁做好的源码可以拿出来供大家参考吗? 现在国内的软件都没有国外的好,希望大家多把不涉及到商业机密的源码公开一下,大家共同进步!
&回复: 高效屏幕录制
查过一些资料,好像用netmeeting sdk和windows media format sdk也可以做这些远程控制的软件,这里怎么没有谈到这些的,是不是效率比较低??
&回复: 高效屏幕录制
windows media sdk效率相当低,我的机子P43.0,6600显卡,用了之后cpu占用高达90%,开个大点的应用就很慢了。
&回复: 高效屏幕录制
最近本人也在研究VNC源码,待我搞透后,肯定公布自己开发的相关源码,打击下国内那些只想着Money的人的气焰。
随笔 - 148
积分与排名
阅读排行榜
评论排行榜怎样不通过文件共享来播放某个远程机上的VCD文件
[问题点数:200分,结帖人thedream]
怎样不通过文件共享来播放某个远程机上的VCD文件
[问题点数:200分,结帖人thedream]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
本帖子已过去太久远了,不再提供回复功能。DirectShow实现抓图(Delphi) - 好工具站长分享平台
DirectShow实现抓图(Delphi)
& , Messages, SysUtils, Variants, Classes, Graphics, Controls, ms,
& Dialogs, StdCtrls,shlobj, ExtCtrls,&&&&& {TFlatButtonUnit,TFlatPanelUnit,TFlatbarUnit,}
&&& FlatBars, FlatBtns, FlatUtils, FlatP
&//====================窗体类==========================//
& TForm1 = class(TForm)
&&& open: TOpenD&&& //打开对话框控件
&&& FlatPanel1: TFlatP //FlatPanel控件
&&& Button1: TFlatB&&& //按钮控件
&&& Button2: TFlatB&&&&& //按钮控件
&&& FlatTitlebar1: TFlatT //Titlebar 控件
&&& FlatButton1: TFlatB& //按钮控件
&&& FlatButton2: TFlatB&&& //按钮控件
&&& //窗口事件
&&& procedure FormClose(Sender: TO var Action: TClosction);&&&& //窗口关闭事件
&&& procedure FormShow(Sender: TObject);& //窗口显示事件
&&& procedure Button1Click(Sender: TObject); //Button1的Click事件
&&& procedure Button2Click(Sender: TObject); //Button2的Click事件
&&& procedure FlatButton1Click(Sender: TObject); //FlatButton1的Click事件
&&& procedure FlatButton2Click(Sender: TObject);& //FlatButton2的Click事件
&&& { Private declarations }
&&& mtv:&&&& //名
&&& { Public declarations }
&&&& fillcolor:TC&& //需要填充的颜色
&&& catchcolor:TC&& //需要抠出的颜色
&&& detal:B&&&&&&&&& //颜色误差范围
&&& procedure CreatD&&& //创建Directshow环境
&&& Procedure D&&&& //释放Directshow环境资源
&&& pr&&&&&& //捕捉视频图象,并做处理
& Form1: TForm1;& //定义窗体对象
implementation
{$R *.dfm}
Directshow9,obj,DSutil, Unit2; //包含附加的单元。Directshow9为DirectX SDK中Directshow的DELPHI单元文件
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //comobj为DELPHI的COM的单元
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //DSUtil为DIRECTSHOW的DELPHI单元
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //Unit2为 设置窗口 的单元
& //==================变量定义部分===============//
FilterGraph:IGraphBlder=& //Directshow的IGraphBuilder,用于Directshow的
iaControl:IMediaControl= //Directshow的IMediaControl接口,用于播放,暂停,停止
&VideoRender:IBaseFilter=& //Directshow的IBaseFilter接口,IBaseFiler是Directshow中所有Filter的基类.此处是保存的VMR Video Filter
&SampleGrabber:ISampleGrabber=//Directshow的ISampleGrabber接口,此接口存在于SampleGrabber Filter上,用这接口可从 SampleGrabber Filter中获得视频图象颜色信息
&id:integer=0;//调试所用,用于在DIRECTSHOW SDK自带的 graphedt工具中申明个ID ,用于调试。
//===================函数实现部分===============//
{DELPHI函数格式简介:
& 1.procedure 名称 (参数) ;&& //如果没有参数则省略"()"
&&& //局部变量申明
&&& var //变量申明
&&& MediaRect:TR//其中MediaRect为变量名称,TRect为变量类型
&&&& ...&&&&&&& //函数体部分
&&&&&& // begin.....end 结构类似于C++中的 {.......}
{& 2.function 函数名称(参数):返回值类型; //如果没有参数则可以省略"()"
&&&&& //局部变量申明
&&& var //变量申明系统关键字
&&& MediaRect:TR//其中MediaRect为变量名称,TRect为变量类型
&&&& begin
&&&& ...&&&&&&& //函数体部分
&&&& result:=...;//result为返回值变量,不需要自己,它代表函数的返回值变量,":="为DELPHI的赋值符号&
&&&&&& // begin.....end 结构类似于C++中的 {.......}
procedure TForm1.CreatD
//函数局部变量申明部分
MediaRect:TR&&&& //区域局部变量,用于设置视频在窗口显示的区域
pType:_AMMEDIATYPE; //视频媒体类型变量,用于设置SampleGrabber Filter的接收视频的类型(如告诉系统:接受的为视频信息,视频内部图象格式为RGB32位)
Video:IVideoW&&&& //Directshow的IVideoWindow接口,用于对视频的显示窗口做设置(例如:设置其父窗体)
& FilterGraph:=CreateComobject(CLSID_FilterGraph) as IGraphB& //创建Directshow中的FilterGraph COM对象并返回IGraphBuilder接口
& VideoRender:=createcomobject(CLSID_VideoMixingRenderer) as IBaseF //创建Directshow中的VideoMixingRenderer Filter COM对象并返回IBaseFilter接口
& SampleGrabber:=createcomobject(CLSID_SampleGrabber) AS ISampleG& //创建Directshow中的SampleGrabber Filter COM对象并返回ISampleGrabber接口
& Filtergraph.AddFilter(VideoRender,'VideoRender'); //在Filtregraph框架中添加刚创建的VideoMixingRenderer Filter
& FilterGraph.AddFilter(SampleGrabber as IBaseFilter,'SampleGrabber'); //在Filtregraph框架中添加刚创建的SampleGrabber Filter
& fillchar(ptype,sizeof(_AMMEDIATYPE),0);//对ptype变量初始化
&& ptype.majortype:=MEDIATYPE_V//设置主类型为视频格式
& ptype.subtype:=MEDIASUBTYPE_RGB32; //设置辅助类型为RGB32(就是接受视频流为RGB32的,FilterGraph会加入相应的转换Filter)
&& ptype.formattype:=FORMAT_V& //设置媒体信息格式为FORMAT_VideoInfo格式
&&& SampleGrabber.SetMediaType(pType);//将SampleGrabber Filter的类型设置为pType变量所指定的类型
&&& SampleGrabber.SetBufferSamples(true);//将SampleGrabber Filter设置为缓冲模式
&FilterGraph.RenderFile(pwidechar(mtv),nil); //完成播放指定文件的所有Filter连接
&VideoRender.QueryInterface(IID_IVideoWindow, VideoWindow);//从VideoRender中获得IVideoWindow接口
& Videowindow.put_Owner(OAHWND(FlatPanel1.Handle));&& //设置视频窗口的父窗体为FlatPanel控件
&& Videowindow.put_windowstyle(WS_CHILD or WS_Clipsiblings);&& //设置视频窗体为子窗体,剪裁类型
&Videowindow.put_Left(0);//设置视频窗体的LEFT
&Videowindow.put_Top(0);//设置视频窗体的TOP
&Videowindow.put_Width(FlatPanel1.Width); //设置视频窗体的Width
&Videowindow.put_Height(FlatPanel1.Height);//设置视频窗体的Height
&Videowindow.put_Visible(true); //让视频窗体可见
&FilterGraph.QueryInterface(IID_IMediaControl,MediaControl);//从FilterGraph中获得IMediaControl接口
&dsutil.AddGraphToRot(filterGraph,id); //GraphEdit所用的ID,可以方便在GraphEdit控件中调试
procedure TForm1.FreeD
dsutil.RemoveGraphFromRot(id);&& //清除在GraphEdit中注册的ID
&& if VideoRender&&nil then VideoRender:=&& //释放VideoRender
&& if FilterGraph&&nil then FilterGraph:=&& //释放FilterGraph
&& IF SampleGrabber&&NIL THEN SampleGrabber:=NIL;//释放SampleGrabber
procedure TForm1.FormClose(Sender: TO var Action: TCloseAction);
& //释放Directshow环境
procedure TForm1.FormShow(Sender: TObject);
open.DefaultExt:=extractfiledir(lication.ExeName); //设置打开对话框的打开默认,为程序的当前路径
&if open.Execute=false then& //如果没有打开的文件,则关闭程序
&if trim(open.FileName)='' //如果打开文件的文件名为空,则关闭程序
&if not fileexists(open.FileName) //如果打开不存在的文件,则关闭程序
& mtv:=open.FileN //将打开窗口中选择的文件的名称赋值给MTV变量
CreatD& //创建Directshow环境
//============抓图处理关键代码部分==============//
procedure TForm1.
ptype:_AMMEDIATYPE; //视频媒体类型变量,详细介绍见,CreateDirectshow函数部分
buf:&&&&&&&& //用于存放获得的视频的缓冲区
bmphead:tagB//BMP的文件头结构体变量
BMPINFO:PB//BMP图片的文件头结构体指针变量
bmpcore:tagBITMAPC //BMP图片的Core头结构体变量
tream:TF& //DELPHI的文件流类型变量
catch,current,fill:
test1,test2,test3,test4,test5,test6:
& MediaControl.P& //播放暂停
& SampleGrabber.GetConnectedMediaType(ptype);&& //获得SampleGrabber Filter上的PIN上的连接类型
& size:=0;
& SampleGrabber.GetCurrentBuffer(size,nil);//获得SampleGrabber Filter上的缓冲区大小
&&&&&& buf:=allocmem(size);& //分配buf
&&&&&& SampleGrabber.GetCurrentBuffer(size,buf);//获得视频的当前数据,保存到buf中
&&& if& (ptype.cbFormat=sizeof(VIDEOINFOHEADER))& and (ptype.pbFormat&&nil) and (IsEqualGUID(ptype.formattype,FORMAT_VideoInfo)) then //判断Sampler Grabber中的输入Pin上的类型是否满足的要求
&&&&&&& begin
&&&&&&&&&&& //=设置bmp Head部分=//
&&&&&&&&&&& with bmphead do
&&&&&&&&&&& begin
&&&&&&&&&&&&& bftype:=$4d42;
&&&&&&&&&&&&& bfsize:=sizeof(tagBitmapfileheader);
&&&&&&&&&&&&& bfreserved1:=0;
&&&&&&&&&&&&& bfreserved2:=0;
&&&&&&&&&&&&& bfOffBits:=bfsize+sizeof(tagBITMAPCoreheader);
&&&&&&&&&&&
&&&&&&&&&&&& bmpinfo:=PBitmapinfoheader(@(ideoinfoheader(ptype.pbFormat).bmiHeader));
&&&&&&&&&&&& step:=bmpinfo.biBitCount
&&&&&&&&&&&& bmpcore.bcSize:=sizeof(tagBITMAPCoreheader);
&&&&&&&&&&&& bmpcore.bcWidth:=bmpinfo.biW
&&&&&&&&&&&& bmpcore.bcHeight:=bmpinfo.biH
&&&&&&&&&&&& bmpcore.bcPlanes:=1;
&&&&&&&&&&&& bmpcore.bcBitCount:=bmpinfo.biBitC
&&&&&&&&&& if catchcolor&&fillcolor then
&&&&&&&&&&&& begin
&&&&&&&&&&&&& catch:=COLORTORGB(Catchcolor);
&&&&&&&&&&&&& fill:=COLORTORGB(fillcolor);
&&&&&&&&&&&&& fill:=RGB(GETBValue(fillcolor),GETGValue(fillcolor),GetRValue(fillcolor));
&&&&&&&&&&&&& current:=0;
&&&&&&&&&&&&& for i:=0 to bmpinfo.biWidth*bmpinfo.biHeight-1 do//循环查找视频图象颜色中的数据
&&&&&&&&&&&&&&& begin
&&&&&&&&&&&&&&&& Current:=PInteger(Pchar(buf)+i*step)^;
&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&& if (abs(GetBValue(Current)-GetRValue(catch))&=detal) and (abs(GetGValue(Current)-GetGValue(catch))&=detal) and (abs(GetRValue(Current)-GetBValue(catch))&=detal) then //判断当前像素中的颜色是否抠像填充条件
&&&&&&&&&&&&&&&&&&& begin
&&&&&&&&&&&&&&&&&&&&&&& PInteger(pchar(buf)+i*step)^:=//填充用户设置的填充颜色
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
&&&&&&&&&&&&
&&&&&&&&&&& try
&&&&&&&&&&&&&&&& filestream:=TFilestream.Create(Extractfiledir(Application.ExeName)+'/抓下来的视频图.bmp',fmCreate& or fmOpenWrite);& //创建FileStream视频流
&&&&&&&&&&&&&&&& filestream.WriteBuffer(bmphead,bmphead.bfSize);//将bmphead变量中的数据写入流中
&&&&&&&&&&&&&&& filestream.WriteBuffer(bmpcore,sizeof(tagBITMAPCoreheader)); //将bmpcore变量中的数据写入流中
&&&&&&&&&&&&&&&& filestream.WriteBuffer(buf^,size); //将buf指针所指向的数据写入流中
&&&&&&&&&&&&&&&& windows.MessageBox(handle,'抓图!','提示',MB_ICONINFORMATION);//提示用户,抓图成功
&&&&&&&&&&& finally
&&&&&&&&&&&&&&& filestream.F//释放Filestream视频流
&&&&&&&&&&&&&&
&&& freemem(buf);&& //释放Buf所占用的空间
MediaControl.R//重新播放
procedure TForm1.Button1Click(Sender: TObject);
& MediaControl.R//播放视频
& button1.Enabled:=& //将Button1按钮设为不可用
& button2.Enabled:=&& //将Button2按钮设置为可用
procedure TForm1.Button2Click(Sender: TObject);
catchpicture();&&& //调用自己编写的抓图处理函数
procedure TForm1.FlatButton1Click(Sender: TObject);
& //关闭窗体,也将关闭程序
procedure TForm1.FlatButton2Click(Sender: TObject);
&form2.ShowM//显示FORM2窗体(模态显示,也就是你关闭了FORM2,才能操作程序的其他窗体)
.Net 文章一周点击
.Net 文章一月点击
HaoGongJu.Net ( 好工具 ) All Rights Reserved

我要回帖

更多关于 directshow sdk 的文章

 

随机推荐