videoflip causes critical errors in gstreamer 1.0

adrian at tortenboxer.de adrian at tortenboxer.de
Wed Aug 14 05:47:59 PDT 2013


Hello Tim-Philipp,

Thanks a lot for your answer. I had somehow missed the bug report on bugzilla, sorry.

Boiling down my code to the minimum to reproduce the bug allowed me to pinpoint the cause of the assertion errors, which is in my code and not in gstreamer (but maybe documentation could be improved): I timestamp the buffers before pushing them into the appsrc, but I had not initialized the format property to GST_FORMAT_TIME. I copy/paste my sample code to reproduce the 'bug' below. Compiling as is should produce an executable that spews out the assertion errors. Compiling with either -DINIT_FORMAT or -DNO_TIMESTAMP makes the assertion errors go away, as does obviously the simplified reference case with a videotestsrc instead of the appsrc (-DUSE_APPSRC=0).

No idea why the videoflip element is sensitive to this missing initalization but autovideosink isn't -- this is however not important, it just made me suspect a bug in the wrong place.

The fact that the format property of appsrc needs to be initialized properly is indicated in the application programming guide, but not in the Base Plugins 1.0 Library Reference Manual itself. The latter does mention the "format" property, but only in relation to signals, which I am not using. Do you think the documentation could be improved ?

Adrian

cat >gst-appsrc-test.c <<EOF
/* gstreamer appsrc test
 * Compile with
 * gcc -Wall gst-appsrc-test.c -o gst-appsrc-test $(pkg-config --cflags --libs gstreamer-1.0 gstreamer-app-1.0)
 * Compile options:
 * -DNO_TIMESTAMP ... do not set buffer timestamps on new buffers
 * -DUSE_APPSRC=0 ... use videotestsrc instead of appsrc
 * -DINIT_FORMAT  ... initialize format property of appsrc element
 */

#include <gst/gst.h>
#include <glib.h>
#include <gst/app/gstappsrc.h>

#ifndef USE_APPSRC
#define USE_APPSRC 1
#endif

static gboolean
bus_call (GstBus     *bus,
          GstMessage *msg,
          gpointer    data)
{
  GMainLoop *loop = (GMainLoop *) data;

  switch (GST_MESSAGE_TYPE (msg)) {

    case GST_MESSAGE_EOS:
      g_print ("End of stream\n");
      g_main_loop_quit (loop);
      break;

    case GST_MESSAGE_ERROR: {
      gchar  *debug;
      GError *error;

      gst_message_parse_error (msg, &error, &debug);
      g_free (debug);

      g_printerr ("Error: %s\n", error->message);
      g_error_free (error);

      g_main_loop_quit (loop);
      break;
    }
    default:
      break;
  }

  return TRUE;
}

#if USE_APPSRC > 0
gboolean
new_buffer_cb (gpointer data)
{
  static int framecount = 0;
        GstElement *appsrc;
	GstBuffer *buffer;
	static GstClockTime timestamp = 0;

	appsrc = (GstElement*) data;
	buffer = gst_buffer_new ();

	size_t size;
	GstMemory *memory;
	GstMapInfo info;

	/* allocate memory and add to the buffer */
	size = 512*512;
	memory = gst_allocator_alloc (NULL, size, NULL);

	gst_buffer_append_memory (buffer, memory);

	/* get WRITE access to the memory and copy image */
	gst_buffer_map (buffer, &info, GST_MAP_WRITE);

	int i;
	for (i = 0; i < size; i++)
	  *((char *) info.data + i) = (i + framecount) & 0xff;

	gst_buffer_unmap (buffer, &info);

#ifndef NO_TIMESTAMP
	/* timestamp the buffer */
	GST_BUFFER_DTS (buffer) = timestamp;
	GST_BUFFER_DURATION (buffer) = 40*GST_MSECOND;
	timestamp += 40*GST_MSECOND;
#endif /* NO_TIMESTAMP */

	//fprintf(stderr,"pushing buffer: %s\n",gst_flow_get_name (
	gst_app_src_push_buffer (GST_APP_SRC (appsrc), buffer)
	// ))
	  ;

	framecount++;
	return TRUE;
}
#endif /* USE_APPSRC */

