Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@mndar
Created October 13, 2017 15:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mndar/267478e5b102bd1730a2ceb2631332b9 to your computer and use it in GitHub Desktop.
Save mndar/267478e5b102bd1730a2ceb2631332b9 to your computer and use it in GitHub Desktop.
add_gst_rtp_header.c
/* GStreamer
* Copyright (C) 2008 Wim Taymans <wim.taymans at gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <gst/gst.h>
#include <gst/rtsp-server/rtsp-server.h>
#include <gst/rtp/gstrtpbuffer.h>
#define DEFAULT_RTSP_PORT "8554"
static char *port = (char *) DEFAULT_RTSP_PORT;
static GOptionEntry entries[] = {
{"port", 'p', 0, G_OPTION_ARG_STRING, &port,
"Port to listen on (default: " DEFAULT_RTSP_PORT ")", "PORT"},
{NULL}
};
GstPadProbeReturn
add_rtp_header_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data) {
g_message ("In add_rtp_header_cb");
gst_pad_remove_probe (pad, GST_PAD_PROBE_INFO_ID (info));
GstBuffer *buffer = gst_pad_probe_info_get_buffer (info);
guint8 misc_data[4] = { 1, 2, 3, 4 };
GstRTPBuffer rtp = { NULL, };
guint16 bits;
guint size;
gpointer pointer;
gst_rtp_buffer_map (buffer, GST_MAP_READWRITE, &rtp);
gst_rtp_buffer_add_extension_onebyte_header (&rtp, 5, misc_data, 4);
gst_rtp_buffer_get_extension_onebyte_header (&rtp, 5, 0, &pointer, &size);
guint8 *data = (guint8 *) pointer;
g_message ("Size: %d Data: %d %d %d %d\n", size, data[0], data[1], data[2], data[3]);
gst_rtp_buffer_unmap (&rtp);
return GST_PAD_PROBE_OK;
}
gboolean add_rtp_header (gpointer data) {
GstPad *pay_src_pad = (GstPad *) data;
gst_pad_add_probe (pay_src_pad, GST_PAD_PROBE_TYPE_DATA_DOWNSTREAM, add_rtp_header_cb, NULL, NULL);
return TRUE;
}
void rtsp_client_connected (GstRTSPServer *gstrtspserver, GstRTSPClient *rtsp_client, gpointer user_data) {
g_message ("Client Connected");
g_timeout_add_seconds (1, add_rtp_header, user_data);
}
int
main (int argc, char *argv[])
{
GMainLoop *loop;
GstRTSPServer *server;
GstRTSPMountPoints *mounts;
GstRTSPMediaFactory *factory;
GOptionContext *optctx;
GError *error = NULL;
optctx = g_option_context_new ("<launch line> - Test RTSP Server, Launch\n\n"
"Example: \"( videotestsrc ! x264enc ! rtph264pay name=pay0 pt=96 )\"");
g_option_context_add_main_entries (optctx, entries, NULL);
g_option_context_add_group (optctx, gst_init_get_option_group ());
if (!g_option_context_parse (optctx, &argc, &argv, &error)) {
g_printerr ("Error parsing options: %s\n", error->message);
g_option_context_free (optctx);
g_clear_error (&error);
return -1;
}
g_option_context_free (optctx);
loop = g_main_loop_new (NULL, FALSE);
/* create a server instance */
server = gst_rtsp_server_new ();
g_object_set (server, "service", port, NULL);
/* get the mount points for this server, every server has a default object
* that be used to map uri mount points to media factories */
mounts = gst_rtsp_server_get_mount_points (server);
/* make a media factory for a test stream. The default media factory can use
* gst-launch syntax to create pipelines.
* any launch line works as long as it contains elements named pay%d. Each
* element with pay%d names will be a stream */
factory = gst_rtsp_media_factory_new ();
gst_rtsp_media_factory_set_launch (factory, argv[1]);
gst_rtsp_media_factory_set_shared (factory, TRUE);
/* attach the test factory to the /test url */
gst_rtsp_mount_points_add_factory (mounts, "/test", factory);
/* don't need the ref to the mapper anymore */
g_object_unref (mounts);
/* attach the server to the default maincontext */
gst_rtsp_server_attach (server, NULL);
GstRTSPUrl *url;
g_message ("URL Parse: %d", gst_rtsp_url_parse ("rtsp://127.0.0.1:8554/test", &url));
GstElement *bin = gst_rtsp_media_factory_create_element (factory, url);
g_message ("IS_BIN: %d", GST_IS_BIN (bin));
GstElement *pay = gst_bin_get_by_name (GST_BIN (bin), "pay0");
g_message ("IS_ELEMENT: %d", GST_IS_ELEMENT (pay));
GstPad *pay_src_pad = gst_element_get_static_pad (pay, "src");
g_signal_connect (server, "client-connected", G_CALLBACK (rtsp_client_connected), pay_src_pad);
/* start serving */
g_print ("stream ready at rtsp://127.0.0.1:%s/test\n", port);
g_main_loop_run (loop);
return 0;
}
@mndar
Copy link
Author

mndar commented Oct 13, 2017

/* GStreamer

  • Copyright (C) 2008 Wim Taymans <wim.taymans at gmail.com>
  • This library is free software; you can redistribute it and/or
  • modify it under the terms of the GNU Library General Public
  • License as published by the Free Software Foundation; either
  • version 2 of the License, or (at your option) any later version.
  • This library is distributed in the hope that it will be useful,
  • but WITHOUT ANY WARRANTY; without even the implied warranty of
  • MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  • Library General Public License for more details.
  • You should have received a copy of the GNU Library General Public
  • License along with this library; if not, write to the
  • Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
  • Boston, MA 02110-1301, USA.
    */

