GstRtspSink - C Examples

From RidgeRun Developer Wiki

Follow Us On Twitter LinkedIn Email Share this page



Previous: Multicast_Audio_Video Index Next: Performance



The C examples show how to integrate GstRtspSink into a real application instead of a shell-only prototype. This is the right place to learn how request pads, element creation, and application-owned pipeline control work together.

Why the C examples matter

Shell pipelines are useful for fast validation, but products usually need:

  • Explicit element creation
  • Dynamic error handling
  • Bus message handling
  • Application lifecycle control
  • Integration with UI, networking, or product logic

Where the examples live

The documented examples are typically located in:

gst-rtsp-sink/src/examples/

The examples are built along with the the plug-in. All the examples will stream using the following configuration:

Service
12345
Mapping
/ridgerun

Server-side GStreamer Manual Link Example

This example shows an example application on how to manually create and link each element independently. For this gst_element_factory_make and gst_element_link_many are used.

/* 
 * Copyright (C) 2016-2017 RidgeRun, LLC (http://www.ridgerun.com)
 * All Rights Reserved.
 *
 * The contents of this software are proprietary and confidential to RidgeRun,
 * LLC.  No part of this program may be photocopied, reproduced, or translated
 * into another programming language without the prior written consent of 
 * RidgeRun, LLC.  The user is free to modify the source code after obtaining
 * a software license from RidgeRun.  All source code changes must be provided
 * back to RidgeRun without any encumbrance.
 */
#include <gst/gst.h>
#include <glib-unix.h>

#define MAPPING "/ridgerun"
#define SERVICE "12345"

gboolean
signal_handler (gpointer user_data)
{
  GMainLoop * loop = (GMainLoop *)user_data;

  g_print ("Interrupt received, closing...\n");
  g_main_loop_quit (loop);

  return TRUE;
}

int main (gint argc, gchar *argv[])
{
  GstElement * pipeline;
  GstElement * vts;
  GstElement * encoder;
  GstElement * capsfilter;
  GstElement * rtsp;
  GstCaps * caps;
  GMainLoop * loop;
  gint ret = -1;
  
  gst_init (&argc, &argv);

  pipeline = gst_pipeline_new ("GstRtspSink");

  /* Creating the different elements in the pipeline */
  vts = gst_element_factory_make ("videotestsrc", "videotestsrc");
  if (!vts) {
    g_printerr ("Unable to create videotestsrc\n");
    goto no_vts;
  }
  g_object_set (vts, "is-live", TRUE, NULL);
  
  encoder = gst_element_factory_make ("x264enc", "x264enc");
  if (!encoder) {
    g_printerr ("Unable to create x264enc\n");
    goto no_enc;
  }
  g_object_set (encoder, "speed-preset", 1, "key-int-max", 10, NULL);

  capsfilter = gst_element_factory_make ("capsfilter", "capsfilter");
  if (!capsfilter) {
    g_printerr ("Unable to create capsfilter\n");
    goto no_caps;
  }
  caps = gst_caps_from_string ("video/x-h264,mapping=" MAPPING);
  g_object_set (capsfilter, "caps", caps, NULL);
  gst_caps_unref (caps);

  rtsp = gst_element_factory_make ("rtspsink", "rtspsink");
  if (!rtsp) {
    g_printerr ("Unable to create rtspsink\n");
    goto no_rtsp;
  }
  g_object_set (rtsp, "service", SERVICE, NULL);

  /* Linking all the elements together */
  gst_bin_add_many (GST_BIN (pipeline), vts, encoder, capsfilter, rtsp, NULL);
  gst_element_link_many (vts, encoder, capsfilter, rtsp, NULL);

  /* Playing the pipeline */
  gst_element_set_state (pipeline, GST_STATE_PLAYING);
  g_print ("New RTSP stream started at rtsp://127.0.0.1:" SERVICE MAPPING "\n");
  
  /* Block until CTRL+C is pressed */
  loop = g_main_loop_new (NULL, TRUE);
  g_unix_signal_add (SIGINT, signal_handler, loop);
  g_main_loop_run (loop);
  g_main_loop_unref (loop);
  
  /* NULL the pipeline */
  gst_element_set_state (pipeline, GST_STATE_NULL);

  /* Successful run */
  g_print ("Successfully closed\n");
  ret = 0;
  goto no_vts;
  
 no_rtsp:
  gst_object_unref (capsfilter);
  
 no_caps:
  gst_object_unref (encoder);
  
 no_enc:
  gst_object_unref (vts);
  
 no_vts:
  gst_object_unref (pipeline);
  gst_deinit ();
  
  return ret;
}

