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

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

在Directshow中使用VMR9

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

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

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

VMR9 图像视频混合模式介绍

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

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

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

关于VMR9AllocatorPresenter与多路视频播放实践

一、几种模式比较VMR9 Render在连接AllocatorPresenter时,可以为Renderer设置一个UserID。这个UserID与VMR9Renderer一一对应。HRESULT Se...
  • frankshcn
  • frankshcn
  • 2011-02-25 13:22:00
  • 1102

Linux WiFi AP Master Mode USB Chips|使用Linux做AP如何选择无线网卡?

1.IBM T43 Intel ipw2200 虽说有说法称驱动支持AP模式,但一则驱动太老,失去维护,二则基本编译不能通过,除非你用老版本kernel。 2.HostAP Driver 与 Hos...
  • cl2006ky
  • cl2006ky
  • 2014-12-19 11:14:55
  • 734

Directshow VMR9播放器

  • 2011年02月22日 15:28
  • 54KB
  • 下载

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

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

RT3070 AP模式移植 基于linux3.0内核

一、移植AP 模式驱动 1.1 下载文件 其实AP模式和STA模式的驱动不是同一个文件,我也是找了好久才找到的。现在分享一个链接 1.2 解压文件,并改文件名 1.2.1解压文件 tar -...
  • very__good
  • very__good
  • 2016-01-16 21:52:57
  • 899
收藏助手
不良信息举报
您举报文章:VMR9的定制AP
举报原因:
原因补充:

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