WM_GRAPHNOTIFY, это особый экземпляр для его filtergraph - PullRequest
0 голосов
/ 08 мая 2018

У нас есть приложение, которое использует DirectShow с двумя фильтрами для реализации бесшовного воспроизведения видео. каждая «панель» инициализируется фильтром new QuartzTypeLib.FilgraphManager() и позже присваивается WndProc с использованием MediaEventEx.SetNotifyWindow для того же окна, но с другим LParam (идентификатор панели 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);
}

1 Ответ

0 голосов
/ 08 мая 2018

Графики выдают уведомления о доступности новых событий, поэтому нет коллизий или проблем, в противном случае несколько графиков отправляют одно и то же сообщение окна. Уже не связанные, нет проблем, если вы передаете сообщение GetEvent обоим графикам, включая не тот, который выдал уведомление в первую очередь.

Также еще один способ различить отправителей - это отправить WM_GRAPHNOTIFY + 0 и WM_GRAPHNOTIFY + 1 и обработать соответственно. Вы можете иметь больше идентификационной информации, LPARAM, а также смещение сообщения.

...