我们有一个应用程序,它使用带有两个滤镜图的directshow来实现无缝视频播放。
每个“面板”用filtergraph初始化
new QuartzTypeLib.FilgraphManager()
后来使用WndProc
将MediaEventEx.SetNotifyWindow
分配到同一窗口但使用不同的LParam(面板ID 0或1)
文档说明在有新事件时发送WM_GRAPHNOTIFY,但队列中可能有多个事件,或者队列可能为空。此外,每个事件不会发送一次WM_GRAPHNOTIFY,但如果队列中有一个或多个事件,则可以发送一次。
由于我使用相同的窗口来处理来自两个过滤器图的通知,我可以确定如果它们同时发生,我会从两个队列中获取事件,或者我是否需要在每个WM_GRAPHNOTIFY消息上解析两个队列,或者我是否可以安全地处理从lParam排队?
以下是我的代码的非常剥离版本。
private const int WM_APP = 0x8000;
private const int WM_GRAPHNOTIFY = WM_APP + 1;
private const int EC_COMPLETE = 0x01;
private const int EC_USERABORT = 0x02;
private const int EC_ERRORABORT = 0x03;
void InitializePanels()
{
for (int panel = 0; panel <= 1; panel++)
{
PlaybackPanels[panel].FilterGraph = new QuartzTypeLib.FilgraphManager();
PlaybackPanels[panel].MediaEventEx = PlaybackPanels[(panel].FilterGraph as IMediaEventEx;
PlaybackPanels[panel].MediaEventEx.SetNotifyWindow((int)this.Handle, WM_GRAPHNOTIFY, panel);
PlaybackPanels[panel].MediaControl = PlaybackPanels[panel].FilterGraph as IMediaControl;
// Additional code to load media files here...
PlaybackPanels[panel].MediaControl.Pause();
}
PlaybackPanels[0].MediaControl.Run();
}
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_GRAPHNOTIFY)
{
int lEventCode;
int lParam1, lParam2;
int playerPanelID = m.LParam.ToInt32();
int _while = 0;
while (_while < 100)
{
try
{
PlaybackPanels[playerPanelID].MediaEventEx.GetEvent(out lEventCode, out lParam1, out lParam2, 0);
PlaybackPanels[playerPanelID].MediaEventEx.FreeEventParams(lEventCode, lParam1, lParam2);
if (lEventCode == EC_COMPLETE)
{
int nextPanel = 1 - playerPanelID;
PlaybackPanels[nextPanel].MediaControl.Run();
}
else if (lEventCode == EC_USERABORT || lEventCode == EC_ERRORABORT)
{
/// Handle error...
}
}
catch (System.Runtime.InteropServices.COMException ex)
{
// REMARKS: When the window receives the message, it should call the IMediaEvent::GetEvent method to retrieve the event.
// Events are asynchronous, so the queue might contain several events (or none).
// Call GetEvent repeatedly, until it returns an error code.
if ((uint)ex.ErrorCode == 0x80004004) //Operation Aborted (E_ABORT)
{
// We are done processing the event queue. *Resume event loop*
break;
}
else
{
throw;
}
}
_while++;
}
}
base.WndProc(ref m);
}
答案 0 :(得分:0)
图表会发出有关新事件可用性的通知,因此没有冲突或问题,否则多个图表会发送相同的窗口消息。已经无关,如果您发送邮件GetEvent
两个图表(包括不是首先发出通知的图表),也没有问题。
区分发件人的另一种方法是分别发送WM_GRAPHNOTIFY + 0
和WM_GRAPHNOTIFY + 1
并处理。您可以拥有更多标识信息,LPARAM以及消息偏移。