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.
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; } _______________________________________________ gstreamer-devel mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
On Wed, 2012-10-31 at 16:55 +0900, ByoungSoon Lee wrote:
Hi, > 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? Depending on the video sink actually chose, you might also need a videoscale element between ffmpegcolorspace and autovideosink (for pixel aspect ration adjustment, if the sink can't scale by itself). If that's not it, perhaps make a GST_DEBUG log and have a look for where it posts the error, and look at the lines before that to get an idea what's going wrong. Cheers -Tim _______________________________________________ gstreamer-devel mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Free forum by Nabble | Edit this page |