[gst-devel] Save a stream to different file every hour

Arnout Vandecappelle arnout at mind.be
Thu Jun 18 08:46:44 CEST 2009

On Wednesday 17 June 2009 10:29:43 Viraj Karandikar wrote:
> And after every hour you will have to: pause the pipeline, create new
> filesink, disconnect old filesink, connect new filesink and close old
> filesink. 

 Actually, no.  Pausing the pipeline will not (immediately) stop the threads 
in the source and queues.  In addition, once it's paused any new data coming 
in on the live source will be dropped until it plays again, which probably is 
not the intention.

 Instead, you have to use blocking.  Below there's a piece of code that I use.  
See also docs/design/part-block.txt.  There should be high-level API for 
that, but nobody has bothered up to now to write it.

 You need to replace the decoder and muxer as well, so the proper headers are 
created in the new file.  To simplify all that I put it in a bin (which can 
be unreffed as a whole).

> You can do above things in another independent thread which will 
> just wait till 1 hour is complete. 

 Or you can use g_timeout_add_seconds (3600, ...) in your main loop.



static gboolean destroy_bin_cb (gpointer user_data)
    GstElement *oldbin = user_data;

    log_message("Destroying old bin.\n");
    if (pipeline)
        gst_element_set_state (oldbin, GST_STATE_NULL);
        gst_bin_remove (GST_BIN(pipeline), oldbin);
    return FALSE;

static void replace_filesink_blocked_cb (GstPad *pad, gboolean blocked, 
gpointer user_data)
    if (blocked)
        GstElement *oldbin;
        GstPad *sinkpad;

        log_message("Blocked filesink queue.\n");
        oldbin = filesinkbin;
        sinkpad = gst_element_get_static_pad(oldbin, "sink");
        if (!sinkpad)
            log_message("replace_filesink_blocked_cb: oldbin doesn't have sink 
            goto fail;
        gst_pad_unlink(queuesrcpad, sinkpad);

        /* Finalize the old tail. */
        /* Sending EOS should be done from here (we're in the queue thread). 
        gst_pad_send_event(sinkpad, gst_event_new_eos());
        log_message("Sent event.\n");

        log_message("Checked sinks.\n");
        /* Setting state should be done from the main thread. Do it before the
           pipeline has been set to PLAYING - implicitly, because that is also
           done in an idle callback, but one that is started after this one.
        g_idle_add(destroy_bin_cb, oldbin);

        log_message("Created filesink.\n");
        log_message("Unlocked mutex.\n");

        /* And unblock again. */
        gst_pad_set_blocked_async(queuesrcpad, FALSE, 
replace_filesink_blocked_cb, NULL);

        log_message("Done replacing filesink.\n");
        log_message("Unblocked filesink queue.\n");


static void replace_filesink()
    if (queuesrcpad == NULL)
        log_message("replace_filesink while no queuesrcpad yet, waiting for it 
to appear.\n");
        gst_pad_set_blocked_async(queuesrcpad, TRUE, 
replace_filesink_blocked_cb, NULL);

Arnout Vandecappelle                               arnout at mind be
Senior Embedded Software Architect                 +32-16-286540
Essensium/Mind                                     http://www.mind.be
G.Geenslaan 9, 3001 Leuven, Belgium                BE 872 984 063 RPR Leuven
LinkedIn profile: http://www.linkedin.com/in/arnoutvandecappelle
GPG fingerprint:  D206 D44B 5155 DF98 550D  3F2A 2213 88AA A1C7 C933

More information about the gstreamer-devel mailing list