我有这个小 C++ 代码用DirectShow播放视频剪辑。我想要的是视频永远不会停止,所以一旦它到达终点,我再次将位置设置为 0。问题是在新循环的结束和开始之间有一个我想删除的小延迟。我的代码如下所示:
#define WM_GRAPHNOTIFY WM_USER
// Global vars
IGraphBuilder* g_pGraphBuilder;
IMediaControl* g_pMediaCtrl;
IMediaPosition* g_pMediaPos;
IMediaEventEx* g_pMediaEvent;
HWND h_MainWindow;
// PlayVideo() - I removed the errors checking lines (irrelevant right now)
RECT grc;
IVideoWindow *pVidWin = NULL;
HRESULT hr = CoInitialize(NULL);
hr = CoCreateInstance(
CLSID_FilterGraph,
NULL,
CLSCTX_INPROC_SERVER,
IID_IGraphBuilder,
(void**)&g_pGraphBuilder
);
hr = g_pGraphBuilder->RenderFile(L"Clip.mpeg", NULL);
hr = g_pGraphBuilder->QueryInterface(IID_IVideoWindow, (void **)&pVidWin);
hr = pVidWin->put_Owner((OAHWND)h_MainWindow);
hr = pVidWin->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS);
GetClientRect(h_MainWindow, &grc);
pVidWin->SetWindowPosition(0, 0, grc.right, grc.bottom);
hr = g_pGraphBuilder->QueryInterface(IID_IMediaEventEx, (void **)&g_pMediaEvent);
hr = g_pGraphBuilder->QueryInterface(IID_IMediaPosition, (void**)&g_pMediaPos);
hr = g_pMediaEvent->SetNotifyWindow((OAHWND)h_MainWindow, WM_GRAPHNOTIFY, 0);
g_pMediaEvent->SetNotifyFlags(0);
hr = g_pGraphBuilder->QueryInterface(IID_IMediaControl, (void **)&g_pMediaCtrl);
g_pMediaCtrl->Run();
// WndPrc of the main window, the WM_GRAPHNOTIFY message
long EventCode, Param1, Param2;
// ...
case WM_GRAPHNOTIFY:
while (g_pMediaEvent->GetEvent(&EventCode, &Param1, &Param2, 0)!=E_ABORT) {
switch (EventCode) {
case EC_COMPLETE:
// Going back to the start of the clip
g_pMediaPos->put_CurrentPosition(0);
break;
default:
break;
}
g_pMediaEvent->FreeEventParams(EventCode, Param1, Param2);
}
break;
// ...
正如我所说,这里的问题是视频停止和重新开始时存在明显的延迟。看起来 EC_COMPLETE 并没有在视频停止时准确发送,或者它可能是但put_CurrentPosition()
需要一些时间才能将位置设置回 0。无论如何,问题是这样,我想知道是否有解决方案。