Server-side GStreamer Parse Launch Example

This example shows an example application on how to automatically build the pipeline. For this gst_parse_launch_full' is used.

/* 
 * Copyright (C) 2016-2017 RidgeRun, LLC (http://www.ridgerun.com)
 * All Rights Reserved.
 *
 * The contents of this software are proprietary and confidential to RidgeRun,
 * LLC.  No part of this program may be photocopied, reproduced or translated
 * into another programming language without prior written consent of 
 * RidgeRun, LLC.  The user is free to modify the source code after obtaining
 * a software license from RidgeRun.  All source code changes must be provided
 * back to RidgeRun without any encumbrance.
 */
#include <gst/gst.h>
#include <gst/rtsp-server/rtsp-server.h>
#include <glib-unix.h>

#define MAPPING "/ridgerun"
#define SERVICE "12345"

static gboolean
signal_handler (gpointer user_data)
{
  GMainLoop * loop = (GMainLoop *)user_data;

  g_print ("Interrupt received, closing...\n");
  g_main_loop_quit (loop);

  return TRUE;
}

static void
client_removed_cb(GstElement *rtspsink, GstRTSPUrl * url, gpointer data)
{
  g_print("Removed Client: %s:%d\n", url->host, url->port);
}

static void
client_added_cb(GstElement *rtspsink, GstRTSPUrl * url, gpointer data)
{
  g_print("Added Client: %s:%d\n", url->host, url->port);
}

int main (gint argc, gchar *argv[])
{
  GstElement * pipeline;
  GstElement * rtspsink;
  GMainLoop * loop;
  gint ret = -1;
  const gchar * desc;
  GError *error = NULL;
  
  gst_init (&argc, &argv);

  desc = "videotestsrc is-live=true ! x264enc speed-preset=ultrafast key-int-max=10 ! "
    "video/x-h264,mapping=" MAPPING " ! rtspsink name=sink service=" SERVICE;
  pipeline = gst_parse_launch_full (desc, NULL, GST_PARSE_FLAG_FATAL_ERRORS, &error);
  if (!pipeline || error) {
    g_printerr ("Unable to build pipeline: %s", error->message ? error->message : "(no debug)");
    goto out;
  }

  rtspsink = gst_bin_get_by_name(GST_BIN(pipeline), "sink");

  g_signal_connect(rtspsink, "client-added", G_CALLBACK(client_added_cb), NULL);
  g_signal_connect(rtspsink, "client-removed", G_CALLBACK(client_removed_cb), NULL);

  /* Playing the pipeline */
  gst_element_set_state (pipeline, GST_STATE_PLAYING);
  g_print ("New RTSP stream started at rtsp://127.0.0.1:" SERVICE MAPPING "\n");
  
  /* Block until CTRL+C is pressed */
  loop = g_main_loop_new (NULL, TRUE);
  g_unix_signal_add (SIGINT, signal_handler, loop);
  g_main_loop_run (loop);
  g_main_loop_unref (loop);
  
  /* NULL the pipeline */
  gst_element_set_state (pipeline, GST_STATE_NULL);
  gst_object_unref (pipeline);
  
  /* Successful run */
  g_print ("Successfully closed\n");
  ret = 0;

 out:
  gst_deinit ();
  
  return ret;
}

RTSP Client-side

VLC

IP_ADDRESS=127.0.0.1
PORT=12345
MAPPING=ridgerun

vlc rtsp://${IP_ADDRESS}:${PORT}/${MAPPING}

GStreamer

IP_ADDRESS=127.0.0.1
PORT=12345
MAPPING=ridgerun

gst-launch-1.0 playbin uri=rtsp://${IP_ADDRESS}:${PORT}/${MAPPING}

MPlayer

IP_ADDRESS=127.0.0.1
PORT=12345
MAPPING=ridgerun

mplayer rtsp://${IP_ADDRESS}:${PORT}/${MAPPING}

Totem

IP_ADDRESS=127.0.0.1
PORT=12345
MAPPING=ridgerun

totem rtsp://${IP_ADDRESS}:${PORT}/${MAPPING}

Summary

The C examples show how to use rtspsink to publish RTSP URLs from application code.

Problems running the examples on this page? See GStreamer Debugging for practical debugging steps.

Related pages

FAQ

Why are C examples important if gst-launch examples already exist?
Because product code needs lifecycle control, error handling, and explicit pad management.



Previous: Multicast_Audio_Video Index Next: Performance