Upon checking the source code of dlls/quartz I found out about the method SetSyncSource defined in the IBaseFilter interface:
dsoundrender.c:static HRESULT WINAPI DSoundRender_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock) filesource.c:static HRESULT WINAPI AsyncReader_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock) filtergraph.c:static HRESULT WINAPI MediaFilter_SetSyncSource(IMediaFilter *iface, IReferenceClock *pClock) parser.c:static HRESULT WINAPI Parser_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock) transform.c:static HRESULT WINAPI TransformFilter_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock) videorenderer.c:static HRESULT WINAPI VideoRenderer_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock)
In particular, I see the following two things about sync sources: 1) I see no effort on part of filtergraph.c to add a sync source when simply asked to render a file 2) Even if it did, current implementation of videorenderer.c does nothing with its sync source
So I have a couple of questions: 1) Am I right to assume that a sync source might be used to synchronize and (if necessary) drop frames at the videorenderer in order to maintain synchronization and avoid stuttering? 2) Could the sttutering really be solved by implementing the using and passing of a synchronization source (systemclock.c) in file rendering? If so, then the migration to DirectDraw would become just an optimization to increase the frame rate.
Alex Villacís Lasso
On Wednesday 20 June 2007 11:11:29 am Alex Villacís Lasso wrote:
In particular, I see the following two things about sync sources:
- I see no effort on part of filtergraph.c to add a sync source when
simply asked to render a file
Right. What's supposed to happen is that the filter graph is supposed to call IFilterGraph::SetDefaultSyncSource when it's run, however Wine does not currently implement this function.
How that function is supposed to work is to set a reference clock on the following criteria (in order of priority): * If the app has selected a non-NULL sync source (by calling SetSyncSource with a non-NULL argument on the filter graph's IMediaFilter interface), use that. else: * If a "live source" filter in the graph exposes the IReferenceClock interface, use that (see: http://msdn2.microsoft.com/en-us/library/ms787249.aspx for info about live sources). else: * If a connected renderer filter exposes the IReferenceClock interface, use that. else: * If a filter down the chain from the renderer exposes the IReferenceClock interface, use the one closest to a renderer that has it. else: * If a non-connected filter exposes the IReferenceClock interface, use that. else: * Use the system clock (CLSID_SystemClock)
Under normal circumstances (no custom source set and no live sources), the audio renderer will be picked if there's an audio stream. Wine's DSound renderer filter does implement the IReferenceClock interface, although it hasn't been tested.
- Even if it did, current implementation of videorenderer.c does
nothing with its sync source
All renderers (audio and video) need to handle the sync source, not just the video renderer.
So I have a couple of questions:
- Am I right to assume that a sync source might be used to synchronize
and (if necessary) drop frames at the videorenderer in order to maintain synchronization and avoid stuttering?
Yes. A renderer is supposed to drop frames/samples if it's falling behind. It also has to deal with running ahead.