Advertisement
Guest User

GstAppSrc problem

a guest
Dec 1st, 2010
189
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.69 KB | None | 0 0
  1. #include <gst/gst.h>
  2. #include <gst/app/gstappsrc.h>
  3.  
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include <stdlib.h>
  7.  
  8. #include <gdk-pixbuf/gdk-pixbuf.h>
  9.  
  10. GST_DEBUG_CATEGORY (appsrc_pipeline_debug);
  11. #define GST_CAT_DEFAULT appsrc_pipeline_debug
  12.  
  13. typedef struct _App App;
  14.  
  15. struct _App
  16. {
  17.   GstElement *pipeline;
  18.   GstElement *appsrc;
  19.  
  20.   GMainLoop *loop;
  21.   guint sourceid;
  22.  
  23.   GTimer *timer;
  24.  
  25. };
  26.  
  27. App s_app;
  28.  
  29. static gboolean
  30. read_data (App * app)
  31. {
  32.     guint len;
  33.     GstFlowReturn ret;
  34.     gdouble ms;
  35.  
  36.     ms = g_timer_elapsed(app->timer, NULL);
  37.     if (ms > 1.0/20.0) {
  38.         GstBuffer *buffer;
  39.         GdkPixbuf *pb;
  40.         gboolean ok = TRUE;
  41.  
  42.         buffer = gst_buffer_new();
  43.  
  44.         pb = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, 640, 480);
  45.         gdk_pixbuf_fill(pb, 0xffffffff);
  46.  
  47.         GST_BUFFER_DATA (buffer) = gdk_pixbuf_get_pixels(pb);
  48.         GST_BUFFER_SIZE (buffer) = 640*480*3*sizeof(guchar);
  49.  
  50.         GST_DEBUG ("feed buffer");
  51.         g_signal_emit_by_name (app->appsrc, "push-buffer", buffer, &ret);
  52.         gst_buffer_unref (buffer);
  53.  
  54.         if (ret != GST_FLOW_OK) {
  55.             /* some error, stop sending data */
  56.             GST_DEBUG ("some error");
  57.             ok = FALSE;
  58.         }
  59.  
  60.         g_timer_start(app->timer);
  61.  
  62.         return ok;
  63.     }
  64.  
  65.     //  g_signal_emit_by_name (app->appsrc, "end-of-stream", &ret);
  66.     return FALSE;
  67. }
  68.  
  69. /* This signal callback is called when appsrc needs data, we add an idle handler
  70.  * to the mainloop to start pushing data into the appsrc */
  71. static void
  72. start_feed (GstElement * pipeline, guint size, App * app)
  73. {
  74.   if (app->sourceid == 0) {
  75.     GST_DEBUG ("start feeding");
  76.     app->sourceid = g_idle_add ((GSourceFunc) read_data, app);
  77.   }
  78. }
  79.  
  80. /* This callback is called when appsrc has enough data and we can stop sending.
  81.  * We remove the idle handler from the mainloop */
  82. static void
  83. stop_feed (GstElement * pipeline, App * app)
  84. {
  85.   if (app->sourceid != 0) {
  86.     GST_DEBUG ("stop feeding");
  87.     g_source_remove (app->sourceid);
  88.     app->sourceid = 0;
  89.   }
  90. }
  91.  
  92. static gboolean
  93. bus_message (GstBus * bus, GstMessage * message, App * app)
  94. {
  95.   GST_DEBUG ("got message %s",
  96.       gst_message_type_get_name (GST_MESSAGE_TYPE (message)));
  97.  
  98.   switch (GST_MESSAGE_TYPE (message)) {
  99.     case GST_MESSAGE_ERROR: {
  100.         GError *err = NULL;
  101.         gchar *dbg_info = NULL;
  102.  
  103.         gst_message_parse_error (message, &err, &dbg_info);
  104.         g_printerr ("ERROR from element %s: %s\n",
  105.             GST_OBJECT_NAME (message->src), err->message);
  106.         g_printerr ("Debugging info: %s\n", (dbg_info) ? dbg_info : "none");
  107.         g_error_free (err);
  108.         g_free (dbg_info);
  109.         g_main_loop_quit (app->loop);
  110.         break;
  111.     }
  112.     case GST_MESSAGE_EOS:
  113.       g_main_loop_quit (app->loop);
  114.       break;
  115.     default:
  116.       break;
  117.   }
  118.   return TRUE;
  119. }
  120.  
  121. int
  122. main (int argc, char *argv[])
  123. {
  124.   App *app = &s_app;
  125.   GError *error = NULL;
  126.   GstBus *bus;
  127.   GstCaps *caps;
  128.  
  129.   gst_init (&argc, &argv);
  130.  
  131.   GST_DEBUG_CATEGORY_INIT (appsrc_pipeline_debug, "appsrc-pipeline", 0,
  132.       "appsrc pipeline example");
  133.  
  134.   /* create a mainloop to get messages and to handle the idle handler that will
  135.    * feed data to appsrc. */
  136.   app->loop = g_main_loop_new (NULL, TRUE);
  137.   app->timer = g_timer_new();
  138.  
  139.   app->pipeline = gst_parse_launch("appsrc name=mysource ! video/x-raw-rgb,width=640,height=480,bpp=24,depth=24 ! ffmpegcolorspace ! videoscale method=1 ! theoraenc bitrate=150 ! udpsink host=127.0.0.1 port=1234", NULL);
  140.   g_assert (app->pipeline);
  141.  
  142.   bus = gst_pipeline_get_bus (GST_PIPELINE (app->pipeline));
  143.   g_assert(bus);
  144.  
  145.   /* add watch for messages */
  146.   gst_bus_add_watch (bus, (GstBusFunc) bus_message, app);
  147.  
  148.   /* get the appsrc */
  149.     app->appsrc = gst_bin_get_by_name (GST_BIN(app->pipeline), "mysource");
  150.     g_assert(app->appsrc);
  151.     g_assert(GST_IS_APP_SRC(app->appsrc));
  152.     g_signal_connect (app->appsrc, "need-data", G_CALLBACK (start_feed), app);
  153.     g_signal_connect (app->appsrc, "enough-data", G_CALLBACK (stop_feed), app);
  154.  
  155.   /* set the caps on the source */
  156.   caps = gst_caps_new_simple ("video/x-raw-rgb",
  157.     "bpp",G_TYPE_INT,24,
  158.     "depth",G_TYPE_INT,24,
  159.      "width", G_TYPE_INT, 640,
  160.      "height", G_TYPE_INT, 480,
  161.      NULL);
  162.    gst_app_src_set_caps(GST_APP_SRC(app->appsrc), caps);
  163.  
  164.  
  165.   /* go to playing and wait in a mainloop. */
  166.   gst_element_set_state (app->pipeline, GST_STATE_PLAYING);
  167.  
  168.   /* this mainloop is stopped when we receive an error or EOS */
  169.   g_main_loop_run (app->loop);
  170.  
  171.   GST_DEBUG ("stopping");
  172.  
  173.   gst_element_set_state (app->pipeline, GST_STATE_NULL);
  174.  
  175.   gst_object_unref (bus);
  176.   g_main_loop_unref (app->loop);
  177.  
  178.   return 0;
  179. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement