问关于一个Directshow的问题..

Karja 2011-05-08 08:37:06
近期想使用DS和C++在VS中来写一个播放视频的小程序,但是发现播放的时候只有声音而没有图像。
查阅了很多网上的代码,貌似都是使用微软官网的一个SAMPLE。有用的信息也不多,外文网站大多都是使用C#或者版本比较老。所以东拼西凑的代码难免有问题。
我使用的是VRM的Windowless模式来播放,刚开始还以为是FILTER没有链接对,后来下载了FFSHOW的解码器安装并且利用GraphEdit来查看发现链接都是正确的,于是百思不得其解只好来这里求救了。还望各位多多指教
以下是代码:

//头文件
#include "Ra_Video.h"
//**********************************

//构造函数
Video::Video()
{
}

//设置
void Video::Setvideo(string filename,HWND hwnd,bool isfull)
{
//设置可用
this->avilable = false;

//文件名
this->name = filename;

//窗口句柄
this->windowshwnd = hwnd;

//是否全屏
this->isfullscreen = isfull;

//设置COM
CoInitialize(0);

//创建滤波器
CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&g_graph_builder);

//设置控制接口
g_graph_builder->QueryInterface(IID_IMediaControl, (void**)&g_media_control);

//设置位置接口
g_graph_builder->QueryInterface(IID_IMediaPosition,(void**)&g_media_position);

//设置事件接口
g_graph_builder->QueryInterface(IID_IMediaEvent, (void**)&g_media_event);

//添加VRM
InitWindowlessVMR(windowshwnd,g_graph_builder, &g_pWc);

long lWidth, lHeight;

//获得本地视频大小
g_pWc->GetNativeVideoSize(&lWidth, &lHeight, NULL, NULL);

// 设置Source尺寸
SetRect(&rcSrc, 0, 0, lWidth, lHeight);

// 获得显示窗体的客户区尺寸
GetClientRect(windowshwnd, &rcDest);

//设置destination尺寸
SetRect(&rcDest, 0, 0, rcDest.right, rcDest.bottom);

// 视频定位
g_pWc->SetVideoPosition(&rcSrc,&rcDest);

//设定位置
g_media_position->put_CurrentPosition(0);

}

//播放
bool Video::Load()
{
WCHAR w_filename[MAX_PATH] = {0};

mbstowcs(w_filename, name.c_str(), MAX_PATH);

// render the file
g_graph_builder->RenderFile(w_filename, NULL);

// play the file, switches the entire filter graph into a running state.
this->g_media_control->Run();

return TRUE;
}

//删除
bool Video::Delete()
{
g_media_control->Stop();

g_media_event->Release();
g_media_event = NULL;

g_media_position->Release();
g_media_position = NULL;

g_media_control->Release();
g_media_control = NULL;

CoUninitialize();
return true;
}

//检查是否完成
bool Video::Iscomplete()
{
long event_code, param1, param2;

// retrieves the next notification event
if(SUCCEEDED(this->g_media_event->GetEvent(&event_code, ¶m1, ¶m2, 1)))
{
if(event_code == EC_COMPLETE)
{
// frees resources associated with the parameters of an events.
g_media_event->FreeEventParams(event_code, param1, param2);
return true;
}
}
g_media_event->FreeEventParams(event_code, param1, param2);
return false;
}

//添加VMR
HRESULT Video::InitWindowlessVMR(HWND hwndApp,IGraphBuilder* pGraph,IVMRWindowlessControl** ppWc)
{
//if (!pGraph || !ppWc) return E_POINTER;

IBaseFilter* pVmr = NULL;

IVMRWindowlessControl* pWc = NULL;

// 创建VMR
CoCreateInstance(CLSID_VideoMixingRenderer, NULL,CLSCTX_INPROC, IID_IBaseFilter, (void**)&pVmr);

// 把VMR添加到过滤器图表中
pGraph->AddFilter(pVmr, L"Video Mixing Renderer");

// 设置显示模式
IVMRFilterConfig* pConfig;
pVmr->QueryInterface(IID_IVMRFilterConfig, (void**)&pConfig);
pConfig->SetRenderingMode(VMRMode_Windowless);
pConfig->Release();

// 设置窗体
pVmr->QueryInterface(IID_IVMRWindowlessControl, (void**)&pWc);
pWc->SetVideoClippingWindow(hwndApp);

//返回AddRef指针
*ppWc = pWc;
pVmr->Release();
return NULL;
}

//响应PAINT消息
void Video::Dopaint()
{
PAINTSTRUCT ps;
HDC hdc;
RECT rcClient;
RECT g_rcDest;
GetClientRect(windowshwnd, &rcClient);
hdc = BeginPaint(windowshwnd, &ps);
if (g_pWc != NULL)
{
g_rcDest=rcClient;
// 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(windowshwnd, hdc);
}
else // There is no video, so paint the whole client area.
{
//FillRect(hdc, &rc2, (HBRUSH)(COLOR_BTNFACE + 1));
}
EndPaint(windowshwnd, &ps);
}
...全文
79 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
gxing1339 2013-04-04
  • 打赏
  • 举报
回复
楼主,我也是遇到这个问题,你解决了吗
Karja 2011-05-08
  • 打赏
  • 举报
回复
本身是嵌套在一个自己写的游戏引擎中的,所以窗口实现以及其他部分就不贴出了...太多了..

3,881

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 其它技术问题
社区管理员
  • 其它技术问题社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