DirectShow入门之Directshow的基本技巧 1

本文深入探讨了DirectShow中视频渲染的基本概念和技术细节,包括窗口模式与无窗口模式下的视频播放实现方法,以及如何设置视频位置等关键操作。

2006-10-13 07:00作者:智慧的鱼出处:天极开发责任编辑:方舟

摘要:本文主要讲述了Directshow开发的一些基本概念和技巧,主要内容如下: 

  1、视频播放(Video Rendering) 

  2、如何处理事件通知(Event Notification) 

  3、如何枚举系统的设备和过虑器 

  4、如何枚举Graph图中的对象(filter,pin) 

  5、Seeking Filter graph 

  6、如何设置Graph时钟(Setting Graph Clock) 

  视频播放(Video Rendering) 

  dshow的视频提交过滤器可以在窗口模式和无窗口模式下工作。在窗口模式下,过滤器创建一个自己的窗口,在里面播放视频。在无窗口模式下,过滤器直接将视频在应用程序提供的窗口上显示,过滤器本身不创建窗口。 

  窗口模式

  在窗口模式下,视频提交过滤器创建一个窗口,然后将视频祯帖到窗口上,你可以将这个窗口帖到你的应用程序的窗口。
Video Renderer只支持窗口模式,VMR-7 and VMR-9缺省的是窗口模式,也支持无窗口模式。

  为了在你的应用程序中显示视频,你可以将视频窗口设置成应用程序的子窗口。你可以通过

IVideoWindow *pVidWin = NULL;
pGraph->QueryInterface(IID_IVideoWindow, (void **)&g_pVidWin);
pVidWin->put_Owner((OAHWND)hwnd);
pVidWin->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS);
RECT grc;
GetClientRect(hwnd, &grc);
pVidWin->SetWindowPosition(0, 0, grc.right, grc.bottom);

  结束时一定要清理现场:

pControl->Stop(); 
pVidWin->put_Visible(OAFALSE);
pVidWin->put_Owner(NULL);

  无窗口模式

  当采用无窗口的模式时,就没有必要暴露IVideoWindow接口了。

  为了能够使用VMR的缺省行为,在构建Graph图之前必须要调整VMR。

  1、创建一个过虑器图表管理器

  2、创建一个VMR,加入到graph中

  3、调用VMR的IVMRFilterConfig::SetRenderingMode方法设置VMRMode_Windowless标志。

  4、调用IVMRWindowlessControl::SetVideoClippingWindow 给视频指定一个显示窗口。 

  然后调用IGraphBuilder::RenderFile或者其他的方法来创建其他的Graph。

  下面的代码显示了如何创建一个VMR,将其添加到Graph,如何设置无窗口模式

HRESULT InitWindowlessVMR( 
HWND hwndApp, // Window to hold the video. 
IGraphBuilder* pGraph, // Pointer to the Filter Graph Manager. 
IVMRWindowlessControl** ppWc, // Receives a pointer to the VMR. ) 

 if (!pGraph || !ppWc) return E_POINTER;
 IBaseFilter* pVmr = NULL; 
 IVMRWindowlessControl* pWc = NULL; 
 // Create the VMR. 
 HRESULT hr = CoCreateInstance(CLSID_VideoMixingRenderer, NULL, 
CLSCTX_INPROC, IID_IBaseFilter, (void**)&pVmr); 
 if (FAILED(hr))
 {
  return hr;
 }

 // Add the VMR to the filter graph.
 hr = pGraph->AddFilter(pVmr, L"Video Mixing Renderer"); 
 if (FAILED(hr)) 
 {
  pVmr->Release();
  return hr;
 }
 // Set the rendering mode. 
 IVMRFilterConfig* pConfig; 
 hr = pVmr->QueryInterface(IID_IVMRFilterConfig, (void**)&pConfig); 
 if (SUCCEEDED(hr)) 
 { 
  hr = pConfig->SetRenderingMode(VMRMode_Windowless); 
  pConfig->Release(); 
 }
 if (SUCCEEDED(hr))
 {
  // Set the window. 
  hr = pVmr->QueryInterface(IID_IVMRWindowlessControl, (void**)&pWc);
  if( SUCCEEDED(hr)) 
  { 
   hr = pWc->SetVideoClippingWindow(hwndApp); 
   if (SUCCEEDED(hr))
   {
    *ppWc = pWc; // Return this as an AddRef'd pointer. 
   }
   else
   {
    // An error occurred, so release the interface.
    pWc->Release();
   }
  } 
 } 
 pVmr->Release(); 
 return hr; 
}

  你也可以调用下面的函数

