[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.
Regards,
Arnout
--
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");
g_static_rec_mutex_lock(&mutex);
log_message("Locked.\n");
oldbin = filesinkbin;
sinkpad = gst_element_get_static_pad(oldbin, "sink");
if (!sinkpad)
{
log_message("replace_filesink_blocked_cb: oldbin doesn't have sink
pad.\n");
goto fail;
}
gst_pad_unlink(queuesrcpad, sinkpad);
log_message("Unlinked.\n");
/* 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);
create_filesink_tail();
log_message("Created filesink.\n");
g_static_rec_mutex_unlock(&mutex);
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");
}
else
{
log_message("Unblocked filesink queue.\n");
}
return;
fail:
pipeline_terminate_async();
g_static_rec_mutex_unlock(&mutex);
}
static void replace_filesink()
{
if (queuesrcpad == NULL)
log_message("replace_filesink while no queuesrcpad yet, waiting for it
to appear.\n");
else
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