C++ 用imediseek检测视频结束

C++ 用imediseek检测视频结束,c++,directx,directshow,C++,Directx,Directshow,我正在播放一段视频,以便使用DirectShow获得一些屏幕 我通过调用IMediaControl->Run,IVMRWindowlessControl->GetCurrentImage,然后调用IMediaSeeking->SetPositions,在一个循环中执行此操作 问题是我无法检测视频何时结束imediseek->SetPositions返回始终相同的值(S_FALSE)IMediaControl->Run也会返回always S S_FALSE。在调用IMediaControl->R

我正在播放一段视频,以便使用DirectShow获得一些屏幕

我通过调用
IMediaControl->Run
IVMRWindowlessControl->GetCurrentImage
,然后调用
IMediaSeeking->SetPositions
,在一个循环中执行此操作

问题是我无法检测视频何时结束
imediseek->SetPositions
返回始终相同的值(S_FALSE)<代码>IMediaControl->Run也会返回always S S_FALSE。在调用
IMediaControl->Run
检查
EC\u COMPLETE
后,我还尝试了
imediavent->GetEvent
,但返回(始终)
EC\u CLOCK\u CHANGED

如何检测视频的结尾?谢谢

更新:执行以下操作

    long eventCode = 0;
    LONG_PTR ptrParam1 = 0;
    LONG_PTR ptrParam2 = 0;
    long timeoutMs = INFINITE;

    while (SUCCEEDED(pEvent->GetEvent(&eventCode, &ptrParam1, &ptrParam1, timeoutMs)))
    {
        if (eventCode == EC_COMPLETE) 
        {
            break;
        }

        // Free the event data.
        hr = pEvent->FreeEventParams(eventCode, ptrParam1, ptrParam1);
        if (FAILED(hr))
        {
            break;
        }
    }

在几个事件之后阻塞:0x53(EC_VMR_RENDERDEVICE_SET)、0x0D(EC_CLOCK_CHANGED)、0x0E(EC_PAUSED),对GetEvent的下一个调用是阻塞,并且在my
IVideoWindow中渲染视频(逐帧播放)

检查过滤图的状态,并查看它是否停止。您还可以从中获取视频的持续时间,您可能会觉得这很有用


另一个选择是使用。此事件处理可以脱离线程

您应该执行
imediavent->GetEvent
,但是请注意,您将收到各种事件,而不仅仅是
EC\u CLOCK\u发生了变化
。继续接收,您将获得
EC_COMPLETE
。MSDN上详细解释了这一点。

true,但枚举事件似乎会阻塞。我用一些代码更新了我的问题。如果你提供
INFINITE
timeout,它肯定会阻塞。这就是为什么您需要查看MSDN,了解如何使用窗口消息或事件对象获得新事件的通知。我注意到了INFINITE参数,但我不认为任意值(例如:3000)是正确的解决方案。因此,我明白,像我一样枚举值不是正确的方法,但我应该注册一个事件(使用wnd msg或object)。在我看来(这是我第一次接触DirectShow),这就是我通过枚举
IMediaEvent
对象所做的。你能更具体一点,或者在msdn中提供一个更准确的位置,我可以在那里找到更多信息吗?谢谢,我发现我应该注册
pEvent->SetNotifyWindow(hWnd,WM_GRAPHNOTIFY,0)
并在
WM\u GRAPHNOTIFY
上调用
imediavent->GetEvent
。希望如此;这条路是对的。感谢您订阅
SetNotifyWindow
,查看哪里有新的活动可用。收到此消息后,您将使用
GetEvent
枚举并设置零超时,直到刷新所有挂起的事件。DirectShow事件处理是否在单独的线程上运行?目前与窗口在同一线程上。