[gst-devel] Seek works strangely with filesink

Aurelien Grimaud gstelzz at yahoo.fr
Wed Sep 17 23:17:53 CEST 2008


Hi,
audiosink is sync on the clock, not filesink.
So your pipeline with filesink runs as fast as possible, while the 
audiosink one runs at real time.
Your filesink pipelines misses a sync element.
Try add identity with sync=TRUE in it to force clock sync.

gst-launch -v filesrc location=/home/musique/Heidsieck-Bernard.mp3 \
! decodebin ! identity sync=TRUE ! wavenc ! filesink location=/tmp/xx.wav

Note:
I was first expecting sync option on filesink to do the trick, but it 
fails :
gst-launch -v filesrc location=/home/musique/Heidsieck-Bernard.mp3 \
! decodebin ! wavenc ! identity ! filesink location=/tmp/xx.wav sync=TRUE

So I tried
gst-launch -v filesrc location=/home/musique/Heidsieck-Bernard.mp3 \
! decodebin ! wavenc ! identity sync=TRUE ! filesink location=/tmp/xx.wav
but it runs too fast too.

Aurelien

David Banks a écrit :
> Hi, I'm just getting started with GStreamer.  I want to write a program to load
> an Ogg file, play it, and seek to a random point within the file every two
> seconds.  In addition, I want to be able to save the output of the program to a
> file.
>
> I initially wrote the program using the pipeline:
>
> filesrc | oggdemux | vorbisdec | audioconvert | autoaudiosink
>
> Basically according to the example given in the application development manual.
> I added the function 'cb_timeout0' to detect the length and do the seek.  That
> version worked perfectly and produced exactly what I expected.
>
> I then tried to make it write its output to a file.  I initially tried to simply
> replace 'autoaudiosink' with 'filesink', but couldn't figure out the format of
> the raw samples in the output file.  Since I wanted WAV output anyway, I tried
> using wavenc.  After a little trial and error, I found the pipeline below:
>
> filesrc | oggdemux | vorbisdec | audioconvert | wavenc | filesink
>
> I converted it to the program below.  This program displays an odd behaviour,
> however.  Its output is always the size of the fully decoded Ogg file, no matter
> where you interrupt it.  That is, even if you run it for only a few seconds
> (when it .  In addition, the seeks in the output are erratic.  For
> example, if you run the program for three minutes, the output file might contain
> only three or four seeks.  They seem to occur at random points in the output.
>
> Why is the filesink output so different from the autoaudiosink output?  Is it
> possible the seeks are happening in the *output* rather than the input file?  I
> tried replacing the first parameter to gst_element_seek() with a pointer to the
> demuxer rather than the entire pipeline, but still the same behaviour.
>
> // gcc -o demo -Wall -g $(pkg-config --libs --cflags $(libs)) demo.c
>
> #include <stdio.h>
>
> #include <gst/gst.h>
> #include <glib.h>
>
> static gboolean cb_bus(GstBus *bus, GstMessage *msg, gpointer data);
> static void cb_pad_added(GstElement *element, GstPad *pad, gpointer data);
> gboolean cb_timeout0(gpointer data);
>
> gint32 pos = 0;
>
> int main(int argc, char **argv) {
>     GMainLoop *loop;
>     GstElement *pipeline, *source, *demuxer, *decoder, *conv1, *conv2, *sink;
>     GstBus *bus;
>
>     gst_init(&argc, &argv);
>     loop = g_main_loop_new(NULL, FALSE);
>
>     if (argc != 2) {
>         g_printerr("Usage: %s <ogg vorbis filename>\n", argv[0]);
>         return 1;
>     }
>
>     pipeline = gst_pipeline_new("audio-player");
>     source = gst_element_factory_make("filesrc", "file-source");
>     demuxer = gst_element_factory_make("oggdemux", "ogg-demuxer");
>     decoder = gst_element_factory_make("vorbisdec", "vorbis-decoder");
>     conv1    = gst_element_factory_make("audioconvert", NULL);
>     conv2    = gst_element_factory_make("wavenc", NULL);
>     sink    = gst_element_factory_make("filesink", "audio-output");
>
>     if (!pipeline || !source || !demuxer || !decoder || !conv1 ||
> !conv2 || !sink) {
>         g_printerr("pipeline failed to create properly, exiting\n");
>         return 1;
>     }
>
>     g_object_set(G_OBJECT(source), "location", argv[1], NULL);
>     g_object_set(G_OBJECT(sink), "location", "/home/amoe/foo.wav", NULL);
>
>     bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
>     gst_bus_add_watch(bus, cb_bus, loop);
>     gst_object_unref(bus);
>
>     gst_bin_add_many(
>         GST_BIN(pipeline),
>         source, demuxer, decoder, conv1, conv2, sink, NULL
>     );
>
>     gst_element_link(source, demuxer);
>     gst_element_link_many(decoder, conv1, conv2, sink, NULL);
>
>
>     g_signal_connect(
>         demuxer, "pad-added", G_CALLBACK(cb_pad_added), decoder
>     );
>
>     g_print("Now playing: %s\n", argv[1]);
>     gst_element_set_state(pipeline, GST_STATE_PLAYING);
>
>     // seek
>     g_timeout_add(2 * 1000, cb_timeout0, pipeline);
>
>     g_print("running...\n");
>     g_main_loop_run(loop);
>
>     g_print("returned, stopping playback\n");
>     gst_element_set_state(pipeline, GST_STATE_NULL);
>
>     g_print("deleting pipeline\n");
>     gst_object_unref(GST_OBJECT(pipeline));
>
>     return 0;
> }
>
> gboolean cb_timeout0(gpointer data) {
>     GstElement *pipeline = (GstElement *) data;
>     GstFormat fmt = GST_FORMAT_TIME;
>     gboolean test;
>     gint64 len;
>     guint64 len_seconds;
>
>     test = gst_element_seek(
>         pipeline,
>         1.0,
>         GST_FORMAT_TIME,
>         GST_SEEK_FLAG_FLUSH,
>         GST_SEEK_TYPE_SET,
>         pos * GST_SECOND,
>         GST_SEEK_TYPE_NONE,
>         -1
>         );
>     printf("seek: %d\n", test);
>
>     test = gst_element_query_duration(
>         pipeline, &fmt, &len
>     );
>
>     len_seconds = len / GST_SECOND;
>     printf("total time: %lld (%llds)\n", len, len_seconds);
>     pos = g_random_int_range(0, len_seconds);
>     printf("random: %d\n", pos);
>
>     puts("timeout called");
>
>     return TRUE;
> }
>
> static gboolean cb_bus(GstBus *bus, GstMessage *msg, gpointer data) {
>
>     return TRUE;
> }
>
> static void cb_pad_added(GstElement *element, GstPad *pad, gpointer data) {
>
>     GstPad *sinkpad;
>     GstElement *decoder = (GstElement *) data;
>
>     puts("pad added callback");
>     g_print("dynamic pad created, linking demuxer/decoder\n");
>
>     sinkpad = gst_element_get_static_pad(decoder, "sink");
>     gst_pad_link(pad, sinkpad);
>
>     gst_object_unref(sinkpad);
>
> }
>
> Thanks,
>   






More information about the gstreamer-devel mailing list