DSPack, Citrix и SetSyncSource()

Я использовал Delphi XE и DSPack 2.3.3. Я поддерживаю настольное приложение с захватом веб-камеры. Пользователь может захватывать фотографии посетителей и документы. Все работает нормально. Один из наших крупнейших клиентов переходит на Citrix 7.13, а веб-камера зависает.

Их поддержка обратилась в Citrix, и Citrix Engineering хотела бы знать, вызывает ли приложение метод IMediaFilter::SetSyncSource, чтобы явно установить "опорные часы" для графа фильтра в их коде, касающемся захвата веб-камеры. Я сделал несколько тестов, и на самом деле есть звонок, когда начинается рендеринг. Вы можете увидеть вызов при запуске демонстрации DSPack "VideoCap":

  // now render streams
  with CaptureGraph as IcaptureGraphBuilder2 do
  begin
    // set the output filename
    SetOutputFileName(MEDIASUBTYPE_Avi, PWideChar(CapFile), multiplexer, Writer);

    // Connect Video preview (VideoWindow)
    if VideoSourceFilter.BaseFilter.DataLength > 0 then
      RenderStream(@PIN_CATEGORY_PREVIEW, nil, VideoSourceFilter as IBaseFilter,
        nil , VideoWindow as IBaseFilter);

    // Connect Video capture streams
    if VideoSourceFilter.FilterGraph <> nil then
      RenderStream(@PIN_CATEGORY_CAPTURE, nil, VideoSourceFilter as IBaseFilter,
        nil, multiplexer as IBaseFilter);

    // Connect Audio capture streams
    if AudioSourceFilter.FilterGraph <> nil then
    begin

      RenderStream(nil, nil, AudioSourceFilter as IBaseFilter,
        nil, multiplexer as IBaseFilter);
    end;
  end;
  CaptureGraph.Play; 

Согласно комментариям источника DSpack:

{ The reference clock has changed. The filter graph manager sends this event
  when its IMediaFilter.SetSyncSource method is called.}
property OnGraphClockChanged: TNotifyEvent read FOnGraphClockChanged write FOnGraphClockChanged;

На самом деле OnGraphClockChanged запускается после вызова CaptureGraph.Play.

Можно ли избежать вызова SetSyncSource? Вы знаете, решит ли это эту проблему?

ТИА, Клемент

1 ответ

Решение

Цитирование страницы MSDN на IMediaFilter::SetSyncSource:

Когда график запускается, менеджер графиков фильтров вызывает этот метод для каждого фильтра в графике, чтобы уведомить их о ссылочных часах графика. Используйте этот метод для хранения указателя IReferenceClock. Увеличить счетчик ссылок на сохраненный указатель. Перед удалением фильтра из графика менеджер графиков фильтров снова вызывает SetSyncSource со значением NULL.

Это означает, что SetSyncSource() вызывается независимо от вашего кода. Если используемый вами фильтр останавливается из-за того, что график фильтра вызывает его SetSyncSource() метод, то это похоже на дефект в фильтре.

В этом случае потенциальным обходным решением будет создание фильтра-оболочки вокруг рассматриваемого фильтра захвата и перенаправление всех вызовов методов, кроме SetSyncSource(), Но, скорее всего, проблема имеет другое происхождение.

Держу пари, что установка часов на NULL решит проблему. Для этого вам нужно запросить IMediaFilter интерфейс от IFilterGraph и позвонить SetSyncSource(NULL), Это отключит всю синхронизацию графика и отобразит каждый мультимедийный образец так же быстро, как он генерируется.

Более подробную информацию о графиках исходного фильтра можно найти на этой странице MSDN - https://msdn.microsoft.com/en-us/library/windows/desktop/dd390645(v=vs.85).aspx

Другие вопросы по тегам