gst-launch works fine, but appsrc got Internal data flow error.

ByoungSoon Lee l22bss at gmail.com
Wed Oct 31 00:55:21 PDT 2012


I'm trying to play video stream over the network, but before that I test my
pipeline with local video file.

My first try is this and works fine.
  gst-launch filesrc location=test.avi ! decodebin2 ! ffmpegcolorspace !
autovideosink
My second try also works fine, too.
The video_only.mpeg2 file is a video file without container information,
i.e., only included raw video data.
  gst-launch filesrc location=video_only.mpeg2 ! mpegvideoparse !
ffdec_mpeg2video ! ffmpegcolorspace ! autovideosink
I have trouble when I run the code above using appsrc. I got  error message
: "Error Internal data flow error."
Does anybody can give me any suggestions or guide reference?

I asked this issue to Stackoverflow a few days ago, but no one answers. So
I post the same question again.
(
http://stackoverflow.com/questions/13074894/gstreamer-appsrc-video-streaming-over-the-network
 )

I attach source code for reference.

// http://amarghosh.blogspot.kr/2012/01/gstreamer-appsrc-in-action.html
// http://www.cs.odu.edu/~cs476/Xlib/xlines.c
/*
  I don't know if it is syntax highlighter or blogger, but I can't seem to
  put angle brackets around header file names properly.
*/
#include <X11/Xlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>
#include <gst/gst.h>
#include <gst/app/gstappsrc.h>
#include <gst/interfaces/xoverlay.h>

typedef struct {
 GstPipeline *pipeline;
 GstAppSrc *src;
 GstElement *queue;
 GstElement *decoder;
 GstElement *ffmpeg;
 GstElement *videoscale;
 GstElement *convertcolor;
 GstElement *videosink;
 GMainLoop *loop;
 guint sourceid;
 FILE *file;
}gst_app_t;

static gst_app_t gst_app;

#define BUFF_SIZE (4 * 1024)
static   Window child_window = 0;
static Window window = 0;

static gboolean read_data(gst_app_t *app)
{
 GstBuffer *buffer;
 guint8 *ptr;
 gint size;
 GstFlowReturn ret;

 ptr = g_malloc(BUFF_SIZE);
 g_assert(ptr);

 size = fread(ptr, 1, BUFF_SIZE, app->file);

 if(size == 0){
  ret = gst_app_src_end_of_stream(app->src);
  g_debug("eos returned %d at %d\n", ret, __LINE__);
  return FALSE;
 }

 buffer = gst_buffer_new();
 GST_BUFFER_MALLOCDATA(buffer) = ptr;
 GST_BUFFER_SIZE(buffer) = size;
 GST_BUFFER_DATA(buffer) = GST_BUFFER_MALLOCDATA(buffer);

 ret = gst_app_src_push_buffer(app->src, buffer);

 if(ret !=  GST_FLOW_OK){
  g_debug("push buffer returned %d for %d bytes \n", ret, size);
  return FALSE;
 }

 if(size != BUFF_SIZE){
  ret = gst_app_src_end_of_stream(app->src);
  g_debug("eos returned %d at %d\n", ret, __LINE__);
  return FALSE;
 }

 return TRUE;
}

static void start_feed (GstElement * pipeline, guint size, gst_app_t *app)
{
 if (app->sourceid == 0) {
  g_print("start feeding");
  app->sourceid = g_idle_add ((GSourceFunc) read_data, app);
 }
}

static void stop_feed (GstElement * pipeline, gst_app_t *app)
{
 if (app->sourceid != 0) {
  g_print("stop feeding");
  g_source_remove (app->sourceid);
  app->sourceid = 0;
 }
}

static void on_pad_added(GstElement *element, GstPad *pad)
{
 GstCaps *caps;
 GstStructure *str;
 gchar *name;
 GstPad *ffmpegsink;
 GstPadLinkReturn ret;

 g_debug("pad added");

 caps = gst_pad_get_caps(pad);
 str = gst_caps_get_structure(caps, 0);

 g_assert(str);

 name = (gchar*)gst_structure_get_name(str);

 g_debug("pad name %s", name);

 if(g_strrstr(name, "video")){

  ffmpegsink = gst_element_get_pad(gst_app.ffmpeg, "sink");
  g_assert(ffmpegsink);
  ret = gst_pad_link(pad, ffmpegsink);
  g_debug("pad_link returned %d\n", ret);
  gst_object_unref(ffmpegsink);
 }
 gst_caps_unref(caps);
}

static gboolean bus_callback(GstBus *bus, GstMessage *message, gpointer
*ptr)
{
 gst_app_t *app = (gst_app_t*)ptr;

 switch(GST_MESSAGE_TYPE(message)){

    case GST_MESSAGE_ELEMENT:
 gst_x_overlay_set_window_handle (GST_X_OVERLAY (GST_MESSAGE_SRC(message)),
child_window);
        break;
 case GST_MESSAGE_ERROR:{
  gchar *debug;
  GError *err;

  gst_message_parse_error(message, &err, &debug);
  g_print("Error %s\n", err->message);
  g_error_free(err);
  g_free(debug);
  g_main_loop_quit(app->loop);
 }
 break;

 case GST_MESSAGE_WARNING:{
  gchar *debug;
  GError *err;
  gchar *name;

  gst_message_parse_warning(message, &err, &debug);
  g_print("Warning %s\nDebug %s\n", err->message, debug);

  name = GST_MESSAGE_SRC_NAME(message);

  g_print("Name of src %s\n", name ? name : "nil");
  g_error_free(err);
  g_free(debug);
 }
 break;

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

 case GST_MESSAGE_STATE_CHANGED:
  break;

 default:
  g_print("got message %s\n", \
   gst_message_type_get_name (GST_MESSAGE_TYPE (message)));
  break;
 }

 return TRUE;
}

