Advertisement
Guest User

Untitled

a guest
Nov 18th, 2017
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.49 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <gst/gst.h>
  3. #include <gst/app/gstappsrc.h>
  4. #include <gst/app/gstappsink.h>
  5.  
  6. typedef struct
  7. {
  8.     GMainLoop *loop;
  9.     GstElement *source;
  10.     GstElement *sink;
  11. } ProgramData;
  12.  
  13. /* called when we get a GstMessage from the source pipeline when we get EOS, we
  14. * notify the appsrc of it. */
  15. static gboolean on_source_message(GstBus * bus, GstMessage * message, ProgramData * data)
  16. {
  17.     GstElement *source;
  18.     GError *err = NULL;
  19.     gchar *dbg_info = NULL;
  20.  
  21.     switch (GST_MESSAGE_TYPE(message)) {
  22.     case GST_MESSAGE_EOS:
  23.         g_print("The source got dry\n");
  24.         source = gst_bin_get_by_name(GST_BIN(data->sink), "testsource");
  25.         gst_app_src_end_of_stream(GST_APP_SRC(source));
  26.         gst_object_unref(source);
  27.         break;
  28.     case GST_MESSAGE_ERROR:
  29.         gst_message_parse_error(message, &err, &dbg_info);
  30.         g_printerr("Received error on source: %s\n", err->message);
  31.         g_printerr("Debugging info: %s\n", (dbg_info) ? dbg_info : "none");
  32.         g_main_loop_quit(data->loop);
  33.         break;
  34.     default:
  35.         break;
  36.     }
  37.     return TRUE;
  38. }
  39.  
  40. /* called when the appsink notifies us that there is a new buffer ready for
  41. * processing */
  42. static GstFlowReturn on_new_sample_from_sink(GstElement * elt, ProgramData * data)
  43. {
  44.     GstSample *sample;
  45.     GstBuffer *app_buffer, *buffer;
  46.     GstElement *source;
  47.     GstFlowReturn ret;
  48.     GstMapInfo info_in;
  49.     guint8 *in;
  50.  
  51.     /* get the sample from appsink */
  52.     sample = gst_app_sink_pull_sample(GST_APP_SINK(elt));
  53.     buffer = gst_sample_get_buffer(sample);
  54.  
  55.     /* make a copy */
  56.     app_buffer = gst_buffer_copy(buffer);
  57.  
  58.     /* we don't need the appsink sample anymore */
  59.     gst_sample_unref(sample);
  60.  
  61.     /* get map and modify it */
  62.     gst_buffer_map(app_buffer, &info_in, GST_MAP_WRITE);
  63.     in = info_in.data;
  64.     for (int i = 0; i < 10; i++) {
  65.         in[i] = 0;
  66.     }
  67.     gst_buffer_unmap(app_buffer, &info_in);
  68.  
  69.     /* get source an push new buffer */
  70.     source = gst_bin_get_by_name(GST_BIN(data->sink), "testsource");
  71.     ret = gst_app_src_push_buffer(GST_APP_SRC(source), app_buffer);
  72.  
  73.     gst_object_unref(source);
  74.  
  75.     return ret;
  76. }
  77.  
  78. /* called when we get a GstMessage from the sink pipeline when we get EOS, we
  79. * exit the mainloop and this testapp. */
  80. static gboolean on_sink_message(GstBus * bus, GstMessage * message, ProgramData * data)
  81. {
  82.     GError *err = NULL;
  83.     gchar *dbg_info = NULL;
  84.  
  85.     switch (GST_MESSAGE_TYPE(message)) {
  86.     case GST_MESSAGE_EOS:
  87.         g_print("Finished playback\n");
  88.         g_main_loop_quit(data->loop);
  89.         break;
  90.     case GST_MESSAGE_ERROR:
  91.         gst_message_parse_error(message, &err, &dbg_info);
  92.         g_printerr("Received error on sink: %s\n", err->message);
  93.         g_printerr("Debugging info: %s\n", (dbg_info) ? dbg_info : "none");
  94.         g_main_loop_quit(data->loop);
  95.         break;
  96.     default:
  97.         break;
  98.     }
  99.     return TRUE;
  100. }
  101.  
  102. int main()
  103. {
  104.     gchar *filename = NULL;
  105.     ProgramData *data = NULL;
  106.     gchar *string = NULL;
  107.     GstBus *bus = NULL;
  108.     GstElement *testsink = NULL;
  109.     GstElement *testsource = NULL;
  110.  
  111.     gst_init(NULL, NULL);
  112.  
  113.     filename = g_strdup("D:\\\\Visual Studio Files\\\\CudaGStreamer\\\\video.mp4");
  114.  
  115.     if (!g_file_test(filename, G_FILE_TEST_EXISTS)) {
  116.         g_print("File %s does not exist\n", filename);
  117.         return -1;
  118.     }
  119.  
  120.     data = g_new0(ProgramData, 1);
  121.  
  122.     data->loop = g_main_loop_new(NULL, FALSE);
  123.  
  124.     /* setting up source pipeline */
  125.     string = g_strdup_printf("filesrc location=\"%s\" ! decodebin ! appsink name=testsink", filename);
  126.     // string = g_strdup_printf("filesrc location=\"%s\" ! appsink name=testsink", filename);
  127.     g_free(filename);
  128.     data->source = gst_parse_launch(string, NULL);
  129.     g_free(string);
  130.  
  131.     if (data->source == NULL) {
  132.         g_print("Bad source\n");
  133.         return -1;
  134.     }
  135.  
  136.     /* to be notified of messages from this pipeline, mostly EOS */
  137.     bus = gst_element_get_bus(data->source);
  138.     gst_bus_add_watch(bus, (GstBusFunc)on_source_message, data);
  139.     gst_object_unref(bus);
  140.  
  141.     /* we use appsink in push mode, it sends us a signal when data is available
  142.     * and we pull out the data in the signal callback. We want the appsink to
  143.     * push as fast as it can, hence the sync=false */
  144.     testsink = gst_bin_get_by_name(GST_BIN(data->source), "testsink");
  145.     g_object_set(G_OBJECT(testsink), "emit-signals", TRUE, "sync", FALSE, NULL);
  146.     g_signal_connect(testsink, "new-sample", G_CALLBACK(on_new_sample_from_sink), data);
  147.     gst_object_unref(testsink);
  148.  
  149.     /* setting up sink pipeline. We have no blocking behaviour on the src which means
  150.     * that we will push the entire file into memory. */
  151.     string = g_strdup_printf(
  152.         "appsrc name=testsource ! "
  153.         "filesink location=\"D:\\\\Visual Studio Files\\\\CudaGStreamer\\\\out.mp4\""
  154.     );
  155.     data->sink = gst_parse_launch(string, NULL);
  156.     g_free(string);
  157.  
  158.     if (data->sink == NULL) {
  159.         g_print("Bad sink\n");
  160.         return -1;
  161.     }
  162.  
  163.     testsource = gst_bin_get_by_name(GST_BIN(data->sink), "testsource");
  164.     /* configure for time-based format */
  165.     g_object_set(testsource, "format", GST_FORMAT_TIME, NULL);
  166.     /* uncomment the next line to block when appsrc has buffered enough */
  167.     // g_object_set (testsource, "block", TRUE, NULL);
  168.     gst_object_unref(testsource);
  169.  
  170.     bus = gst_element_get_bus(data->sink);
  171.     gst_bus_add_watch(bus, (GstBusFunc)on_sink_message, data);
  172.     gst_object_unref(bus);
  173.  
  174.     /* launching things */
  175.     gst_element_set_state(data->sink, GST_STATE_PLAYING);
  176.     gst_element_set_state(data->source, GST_STATE_PLAYING);
  177.  
  178.     /* let's run !, this loop will quit when the sink pipeline goes EOS or when an
  179.     * error occurs in the source or sink pipelines. */
  180.     g_print("Let's run!\n");
  181.     g_main_loop_run(data->loop);
  182.     g_print("Going out\n");
  183.  
  184.     gst_element_set_state(data->source, GST_STATE_NULL);
  185.     gst_element_set_state(data->sink, GST_STATE_NULL);
  186.  
  187.     gst_object_unref(data->source);
  188.     gst_object_unref(data->sink);
  189.     g_main_loop_unref(data->loop);
  190.     g_free(data);
  191.  
  192.     return 0;
  193. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement