From: Aurelien G. <gs...@ya...> - 2008-09-17 21:17:54
|
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, > |