Created
September 12, 2012 10:45
-
-
Save angri/3705883 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <sys/time.h> | |
#include <glib.h> | |
#define GST_USE_UNSTABLE_API | |
#include <gst/gst.h> | |
#include <gst/rtsp-server/rtsp-server.h> | |
static gboolean bus_call(GstBus *bus, GstMessage *msg, gpointer data) | |
{ | |
GMainLoop *loop = (GMainLoop *) data; | |
switch (GST_MESSAGE_TYPE (msg)) { | |
case GST_MESSAGE_EOS: | |
g_print ("End of stream\n"); | |
g_main_loop_quit (loop); | |
break; | |
case GST_MESSAGE_ERROR: { | |
gchar *debug; | |
GError *error; | |
gst_message_parse_error (msg, &error, &debug); | |
g_free (debug); | |
g_printerr ("Error: %s\n", error->message); | |
g_error_free (error); | |
g_main_loop_quit (loop); | |
break; | |
} | |
default: | |
//g_print ("unknown message: %s\n", | |
// gst_message_type_get_name(GST_MESSAGE_TYPE (msg))); | |
break; | |
} | |
return TRUE; | |
} | |
GstPipeline * | |
make_pipeline (int argc, char *argv[]) | |
{ | |
/* make a parseable argvn array */ | |
gchar **argvn = g_new0 (char *, argc); | |
memcpy (argvn, argv + 1, sizeof (char *) * (argc - 1)); | |
GError *error = NULL; | |
GstElement *pipeline = gst_parse_launchv((const gchar **)argvn, &error); | |
if (!pipeline || error) { | |
g_printerr ("pipeline couldn't be created: %s\n", error->message); | |
return NULL; | |
} | |
if (!GST_IS_PIPELINE(pipeline)) { | |
g_printerr ("complete pipeline required\n"); | |
return NULL; | |
} | |
return GST_PIPELINE (pipeline); | |
} | |
GstElement * | |
get_element (GstRTSPMediaFactory *factory, const GstRTSPUrl *url) | |
{ | |
// hack, see set_rtsp_server() | |
GstPipeline *pipeline = (GstPipeline *) factory->launch; | |
GstElement *stream = gst_bin_get_by_name (GST_BIN (pipeline), "stream"); | |
GstPad *src = gst_element_get_static_pad (stream, "src"); | |
g_object_unref (stream); | |
GstBin *streambin = GST_BIN (gst_pipeline_new ("streambin")); | |
GstElement *queue = gst_element_factory_make ("queue", "pay0"); | |
if (FALSE == gst_bin_add (streambin, queue)) { | |
printf ("couldn't add queue to streambin\n"); | |
return NULL; | |
} | |
GstPad *ghost_pad; | |
GstPad *queue_sinkpad = gst_element_get_static_pad (queue, "sink"); | |
if (NULL == (ghost_pad = gst_ghost_pad_new (NULL, queue_sinkpad))) { | |
printf ("couldn't create ghost pad\n"); | |
return NULL; | |
} | |
g_object_unref (queue_sinkpad); | |
if (GST_PAD_LINK_OK != gst_pad_link (src, ghost_pad)) { | |
g_printerr ("couldn't link src and ghost pad\n"); | |
return NULL; | |
} | |
return GST_ELEMENT (streambin); | |
} | |
int | |
set_rtsp_server (GstPipeline *pipeline, GMainLoop *loop) | |
{ | |
GstRTSPServer *server = gst_rtsp_server_new (); | |
GstRTSPMediaMapping *mapping = gst_rtsp_server_get_media_mapping (server); | |
GstRTSPMediaFactory *factory = gst_rtsp_media_factory_new (); | |
// hack: save a pointer to pipeline object in factory->launch property | |
factory->launch = (char *) pipeline; | |
GST_RTSP_MEDIA_FACTORY_GET_CLASS (factory)->get_element = get_element; | |
gst_rtsp_media_factory_set_shared (factory, TRUE); | |
gst_rtsp_media_mapping_add_factory (mapping, "/test", factory); | |
g_object_unref (mapping); | |
if (0 == gst_rtsp_server_attach (server, NULL)) { | |
g_printerr ("couldn't attach rtsp server to the context\n"); | |
return -4; | |
} | |
return 0; | |
} | |
int | |
main(int argc, char *argv[]) | |
{ | |
if (argc < 2) { | |
g_printerr ("Usage: %s <source> ! <filter> ! <filter> ... \n", argv[0]); | |
return -1; | |
} | |
gst_init(&argc, &argv); | |
GstPipeline *pipeline = make_pipeline (argc, argv); | |
if (NULL == pipeline) | |
return -1; | |
GMainLoop *loop = g_main_loop_new (NULL, FALSE); | |
GstBus *bus = gst_pipeline_get_bus (pipeline); | |
gst_bus_add_watch (bus, bus_call, loop); | |
gst_object_unref (bus); | |
if (0 != set_rtsp_server (pipeline, loop)) | |
return -6; | |
g_print ("Now playing\n"); | |
gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING); | |
g_main_loop_run (loop); | |
g_print ("Returned, stopping playback\n"); | |
gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL); | |
g_print ("Deleting pipeline\n"); | |
gst_object_unref (GST_OBJECT (pipeline)); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment