Advertisement
Guest User

Untitled

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