Re: WMR9, dual-screen, EC_PAUSED and delay in video playback



On Mon, 23 Apr 2007 10:45:18 +0100, Mehdi wrote:

Hi Alessandro,

On Fri, 20 Apr 2007 12:45:13 -0400, Alessandro Angeli wrote:

The documentation is very clear on this: when you run the
graph, the filter graph manager first pauses the graph, if
it is not already paused, so that data can be cued, then
actually runs it.
[...]
Check whether the graph changed (either different filters or
different connection media types) after it starts running on
the secondary display. It is likely that the secondary
display hardware has different requirements from the primary
one, so the renderer may need to be reconnected and it may
take some time for IntelligentConnect to build a suitable
filter chain.

Thanks for your help. This makes senses. I'll try to write some code to see
what exactly happens to the graph when I run it on the secondary screen.
What still worries me though is that when I run it on the primary screen,
it buffers 2 frames before starting the playback while when i run it on the
secondary screen it seems to want to buffer 9 frames initally which causes
a huge delay in playback. I'm don't quite know how to solve this problem.
In case anybody else is having the same problem, I've overriden the Pause,
Stop and Run mehtods of my source filter in order to see when they are
being called. The sequence of events goes like this:

*** When run on the primary screen ***
Graph event: EC_VMR_RENDERDEVICE_SET
Pause()
FillBuffer()
FillBuffer()
Graph event: EC_PAUSED
Run()
FillBuffer()
... (calls to FillBuffer())
=> Video plays with almost no delay

*** When run on the secondary screen ***
Graph event: EC_VMR_RENDERDEVICE_SET
Pause()
FillBuffer()
FillBuffer()
Stop()
Graph event: EC_VMR_RENDERDEVICE_SET
Pause()
FillBuffer()
FillBuffer()
FillBuffer()
FillBuffer()
FillBuffer()
FillBuffer()
FillBuffer()
FillBuffer()
FillBuffer()
Run()
Graph event: EC_PAUSED
FillBuffer() called
... (calls to FillBuffer())
=> Video plays with a 1 second delay


2 observations:

- the EC_PAUSED event is traced long after Pause() has been called. It
might be because I'm retrieving graph events using IMediaEvents.GetEvent()
in a separate thread which is maybe not scheduled to run before some time
after Pause() has been called. However, the fact that EC_PAUSED always gets
traced after Run() has been called is a bit strange. If thread scheduling
timing was involved, I would have expected to see some randomness here but
the sequence of events is always exactly the same as above.

- For some reason, I only get one EC_PAUSED event in the second case even
though Pause() has been called twice. I'm not sure why. It might be that
the renderer somehow cancels the first pause but I'd need to do some more
reading on how these things work.

A few observations that might help:

- The EC_PAUSED is raised once the graph completes the transition to paused
mode, not when Pause() is called -- that is, you get the event once all the
filters have completed the pause transition, which means that the renderers
all have received data. On the secondary monitor, the renderer requests a
rebuild to handle the change in device -- it does this once it goes active
and the window is shown, I guess, and hence the graph is stopped before the
pause transition completes.

- After the rebuild, it takes longer for the graph to go active. I guess
this is a consequence of the decoder: try putting an in-place transform or
similar to monitor the flow of data actually into the renderer. I would
guess that the Run occurs immediately after data is received by the
renderer in both cases.

- The point of this cueing behaviour is to ensure that the buffers are
pre-fetched sufficiently to ensure smooth playback. For a live source, you
probably don't want this. Turn off cueing by returning VFW_S_CANT_CUE
instead of S_OK from your filter's GetState method (if paused). Then the
graph will transition immediately from pause to run. Then, if you need to,
you can control the required latency by adjusting the timestamp on the
first buffer from 0.

G
.



Relevant Pages

  • Help needed with Pin connections in 2 graph technique
    ... The first one ends with 2 custom renderers I wrote. ... the same custom renderer one for audio, one for video stream (the filter ... For the second Graph I wrote a custom source ...
    (microsoft.public.win32.programmer.directx.video)
  • Re: Confusing message from GraphEdit
    ... Here is the description of my graph: ... The last filter is the recompiled Minimal Null-Null transform in place ... The dialog that GraphEdit displays offers two options: ... From GraphEdit I press Run and Pause - works fine. ...
    (microsoft.public.win32.programmer.directx.video)
  • Re: CTransformFilter with its own GUI
    ... Then tear the graph down and rebuild ... If you discard the timestamps on the samples going to the renderer then the ... > I'm trying to do something unusual with a transform filter and would like ... > Calibration mode will be initiated by the application calling a method (of ...
    (microsoft.public.win32.programmer.directx.video)
  • Re: DVD Player sound renderer filter
    ... When I look at the graph with graphedt, the audio ... > renderer is "Dsound Renderer". ... > Device" and play the graph the audio works fine. ... If you add a filter to the graph before rendering a pin, ...
    (microsoft.public.win32.programmer.directx.audio)
  • Re: find time difference between audio renderer clock & system clock
    ... JoinFilterGraph method and successfully get a pointer to ... the default directsound renderer (or do I have to ... Remember that, even if unlikely, the graph may use ... other filter or an external source and the audio renderer ...
    (microsoft.public.win32.programmer.directx.audio)

Loading