2012-01-23 4 views
2

Я играю видео, чтобы получить некоторые экраны с помощью DirectShow.Обнаружение конца видео с помощью IMediaSeeking

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

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

Как я могу определить конец видео? Благодаря

UPDATE: Делать что-то вроде

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

+0

Выполняется ли обработка событий DirectShow в отдельном потоке? –

+0

На данный момент находится тот же поток, что и окно. – cprogrammer

ответ

2

Вы должны делать IMediaEvent->GetEvent, однако обратите внимание, что вы будете получать различные мероприятия, а не только EC_CLOCK_CHANGED. Продолжайте получать, и вы должны получить EC_COMPLETE. Step 6: Handle Graph Events в MSDN объясняет это подробно.

+0

true, но перечисление событий, похоже, блокируется. Я обновил свой вопрос с помощью некоторого кода. – cprogrammer

+0

Это, безусловно, блокирует, если вы предоставляете тайм-аут 'INFINITE'. Вот почему вам нужно заглянуть в MSDN о том, как получать уведомление о новом событии, используя сообщение окна или объект события. –

+0

Я заметил параметр INFINITE, но я не думаю, что произвольное значение (например: 3000) является правильным решением. Итак, я понимаю, что перечисление значений, как и я, не является правильным подходом, но вместо этого я должен зарегистрироваться для события (используя wnd msg или object). С моей точки зрения (это мой первый контакт с DirectShow), это то, что я делаю, перечисляя объект IMediaEvent. Можете ли вы быть более конкретным или предоставить более точное местоположение в msdn, где я могу найти больше информации? Спасибо – cprogrammer

1

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

Другой вариант - использовать event signaling. Эта обработка событий может быть отключена.

Смежные вопросы