How can a filter implementing IStream know when it won't receive any further IStream commands

感情迁移 提交于 2019-12-04 14:36:33

It's been a while since I asked this question and I still haven't worked out how the MS file writer works out when to close its output file.

Here are some possible solutions, some better than others:

  1. Don't close the output stream until the filter is destroyed or removed from the graph. Clearly the MS file writer does not do this. The internal analyzer file writer filter in GraphStudioNext uses this approach cpp file, h file
  2. Set a timer in Stop() on the downstream filter which periodically checks whether the upstream filter is still active. As soon as the upstream filter is no longer active, Stop() has finished and there should not be any further IStream calls so the output stream can be closed. This should work but isn't guaranteed to close the output stream before the Stop() call on the graph has returned. UPDATE - It's probably not safe to assume that because a filter is stopped it will not generate further IStream calls. According to File Writer Filter Documentation, "... It supports IStream to allow reading and writing the file header AFTER the graph is stopped." [my emphasis]
  3. Close the stream when the last reference to the IStream interface is released. Likely to go wrong if there are any reference counting bugs on the IStream interface. Upstream filter may hang onto IStream reference until pin is disconnected and/or filter destroyed.
  4. Insert an extra unconnected dummy filter in the graph whose only purpose is to wait in its own Stop() function until the upstream filter is closed to notify the downstream filter so it can close its output stream. Seems like a dirty hack with possible side effects. Relies on the Stop() calls being preemptive among different renderers in the graph.
  5. In the downstream filter, respond to some other callback that happens after Stop() is called on the upstream filter but before Stop() on the graph returns. Would be ideal but I haven't found any mechanism to do this.
  6. UPDATE 2 : another possible idea. On a timer callback QueryInterface on the containing graph and close the file output stream with GetState() on the graph returns State_Stopped as this doesn't seem to happen until all filters have returned from Stop() and all streaming should have finished. UPDATE 3 : This appears to be the best solution using CreateTimerQueueTimer called with the flag WT_EXECUTELONGFUNCTION and TryEnterCriticalSection on a dedicated CRITICAL_SECTION in the callback to prevent re-entrancy and thread bloat. Though it doesn't guarantee the output stream closes before Stop on the graph returns it should close the file soon afterwards (potentially very soon if a fine grained timer is used). Requires some care to avoid deadlocks and race conditions; e.g. the timer callback should not cache an AddRef'd filter graph interface, shouldn't hold the filter lock when calling IMediaControl::GetState() on the filter graph, ensuring elsewhere in the code that the timer callback is definitely terminated before streaming restarts, the filter is paused, disconnected, removed from the graph etc. It could even be that the MS File Writer uses this technique too and the output file closes so soon after Stop() that it's not easily detectable.
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!