Reading of GST tags with explicit pipeline and not decodebin/playbin

Stefan Kost ensonic at hora-obscura.de
Mon May 2 12:11:19 PDT 2011


Am 02.05.2011 18:02, schrieb Mihai Stoica:
> Hi,
> 
> I have some issues trying to extract GST tags from a mov file.
> Because of performance requirements I don't want to use a decoder.. so
> the pipeline would be similar to:
> gst-launch filesrc location=./movie.mov ! qtdemux ! fakesink --tags,
> but written with GStreamer API with C.
> 
> If I execute this pipeline in command line I can see all tags being
> extracted, but when trying to execute the C code no GST_MESSAGE_TAG is
> being received.
> If I replace qtdemux with decodebin without doing other changes to the
> code... tag messages are being captured without any issues.
> 
> Could anyone give me a hint about what am I doing wrong ?

I don't see anything obvious right now, but wonder why you are not using
GstDiscoverer instead.

Stefan

> 
> The code would be like this:
> 
> static GstElement *
> create_decodebin_pipeline (MetadataExtractor *extractor, const gchar *uri)
> {
> 	GstElement *pipeline = NULL;
> 
> 	GstElement *filesrc  = NULL;
> 	GstElement *bin      = NULL;
> 
> 	pipeline = gst_element_factory_make ("pipeline", NULL);
> 	if (!pipeline) {
> 		g_warning ("Failed to create GStreamer pipeline");
> 		return NULL;
> 	}
> 
> 	filesrc = gst_element_factory_make ("giosrc", NULL);
> 	if (!filesrc) {
> 		g_warning ("Failed to create GStreamer giosrc");
> 		gst_object_unref (GST_OBJECT (pipeline));
> 		return NULL;
> 	}
> 
> 	bin = gst_element_factory_make ("qtdemux", "qtdemux");
> 	if (!bin) {
> 		g_warning ("Failed to create GStreamer qtdemux");
> 		gst_object_unref (GST_OBJECT (pipeline));
> 		gst_object_unref (GST_OBJECT (filesrc));
> 		return NULL;
> 	}
> 	
> 	g_object_set (G_OBJECT (bin), "name", "demux", NULL);
> 
> 	g_signal_connect (G_OBJECT (bin),
> 			  "pad-added",
> 			  G_CALLBACK (dbin_dpad_cb),
> 			  extractor);
> 
> 	gst_bin_add (GST_BIN (pipeline), filesrc);
> 	gst_bin_add (GST_BIN (pipeline), bin);
> 
> 	if (!gst_element_link_many (filesrc, bin, NULL)) {
> 		g_warning ("Could not link GStreamer elements");
> 		gst_object_unref (GST_OBJECT (pipeline));
> 		return NULL;
> 	}
> 
> 	g_object_set (G_OBJECT (filesrc), "location", uri, NULL);
> 
> 	extractor->bin = bin;
> 
> 	return pipeline;
> }
> 
> 
> static void
> dbin_dpad_cb (GstElement* e, GstPad* pad, gboolean cont, gpointer data_)
> {
> 	MetadataExtractor *extractor = (MetadataExtractor *)data_;
> 	GstElement        *fsink;
> 	GstPad            *fsinkpad;
> 	GValue             val = {0, };
> 
> 	fsink = gst_element_factory_make ("fakesink", NULL);
> 
> 	/* We increase the preroll buffer so we get duration (one frame not enough)*/
> 	g_value_init (&val, G_TYPE_INT);
> 	g_value_set_int (&val, 51);
> 	g_object_set_property (G_OBJECT (fsink), "preroll-queue-len", &val);
> 	g_value_unset (&val);
> 
> 	extractor->fsinks = g_list_append (extractor->fsinks, fsink);
> 	gst_element_set_state (fsink, GST_STATE_PAUSED);
> 
> 	gst_bin_add (GST_BIN (extractor->pipeline), fsink);
> 	fsinkpad = gst_element_get_static_pad (fsink, "sink");
> 	gst_pad_link (pad, fsinkpad);
> 	gst_object_unref (fsinkpad);
> }
> 
> 
> static gboolean
> poll_for_ready (MetadataExtractor *extractor,
>                 GstState state, /* GST_STATE_PAUSED */
>                 gboolean ready_with_state, /* TRUE */
>                 gboolean ready_with_eos) /* FALSE */
> {
> 
> 	gint64              timeout   = 5 * GST_SECOND;
> 	GstBus             *bus       = extractor->bus;
> 	GstTagList         *new_tags;
> 
> 	gst_element_set_state (extractor->pipeline, state);
> 
> 	while (TRUE) {
> 		GstMessage *message;
> 		GstElement *src;
> 
> 		message = gst_bus_timed_pop (bus, timeout);
> 
> 		if (!message) {
> 			g_warning ("Pipeline timed out");
> 			return FALSE;
> 		}
> 
> 		src = (GstElement*)GST_MESSAGE_SRC (message);
> 
> 		switch (GST_MESSAGE_TYPE (message)) {
> 		case GST_MESSAGE_TAG: {
> 
> 			gst_message_parse_tag (message, &new_tags);
> 			add_tags (new_tags, extractor);
> 			gst_tag_list_free (new_tags);
> 			break;
> 		}
> 		default:
> 			/* Nothing to do here */
> 			break;
> 		}
> 
> 		gst_message_unref (message);
> 	}
> 
> 	g_assert_not_reached ();
> 
> 	return FALSE;
> }
> 
> Thanks,
> Mihai.
> _______________________________________________
> gstreamer-devel mailing list
> gstreamer-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel



More information about the gstreamer-devel mailing list