1

I am using the excellent GMFBridge directshow family of filters to great effect, allowing me to close a video recording graph and open a new one, with no data-loss.

My original source graph was capturing live video from standard video and audio inputs.

There is an undocumented method on the GMFBridgeController filter named SetLiveTiming(). From the name, I figured that this should be set to true if we are capturing from a Live graph (not from a file) as is my case. I set this value to true and everything worked as expected

The same capture hardware allows me to capture live TV signals (ATSC in my case), so I created a new version of the graph using the BDA architecture filters, for tuning purposes. Once the data flows out from the MPEG demuxer, the rest of the graph is virtually the same as my original graph.

However, on this ocassion my muxing graph (on the other side of the bridge) was not working. Data flowed from the BridgeSource filter (video and audio) and reached an MP4 muxer filter, however no data was flowing from the muxer output feeding a FileWriter filter.

After several hours I traced the problem to the SetLiveTiming() setting. I turned it off and everything began working as expected. and the muxer filter began producing an output file, however, the audio was not synchronized to the video.

Can someone enlighten me on the real purpose of the SetLiveTiming() setting and perhaps, why one graph works with the setting enabled, while the other fails?

UPDATE

I managed to compile the GMFBridge Project, and it seems that the filter is dropping every received sample because of a negative timestamp computation. However I am completely baffled at the results I am seeing after enabling the filter log.

UPDATE 2: The dropped samples were introduced by the way I launched the secondary (muxer) graph. I inspected a sample using a SampleGrabber (thus inside a streaming thread) as a trigger-point and used a Task.Run() .NET call to instantiate the muxer graph. This somehow messed up the clocks and I ended having a 'reference start point' in the future - when the bridge attempted to fix the timestamp by subtracting the reference start point, it produced a negative timestamp - once I corrected this and spawned the graph from the application thread (by posting a graph event), the problem was fixed.

Unfortunately, my multiplexed video (regardless of the SetLiveTiming() setting) is still out of sync.

I read that the GMFBridge filter can have trouble when the InfTee filter is being used, however, I think that my graph shouldn't have this problem, as no instance of the InfTee filter is directly connected to the bridge sink.

Here is my current source graph:

                                                                   -->[TIF]
                                                                  |
 [NetworkProvider]-->[DigitalTuner]-->[DigitalCapture]-->[demux]--|-->[Mpeg Tables]
                                                                  |
                                                                  |-->[lavAudioDec]-->[tee]-->[audioConvert]-->[sampleGrabber]-->[NULL]
                                                                  |                        |
                                                                  |                        |
                                                                  |                         ->[aacEncoder]----------------
                                                                  |                                                       |--->[*Bridge Sink*]
                                                                   -->[VideoDecoder]-->[sampleGrabber]-->[x264Enc]--------

Here is my muxer graph:

                      video  
 ...  |bridge source|-------->[MP4 muxer]--->[fileWriter]
             |                     ^
             |        audio        |
              ---------------------

All the sample grabbers in the graph are read-only. If I mux the output file without bridging (by placing the muxer on the capture graph), the output file remains in sync, (this ended being not true, the out-of-sync problem was introduced by a latency setting in the H264 encoder) but then I can't avoid losing some seconds between releasing the current capture graph, and running the new one (with the updated file name)

UPDATE 3:

The out of sync problem was inadvertently introduced by me several days ago, when I switched off a "Zero-latency" setting in the x264vfw encoder. I hadn't noticed that this setting had desynchronized my already-working graphs too and I was blaming the bridge filter.

In summary, I screwed up things by:

  1. Launching the muxer graph from a thread other than the Application thread (the thread processing the graph's event loop).

  2. A latency switch in an upstream filter that was probably delaying things too much for the muxer to be able to keep-up.

BlueStrat
  • 2,202
  • 17
  • 27

1 Answers1

2

Author's comment:

// using this option, you can share a common clock 
// and avoid any time mapping (essential if audio is in mux graph)
[id(13), helpstring("Live Timing option")]
HRESULT SetLiveTiming([in] BOOL bIsLiveTiming);

The method enables a special mode of operation which addresses live data. In this mode sample times are converted between the graphs as relative to respective clock start times. Otherwise, the default mode is to expect reset of time stamps to zero with graph changes.

Roman R.
  • 68,205
  • 6
  • 94
  • 158
  • Thank you Roman, from that insight I now notice that I can safely keep the flag off on both graphs for my use-cases. Do you have an idea of what could be causing the muxer filter to refuse to produce output with the setting enabled? (it could be a red-flag that I am doing something inherently wrong with my graph-building code). Thanks again! – BlueStrat Sep 14 '18 at 23:21
  • One thing I just noticed, turning off the setting produces output, but the audio and video are no longer synchronized in the final recording :( – BlueStrat Sep 14 '18 at 23:44
  • 1
    I suppose that samples are eventually discarded due to time stamp collision. You might need to build bridge from source and debug/trace sample times to get an idea what is going there exactly. Eventually multiplexer requires that incoming samples are timestamped continuously or otherwise it would itself ignore them or raise a failure. With no live timing setting bridge anyway solves the problem of continuous time stamping when you change a graph, however it is using another method. Presumably it losts sync between video and audio and then you see this effect in the produced file. – Roman R. Sep 15 '18 at 06:22
  • 1
    I noticed you updated post and already included trace excerpt. Note that in live timing mode time stamps are adjusted twice, in source (what you included in your post) but also in sink as well. STO is removed in source and upstream graph's STO is added in sink. Confusing math might be in both places. If your original data is not live, I would rather look into sync loss rather than fixing `SetLiveTiming`. I would prefer to not use times relative to clock start time unless your streaming is indeed live. – Roman R. Sep 15 '18 at 06:29
  • Hi again Roman, I managed to trace the source of the discarded samples. I was creating and starting the secondary graph (the muxer graph) using a Task.Run() method to queue the work in .Net's thread pool. I changed this and use a graph event notification instead to request the graph's creation, after this, no samples are being discarded. Unfortunately, my output video is still out-of-sync… no matter the settings. – BlueStrat Sep 15 '18 at 16:02
  • I will experiment and see what happens if I keep the muxer filter on the capture graph and bridge the output (just leaving the filewriter on the secondary graph) – BlueStrat Sep 15 '18 at 17:10
  • Bad idea - the muxer is responsible of properly closing the produced MP4 file, so it can't be on the capture graph – BlueStrat Sep 15 '18 at 17:45
  • 1
    Finally I got it… The "original" problem was indeed the way I was starting the muxer graph. The out-of-sync problem was introduced by a setting in the x264vfw filter. I unchecked an option called "Zero-latency" several days ago, and I hadn't noticed that it caused the muxed recordings to go out-of-sync, even with the bridge removed! After re-enabling the setting, the bridge is working perfectly. Thanks again Roman! =D – BlueStrat Sep 16 '18 at 02:29