Выяснение того, когда samplegrabber готов в DirectShow - PullRequest
1 голос
/ 17 февраля 2011

Я продолжаю работать над моим приложением DirectShow и просто завершаю его.Программа выполняет просмотр видеофайла с интервалом в 1 секунду и захватывает из буфера выборки текущий буфер и обрабатывает его перед тем, как продолжить.Тем не менее, я заметил, что я получал дубликаты изображений в своих тестах, и я обнаружил, что DirectShow не увеличивал видео в этом интервале достаточно быстро.У меня вопрос, есть ли способ проверить, готов ли DirectShow для меня вызвать samplegrabber, чтобы получить текущий кадр и обработать его.На данный момент я вызываю сон на 1 секунду, но должен быть лучший метод.Заранее спасибо за помощь.

РЕДАКТИРОВАТЬ

Я только что попытался запустить проверку, чтобы увидеть, равна ли позиция видео следующей позиции, которую я хотел бызахватить и обработать.Это уменьшило количество повторяющихся кадров, но я все еще вижу, что они появляются кусками.

Ответы [ 2 ]

0 голосов
/ 17 февраля 2011

Попробуйте установить таймер графика на NULL. Это позволит:

  • обработать файл как можно быстрее
  • избавит вас от проблем.

Конечно, это не сработает, если вы одновременно рендерите файл на экран.

0 голосов
/ 17 февраля 2011

Я всегда позволяю платформе DS обрабатывать скорость обработки: в главном потоке приложения настройте образец обратного вызова граббера, а затем при запуске обратного вызова вы получите образец медиа, а также время выборки: в этот момент вы можете обработать образец, если истек соответствующий интервал, т. е. 1 секунда.

Что вы имеете в виду, что вы называете сон на секунду и откуда (какой поток) вы это называете? Если вы делаете это из-за обратного вызова, вы фактически блокируете конвейер DirectShow? Возможно, если бы вы могли объяснить ваши настройки более подробно, я мог бы быть более полезным.

/// Callback that is triggered per media sample
/// Note this all happens in the DirectShow streaming thread!
STDMETHODIMP SampleCB( double dSampleTime, IMediaSample * pSample )
{
  // check timestamp and if one second has elapsed process sample accordingly
  // else do nothing

  ...

  // Get byte pointer
  BYTE* pbData(NULL);
  HRESULT hr = pSample->GetPointer(&pbData);
  if (FAILED(hr)) 
  {
    return hr;
  }

  ...
}

P.S. Если вы хотите обработать выборки как можно быстрее, вы можете установить временную метку выборки в значение NULL в вашем обратном вызове.

  // set time to NULL to allow for fast rendering since the 
  // the video renderer controls the rendering rate according
  // to the timestamps
  pSample->SetTime(NULL, NULL);
...