Video sync via GstClock

Marc Leeman marc.leeman at gmail.com
Tue Mar 12 09:57:38 PDT 2013


I think these were the scripts I used for the demo (the devices are
powered off, so I cannot check atm).

the setup was a 2x2 of Blood and Chrome

the top left was the original and the three others were files that
were converted with some effect of videoconvert (sepia, xray, ...).

These files were all stored on the HDDs driving the monitor (4
monitors, 4 devices (AD10)). Oh, and the files are TS, I had an issue
with MKV but not yet look into it as to why.

marc at drd1812:~$ cat play-master-file.py
#!/usr/bin/env python

import sys

import pygst
pygst.require('0.10')
import gst

def main(args):
    _, uri, port, crop = args
    port = int(port)
    crop = crop.split(':')

    # make the pipeline
    # pipeline = gst.element_factory_make("playbin2", "player")
    # pipeline.set_property("uri", uri)

    # gstline = "filesrc name=src ! decodebin ! videocrop left=%s
right=%s top=%s bottom=%s ! autovideosink" % (crop[0], crop[1],
crop[2], crop[3])
    # make pipeline more explicit for older code (require parser)
    gstline = "filesrc name=src ! mpegtsdemux ! mpeg4videoparse !
ffdec_mpeg4 ! videocrop left=%s right=%s top=%s bottom=%s !
timeoverlay ! ffmpegcolorspace ! videoscale !
video/x-raw-rgb,height=1200,width=1920 ! ximagesink" % (crop[0],
crop[1], crop[2], crop[3])
    print gstline

    pipeline = gst.parse_launch (gstline)
    pipeline.get_by_name('src').set_uri(uri) # uri interface

    # make sure some other clock isn't autoselected
    clock = pipeline.get_clock()
    print 'Using clock: ', clock
    pipeline.use_clock(clock)

    # this will start a server listening on a UDP port
    clock_provider = gst.NetTimeProvider(clock, None, port)

    # we explicitly manage our base time
    base_time = clock.get_time()
    print ('Start slave as: python ./play-slave.py %s [IP] %d %s:%s:%s:%s %d'
           % (uri, port, crop[0], crop[1], crop[2], crop[3], base_time))

    # disable the pipeline's management of base_time -- we're going
    # to set it ourselves.
    pipeline.set_new_stream_time(gst.CLOCK_TIME_NONE)
    pipeline.set_base_time(base_time)

    # now we go :)
    pipeline.set_state(gst.STATE_PLAYING)

    # wait until things stop
    pipeline.get_bus().poll(gst.MESSAGE_EOS | gst.MESSAGE_ERROR, -1)
    pipeline.set_state(gst.STATE_NULL)

if __name__ == '__main__':
    main(sys.argv)


slave:

marc at drd1812:~$ cat play-slave-file.py
#!/usr/bin/env python

import sys

import pygst
pygst.require('0.10')
import gst

def main(args):
    _, uri, ip, port, crop, base_time = args
    port, base_time, crop= int(port), int(base_time), crop.split(':')

    # make the pipeline
    # pipeline = gst.element_factory_make("playbin2", "player")
    # pipeline.set_property("uri", uri)

    # gstline = "filesrc name=src ! decodebin ! videocrop left=%s
right=%s top=%s bottom=%s ! autovideosink" % (crop[0], crop[1],
crop[2], crop[3])
    # make pipeline more explicit for older code (require parser)
    gstline = "filesrc name=src ! mpegtsdemux ! mpeg4videoparse !
ffdec_mpeg4 ! videocrop left=%s right=%s top=%s bottom=%s !
timeoverlay ! ffmpegcolorspace ! videoscale !
video/x-raw-rgb,height=1200,width=1920 ! ximagesink" % (crop[0],
crop[1], crop[2], crop[3])
    print gstline

    pipeline = gst.parse_launch (gstline)
    pipeline.get_by_name('src').set_uri(uri) # uri interface
    # disable the pipeline's management of base_time -- we're going
    # to set it ourselves.
    pipeline.set_new_stream_time(gst.CLOCK_TIME_NONE)

    # make a clock slaving to the network
    clock = gst.NetClientClock(None, ip, port, base_time)

    # use it in the pipeline
    pipeline.set_base_time(base_time)
    pipeline.use_clock(clock)

    # now we go :)
    pipeline.set_state(gst.STATE_PLAYING)

    # wait until things stop
    pipeline.get_bus().poll(gst.MESSAGE_EOS | gst.MESSAGE_ERROR, -1)
    pipeline.set_state(gst.STATE_NULL)

if __name__ == '__main__':
    main(sys.argv)


More information about the gstreamer-devel mailing list