IVMRWindowlessControl *pWc = NULL;
hr = InitWindowlessVMR(hwnd, pGraph, &g_pWc);
if (SUCCEEDED(hr))
{
 // Build the graph. For example:
 pGraph->RenderFile(wszMyFileName, 0);
 // Release the VMR interface when you are done.
 pWc->Release();
}

  下面看看如何设置视频的位置

  有两个矩形需要考虑,一个是源矩形,一个是目的矩形。源矩形决定开始播放视频的位置,目的矩形决定在窗口显示视频的区域。VMR将源矩形按照目的矩形的大小进行扩展。

  IVMRWindowlessControl::SetVideoPosition可以设置两个矩形的大小,源矩形必须小于等于本地视频大小。你可以通过IVMRWindowlessControl::GetNativeVideoSize获取本地的视频区域大小。

// Find the native video size.
long lWidth, lHeight; 
HRESULT hr = g_pWc->GetNativeVideoSize(&lWidth, &lHeight, NULL, NULL); 

if (SUCCEEDED(hr))
{
 RECT rcSrc, rcDest; 
 // Set the source rectangle.
 SetRect(&rcSrc, 0, 0, lWidth/2, lHeight/2); 

 // Get the window client area.
 GetClientRect(hwnd, &rcDest); 
 // Set the destination rectangle.
 SetRect(&rcDest, 0, 0, rcDest.right/2, rcDest.bottom/2); 

 // Set the video position.
 hr = g_pWc->SetVideoPosition(&rcSrc, &rcDest); 
}

/---------------------------------------------------------------------\ * 书 名:《DirectShow开发指南》 * 作 者: 陆其明(著) 金邦飞(审校) * 内容提要: 本书以DirectX SDK 9.0版为蓝本,涉及的内容几乎涵盖了在Windows平台上使 用DirectShow进行C++编码的方方面面。全书共分4个部分。第1部分详细介绍了 DirectShow的基础知识。第2部分重点讨论了Filter的开发,以及DirectShow 应用程序的开发,包括目前非常流行的如音视频采集、数码摄像机的支持、非线性 编辑等应用。第3部深入分析了DirectShow SDK提供的部分典型源代码例子。第 4部分结合作者个人的一些开发实践,通过案例和开放源码分析,进一步介绍 DirectShow的实务应用。 本书完全忠实于DirectX SDK 9.0的帮助文档以及基类源代码,并结合作者多年 的实践,经过提炼而成。内容丰富,条理清晰,实用性强。适合广大的流媒体应用 开发人员,以及对Windows平台上多媒体处理感兴趣的编程爱好者、学生学习和参 考。 * 下载内容说明: readme.txt:本说明文件。 Chapter04:第4章用到的代码,其中AppIPTransform为MFC Filter的例子, DsDemo是一些演示代码,FilterTitleOverlay是字符叠加Filter的源代码。 Chapter05:第5章用到的代码,其中GraphBuilding为Filter Graph构建技术 的一些代码,SimplePlayer为一个简单的播放器例子。 Chapter07:第7章用到的代码,其中DsDemo是一些演示代码。 Chapter09:第9章用到的代码,其中DESCallback演示了控制DirectShow智能 连接的方法。 Chapter18:第18章用到的代码,其中MpegNetwork为“MPEG流的网络客户端播放” 实现的所有源代码(请打开Daisy.dsw浏览各项目)。 Chapter19:第19章用到的代码,其中DVD2AVI_1.77.3_SRC.zip为开放源码, FilterMpeg2VD为此开放源码基础上开发的MPEG-2 Video Decoder Filter例子。 除上述代码外,本书各章用到的其他代码均在DirectX SDK安装目录的Samples 子目录下可以找到。 * 备注: DirectX SDK 9.0以及DirectX 9.0运行时库可以到微软的网站上下载。 请访问微软的网站首页http://www.microsoft.com,然后输入DirectX进行搜 索;或者直接访问http://www.microsoft.com/directx下载运行时库,或者 http://www.microsoft.com/downloads/details.aspx?FamilyId=9216652F-51E0-402E-B7B5-FEB68D00F298&displaylang=en * 技术支持网站:http://hqtech.nease.net \---------------------------------------------------------------------/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值