VMR9的定制AP

转载 2011年02月22日 11:06:00

http://blog.csdn.net/foruok/archive/2008/07/27/2719724.aspx

 

我要在3D场景中播放电影,或者把电影作为纹理来使用。
    有两个办法,一个是写一个video render,用它来接管filter graph的最终输出,将视频数据拷贝到我们的私有纹理上,然后在合适的时候来使用它(主要是在D3D相关的主循环中)。
    另一个是利用VMR9。VMR9允许我们自己提供Allocator-Presenter,以便完成一些特殊的需要。我们提供自己的A/P,VMR9会调用AP的PresentImage函数来做实际的渲染。我们可以在这里把视频数据旁路到私有纹理中。
    第一个办法比较麻烦,因为视频解码后的格式多种多样,这些你都要自己处理。比如YUV、RGB565、RGB32、YUY2等等,乱七八糟。当我播放输出为YUY2的电影时由于我的video render只接收RGB格式,ActiveMovie窗口弹了出来,大煞风景。
    而用后一种办法,上面这些东西VMR9都帮你处理好了,你所要的只是一个StretchRect调用而已!
    SDK中有个MultiVMR9(Samples/cpp/DirectShow/VMR9/MultiVMR9/MultiPlayer)和GamePlayer(Samples/cpp/DirectShow/VMR9/MultiVMR9/MultiPlayer)的例子,还有一个VMR9Allocator(Samples/C++/DirectShow/VMR9/VMR9Allocator),这几个例子相当有用。GamePlayer构造了一面电影墙,效果很酷。
    不过在这些例子中,D3D是作为视频播放流程的附属而存在。我们现在想反过来,D3D为主,视频播放为副,平常主要是3D渲染,视频播放可以没事儿一边自我娱乐,把解码好的视频拷贝到一个纹理上,当3D场景想起它了,直接拿来用。
    OK,研究一下VMR9Allocator。似乎修改下面几点就可以完成了。
    1. 构造CAllocator时传递D3D和D3DDEVICE给它
    2. 在InitializeDevice函数中,调用AllocateSurfaceHelper 创建文理后再创建一个私有纹理
    3. 在PresentImage中把视频拷贝到私有文理
    4. 提高GetVideoTexture接口,允许D3D部分获取视频纹理用作渲染
    
    确实是这么回事,但是在实际操作时我遇到了一些问题,怎么都解决不了,花了我两天时间!
    1. AllocateSurfaceHelper总是失败
    2. 旁路的视频断断续续
    
    第一个问题,我不需要分配带有VMR9AllocFlag_TextureSurface标记的纹理表面,只需要分配offscreen surfaces。于是我这样做:lpAllocInfo->dwFlags = VMR9AllocFlag_OffscreenSurface;(GamePlayer中也是这么做的,而且没问题),然后调用AllocateSurfaceHelper ,结果总是失败!
    第二个问题更严重,我只能得到有限的几桢图象。

    后来在网上(http://www.gamedev.net/community/forums/topic.asp?topic_id=380264,http://www.gamedev.net/community/forums/topic.asp?topic_id=455515)查到需要用IVMRMixerControl9接口的SetMixingPrefs方法来设置MixerPref9_RenderTargetYUV标记。这样VMR9就不再需要纹理表面而可以只需要离乒表面,同时也不会切换render target。于是我们可以得到完整且连续的视频。不过必须是windows xp sp2以上的系统才可以(http://msdn.microsoft.com/en-us/library/ms788177.aspx)。
    我实验了一下,没有结果,后来发现SetMixingPrefs的调用顺序非常关键!一旦你放错了位置,不但达不到你要的效果,可能会更糟。我遇到了这么几个问题:
    1. 查询不到接口,返回E_NOTIMPL
    2. 得到了接口,设置了MixerPref9_RenderTargetYUV,没什么效果
    3. 设置MixerPref9_RenderTargetYUV后以VMR9AllocFlag_TextureSurface为标记调用AllocateSurfaceHelper 会失败
    
    一头雾水,后来把这个调用放到RenderFile之前,AdviseSurfaceAllocator和AdviseNotify调用之后,这样才可以了。不过在播放rmvb文件时出了莫名其妙的错误(待查)。我现在担心这么做之后,会有一些编码格式在播放时出现问题(假如它的解码filter只输出RGB格式?),这里说明了它的一些限制http://msdn.microsoft.com/en-us/library/ms788177.aspx。
    在我查看GamePlayer及MultVMR9 DLL的源码时,发现它并没有像上面那样做,但依然可以正常使用。可见很有可能是我的一些用法不太正确。

    这里提一下使用VMR9定制A/P的步骤,因为WINDOWS XP默认使用VMR7,我们要自己把VMR9加到filter  graph中。SDK中有相关的文档可以看,按那个办法是可以的,不过比较麻烦。上面提到的几个例子是这么做的:
    1. 创建filter graph
    2. 创建VMR9实例并加入到graph中
    3. 配置VMR9为renderless模式
    4. 查询IVMRSurfaceAllocatorNotify9接口
    5. 创建定制的A/P 
    6. 建议VMR9使用你的A/P(调用IVMRSurfaceAllocatorNotify9::AdviseSurfaceAllocator)
    7. 把allocator notifier提供给你的A/P(AdviseNotify)
    8. 调用RenderFile或者其他方法,让graph智能建立剩余的graph
    9. 查询IMediaControl,IMediaEvent等等接口供后续使用
    10. 删除filter graph时,先停止graph,再断开VMR9的所有pin并将其A/P设为NULL 

    文档在Samples/C++/DirectShow/VMR9/MultiVMR9下面VMR9Multi_Help.htm。我感觉这个文档比directshow的SDK中说的要明白。

VMR9的定制AP

    我要在3D场景中播放电影,或者把电影作为纹理来使用。    有两个办法,一个是写一个video render,用它来接管filter graph的最终输出,将视频数据拷贝到我们的私有纹理上,然...
  • foruok
  • foruok
  • 2008年07月27日 15:45
  • 5227

VMR9的定制AP

http://blog.csdn.net/foruok/archive/2008/07/27/2719724.aspx我要在3D场景中播放电影,或者把电影作为纹理来使用。    有两个办法,一个是写一...
  • zzz822163
  • zzz822163
  • 2009年01月09日 16:26
  • 1856

在Directshow中使用VMR9

声明:欢迎任何人和组织转载本blog中文章,但必须标记文章原始链接和作者信息。  本文链接:http://blog.csdn.net/li_007/archive/2010/03/02/5338976...
  • li_007
  • li_007
  • 2010年03月02日 14:56
  • 6071

VMR9 图像视频混合模式介绍

MixerPref_NoDecimation在渲染到表面时不改变视频的原始大小MixerPref_DecimateOutput视频尺寸的改变为2的整数倍MixerPref_DecimateMask内部...
  • islyb
  • islyb
  • 2007年06月19日 18:03
  • 2158

利用DSHOW中的VMR9 filter 将视频渲染成纹理 供D3D使用

先说下VMR9,这个 filter是个视频混合的组件,可以很方便的将多路视频合成一路视频,添加字幕和静态图片,这个组件的内部实现采用了DX9的接口。如果想把VMR9混合输出后的视频图像当作纹理渲染到3...
  • R_hgt
  • R_hgt
  • 2015年04月23日 11:38
  • 1468

使用VMR9采集n个视频的一帧到一张位图

近来看DirectX 9.0文档,越来越觉得它功能的强大。结合目前解决的一个问题: 即采集多个视频源的一帧到一张位图。它需要用到DirectX中的VMR。 VMR是新一代的video renderer...
  • mapper
  • mapper
  • 2008年01月31日 11:54
  • 4456

使用VMR9+D3D解码和播放视频

VMR-9是DirectShow的渲染filter,可以修改它的allocator-presenter实现获取解码数据并自己渲染...
  • xfgryujk
  • xfgryujk
  • 2016年10月30日 10:37
  • 1084

屏幕监控编程

This documentation specifically refers to the Windows Vista extensions for DirectX graphics. To deve...
  • frankshcn
  • frankshcn
  • 2011年05月19日 15:45
  • 1025

D3D下使用VMR9播放视频文件

随着DX开发包的不断升级,其提供给媒体程序开发人员的接口功能也空前强大起来。本文就D3D下使用VMR9播放视频向初学者谈谈心得。高手请止步(不想让你看了吐血^_^)。        早在DX8时代,S...
  • zzz822163
  • zzz822163
  • 2009年01月09日 16:01
  • 2479

深入浅出VMR7、VMR9、Video Renderer,Media菜鸟进阶

在使用KMP、MPC等播放器时,我们对DirectShow视频渲染器总是一头雾水,到底什么是VMR7、VMR9?让我们先从Video Renderer和Overlay Mixer说起。一、Video ...
  • suck666
  • suck666
  • 2010年01月08日 13:59
  • 1871
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:VMR9的定制AP
举报原因:
原因补充:

(最多只允许输入30个字)