Обнаружить конец видео с IMediaSeeking - PullRequest
2 голосов
/ 23 января 2012

Я играю видео, чтобы получить несколько экранов, используя DirectShow.

Я делаю это в цикле, вызывая IMediaControl->Run, IVMRWindowlessControl->GetCurrentImage и затем IMediaSeeking->SetPositions.

Проблема в том, что я не могу определить, когда видео закончилось. IMediaSeeking->SetPositions возвращает всегда одно и то же значение (S_FALSE). IMediaControl->Run также всегда возвращает S_FALSE. Я также пытался IMediaEvent->GetEvent после вызова IMediaControl->Run проверить на EC_COMPLETE, но вместо этого возвращает (всегда) EC_CLOCK_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 блокируется, и видео воспроизводится (воспроизводится кадр за кадром) в моем IVideoWindow

Ответы [ 2 ]

2 голосов
/ 24 января 2012

Вы должны делать IMediaEvent->GetEvent, однако учтите, что вы будете получать различные события, не только EC_CLOCK_CHANGED. Продолжайте получать, и вы получите EC_COMPLETE. Шаг 6. Обработка событий графика в MSDN объясняет это подробно.

1 голос
/ 23 января 2012

Проверьте состояние графа фильтра с помощью IMediaControl :: GetState и посмотрите, остановлен ли он. Вы также можете получить длительность видео из IMediaSeeking :: GetDuration , которое может оказаться полезным.

Другим вариантом является использование сигнализации о событиях . Эта обработка событий может быть поточной.

...