2014-09-05 86 views
0

到底是如何你的意思是实现能够通过IMediaFilter::SetSyncSource设置的IReferenceClockDirectShow的IReferenceClock实施

我有一个系统,实现GetTimeAdviseTime,UnadviseTime。当一个流开始播放时,它会通过AdviseTime设置一个基准时间,然后为每个后续提示增加流时间。

但是,我应该怎么知道新图形运行的时间?我需要为给定的参考时钟设置一个零点。否则,如果我创建了一个参考时钟,然后在10秒钟后,我开始绘制图表,现在我处于不知道是否应该在播放10秒钟或者是否应该从0开始的位置。显然,基准时间会说我从0开始,但是我只是停了10秒钟,我是否需要放下一堆帧?

我真的似乎无法弄清楚如何写一个适当的IReferenceClock所以任何提示或想法将非常感激。

编辑:我有一个问题的一个例子是,我有2个图表和2个视频。来自两个视频的音频都将转为空渲染器。视频转换为标准的CLSID_VideoRenderer。现在,如果我设置相同的参考时钟,然后运行图1似乎都很好。但是,如果在线10秒钟后运行图形2,那么它将运行,就好像SetSyncSource在前10秒左右为空,直到它赶上另一个视频。

显然,如果叫GetTime图表得到他们的“基地的时间”,这将解决这个问题,但这不是我所看到的情况发生。这两个视频最终的基准时间为0,因为这是我运行它们的关键。

其值得注意的是,如果我设置完全没有时钟(或称SetDefaultSyncSource),那么这两个图表跑得快,因为他们可以。我认为这是由于缺乏音频渲染器...

回答

2

但是我怎么知道新图形运行的时候?

时钟单独运行,它是图形对齐时钟而不是其他操作。该图形接收到外部呼叫Run,然后它检查当前时钟时间,并将分配给滤波器的基准时间分配为“当前时钟时间+事件起飞的一段时间”。时钟本身不必对这一切有最明确的想法,其任务是保持运行并不断增加时间。

特别是,时钟时间不必在任何时候重置为零。

从技术文档:

The clock's baseline—the time from which it starts counting—depends on the implementation, so the value returned by GetTime is not inherently meaningful. What matters is the delta from when the graph started running.

When an application calls IMediaControl::Run to run the filter graph, the Filter Graph Manager calls IMediaFilter::Run on each filter. To compensate for the slight amount of time it takes for the filters to start running, the Filter Graph Manager specifies a start time slightly in the future.

基类的提供CBaseReferenceClock类,你可以作为参考实现使用(在参考时钟,*)。

评论您的编辑:

你显然不能说明全部的情况下,你会忽略的重要细节。有一个简单的测试:您可以实例化标准时钟(CLSID_SystemClock)并将其用于两个常规图表 - 它们运行良好,即使时间分隔Run次。

我怀疑你正在做一些同步或图形之间的匹配,你是时间戳样本,也使用时钟。大概你在这个时候做错了什么,然后你很难在整个时间里修复它。

+0

谢谢,但我想了解底层系统是如何工作的,所以我避免了CBaseReferenceClock。我用更多信息编辑了我的问题。 – Goz 2014-09-05 21:28:15

+0

我提供了查看'CBaseReferenceClock'代码而不是使用它。你会发现它非常简单,而且最重要的是它无论如何都能增加时间。标准时钟只是'timeGetTime()* 10000' +建议周围的东西。这就足够了。 – 2014-09-05 21:34:10

+0

我现在已经尝试在两个图表上设置一个SystemClock。两个图都像SyncSource设置为NULL(即全速)一样运行。 – Goz 2014-09-05 21:36:37