appsrc using fopen

Bernhard Graaf bernhard.graaf at gmx.de
Sat Oct 31 03:52:03 PDT 2015


Hi,

 

I try to develop an app using appsrc on gstreamer 1.6.0.

The basic of this app is the 'appsrc_seek.c' from this example:
<http://cgit.freedesktop.org/gstreamer/gst-plugins-base/tree/tests/examples/
app/appsrc-seekable.c>
http://cgit.freedesktop.org/gstreamer/gst-plugins-base/tree/tests/examples/a
pp/appsrc-seekable.c, but with fopen() (not with 'mmapped file').

 

After changing the code, I get this error message: 

*** Error in `./appsrc_seek': free(): invalid next size (normal):
0x00007f24c4009000 ***

 

The code is the following:

#ifdef HAVE_CONFIG_H

#include "config.h"

#endif

 

#include <gst/gst.h>

 

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <sys/types.h>

#include <unistd.h>

#include <fcntl.h>

 

GST_DEBUG_CATEGORY (appsrc_playbin_debug);

#define GST_CAT_DEFAULT appsrc_playbin_debug

 

typedef struct _App App;

 

struct _App

{

  GstElement *playbin;

  GstElement *appsrc;

 

  GMainLoop *loop;

 

  FILE *file;

  guint8 *data;

  long length;

  guint64 offset;

};

 

App s_app;

 

#define CHUNK_SIZE  4096

 

/* This method is called by the need-data signal callback, we feed data into
the

 * appsrc with an arbitrary size.

 */

static void

feed_data (GstElement * appsrc, guint size, App * app)

{

  GstBuffer *buffer;

  guint len;

  GstFlowReturn ret;

 

  if (app->offset >= app->length) {

    /* we are EOS, send end-of-stream */

    g_signal_emit_by_name (app->appsrc, "end-of-stream", &ret);

    return;

  }

 

  /* read any amount of data, we are allowed to return less if we are EOS */

 

  len = CHUNK_SIZE;

  if (app->offset + len > app->length)

    len = app->length - app->offset;

 

  buffer = gst_buffer_new_allocate (NULL, len, NULL);

  if(!buffer) printf("Error to allocate memory\n");

  printf("Buffersize: %" G_GSIZE_FORMAT "\n", gst_buffer_get_size (buffer));

  fseek(app->file,app->offset,SEEK_SET);

  fread (buffer,1,len,app->file);

 

   

  GST_DEBUG ("feed buffer %p, offset %" G_GUINT64_FORMAT "-%u", buffer,

      app->offset, len);

  

  printf("feed buffer %p, offset %"G_GUINT64_FORMAT", len %u \n", buffer,
app->offset, len);

  g_signal_emit_by_name (app->appsrc, "push-buffer", buffer, &ret);

  gst_buffer_unref (buffer);

 

  app->offset += len;

 

  return;

}

 

/* called when appsrc wants us to return data from a new position with the
next

 * call to push-buffer. */

static gboolean

seek_data (GstElement * appsrc, guint64 position, App * app)

{

  GST_DEBUG ("seek to offset %" G_GUINT64_FORMAT, position);

  app->offset = position;

 

  return TRUE;

}

 

static void

found_source (GObject * object, GObject * orig, GParamSpec * pspec, App *
app)

{

  /* get a handle to the appsrc */

  g_object_get (orig, pspec->name, &app->appsrc, NULL);

 

  GST_DEBUG ("got appsrc %p", app->appsrc);

 

  g_object_set (app->appsrc, "size", (gint64) app->length, NULL);

  gst_util_set_object_arg (G_OBJECT (app->appsrc), "stream-type",
"seekable");

 

  g_signal_connect (app->appsrc, "need-data", G_CALLBACK (feed_data), app);

  g_signal_connect (app->appsrc, "seek-data", G_CALLBACK (seek_data), app);

}

 

static gboolean

bus_message (GstBus * bus, GstMessage * message, App * app)

{

  GST_DEBUG ("got message %s",

      gst_message_type_get_name (GST_MESSAGE_TYPE (message)));

 

  switch (GST_MESSAGE_TYPE (message)) {

    case GST_MESSAGE_ERROR:

      g_error ("received error");

      g_main_loop_quit (app->loop);

      break;

    case GST_MESSAGE_EOS:

      g_main_loop_quit (app->loop);

      break;

    default:

      break;

  }

  return TRUE;

}

 

 

int

main (int argc, char *argv[])

{

  GstBus *bus;

  App *app = &s_app;

 

  gst_init (&argc, &argv);

 

  GST_DEBUG_CATEGORY_INIT (appsrc_playbin_debug, "appsrc-playbin", 0,

      "appsrc playbin example");

 

  if (argc < 2) {

    g_print ("usage: %s <filename>\n", argv[0]);

    return -1;

  }

 

  app->file = fopen (argv[1], "rb");

  if (app->file == NULL) {

    printf("open file error\n");

    return -2;

  }

 

  fseek(app->file, 0, SEEK_END);

  app->length = ftell (app->file);

  rewind (app->file);

  app->offset = 0;

  printf("Filesize: %ld\n", app->length);

 

  /* create a mainloop to get messages */

  app->loop = g_main_loop_new (NULL, TRUE);

 

  app->playbin = gst_element_factory_make ("playbin", NULL);

  g_assert (app->playbin);

 

  bus = gst_pipeline_get_bus (GST_PIPELINE (app->playbin));

 

  /* add watch for messages */

  gst_bus_add_watch (bus, (GstBusFunc) bus_message, app);

 

  /* set to read from appsrc */

  g_object_set (app->playbin, "uri", "appsrc://", NULL);

 

  /* get notification when the source is created so that we get a handle to
it

   * and can configure it */

  g_signal_connect (app->playbin, "deep-notify::source",

      (GCallback) found_source, app);

 

  /* go to playing and wait in a mainloop. */

  gst_element_set_state (app->playbin, GST_STATE_PLAYING);

 

  /* this mainloop is stopped when we receive an error or EOS */

  g_main_loop_run (app->loop);

 

  GST_DEBUG ("stopping");

 

  gst_element_set_state (app->playbin, GST_STATE_NULL);

 

  /* free the file */

//  g_mapped_file_unref (app->file);

 

  gst_object_unref (bus);

  g_main_loop_unref (app->loop);

 

  return 0;

}

 

 

The only code changes are marked in bold.

I don't understand where the fault is.

Any idea?

 

Thanks a lot

Bernhard

 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/gstreamer-devel/attachments/20151031/43b0330d/attachment-0001.html>


More information about the gstreamer-devel mailing list