#include <gst/gst.h>

#include <gst/rtsp-server/rtsp-server.h>
#include <gst/rtp/gstrtpbuffer.h>
#define DEFAULT_RTSP_PORT "8554"

static char *port = (char *) DEFAULT_RTSP_PORT;

static GOptionEntry entries[] = {
{"port", 'p', 0, G_OPTION_ARG_STRING, &port,
"Port to listen on (default: " DEFAULT_RTSP_PORT ")", "PORT"},
{NULL}
};

GstPadProbeReturn
add_rtp_header_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data) {
g_message ("In add_rtp_header_cb");
gst_pad_remove_probe (pad, GST_PAD_PROBE_INFO_ID (info));
GstBuffer *buffer = gst_pad_probe_info_get_buffer (info);
guint8 misc_data[4] = { 1, 2, 3, 4 };
GstRTPBuffer rtp = { NULL, };
guint16 bits;
guint size;
gpointer pointer;
gst_rtp_buffer_map (buffer, GST_MAP_READWRITE, &rtp);
gst_rtp_buffer_add_extension_onebyte_header (&rtp, 5, misc_data, 4);
gst_rtp_buffer_get_extension_onebyte_header (&rtp, 5, 0, &pointer, &size);
guint8 *data = (guint8 *) pointer;
g_message ("Size: %d Data: %d %d %d %d\n", size, data[0], data[1], data[2], data[3]);
gst_rtp_buffer_unmap (&rtp);
return GST_PAD_PROBE_OK;

}

gboolean add_rtp_header (gpointer data) {
GstPad *pay_src_pad = (GstPad *) data;
gulong ret;
ret = gst_pad_add_probe (pay_src_pad, GST_PAD_PROBE_TYPE_DATA_DOWNSTREAM, add_rtp_header_cb, data, NULL);
g_message ("Pad Probe ret: %d", ret);
return TRUE;
}

void rtsp_client_connected (GstRTSPServer *gstrtspserver, GstRTSPClient *rtsp_client, gpointer user_data) {
g_message ("Client Connected");
g_timeout_add_seconds (1, add_rtp_header, user_data);
}

void
factory_get_element_cb (GstRTSPMediaFactory *gstrtspmediafactory,
GstRTSPMedia *arg1,
gpointer user_data) {
GstElement *bin = gst_rtsp_media_get_element (arg1);
GstElement *payloader = gst_bin_get_by_name (GST_BIN (bin), "pay0");

GstPad *pay_src_pad = (GstPad *) gst_element_get_static_pad (payloader, "src");
gulong ret;
ret = gst_pad_add_probe (pay_src_pad, GST_PAD_PROBE_TYPE_BUFFER, add_rtp_header_cb, NULL, NULL);	
//g_timeout_add_seconds (1, add_rtp_header, pay_src_pad);
g_message ("Pad Probe ret: %d", ret);

}

int
main (int argc, char *argv[])
{
GMainLoop *loop;
GstRTSPServer *server;
GstRTSPMountPoints *mounts;
GstRTSPMediaFactory *factory;
GOptionContext *optctx;
GError *error = NULL;

optctx = g_option_context_new (" - Test RTSP Server, Launch\n\n"
"Example: "( videotestsrc ! x264enc ! rtph264pay name=pay0 pt=96 )"");
g_option_context_add_main_entries (optctx, entries, NULL);
g_option_context_add_group (optctx, gst_init_get_option_group ());
if (!g_option_context_parse (optctx, &argc, &argv, &error)) {
g_printerr ("Error parsing options: %s\n", error->message);
g_option_context_free (optctx);
g_clear_error (&error);
return -1;
}
g_option_context_free (optctx);

loop = g_main_loop_new (NULL, FALSE);

/* create a server instance */
server = gst_rtsp_server_new ();
g_object_set (server, "service", port, NULL);

/* get the mount points for this server, every server has a default object

  • that be used to map uri mount points to media factories */
    mounts = gst_rtsp_server_get_mount_points (server);

/* make a media factory for a test stream. The default media factory can use

  • gst-launch syntax to create pipelines.
  • any launch line works as long as it contains elements named pay%d. Each
  • element with pay%d names will be a stream */
    factory = gst_rtsp_media_factory_new ();
    gst_rtsp_media_factory_set_launch (factory, argv[1]);
    gst_rtsp_media_factory_set_shared (factory, FALSE);

/* attach the test factory to the /test url */
gst_rtsp_mount_points_add_factory (mounts, "/test", factory);

/* don't need the ref to the mapper anymore */
g_object_unref (mounts);

/* attach the server to the default maincontext */
gst_rtsp_server_attach (server, NULL);
GstRTSPUrl *url;
g_message ("URL Parse: %d", gst_rtsp_url_parse ("rtsp://127.0.0.1:8554/test", &url));
GstElement *bin = gst_rtsp_media_factory_create_element (factory, url);
g_message ("IS_BIN: %d", GST_IS_BIN (bin));
GstElement *pay = gst_bin_get_by_name (GST_BIN (bin), "pay0");
g_message ("IS_ELEMENT: %d", GST_IS_ELEMENT (pay));
GstPad pay_src_pad = gst_element_get_static_pad (pay, "src");
//g_signal_connect (server, "client-connected", G_CALLBACK (rtsp_client_connected), pay_src_pad);
g_signal_connect (factory, "media-constructed", G_CALLBACK (factory_get_element_cb), NULL);
/
start serving */
g_print ("stream ready at rtsp://127.0.0.1:%s/test\n", port);
g_main_loop_run (loop);

return 0;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment