您的位置:首页 > 其它

Directshow 学习入门

2014-01-24 11:47 441 查看
一、视频播放(Video Rendering)

视频播放(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);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: