关闭

DShow之使用VMR进行Windowless控制

1676人阅读 评论(0) 收藏 举报
一般步骤:
  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
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:3233次
    • 积分:46
    • 等级:
    • 排名:千里之外
    • 原创:1篇
    • 转载:1篇
    • 译文:0篇
    • 评论:0条
    文章存档