After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 744442 - Clash between gst_element_get_clock() and gst_pipeline_get_clock()
Clash between gst_element_get_clock() and gst_pipeline_get_clock()
Product: GStreamer
Classification: Platform
Component: gstreamer (core)
Other other
: Normal normal
: 1.5.1
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Reported: 2015-02-12 22:41 UTC by Steve Johnson
Modified: 2015-04-02 21:34 UTC
See Also:
GNOME target: ---
GNOME version: ---

pipeline: Add binding friendly gst_pipeline_get_pipeline_clock() (3.37 KB, patch)
2015-02-13 00:43 UTC, Olivier Crête
committed Details | Review
element: Document when a clock is available from gst_element_get_clock() (934 bytes, patch)
2015-02-13 00:43 UTC, Olivier Crête
committed Details | Review

Description Steve Johnson 2015-02-12 22:41:39 UTC
Using simple example extracted from android-tutorial-5, adding a call to gst_get_element_clock() returns 0x0.

static void *test_player(void *userdata) {

    CustomData *data = (CustomData *)userdata;
    GError *error = NULL;

    GST_DEBUG ("Creating test pipeline");

    // Create our own GLib Main Context and make it the default one
    data->context = g_main_context_new ();

    // Build pipeline
    data->pipeline = gst_parse_launch("playbin", &error);
    if (error) {
        gchar *message = g_strdup_printf("Unable to build pipeline: %s", error->message);
        g_clear_error (&error);
        set_ui_message(message, data);
        g_free (message);
        return NULL;

    gchar* uri = "";
    g_object_set(data->pipeline, "uri", uri, NULL);

    // Set the pipeline to READY, so it can already accept a window handle, if we have one
    data->target_state = GST_STATE_READY;
    gst_element_set_state(data->pipeline, GST_STATE_READY);

    // Get clock for netprovider
    GstClock* clock = gst_element_get_clock(data->pipeline);
    GST_DEBUG ("gst_element_get_clock... (GstClock:%p)", clock); 

    // clock == 0x0

Comment 1 Olivier Crête 2015-02-12 23:47:29 UTC
You are only guaranteed to get a clock when you reach the playing state as the selection of the clock is done during the paused->playing transition.

So you want to do something like:
gst_element_set_state(data->pipeline, GST_STATE_PLAYING);
gst_element_get_state(data->pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
GstClock* clock = gst_element_get_clock(data->pipeline);

Note that the get_state() may block for some time, so you may want to instead way for the state change GstMessage on the bus if you don't want to block.

To use with the net clock provider, the most common case is just to use the system clock that you can get with gst_system_clock_obtain().
Comment 2 Steve Johnson 2015-02-13 00:05:24 UTC
Thank you Olivier. Unfortunately this excellent information is not easily found in the GStreamer docs. I added your code and it works. Thank you.

I am porting a python application (syncing playback across two devices - []) and the following code works properly without first having to play the video. This runs on Ubuntu 14.04. Can you see any reason why they would behave differently? Thanks.

#!/usr/bin/env python

import sys

from gi.repository import Gst
from gi.repository import GstNet

def main(args):
    _, uri, port = args
    port = int(port)


    # make the pipeline
    pipeline = Gst.parse_launch('playbin')
    pipeline.set_property('uri', uri) # uri interface

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

    # this will start a server listening on a UDP port
    clock_provider =, None, port)

    # we explicitly manage our base time
    base_time = clock.get_time()
    print ('Start slave as: python ./ %s [IP] %d %d'
           % (uri, port, base_time))

    # disable the pipeline's management of base_time -- we're going
    # to set it ourselves.

    # now we go :)

    # wait until things stop
    pipeline.get_bus().poll(Gst.MessageType.EOS | Gst.MessageType.ERROR, Gst.CLOCK_TIME_NONE)

if __name__ == '__main__':
Comment 3 Olivier Crête 2015-02-13 00:27:12 UTC
In Python, you're calling gst_pipeline_get_clock(), not gst_element_get_clock(). But it's still not useful to do that before going to playing, because you'll always get the system clock, so you shoul use gst_system_clock_obtain() instead.

I'm renaming this bug about the API clash.

I suggest we create an alias for one of them (and deprecate it), as it means one of these functions (surprise surprise which!) is not available in most OO bindings.
Comment 4 Olivier Crête 2015-02-13 00:43:12 UTC
Created attachment 296729 [details] [review]
pipeline: Add binding friendly gst_pipeline_get_pipeline_clock()

I suggest we add a gst_pipeline_get_pipeline_clock() and skip gst_pipeline_set/set_clock() from the GIR to avoid this confusion.

This patch implements this, also tries to document how gst_pipeline_get_pipeline_clock() is different from gst_element_get_clock()...

API: gst_pipeline_get_pipeline_clock()
Comment 5 Olivier Crête 2015-02-13 00:43:18 UTC
Created attachment 296730 [details] [review]
element: Document when a clock is available from gst_element_get_clock()
Comment 6 Nicolas Dufresne (ndufresne) 2015-04-02 21:23:01 UTC
Comment 7 Olivier Crête 2015-04-02 21:34:11 UTC

commit 518babf6cb6f71b2704a4b420804322cfa1dda54
Author: Olivier Crête <>
Date:   Thu Feb 12 19:39:44 2015 -0500

    element: Document when a clock is available from gst_element_get_clock()

commit 59d9992ed02f0e9f650481e940e8aba8d96409f1
Author: Olivier Crête <>
Date:   Thu Feb 12 19:40:06 2015 -0500

    pipeline: Add binding friendly gst_pipeline_get_pipeline_clock()
    Also skip gst_pipeline_get_clock() and gst_pipeline_set_clock() from the
    bindings as they are confused with gst_element_*_clock().
    API: gst_pipeline_get_pipeline_clock()