DSPack、Citrix 和 SetSyncSource()

DSPack, Citrix and SetSyncSource()

我使用 Delphi XE 和 DSPack 2.3.3。 我正在维护一个带有网络摄像头捕获的桌面应用程序。用户能够捕获访客和文档的图片。 一切正常。我们最大的客户之一正在迁移到 Citrix 7.13,但网络摄像头死机了。

他们的支持人员联系了 Citrix,Citrix Engineering 想知道应用程序是否正在调用 IMediaFilter::SetSyncSource 方法以在其有关网络摄像头捕获的代码中将“参考时钟”显式设置为过滤图。 我做了一些测试,实际上在渲染开始时有一个调用。 运行 DSPack demo "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? 您知道这是否会解决这个问题吗?

TIA, 克莱门特

引用 IMediaFilter::SetSyncSource 上的 MSDN 页面:

When the graph runs, the Filter Graph manager calls this method on every filter in the graph, to notify them of the graph reference clock. Use this method to store the IReferenceClock pointer. Increment the reference count on the stored pointer. Before the filter is removed from the graph, the Filter Graph Manager calls SetSyncSource again with the value NULL.

这意味着无论您的代码如何,都会调用 SetSyncSource()。如果您使用的过滤器由于过滤器图形调用它的 SetSyncSource() 方法而停止,那么这似乎是过滤器中的一个缺陷。

在这种情况下,一个潜在的解决方法是在有问题的捕获过滤器周围创建一个包装器过滤器,并转发除 SetSyncSource() 之外的所有方法调用。但问题很可能有其他原因。

我敢打赌,将参考时钟设置为 NULL 将解决问题。为此,您必须从 IFilterGraph 查询 IMediaFilter 接口并调用 SetSyncSource(NULL)。这将禁用图形的整个计时,并在生成每个多媒体样本时尽可能快地呈现它。

有关实时源筛选器图表的更多详细信息,请访问此 MSDN 页面 - https://msdn.microsoft.com/en-us/library/windows/desktop/dd390645(v=vs.85).aspx