没有合适的资源?快使用搜索试试~ 我知道了~
首页Directshow开发的基本技巧.doc
Directshow开发的基本技巧.doc
4星 · 超过85%的资源 需积分: 7 69 下载量 163 浏览量
更新于2023-03-16
评论
收藏 144KB DOC 举报
Directshow开发的基本技巧文档,对于Directshow的初学者比较有用,可以参考一下。
资源详情
资源评论
资源推荐
Directshow
开发的基本技巧
摘要:本篇文档主要讲述了
Directshow
开发的一些基本概念和技巧
1
视频播放(
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);
结束时一定要清理现场
无窗口模式
当采用无窗口的模式时,就没有必要暴露
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);
}
处理窗口消息
因为
VMR
没有自己的窗口,所以当视频需要重画或者改变的时候你要通知它。
1
当你接到一个
WM_PAINT
消息,你就要调用
IVMRWindowlessControl::RepaintVideo
来重画视频
2
当你接到一个
WM_DISPLAYCHANGE
消息,你就要调用
IVMRWindowlessControl::DisplayModeChanged.
3
当你接到一个
WM_SIZE
消息时,重新计算视频的位置,然后调用
SetVideoPostion
。
下面的代码演示了
WM_PAINT
消息的处理
void OnPaint(HWND hwnd)
{
PAINTSTRUCT ps;
HDC hdc;
RECT rcClient;
GetClientRect(hwnd, &rcClient);
hdc = BeginPaint(hwnd, &ps);
if (g_pWc != NULL)
{
// Find the region where the application can paint by subtracting
// the video destination rectangle from the client area.
// (Assume that g_rcDest was calculated previously.)
HRGN rgnClient = CreateRectRgnIndirect(&rcClient);
HRGN rgnVideo = CreateRectRgnIndirect(&g_rcDest);
CombineRgn(rgnClient, rgnClient, rgnVideo, RGN_DIFF);
// Paint on window.
HBRUSH hbr = GetSysColorBrush(COLOR_BTNFACE);
FillRgn(hdc, rgnClient, hbr);
// Clean up.
DeleteObject(hbr);
DeleteObject(rgnClient);
DeleteObject(rgnVideo);
// Request the VMR to paint the video.
HRESULT hr = g_pWc->RepaintVideo(hwnd, hdc);
}
else // There is no video, so paint the whole client area.
{
FillRect(hdc, &rc2, (HBRUSH)(COLOR_BTNFACE + 1));
}
EndPaint(hwnd, &ps);
}
尽管我们要自己处理
onpaint
消息,但是已经非常简单了。
2
如何处理事件通知(
Event Notification
)
当一个
Directshow
的应用程序运行的时候,在
filter Graph
内部就会发生各种
各样的事件,例如,一个
filter
也许发生数据流错误。
Filter
通过给
graph
mangaer
发送事件通知来和
graph
通信,这个事件通知包括一个事件码和两个事
件参数。事件码表示发生事件的类型,两个参数用来传递信息。
剩余15页未读,继续阅读
ljwjldx
- 粉丝: 5
- 资源: 10
上传资源 快速赚钱
- 我的内容管理 收起
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
会员权益专享
最新资源
- 27页智慧街道信息化建设综合解决方案.pptx
- 计算机二级Ms-Office选择题汇总.doc
- 单链表的插入和删除实验报告 (2).docx
- 单链表的插入和删除实验报告.pdf
- 物联网智能终端项目设备管理方案.pdf
- 如何打造品牌的模式.doc
- 样式控制与页面布局.pdf
- 武汉理工Java实验报告(二).docx
- 2021线上新品消费趋势报告.pdf
- 第3章 Matlab中的矩阵及其运算.docx
- 基于Web的人力资源管理系统的必要性和可行性.doc
- 基于一阶倒立摆的matlab仿真实验.doc
- 速运公司物流管理模式研究教材
- 大数据与管理.pptx
- 单片机课程设计之步进电机.doc
- 大数据与数据挖掘.pptx
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论2