Guest User

gstreamer_splitmuxsink_mpegtsmux

a guest
Sep 18th, 2017
147
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 11.20 KB | None | 0 0
  1. // (1) gst-launch-1.0 -v -e  videotestsrc  ! x264enc  ! rtph264pay  ! udpsink host=127.0.0.1 port=5004
  2. // (2) gst-launch-1.0 -e udpsrc buffer-size=524288 port=5004 caps = "application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264, payload=(int)96" ! rtph264depay ! queue ! splitmuxsink muxer=mpegtsmux max-size-time=10000000000 location=test%05d.ts
  3.  
  4. #include <gst/gst.h>
  5. #include <string.h>
  6.  
  7. /* Structure to contain all our information, so we can pass it to callbacks */
  8. typedef struct _CustomData {
  9.   gboolean    is_live;
  10.   GstElement *pipeline;
  11.   GMainLoop  *loop;
  12.   GstElement *udpsrc;
  13.   GstElement *depayload;
  14.   GstElement *queue;
  15.   GstElement *mpegtsmux;
  16.   GstElement *splitmuxsink;
  17. } CustomData;
  18.  
  19. static void cb_message (GstBus *bus, GstMessage *msg, CustomData *data);
  20.  
  21. int main(int argc, char *argv[]) {
  22.   GstBus *bus;
  23.   CustomData data;
  24.   GstStateChangeReturn ret;
  25.  
  26.   g_print ("Call init, to start...\n");
  27.  
  28.   /* Initialize GStreamer */
  29.   gst_init (&argc, &argv);
  30.  
  31.   /* Initialize our data structure */
  32.   memset (&data, 0, sizeof (data));
  33.  
  34.   /* Create the elements */
  35.   data.udpsrc       = gst_element_factory_make ("udpsrc", "udpsrc-element");                /*** good ***/
  36.   data.depayload    = gst_element_factory_make ("rtph264depay", "depayload-element");       /*** good ***/
  37.   data.mpegtsmux    = gst_element_factory_make ("mpegtsmux", "mpegtsmux-element");          /*** BAD  ***/
  38.   data.queue        = gst_element_factory_make ("queue", "queue-element");                  /***      ***/
  39.   data.splitmuxsink = gst_element_factory_make ("splitmuxsink", "splitmuxsink-element");    /*** good (+BAD mpegtsmux) ***/
  40.  
  41.   /* Create the empty pipeline */
  42.   data.pipeline = gst_pipeline_new ("test-pipeline");
  43.  
  44.   if   (!data.pipeline || !data.udpsrc || !data.depayload || !data.queue || !data.mpegtsmux  || !data.splitmuxsink) {
  45.     g_printerr ("Not all elements could be created.\n");
  46.     return -1;
  47.   }
  48.  
  49.   /* Build the pipeline */
  50.   //gst_bin_add_many (GST_BIN (data.pipeline), data.udpsrc, data.depayload, data.mpegtsmux, data.filesink, NULL);
  51.   gst_bin_add_many (GST_BIN (data.pipeline), data.udpsrc, data.depayload, data.queue, data.splitmuxsink, NULL); //data.mpegtsmux
  52.  
  53.   /* link the pads */
  54.   if (gst_element_link (data.udpsrc, data.depayload) != TRUE    ) {
  55.     g_printerr ("udpsrc - depayload could not be linked.\n");
  56.     gst_object_unref (data.pipeline);
  57.     return -1;
  58.   }
  59.  
  60.   /* link the pads */
  61.   if (gst_element_link (data.depayload, data.queue) != TRUE    ) {
  62.     g_printerr ("depayload - queue could not be linked.\n");
  63.     gst_object_unref (data.pipeline);
  64.     return -1;
  65.   }
  66.  
  67.   /*** REQUEST PAD FROM splitmuxsink to link to queue ***/
  68.   /*  MAKE sink PAD on mpegtsmux */
  69.   GstPad * sinkpad = 0;
  70.   gchar  * sinkname = "empty";
  71.   sinkpad = gst_element_get_request_pad (data.splitmuxsink, "video");
  72.   sinkname = gst_pad_get_name (sinkpad);
  73.   g_print ("A new pad %s was created for splitmuxsink\n", sinkname);
  74.   /* GET source PAD on tsmux */
  75.   GstPad * srcpad = 0;
  76.   gchar  * srcname = "empty";
  77.   srcpad = gst_element_get_compatible_pad (data.queue, sinkpad, NULL);
  78.   /* LINK PADS */
  79.   GstPadLinkReturn test = gst_pad_link (srcpad, sinkpad);
  80.  
  81.   switch (test) {
  82.     case GST_PAD_LINK_OK:
  83.         g_print ("GST_PAD_LINK_OK\n");
  84.       break;
  85.     case GST_PAD_LINK_WRONG_HIERARCHY:
  86.         g_printerr ("GST_PAD_LINK_WRONG_HIERARCHY\n");
  87.       break;
  88.     case GST_PAD_LINK_WAS_LINKED:
  89.         g_printerr ("GST_PAD_LINK_WAS_LINKED\n");
  90.       break;
  91.     case GST_PAD_LINK_WRONG_DIRECTION:
  92.         g_printerr ("GST_PAD_LINK_WRONG_DIRECTION\n");
  93.       break;
  94.     case GST_PAD_LINK_NOFORMAT:
  95.         g_printerr ("GST_PAD_LINK_NOFORMAT\n");
  96.       break;
  97.     case GST_PAD_LINK_NOSCHED:
  98.         g_printerr ("GST_PAD_LINK_NOSCHED\n");
  99.       break;
  100.     case GST_PAD_LINK_REFUSED:
  101.         g_printerr ("GST_PAD_LINK_REFUSED\n");
  102.       break;
  103.     default:
  104.         g_printerr("Unknown response\n");
  105.         break;
  106.   }
  107.  
  108.   srcname = gst_pad_get_name (srcpad);
  109.   g_print ("A new pad %s was created and linked to %s\n", sinkname, srcname);
  110.  
  111.   g_print ("Modify properties...\n");
  112.  
  113.   g_object_set (data.udpsrc, "port", 5004, NULL);
  114.   g_object_set (data.udpsrc, "buffer-size", 524288, NULL); //
  115.  
  116.   GstCaps *caps = gst_caps_new_simple ("application/x-rtp",
  117.      "media", G_TYPE_STRING, "video",
  118.      "clock-rate", G_TYPE_INT, 90000,
  119.      "encoding-name", G_TYPE_STRING, "H264",
  120.      "payload", G_TYPE_INT, 96,
  121.      NULL);
  122.  
  123.   g_object_set (data.udpsrc, "caps", caps, NULL);
  124.  
  125.   g_object_set (data.splitmuxsink, "muxer", data.mpegtsmux, NULL);
  126.   g_object_set (data.splitmuxsink, "max-size-time", 10000000000, NULL);
  127.   g_object_set (data.splitmuxsink, "location", "file%03d.ts", NULL);
  128.  
  129.   g_print ("Call 'play'\n");
  130.  
  131.   /* Start playing */
  132.   ret = gst_element_set_state (data.pipeline, GST_STATE_PLAYING);
  133.   if (ret == GST_STATE_CHANGE_FAILURE) {
  134.     g_printerr ("Unable to set the pipeline to the playing state.\n");
  135.     gst_object_unref (data.pipeline);
  136.     return -1;
  137.   } else if (ret == GST_STATE_CHANGE_NO_PREROLL) {
  138.     data.is_live = TRUE;
  139.   }
  140.  
  141.   g_print ("Called 'play'\n");
  142.  
  143.   bus = gst_element_get_bus (data.pipeline);
  144.   data.loop = g_main_loop_new (NULL, FALSE);
  145.   gst_bus_add_signal_watch (bus);
  146.   g_signal_connect (bus, "message", G_CALLBACK (cb_message), &data);
  147.  
  148.   g_print ("Calling main loop\n");
  149.   g_main_loop_run (data.loop);
  150.   g_print ("Done!\n");
  151.  
  152.   /* Free resources */
  153.   //gst_object_unref (GST_OBJECT (sinkpad));
  154.   //gst_object_unref (GST_OBJECT (srcpad));
  155.   //g_free (sinkname);
  156.   //g_free (srcname);
  157.   //gst_object_unref (GST_OBJECT (sinkpad2));
  158.   //gst_object_unref (GST_OBJECT (srcpad2));
  159.   //g_free (sinkname2);
  160.   //g_free (srcname2);
  161.   //g_main_loop_unref (main_loop);
  162.   //gst_object_unref (bus);
  163.   gst_element_set_state (data.pipeline, GST_STATE_NULL);
  164.   //gst_object_unref (data.pipeline);
  165.  
  166.   return 0;
  167. }
  168.  
  169. static void cb_message (GstBus *bus, GstMessage *msg, CustomData *data) {
  170.  
  171.   switch (GST_MESSAGE_TYPE (msg)) {
  172.   GError *err;
  173.   gchar *debug;
  174.   case GST_MESSAGE_ERROR:{
  175.  
  176.       gst_message_parse_error (msg, &err, &debug);
  177.       g_printerr ("Error received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message);
  178.       g_printerr ("Debugging information: %s\n", debug ? debug : "none");
  179.       g_clear_error (&err);
  180.       //g_error_free (err);
  181.       //g_free (debug);
  182.  
  183.       gst_element_set_state (data->pipeline, GST_STATE_READY);
  184.       g_main_loop_quit (data->loop);
  185.       break;
  186.     }
  187.     case GST_MESSAGE_WARNING: {
  188.         gst_message_parse_warning(msg, &err, &debug);
  189.         g_printerr ("Warning received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message);
  190.         g_printerr ("Debugging information: %s\n", debug ? debug : "none");
  191.             g_clear_error (&err); g_free (debug);
  192.             break;
  193.     }
  194.     case GST_MESSAGE_INFO:{
  195.         gst_message_parse_info(msg, &err, &debug);
  196.         g_printerr ("Info received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message);
  197.         g_printerr ("Debugging information: %s\n", debug ? debug : "none");
  198.         g_clear_error (&err); g_free (debug);
  199.         break;
  200.     }
  201.     case GST_MESSAGE_TAG: {
  202.         //GstTagList *tags = NULL;
  203.         //gst_message_parse_tag (msg, &tags);
  204.         g_print ("Got tags from element %s\n", GST_OBJECT_NAME (msg->src));
  205.         //handle_tags (tags);
  206.         //gst_tag_list_unref (tags);
  207.         break;
  208.     }
  209.     case GST_MESSAGE_EOS:
  210.       /* end-of-stream */
  211.          g_print ("End-Of-Stream reached.\n");
  212.       gst_element_set_state (data->pipeline, GST_STATE_READY);
  213.       g_main_loop_quit (data->loop);
  214.       break;
  215.     case GST_MESSAGE_BUFFERING:{
  216.       gint percent = 0;
  217.       g_print ("b");
  218.  
  219.       /* If the stream is live, we do not care about buffering. */
  220.       if (data->is_live) break;
  221.  
  222.       gst_message_parse_buffering (msg, &percent);
  223.       g_print ("Buffering (%3d%%)\r", percent);
  224.       /* Wait until buffering is complete before start/resume playing */
  225.       if (percent < 100)
  226.         gst_element_set_state (data->pipeline, GST_STATE_PAUSED);
  227.       else
  228.         gst_element_set_state (data->pipeline, GST_STATE_PLAYING);
  229.       break;
  230.     }
  231.     case GST_MESSAGE_CLOCK_LOST:
  232.       /* Get a new clock */
  233.         g_print ("Clock lost\n");
  234.       gst_element_set_state (data->pipeline, GST_STATE_PAUSED);
  235.       gst_element_set_state (data->pipeline, GST_STATE_PLAYING);
  236.       break;
  237.     case GST_MESSAGE_STATE_CHANGED:{
  238.       /* We are only interested in state-changed messages from the pipeline */
  239.       GstState old_state, new_state, pending_state;
  240.       gst_message_parse_state_changed (msg, &old_state, &new_state, &pending_state);
  241.       g_print ("State changed from %s to %s",
  242.               gst_element_state_get_name (old_state), gst_element_state_get_name (new_state));
  243.  
  244.       if (GST_MESSAGE_SRC (msg) == GST_OBJECT (data->pipeline)) {
  245.         g_print (" [Pipeline]");
  246.       }
  247.       g_print ("\n");
  248.       break;
  249.     }
  250.     case GST_MESSAGE_STATE_DIRTY:{
  251.         g_print ("GST_MESSAGE_STATE_DIRTY\n");
  252.       break;
  253.     }
  254.     case GST_MESSAGE_STEP_DONE:{
  255.         g_print ("GST_MESSAGE_STEP_DONE\n");
  256.       break;
  257.     }
  258.     case GST_MESSAGE_CLOCK_PROVIDE:{
  259.         g_print ("GST_MESSAGE_CLOCK_PROVIDE\n");
  260.       break;
  261.     }
  262.     case GST_MESSAGE_NEW_CLOCK:{
  263.         g_print ("GST_MESSAGE_NEW_CLOCK\n");
  264.       break;
  265.     }
  266.     case GST_MESSAGE_STRUCTURE_CHANGE:{
  267.         g_print ("GST_MESSAGE_STRUCTURE_CHANGE\n");
  268.       break;
  269.     }
  270.     case GST_MESSAGE_STREAM_STATUS:{
  271.         g_print ("GST_MESSAGE_STREAM_STATUS\n");
  272.       break;
  273.     }
  274.     case GST_MESSAGE_APPLICATION:{
  275.         g_print ("GST_MESSAGE_APPLICATION\n");
  276.       break;
  277.     }
  278.     case GST_MESSAGE_ELEMENT:{
  279.         g_print ("GST_MESSAGE_ELEMENT\n");
  280.       break;
  281.     }
  282.     case GST_MESSAGE_SEGMENT_START:{
  283.         g_print ("GST_MESSAGE_SEGMENT_START\n");
  284.       break;
  285.     }
  286.     case GST_MESSAGE_SEGMENT_DONE:{
  287.         g_print ("GST_MESSAGE_SEGMENT_DONE\n");
  288.       break;
  289.     }
  290.     case GST_MESSAGE_DURATION_CHANGED:{
  291.         g_print ("GST_MESSAGE_DURATION_CHANGED\n");
  292.       break;
  293.     }
  294.     case GST_MESSAGE_ASYNC_START:{
  295.         g_print ("GST_MESSAGE_ASYNC_START\n");
  296.       break;
  297.     }
  298.     case GST_MESSAGE_ASYNC_DONE:{
  299.         g_print ("GST_MESSAGE_ASYNC_DONE\n");
  300.       break;
  301.     }
  302.     case GST_MESSAGE_LATENCY:{
  303.         g_print ("GST_MESSAGE_LATENCY\n");
  304.       break;
  305.     }
  306.     case GST_MESSAGE_REQUEST_STATE:{
  307.         g_print ("GST_MESSAGE_REQUEST_STATE\n");
  308.       break;
  309.     }
  310.     case GST_MESSAGE_STEP_START:{
  311.         g_print ("GST_MESSAGE_STEP_START\n");
  312.       break;
  313.     }
  314.     case GST_MESSAGE_QOS:{
  315.         g_print ("GST_MESSAGE_QOS\n");
  316.       break;
  317.     }
  318.     case GST_MESSAGE_PROGRESS:{
  319.         g_print ("GST_MESSAGE_PROGRESS\n");
  320.       break;
  321.     }
  322.     case GST_MESSAGE_TOC:{
  323.         g_print ("GST_MESSAGE_TOC\n");
  324.       break;
  325.     }
  326.     case GST_MESSAGE_STREAM_START:{
  327.         g_print ("GST_MESSAGE_STREAM_START\n");
  328.       break;
  329.     }
  330.     case GST_MESSAGE_NEED_CONTEXT:{
  331.         g_print ("GST_MESSAGE_NEED_CONTEXT\n");
  332.       break;
  333.     }
  334.     case GST_MESSAGE_HAVE_CONTEXT:{
  335.         g_print ("GST_MESSAGE_HAVE_CONTEXT\n");
  336.       break;
  337.     }
  338.     case GST_MESSAGE_UNKNOWN:{
  339.         g_print ("GST_MESSAGE_UNKNOWN\n");
  340.       break;
  341.     }
  342.     case GST_MESSAGE_RESET_TIME:{
  343.         g_print ("GST_MESSAGE_RESET_TIME\n");
  344.       break;
  345.     }
  346.     case GST_MESSAGE_EXTENDED:{
  347.         g_print ("GST_MESSAGE_EXTENDED\n");
  348.       break;
  349.     }
  350.     case GST_MESSAGE_DEVICE_ADDED:{
  351.         g_print ("GST_MESSAGE_DEVICE_ADDED\n");
  352.       break;
  353.     }
  354.     case GST_MESSAGE_DEVICE_REMOVED:{
  355.         g_print ("GST_MESSAGE_DEVICE_REMOVED\n");
  356.       break;
  357.     }
  358.     case GST_MESSAGE_ANY:{
  359.         g_print ("GST_MESSAGE_ANY\n");
  360.       break;
  361.     }
  362.     default:
  363.       /* We should not reach here */
  364.       g_printerr ("Unexpected message received.\n");
  365.       break;
  366.     }
  367. }
Add Comment
Please, Sign In to add comment