/*
 * gst-launch filesrc location=test.avi ! decodebin2 ! ffmpegcolorspace !
autovideosink
 * gst-launch filesrc location=video_only.mpeg2 ! mpegvideoparse !
ffdec_mpeg2video ! ffmpegcolorspace ! autovideosink
 *
 * 1. dependency library install
 *    $ sudo apt-get install gstreamer0.10-plugins-bad
 *    $ sudo apt-get install gstreamer0.10-ffmpeg
 *
 * 2. compile
 *    $ gcc hello.c -o hello -lX11 `pkg-config --cflags --libs
gstreamer-0.10 gstreamer-app-0.10` -lgstinterfaces-0.10
 */

void gstreamer_init(int argc, char *argv[])
{
 gst_app_t *app = &gst_app;
 GstBus *bus;
 GstStateChangeReturn state_ret;

 if(argc != 2){
  printf("File name not specified\n");
  return;
 }

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

 g_assert(app->file);

 gst_init(NULL, NULL);

 app->pipeline = (GstPipeline*)gst_pipeline_new("mypipeline");
 bus = gst_pipeline_get_bus(app->pipeline);
 gst_bus_add_watch(bus, (GstBusFunc)bus_callback, app);
 gst_object_unref(bus);

 app->src = (GstAppSrc*)gst_element_factory_make("appsrc", "mysrc");
#if 0// GENERAL_VIDEO_FILE
 app->decoder = gst_element_factory_make("decodebin2", "mydecoder");
 app->ffmpeg = gst_element_factory_make("ffmpegcolorspace", "myffmpeg");
#else
 app->decoder = gst_element_factory_make("mpegvideoparse", "mydecoder");
 app->ffmpeg = gst_element_factory_make("ffdec_mpeg2video", "myffmpeg");
#endif
 app->convertcolor = gst_element_factory_make("ffmpegcolorspace",
"myconvert");
 app->videosink = gst_element_factory_make("autovideosink", "myvsink");

 g_assert(app->src);
 g_assert(app->decoder);
 g_assert(app->ffmpeg);
 g_assert(app->convertcolor);
 g_assert(app->videosink);

 g_signal_connect(app->src, "need-data", G_CALLBACK(start_feed), app);
 g_signal_connect(app->src, "enough-data", G_CALLBACK(stop_feed), app);
 g_signal_connect(app->decoder, "pad-added",
  G_CALLBACK(on_pad_added), app->decoder);

 gst_bin_add_many(GST_BIN(app->pipeline), (GstElement*)app->src,
  app->decoder, app->ffmpeg, app->convertcolor, app->videosink, NULL);

 if(!gst_element_link((GstElement*)app->src, app->decoder)){
  g_warning("failed to link src anbd decoder");
 }

  if(!gst_element_link(app->ffmpeg, app->convertcolor)){
  g_warning("failed to link ffmpeg and convertcolor");
 }

 if(!gst_element_link(app->convertcolor, app->videosink)){
  g_warning("failed to link convertcolor and videosink");
 }
 state_ret = gst_element_set_state((GstElement*)app->pipeline,
GST_STATE_PLAYING);
 g_warning("set state returned %d\n", state_ret);

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

 g_main_loop_run(app->loop);

  state_ret = gst_element_set_state((GstElement*)app->pipeline,
GST_STATE_NULL);
 g_warning("set state null returned %d\n", state_ret);
  gst_object_unref(app->pipeline);

}
int main(int argc, char *argv[])
{
   Display *disp;
   Window root;
   long fgcolor, bgcolor;
   GC gc;
   XGCValues gc_val;
   XEvent event;
   char *msg = "Hello, World!";
   int screen;
   disp = XOpenDisplay(NULL);
   if (disp == NULL) {
     fprintf(stderr, "Cannot open display\n");
     exit(1);
   }

   screen = DefaultScreen(disp);
   root = RootWindow(disp, screen);
   fgcolor = BlackPixel(disp, screen);
   bgcolor = WhitePixel(disp, screen);

   window = XCreateSimpleWindow(disp, root, 100, 100, 1000, 840, 1,
                           fgcolor, bgcolor);
   child_window = XCreateSimpleWindow(disp, window, 100, 100, 800, 600, 1,
                           fgcolor, bgcolor);
    gc_val.foreground = fgcolor;
    gc_val.background = bgcolor;
    gc = XCreateGC(disp, child_window, GCForeground|GCBackground, &gc_val);

   XSelectInput(disp, child_window, ExposureMask | KeyPressMask);

  g_warning("map xwindow");
  XMapWindow(disp, window);
  XMapWindow(disp, child_window);
  XSync(disp, FALSE);

 gstreamer_init(argc, argv);

  sleep(2);
  XDestroySubwindows( disp, window );
  XDestroyWindow( disp, window );
  XCloseDisplay( disp );

 return 0;
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/gstreamer-devel/attachments/20121031/eff971ea/attachment-0001.html>


More information about the gstreamer-devel mailing list