DShow之使用VMR进行Windowless控制

一般步骤:
  1. 创建Graph Builder接口
  2. 创建VMR接口并加入到GraphBuiler中
  3. 查询IVMRFilterConfig接口设置VMR为VMRMode_Windowless模式;查询IVMWindowlessControl接口设置VMR的显示窗口为Application的窗口。
  4. Render视频文件
  5. SetVideoPositon设置视频显示的位置
  6. 查询IMedialControl接口并Run
  7. 相应WM_PAINT消息,注意分别重绘挖去视频窗口的背景和视频窗口(pWc->RepaintVideo)
  8. 清理工作(何时清理那些接口,目前还不清楚,以后再研究^_^)
 
 
还是先写注意吧,因为注意容易忘,而过程写起来比较困难些,呵呵
注意:
  1. 播放没有自己的窗口,是直接把视频绘制(Paint)在Application的窗口上的,所以当Application需要响应WM_PAINT消息的时候,要注意对视频的绘制(Paint)。

    此时,Windowless的视频播放“窗口”(实际上是windowless的)和Application的窗口应该分开来单独重绘(相应WM_PAINT)。

    首先,检测Application的窗口上windowless的视频窗口中是否有video: if (pWc). 其中pWc是创建的IVMRWindowlessControl接口。如果pWc != NULL则表示有video,此时通过创建一个CombineRgn把windowless窗口挖去,先重绘这个CombineRgn,然后再调用 pWc->RepaintVideo重绘windowless视频窗口。即

    void OnPaint(HWND hwnd) 
    { 
        PAINTSTRUCT ps; 
        HDC         hdc; 
        RECT        rcClient; 
        GetClientRect(hwnd, &rcClient); 
        hdc = BeginPaint(hwnd, &ps); 
        if(g_pWc) 
        { 
            HRGN rgnClient = CreateRectRgnIndirect(&rcClient); 
            HRGN rgnVideo  = CreateRectRgnIndirect(&g_rcDest);  // Saved from earlier.
            CombineRgn(rgnClient, rgnClient, rgnVideo, RGN_DIFF);  // Paint on this region.
    
            HBRUSH hbr = GetSysColorBrush(COLOR_BTNFACE); 
            FillRgn(hdc, rgnClient, hbr); 
            DeleteObject(hbr); 
            DeleteObject(rgnClient); 
            DeleteObject(rgnVideo); 
    
            // Request the VMR to paint the video.
            HRESULT hr = g_pWc->RepaintVideo(hwnd, hdc);  
        } 
        else  // No video image. Just paint the whole client area. 
        { 
            FillRect(hdc, &rc2, (HBRUSH)(COLOR_BTNFACE + 1)); 
        } 
        EndPaint(hwnd, &ps); 
    } 

  2. VMR COM接口的类型是 IBaseFilter、 CoCreateInstance第三参数是IID_IBaseFilter
    Graph Buider的是IGraphBuilder、CoCreateInstance第三参数是IID_IGraphBuilder

  3. 创建了VMR实例接口后,应该把该Filter加入到Graph Builder中去。
    pGraph->AddFilter(pVmr, L"Video Mixing Render");  //第二个参数似乎可以随便取个名字,只是个名称而已

  4. 创建了VMR并加入到Graph Builder中后,应该配置VMR。这里需要先后查询两个接口:IVMRFilterConfig和IVMRWindowlessControl,设置渲染模式为windowless( pConfig->SetRenderingMode)、设置VMR的窗口为Application的窗口( pWc->SetVideoClippingWindow(hWinMain))

  5. 还需要指定windowless视频窗口在Application窗口中的位置:pWc->SetVideoPositon(&rcSrc, &rcDest)。这里有两个RECT,分别代表源视频的尺寸区域和要显示在窗口上的区域尺寸。可以通过pWc->GetNativeVideoSize((&lWidth, &lHeight, NULL, NULL)获得源区域尺寸,然后设定要取源画面的多少尺寸Rect:SetRect(&rcSrc, 0, 0, lWidth/2, lHeight/2)//此时只取源画面的1/2。再设定好显示的区域rcDest后用pWc->SetVideoPositon设定。

  6. COLOR_BTNFACE + 1是什么意思?好像+1不+1都差不多呀?
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值