int
main (int   argc,
      char *argv[])
{
  GMainLoop *loop;
  GstElement *pipeline, *source, *conv, *flip, *sink;
  GstBus *bus;
  guint bus_watch_id;
  GstCaps *caps;

  /* Initialisation */
  gst_init (&argc, &argv);
  loop = g_main_loop_new (NULL, FALSE);

  /* Create gstreamer elements */
  pipeline = gst_pipeline_new ("gst-appsrc-test");
#if USE_APPSRC > 0
  source   = gst_element_factory_make ("appsrc", "video source");
#else
  source   = gst_element_factory_make ("videotestsrc", "video source");
#endif /* USE_APPSRC */
  conv     = gst_element_factory_make ("videoconvert", NULL);
  flip     = gst_element_factory_make ("videoflip", NULL);
  sink     = gst_element_factory_make ("autovideosink", "video output");

  if (!pipeline || !source || !conv || !flip || !sink) {
    g_printerr ("One element could not be created. Exiting.\n");
    return -1;
  }

#if USE_APPSRC > 0
  caps = gst_caps_from_string ("video/x-raw");
  gst_caps_set_simple (caps,
		       "format", G_TYPE_STRING, "GRAY8",
		       "width", G_TYPE_INT, 512,
		       "height", G_TYPE_INT, 512,
		       "framerate", GST_TYPE_FRACTION, (unsigned int ) (1000*25), 1000,
		       "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1,
		       NULL);
  g_print ("%s\n", gst_caps_to_string (caps));
  gst_app_src_set_caps (GST_APP_SRC (source), caps);
  gst_caps_unref (caps);
  gst_app_src_set_size (GST_APP_SRC (source),
                              (gint64) -1); // total stream size is not known
  gst_app_src_set_stream_type(GST_APP_SRC (source), 
			      GST_APP_STREAM_TYPE_STREAM);

#ifdef INIT_FORMAT
  g_object_set (G_OBJECT (source),
		"format", GST_FORMAT_TIME, NULL);
#endif /* INIT_FORMAT */

#endif /* USE_APPSRC */

  g_object_set (flip, "method", 1, NULL);

  /* we add a message handler */
  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
  bus_watch_id = gst_bus_add_watch (bus, bus_call, loop);
  gst_object_unref (bus);

  /* Set up the pipeline */

  /* we add all elements into the pipeline */
  gst_bin_add_many (GST_BIN (pipeline), source, conv, flip, sink, NULL);

  /* we link the elements together */
  gst_element_link_many (source, conv, flip, sink, NULL);

  /* Set the pipeline to "playing" state*/
  g_print ("Now playing...");
  gst_element_set_state (pipeline, GST_STATE_PLAYING);

#if USE_APPSRC > 0
  /* Create "stream" */
  g_timeout_add(40, new_buffer_cb, source);
#endif /* USE_APPSRC */

  /* Iterate */
  g_print ("Running...\n");
  g_main_loop_run (loop);

  /* Out of the main loop, clean up nicely */
  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));
  g_source_remove (bus_watch_id);

  return 0;
}
EOF

> Am Sonntag, 11. August 2013 schrieb "Tim-Philipp Müller" <t.i.m at zen.co.uk>
> 
> Hi Adrian,
> 
> On Sat, 2013-08-10 at 15:47 +0200, adrian at tortenboxer.de wrote:
> > I have an application which produces a bunch of the following messages
> > 
> > GStreamer-CRITICAL **: gst_segment_to_stream_time: assertion `segment->format == format' failed
> > 
> > I am not sure if this is a bug in my code or in gstreamer, but it looks
> > a lot like a bug reported by Claudio Basile in march (see below). Just
> > as in his case, the messages go away if I take out the videoflip
> > element (e.g. by replacing it with an identity element). In his reply,
> > Nicolas Dufresne seemed to attribute this to a bug in gst-plugins-good:
> > if this is the case, has the bug been corrected since ? I currently
> > have version 1.1.2 installed.
> 
> I think Claudio's bug was something else, and has been fixed ages ago:
> 
> https://bugzilla.gnome.org/show_bug.cgi?id=696361
> 
> Could you file a bug about your problem, with some information about the
> pipeline you're using, and ideally a way to reproduce it? Thanks!
> 
> It's likely a bug in some plugin.
> 
> Cheers
>  -Tim
> 
> 
> > Quoting from
> > http://lists.freedesktop.org/archives/gstreamer-devel/2013-March/040195.html
> > 
> > > Le jeudi 21 mars 2013 à 16:43 -0700, Claudio Basile a écrit :
> > >> (gst-launch-1.0:20617): GStreamer-CRITICAL **:
> > >> gst_segment_to_stream_time: assertion `segment->format == format'
> > >> failed
> > 
> > On Thu Mar 21 19:58:47 PDT 2013, Nicolas Dufresne answered
> > > This looks like a bug in gst-plugins-good. The segment is of type byte,
> > > but the code assumes it's time. Please visite bugs.gnome.org
> > >
> > > Nicolas


More information about the gstreamer-devel mailing list