【转】[DirectShow] 033 - Using Windowed Mode

文章转自 http://blog.csdn.net/bwmwm/article/details/4423067

·        Note   The legacy Video Renderer Filter always uses windowed mode. The VMR-7 and VMR-9 filters use windowed mode by default, but also support windowless mode.

  • Video Renderer Filter 总是使用windowed模式。VMR-7和VMR-9默认使用windowed模式,也支持windowless模式。

In windowed mode, the video renderer creates its own window where it paints the video frames. Unless you specify otherwise, this window is a top-level window with its own borders and title bar.  Most of the time, however, you will attach the video window to an application window, so that the video is integrated into your application UI. This requires the following steps:

在windowed模式中,video renderer创建一个属于自己的窗口,并在这个窗口上绘制视频帧。除非你指定其他的,否则这个窗口是一个拥有边看和标题栏的顶层窗口。不过,绝大多数情况下,你将视频窗口贴到程序窗口上,以至于视频合并到你的应用程序UI上。这样做需要以下步骤:

1.   Query for IVideoWindow.

2.   Set the parent window.

3.   Set new window styles.

4.   Position the video window inside the owner window.

5.   Notify the video window of WM_MOVE messages.

1.   询问IVideoWindow。

2.   设置父窗口

3.   设置新的窗口风格。

4.   把视频窗口放置在程序窗口上。

5.   通知视频窗口WM_MOVE消息。

Query for IVideoWindow

Before starting playback, query the Filter Graph Manager for the IVideoWindowinterface:

回放之前,向Filter Graph Manager询问IVideoWindow接口:

IVideoWindow *pVidWin = NULL;

pGraph->QueryInterface(IID_IVideoWindow, (void **)&pVidWin);

Set the Parent Window

To set the parent window, call the IVideoWindow::put_Owner method with a handle to your application window. This method takes a variable of type OAHWND, so cast the handle to this type:

.调用IVideoWindow::put_Owner函数设置父窗口,参数就是父窗口的句柄。函数需要OAHWND类型的参数,所以要把句柄转换成这个类型:

pVidWin->put_Owner((OAHWND)hwnd);

Set New Window Styles

Change the style of the video window by calling the IVideoWindow::put_WindowStyle method:

调用IVideoWindow::put_WindowStyle函数改变视频窗口的风格:

pVidWin->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS);

The WS_CHILD flag sets the window to be a child window, and the WS_CLIPSIBLINGS flag prevents the window from drawing inside the client area of another child window.

WS_CHILD标记设置窗口为一个子窗口。WS_CLIPSIBLINGS标记防止画到其他窗口的客户区域。

Position the Video Window

To set the position of the video relative to the application window's client area, call the IVideoWindow::SetWindowPosition method. This method takes a rectangle that specifies the left edge, top edge, width, and height of the video window. For example, the following code stretches the video window to fit the entire client area of the parent window:

调用IVideoWindow::SetWindowPosition函数设置视频相对于应用程序窗口客户区域的位置。函数的参数代表视频窗口的左边,上边,宽和高。例如下面的代码拉伸视频窗口来适应整个父窗口的客户区域:

RECT rc;

GetClientRect(hwnd,& rc);

pVidWin->SetWindowPosition(0, 0, rc.right, rc.bottom);

To get the native size of the video, call the IBasicVideo::GetVideoSize method on the Filter Graph Manager. You can use that information to scale the video and keep the correct aspect ratio.

在Filter Graph Manager上调用IBasicVideo::GetVideoSize方法获得视频的原始大小。你可以使用这些信息来调整视频以保证正确的高宽比。

Respond to WM_MOVE Messages

For best performance, you should notify the video renderer whenever the window moves while the graph is paused. Call the IVideoWindow::NotifyOwnerMessage method to forward the WM_MOVE message:

为达到最佳效果,在graph暂停期间,只要窗口移动,就要通知video renderer。调用IVideoWindow::NotifyOwnerMessage函数发送WM_MOVE消息:

// (Inside your WindowProc)

case WM_MOVE:

   pVidWin->NotifyOwnerMessage((OAHWND)hWnd, msg, wParam, lParam);

    break;

If the renderer is using a hardware overlay, this notification causes the renderer to update the overlay position. (The VMR-9 does not use overlays, so you do not need to call this method if you are using the VMR-9.)

如果renderer使用了硬件overlay,这个通知消息就会导致renderer更新overlay的位置。(VMR-9没有使用overlay,所以如果使用VMR-9就不需要调用这个函数。)

Clean Up

Before the application exits, stop the graph and reset the video window's owner to NULL. Otherwise, window messages might be sent to the wrong window, which is likely to cause errors. Also, hide video window, or else you might see a video image flicker on the screen momentarily:

程序退出之前,停止graph并重新设置视频窗口的拥有者为NULL。否则,窗口消息将发送到错误的窗口,有可能产生错误。而且,隐藏视频窗口,否则可能会看到一个视频图像在屏幕上闪烁。

pControl->Stop();

pVidWin->put_Visible(OAFALSE);

pVidWin->put_Owner(NULL);

  • Note   If the parent of the video window is a child of your main application window (in other words, if the video window is a child of a child), you should create the video window using CoCreateInstance and add it to the graph, instead of letting the Filter Graph Manager add the video renderer during Intelligent Connect. This ensures that the video window and your child window are repainted at the same time. Otherwise, the child window may paint over the video window.
  • Note 如果视频窗口的父窗口是程序主窗口的子窗口(换句话说,如果视频窗口是子窗口的子窗口),你应该使用CoCreateInstance创建一个视频窗口,把它加入到graph中,而不是在智能连接的时候由Filter Graph Manager添加video renderer。这可以确保视频窗口和你的子窗口在同一时刻被重绘。否则,子窗口的绘制会覆盖掉视频窗口。

 

转载于:https://www.cnblogs.com/xuehuzaifei/p/3210402.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值