VC+DirectShow对视频进行图片处理之六

来源:互联网 发布:淘宝充值平台怎么弄 编辑:程序博客网 时间:2024/04/30 12:03
程序的效率和其他问题

  1. 性能

  在DS 封装类中我写了几个GDI画图函数,可以比较方便的显示图片,不过效率低下,我曾发现它的效能竟比D3D画 3D场景还差。这是GDI 的问题,大概它没有很好利用显卡而依赖CPU的缘故吧。所以我在使用 D3D 的时候顺便用上了 ID3DXSprite 接口,它是在没有 DirectDraw的情况下很好的2D 画图工具,而应用了DX 的特性使它效率很高,充分使用显卡加速,很容易做到旋转、缩放、透明等功能,效率很高。不过应注意一个问题:通常看到的D3D 初始化程序都是为得到最大的3D 效能,即使没干什么CPU占用率也会直上到100%,而播放视频文件一般都需要解码,CPU 都让D3D 占去后就没法流畅解码视频,所以应该这样创建D3D 设备,完成初始化:

m_pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING|D3DCREATE_MULTITHREADED,&d3dpp,&m_pd3dDevice)
  一定要加上一个D3DCREATE_MULTITHREADED,让D3D 解箍 CPU,D3D不忙的时候降至 0%,当然了,3D 效能会减掉一些,不过效果尚可。

  还有一个,我发现程序运行需要占很多内存,但最小化后再打开就只占原来的一半左右,十分想不通。

  2.程序错误的修正

  为了程序正确运行,还要解决另一件事。您还记得回调函数吗?就是它惹起了祸。回调函数带来了灵活性的同时也带来了灾难。到目前为止我发现了两点。一是不能在里面调用DirectShow 对象,例如在里面调用 IMediaPosition 来设置进度条,这样当按下“停止”时会发现 IMediaControl 的Stop 方法不能返回,我认为是递归调用所引起的,因此绝对不能这样做,无法在Filter内采取任何措施防止这种情况。

  第二点直接体现灵活性弱点。想想我需要在回调函数中干些什么,我需要调用函数设置D3D纹理吧,那我就要处理纹理在Filter还运作过程中发生参数改变或被释放的问题,在播放过程中打开新文件或关闭程序都有可能发生这种情况。打开新文件时我们会先释放旧的Filter Graph再重建,释放并创建新的纹理会在启动播放后才进行,因为要得到视频参数,所以有可能Filter已经运作了而使用的纹理还是旧的,引起访问错误。DirectShow 的Filter Chain 有自己的线程,调用IMediaControl 的Stop 并不能让它一下子停下来,突然关闭程序就有可能使纹理释放比真正结束播放早,因为我们不会在回调函数中管理纹理而在D3D类中进行管理,关闭时纹理会随D3D类的释放而释放。

  我刚解决问题的办法很稀奇古怪,也许任何一个大虾都反对,不过它工作的很好。定义一个BOOL变量,在打开文件时先把它设为FALSE,结束打开时再设为TRUE,并重载对话框的OnDestroy函数,在该函数中把BOOL变量设为FALSE,这样在回调函数开始处检查此变量,为FALSE时直接返回。后来发现把回调函数设为NULL也可,而且似乎更好。

  3.与其他实用程序相比

  其实微软为DirectShow新配备的VMR9可以无缝与D3D结合,更有很多强大的功能,绝非我写的Filter可比,不过我懒于学习使用它,自认为写Filter比学习它更容易。从VMR9可以自动提供纹理给D3D使用,我萌生一个想法:能不能在一个D3D中创建纹理给另一个D3D 使用呢?我要进行验证。

  最近得到一个叫做“CamTrack”的软件,它很厉害,自带的人脸跟踪功能自不必说,它还能自动侦测到摄像头的使用,在比Filter更低的层级就接收并处理了数据,并把处理后的数据作为摄像头数据传送下来!我惊呆了,好像要从摄像头的WDM 驱动模型去找突破口,但完全没有头绪。

  4.界面

  除了技术落后、结构混杂之外,我的程序还有很大的一个缺陷:界面丑陋,元素排列不合理。这是因为我不熟悉MFC,也不懂得如何设计界面造成的,所以您看到的我的程序是古板的win98 样式,用起来可能很不就手。我初三暑假开始接触编程,一直用了3年多VB6,鄙视VC,转到VC编程还是近大半年的事,虽已乐不知返却从没想过要努力学MFC,毕竟VC.net的net界面编写已不再依赖MFC了,它更像VB,更易用,只是程序载入到界面显示很慢,我用的VC.net2003 是这样。

  全文总结

  这一刻我期待已久,写点东西真的很苦。整个程序只用了简单的逻辑,但编码却不能说很短,进行试验更是花费了很多精力,真是“成如容易却艰辛”。

  在这次编写中我的体会良多,记得看过这样一句话“没写过一万行代码的项目是不会懂得软件工程的”,此时真的把它奉为真理了,想我这个程序才多大点儿,文件已有七八个,平时我看文件有几个的程序都感到头疼,更不敢想象上万行程序的管理,可能管理上花的精力比编码更多。在标准化工厂里,工人都被分工,他们可能不知道自己在干什么,只有管理人员才对一切了如指掌。如果生产的是软件,单会编码的程序员就只能做埋头的工人了,更高层次由不编码的管理人员掌握,事实也是这样。我还发现有时花在界面的时间比所谓的核心功能还多,正如为了控制发动机和轮子,汽车在控制方面要花费很多,而在舒适的驾驶环境和新潮的外型方面更要努力,因为必须要为人所用、易用、好用。现在回过头看所写的Filter,它的确是各种功能的基础,仅此而已,编码的比重并不大。总的说,我的感想是:现代软件开发应用的是现代工业生产模式,标准化、分工合作、流水线操作。当然,我的认识还很肤浅,请指正。 最让我苦恼的是 DirectShow 不支持 rm 文件,或者说 RealNetworks 不支持 DirectShow,毕竟 rm 的算法是保密的,这导致无法用我的程序欣赏很多美妙的影片,强烈希望大虾们用real sdk 写个 Filter 发布出来,让我等享用,我找不着real sdk。

  总算劳累后也有成果,总体效果没有受技术限制,再请看看几幅效果图,以结全文。程序路上,你我共勉。

 

 
原创粉丝点击