Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // (1) gst-launch-1.0 -v -e videotestsrc ! x264enc ! rtph264pay ! udpsink host=127.0.0.1 port=5004
- // (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
- #include <gst/gst.h>
- #include <string.h>
- /* Structure to contain all our information, so we can pass it to callbacks */
- typedef struct _CustomData {
- gboolean is_live;
- GstElement *pipeline;
- GMainLoop *loop;
- GstElement *udpsrc;
- GstElement *depayload;
- GstElement *queue;
- GstElement *mpegtsmux;
- GstElement *splitmuxsink;
- } CustomData;
- static void cb_message (GstBus *bus, GstMessage *msg, CustomData *data);
- int main(int argc, char *argv[]) {
- GstBus *bus;
- CustomData data;
- GstStateChangeReturn ret;
- g_print ("Call init, to start...\n");
- /* Initialize GStreamer */
- gst_init (&argc, &argv);
- /* Initialize our data structure */
- memset (&data, 0, sizeof (data));
- /* Create the elements */
- data.udpsrc = gst_element_factory_make ("udpsrc", "udpsrc-element"); /*** good ***/
- data.depayload = gst_element_factory_make ("rtph264depay", "depayload-element"); /*** good ***/
- data.mpegtsmux = gst_element_factory_make ("mpegtsmux", "mpegtsmux-element"); /*** BAD ***/
- data.queue = gst_element_factory_make ("queue", "queue-element"); /*** ***/
- data.splitmuxsink = gst_element_factory_make ("splitmuxsink", "splitmuxsink-element"); /*** good (+BAD mpegtsmux) ***/
- /* Create the empty pipeline */
- data.pipeline = gst_pipeline_new ("test-pipeline");
- if (!data.pipeline || !data.udpsrc || !data.depayload || !data.queue || !data.mpegtsmux || !data.splitmuxsink) {
- g_printerr ("Not all elements could be created.\n");
- return -1;
- }
- /* Build the pipeline */
- //gst_bin_add_many (GST_BIN (data.pipeline), data.udpsrc, data.depayload, data.mpegtsmux, data.filesink, NULL);
- gst_bin_add_many (GST_BIN (data.pipeline), data.udpsrc, data.depayload, data.queue, data.splitmuxsink, NULL); //data.mpegtsmux
- /* link the pads */
- if (gst_element_link (data.udpsrc, data.depayload) != TRUE ) {
- g_printerr ("udpsrc - depayload could not be linked.\n");
- gst_object_unref (data.pipeline);
- return -1;
- }
- /* link the pads */
- if (gst_element_link (data.depayload, data.queue) != TRUE ) {
- g_printerr ("depayload - queue could not be linked.\n");
- gst_object_unref (data.pipeline);
- return -1;
- }
- /*** REQUEST PAD FROM splitmuxsink to link to queue ***/
- /* MAKE sink PAD on mpegtsmux */
- GstPad * sinkpad = 0;
- gchar * sinkname = "empty";
- sinkpad = gst_element_get_request_pad (data.splitmuxsink, "video");
- sinkname = gst_pad_get_name (sinkpad);
- g_print ("A new pad %s was created for splitmuxsink\n", sinkname);
- /* GET source PAD on tsmux */
- GstPad * srcpad = 0;
- gchar * srcname = "empty";
- srcpad = gst_element_get_compatible_pad (data.queue, sinkpad, NULL);
- /* LINK PADS */
- GstPadLinkReturn test = gst_pad_link (srcpad, sinkpad);
- switch (test) {
- case GST_PAD_LINK_OK:
- g_print ("GST_PAD_LINK_OK\n");
- break;
- case GST_PAD_LINK_WRONG_HIERARCHY:
- g_printerr ("GST_PAD_LINK_WRONG_HIERARCHY\n");
- break;
- case GST_PAD_LINK_WAS_LINKED:
- g_printerr ("GST_PAD_LINK_WAS_LINKED\n");
- break;
- case GST_PAD_LINK_WRONG_DIRECTION:
- g_printerr ("GST_PAD_LINK_WRONG_DIRECTION\n");
- break;
- case GST_PAD_LINK_NOFORMAT:
- g_printerr ("GST_PAD_LINK_NOFORMAT\n");
- break;
- case GST_PAD_LINK_NOSCHED:
- g_printerr ("GST_PAD_LINK_NOSCHED\n");
- break;
- case GST_PAD_LINK_REFUSED:
- g_printerr ("GST_PAD_LINK_REFUSED\n");
- break;
- default:
- g_printerr("Unknown response\n");
- break;
- }
- srcname = gst_pad_get_name (srcpad);
- g_print ("A new pad %s was created and linked to %s\n", sinkname, srcname);
- g_print ("Modify properties...\n");
- g_object_set (data.udpsrc, "port", 5004, NULL);
- g_object_set (data.udpsrc, "buffer-size", 524288, NULL); //
- GstCaps *caps = gst_caps_new_simple ("application/x-rtp",
- "media", G_TYPE_STRING, "video",
- "clock-rate", G_TYPE_INT, 90000,
- "encoding-name", G_TYPE_STRING, "H264",
- "payload", G_TYPE_INT, 96,
- NULL);
- g_object_set (data.udpsrc, "caps", caps, NULL);
- g_object_set (data.splitmuxsink, "muxer", data.mpegtsmux, NULL);
- g_object_set (data.splitmuxsink, "max-size-time", 10000000000, NULL);
- g_object_set (data.splitmuxsink, "location", "file%03d.ts", NULL);
- g_print ("Call 'play'\n");
- /* Start playing */
- ret = gst_element_set_state (data.pipeline, GST_STATE_PLAYING);
- if (ret == GST_STATE_CHANGE_FAILURE) {
- g_printerr ("Unable to set the pipeline to the playing state.\n");
- gst_object_unref (data.pipeline);
- return -1;
- } else if (ret == GST_STATE_CHANGE_NO_PREROLL) {
- data.is_live = TRUE;
- }
- g_print ("Called 'play'\n");
- bus = gst_element_get_bus (data.pipeline);
- data.loop = g_main_loop_new (NULL, FALSE);
- gst_bus_add_signal_watch (bus);
- g_signal_connect (bus, "message", G_CALLBACK (cb_message), &data);
- g_print ("Calling main loop\n");
- g_main_loop_run (data.loop);
- g_print ("Done!\n");
- /* Free resources */
- //gst_object_unref (GST_OBJECT (sinkpad));
- //gst_object_unref (GST_OBJECT (srcpad));
- //g_free (sinkname);
- //g_free (srcname);
- //gst_object_unref (GST_OBJECT (sinkpad2));
- //gst_object_unref (GST_OBJECT (srcpad2));
- //g_free (sinkname2);
- //g_free (srcname2);
- //g_main_loop_unref (main_loop);
- //gst_object_unref (bus);
- gst_element_set_state (data.pipeline, GST_STATE_NULL);
- //gst_object_unref (data.pipeline);
- return 0;
- }
- static void cb_message (GstBus *bus, GstMessage *msg, CustomData *data) {
- switch (GST_MESSAGE_TYPE (msg)) {
- GError *err;
- gchar *debug;
- case GST_MESSAGE_ERROR:{
- gst_message_parse_error (msg, &err, &debug);
- g_printerr ("Error received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message);
- g_printerr ("Debugging information: %s\n", debug ? debug : "none");
- g_clear_error (&err);
- //g_error_free (err);
- //g_free (debug);
- gst_element_set_state (data->pipeline, GST_STATE_READY);
- g_main_loop_quit (data->loop);
- break;
- }
- case GST_MESSAGE_WARNING: {
- gst_message_parse_warning(msg, &err, &debug);
- g_printerr ("Warning received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message);
- g_printerr ("Debugging information: %s\n", debug ? debug : "none");
- g_clear_error (&err); g_free (debug);
- break;
- }
- case GST_MESSAGE_INFO:{
- gst_message_parse_info(msg, &err, &debug);
- g_printerr ("Info received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message);
- g_printerr ("Debugging information: %s\n", debug ? debug : "none");
- g_clear_error (&err); g_free (debug);
- break;
- }
- case GST_MESSAGE_TAG: {
- //GstTagList *tags = NULL;
- //gst_message_parse_tag (msg, &tags);
- g_print ("Got tags from element %s\n", GST_OBJECT_NAME (msg->src));
- //handle_tags (tags);
- //gst_tag_list_unref (tags);
- break;
- }
- case GST_MESSAGE_EOS:
- /* end-of-stream */
- g_print ("End-Of-Stream reached.\n");
- gst_element_set_state (data->pipeline, GST_STATE_READY);
- g_main_loop_quit (data->loop);
- break;
- case GST_MESSAGE_BUFFERING:{
- gint percent = 0;
- g_print ("b");
- /* If the stream is live, we do not care about buffering. */
- if (data->is_live) break;
- gst_message_parse_buffering (msg, &percent);
- g_print ("Buffering (%3d%%)\r", percent);
- /* Wait until buffering is complete before start/resume playing */
- if (percent < 100)
- gst_element_set_state (data->pipeline, GST_STATE_PAUSED);
- else
- gst_element_set_state (data->pipeline, GST_STATE_PLAYING);
- break;
- }
- case GST_MESSAGE_CLOCK_LOST:
- /* Get a new clock */
- g_print ("Clock lost\n");
- gst_element_set_state (data->pipeline, GST_STATE_PAUSED);
- gst_element_set_state (data->pipeline, GST_STATE_PLAYING);
- break;
- case GST_MESSAGE_STATE_CHANGED:{
- /* We are only interested in state-changed messages from the pipeline */
- GstState old_state, new_state, pending_state;
- gst_message_parse_state_changed (msg, &old_state, &new_state, &pending_state);
- g_print ("State changed from %s to %s",
- gst_element_state_get_name (old_state), gst_element_state_get_name (new_state));
- if (GST_MESSAGE_SRC (msg) == GST_OBJECT (data->pipeline)) {
- g_print (" [Pipeline]");
- }
- g_print ("\n");
- break;
- }
- case GST_MESSAGE_STATE_DIRTY:{
- g_print ("GST_MESSAGE_STATE_DIRTY\n");
- break;
- }
- case GST_MESSAGE_STEP_DONE:{
- g_print ("GST_MESSAGE_STEP_DONE\n");
- break;
- }
- case GST_MESSAGE_CLOCK_PROVIDE:{
- g_print ("GST_MESSAGE_CLOCK_PROVIDE\n");
- break;
- }
- case GST_MESSAGE_NEW_CLOCK:{
- g_print ("GST_MESSAGE_NEW_CLOCK\n");
- break;
- }
- case GST_MESSAGE_STRUCTURE_CHANGE:{
- g_print ("GST_MESSAGE_STRUCTURE_CHANGE\n");
- break;
- }
- case GST_MESSAGE_STREAM_STATUS:{
- g_print ("GST_MESSAGE_STREAM_STATUS\n");
- break;
- }
- case GST_MESSAGE_APPLICATION:{
- g_print ("GST_MESSAGE_APPLICATION\n");
- break;
- }
- case GST_MESSAGE_ELEMENT:{
- g_print ("GST_MESSAGE_ELEMENT\n");
- break;
- }
- case GST_MESSAGE_SEGMENT_START:{
- g_print ("GST_MESSAGE_SEGMENT_START\n");
- break;
- }
- case GST_MESSAGE_SEGMENT_DONE:{
- g_print ("GST_MESSAGE_SEGMENT_DONE\n");
- break;
- }
- case GST_MESSAGE_DURATION_CHANGED:{
- g_print ("GST_MESSAGE_DURATION_CHANGED\n");
- break;
- }
- case GST_MESSAGE_ASYNC_START:{
- g_print ("GST_MESSAGE_ASYNC_START\n");
- break;
- }
- case GST_MESSAGE_ASYNC_DONE:{
- g_print ("GST_MESSAGE_ASYNC_DONE\n");
- break;
- }
- case GST_MESSAGE_LATENCY:{
- g_print ("GST_MESSAGE_LATENCY\n");
- break;
- }
- case GST_MESSAGE_REQUEST_STATE:{
- g_print ("GST_MESSAGE_REQUEST_STATE\n");
- break;
- }
- case GST_MESSAGE_STEP_START:{
- g_print ("GST_MESSAGE_STEP_START\n");
- break;
- }
- case GST_MESSAGE_QOS:{
- g_print ("GST_MESSAGE_QOS\n");
- break;
- }
- case GST_MESSAGE_PROGRESS:{
- g_print ("GST_MESSAGE_PROGRESS\n");
- break;
- }
- case GST_MESSAGE_TOC:{
- g_print ("GST_MESSAGE_TOC\n");
- break;
- }
- case GST_MESSAGE_STREAM_START:{
- g_print ("GST_MESSAGE_STREAM_START\n");
- break;
- }
- case GST_MESSAGE_NEED_CONTEXT:{
- g_print ("GST_MESSAGE_NEED_CONTEXT\n");
- break;
- }
- case GST_MESSAGE_HAVE_CONTEXT:{
- g_print ("GST_MESSAGE_HAVE_CONTEXT\n");
- break;
- }
- case GST_MESSAGE_UNKNOWN:{
- g_print ("GST_MESSAGE_UNKNOWN\n");
- break;
- }
- case GST_MESSAGE_RESET_TIME:{
- g_print ("GST_MESSAGE_RESET_TIME\n");
- break;
- }
- case GST_MESSAGE_EXTENDED:{
- g_print ("GST_MESSAGE_EXTENDED\n");
- break;
- }
- case GST_MESSAGE_DEVICE_ADDED:{
- g_print ("GST_MESSAGE_DEVICE_ADDED\n");
- break;
- }
- case GST_MESSAGE_DEVICE_REMOVED:{
- g_print ("GST_MESSAGE_DEVICE_REMOVED\n");
- break;
- }
- case GST_MESSAGE_ANY:{
- g_print ("GST_MESSAGE_ANY\n");
- break;
- }
- default:
- /* We should not reach here */
- g_printerr ("Unexpected message received.\n");
- break;
- }
- }
Add Comment
Please, Sign In to add comment