From da28d1620e74e3bb0ca467d7ef5e81dc56fe60a6 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 20 Feb 2009 15:53:34 +0100 Subject: [PATCH] Add pnm:// uri source Add a new utri handler for pnm:// that for now just redirects to the same uri with the rtsp:// protocol, which usually works nowadays. Separate the registration of the various plugins into a separate source file. --- gst/realmedia/Makefile.am | 7 +- gst/realmedia/pnmsrc.c | 294 ++++++++++++++++++++++++++++++++++++++ gst/realmedia/pnmsrc.h | 58 ++++++++ gst/realmedia/rademux.c | 7 + gst/realmedia/rademux.h | 2 + gst/realmedia/realmedia.c | 59 ++++++++ gst/realmedia/rmdemux.c | 35 +---- gst/realmedia/rmdemux.h | 2 + 8 files changed, 429 insertions(+), 35 deletions(-) create mode 100644 gst/realmedia/pnmsrc.c create mode 100644 gst/realmedia/pnmsrc.h create mode 100644 gst/realmedia/realmedia.c diff --git a/gst/realmedia/Makefile.am b/gst/realmedia/Makefile.am index fd2be10702..5ee101d47a 100644 --- a/gst/realmedia/Makefile.am +++ b/gst/realmedia/Makefile.am @@ -3,7 +3,9 @@ plugin_LTLIBRARIES = libgstrmdemux.la libgstrmdemux_la_SOURCES = rademux.c rmdemux.c \ rmutils.c rdtdepay.c rdtmanager.c \ rtspreal.c realhash.c asmrules.c \ - rdtjitterbuffer.c gstrdtbuffer.c + rdtjitterbuffer.c gstrdtbuffer.c \ + pnmsrc.c realmedia.c + libgstrmdemux_la_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) libgstrmdemux_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) $(GST_BASE_LIBS) $(GST_LIBS)\ @@ -12,7 +14,8 @@ libgstrmdemux_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstrmdemux_la_LIBTOOLFLAGS = --tag=disable-static noinst_HEADERS = rademux.h rmdemux.h rmutils.h rdtdepay.h rdtmanager.h \ - rdtjitterbuffer.h rtspreal.h realhash.h asmrules.h gstrdtbuffer.h + rdtjitterbuffer.h rtspreal.h realhash.h asmrules.h gstrdtbuffer.h \ + pnmsrc.h noinst_PROGRAMS = asmrules asmrules_CFLAGS = $(GST_CFLAGS) -DTEST diff --git a/gst/realmedia/pnmsrc.c b/gst/realmedia/pnmsrc.c new file mode 100644 index 0000000000..29552f0e13 --- /dev/null +++ b/gst/realmedia/pnmsrc.c @@ -0,0 +1,294 @@ +/* GStreamer + * Copyright (C) <2009> Wim Taymans + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "pnmsrc.h" + +GST_DEBUG_CATEGORY_STATIC (pnmsrc_debug); +#define GST_CAT_DEFAULT pnmsrc_debug + +/* elementfactory information */ +static const GstElementDetails gst_pnm_src_details = +GST_ELEMENT_DETAILS ("PNM packet receiver", + "Source/Network", + "Receive data over the network via PNM", + "Wim Taymans "); + +/* PNMSrc signals and args */ +enum +{ + /* FILL ME */ + LAST_SIGNAL +}; + +#define DEFAULT_LOCATION NULL + +enum +{ + PROP_0, + PROP_LOCATION, + PROP_LAST +}; + +static GstStaticPadTemplate gst_pnm_src_template = +GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("application/vnd.rn-realmedia") + ); + +static GstFlowReturn gst_pnm_src_create (GstPushSrc * psrc, GstBuffer ** buf); + +static void gst_pnm_src_uri_handler_init (gpointer g_iface, gpointer iface_data); + +static void +_do_init (GType pnmsrc_type) +{ + static const GInterfaceInfo urihandler_info = { + gst_pnm_src_uri_handler_init, + NULL, + NULL + }; + + g_type_add_interface_static (pnmsrc_type, GST_TYPE_URI_HANDLER, + &urihandler_info); +} + +GST_BOILERPLATE_FULL (GstPNMSrc, gst_pnm_src, GstPushSrc, GST_TYPE_PUSH_SRC, _do_init); + +static void gst_pnm_src_finalize (GObject * object); + +static void gst_pnm_src_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec); +static void gst_pnm_src_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); + +static GstStateChangeReturn gst_pnm_src_change_state (GstElement * + element, GstStateChange transition); + +static void +gst_pnm_src_base_init (gpointer klass) +{ + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&gst_pnm_src_template)); + + gst_element_class_set_details (element_class, &gst_pnm_src_details); + + GST_DEBUG_CATEGORY_INIT (pnmsrc_debug, "pnmsrc", + 0, "Source for the pnm:// uri"); +} + +static void +gst_pnm_src_class_init (GstPNMSrcClass * klass) +{ + GObjectClass *gobject_class; + GstElementClass *gstelement_class; + GstPushSrcClass *gstpushsrc_class; + + gobject_class = (GObjectClass *) klass; + gstelement_class = (GstElementClass *) klass; + gstpushsrc_class = (GstPushSrcClass *) klass; + + parent_class = g_type_class_peek_parent (klass); + + gobject_class->set_property = gst_pnm_src_set_property; + gobject_class->get_property = gst_pnm_src_get_property; + + gobject_class->finalize = gst_pnm_src_finalize; + + g_object_class_install_property (gobject_class, PROP_LOCATION, + g_param_spec_string ("location", "PNM Location", + "Location of the PNM url to read", + DEFAULT_LOCATION, G_PARAM_READWRITE)); + + gstelement_class->change_state = gst_pnm_src_change_state; + + gstpushsrc_class->create = gst_pnm_src_create; +} + +static void +gst_pnm_src_init (GstPNMSrc * pnmsrc, GstPNMSrcClass * klass) +{ + pnmsrc->location = g_strdup (DEFAULT_LOCATION); +} + +gboolean +gst_pnm_src_plugin_init (GstPlugin * plugin) +{ + return gst_element_register (plugin, "pnmsrc", + GST_RANK_MARGINAL, GST_TYPE_PNM_SRC); +} + +static void +gst_pnm_src_finalize (GObject * object) +{ + GstPNMSrc *pnmsrc; + + pnmsrc = GST_PNM_SRC (object); + + g_free (pnmsrc->location); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +gst_pnm_src_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstPNMSrc *src; + + src = GST_PNM_SRC (object); + + switch (prop_id) { + case PROP_LOCATION: + g_free (src->location); + src->location = g_value_dup_string (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_pnm_src_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstPNMSrc *src; + + src = GST_PNM_SRC (object); + + switch (prop_id) { + case PROP_LOCATION: + g_value_set_string (value, src->location); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GstStateChangeReturn +gst_pnm_src_change_state (GstElement * element, GstStateChange transition) +{ + GstPNMSrc *src; + GstStateChangeReturn ret; + + src = GST_PNM_SRC (element); + + switch (transition) { + case GST_STATE_CHANGE_NULL_TO_READY: + break; + case GST_STATE_CHANGE_READY_TO_PAUSED: + break; + default: + break; + } + + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); + + switch (transition) { + case GST_STATE_CHANGE_PAUSED_TO_READY: + break; + case GST_STATE_CHANGE_READY_TO_NULL: + break; + default: + break; + } + return ret; +} + +static GstFlowReturn +gst_pnm_src_create (GstPushSrc * psrc, GstBuffer ** buf) +{ + GstPNMSrc *src; + GstMessage *m; + gchar *url; + + src = GST_PNM_SRC (psrc); + + url = g_strdup_printf ("rtsp%s", &src->location[3]); + + /* the only thing we do is redirect to an RTSP url */ + m = gst_message_new_element (GST_OBJECT_CAST (src), + gst_structure_new ("redirect", + "new-location", G_TYPE_STRING, url, NULL)); + g_free (url); + + gst_element_post_message (GST_ELEMENT_CAST (src), m); + + return GST_FLOW_UNEXPECTED; +} + +/*** GSTURIHANDLER INTERFACE *************************************************/ + +static GstURIType +gst_pnm_src_uri_get_type (void) +{ + return GST_URI_SRC; +} + +static gchar ** +gst_pnm_src_uri_get_protocols (void) +{ + static gchar *protocols[] = { "pnm", NULL }; + + return protocols; +} + +static const gchar * +gst_pnm_src_uri_get_uri (GstURIHandler * handler) +{ + GstPNMSrc *src = GST_PNM_SRC (handler); + + return src->location; +} + +static gboolean +gst_pnm_src_uri_set_uri (GstURIHandler * handler, const gchar * uri) +{ + GstPNMSrc *src = GST_PNM_SRC (handler); + + if (!g_str_has_prefix (uri, "pnm://")) + return FALSE; + + g_free (src->location); + src->location = g_strdup (uri); + + return TRUE; +} + +static void +gst_pnm_src_uri_handler_init (gpointer g_iface, gpointer iface_data) +{ + GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface; + + iface->get_type = gst_pnm_src_uri_get_type; + iface->get_protocols = gst_pnm_src_uri_get_protocols; + iface->get_uri = gst_pnm_src_uri_get_uri; + iface->set_uri = gst_pnm_src_uri_set_uri; +} + diff --git a/gst/realmedia/pnmsrc.h b/gst/realmedia/pnmsrc.h new file mode 100644 index 0000000000..6d6277062e --- /dev/null +++ b/gst/realmedia/pnmsrc.h @@ -0,0 +1,58 @@ +/* GStreamer + * Copyright (C) <2009> Wim Taymans + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_PNM_SRC_H__ +#define __GST_PNM_SRC_H__ + +#include +#include + +G_BEGIN_DECLS + +#define GST_TYPE_PNM_SRC \ + (gst_pnm_src_get_type()) +#define GST_PNM_SRC(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_PNM_SRC,GstPNMSrc)) +#define GST_PNM_SRC_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_PNM_SRC,GstPNMSrcClass)) +#define GST_IS_PNM_SRC(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_PNM_SRC)) +#define GST_IS_PNM_SRC_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_PNM_SRC)) + +typedef struct _GstPNMSrc GstPNMSrc; +typedef struct _GstPNMSrcClass GstPNMSrcClass; + +struct _GstPNMSrc +{ + GstPushSrc parent; + + gchar *location; +}; + +struct _GstPNMSrcClass +{ + GstPushSrcClass parent_class; +}; + +gboolean gst_pnm_src_plugin_init (GstPlugin * plugin); + +G_END_DECLS + +#endif /* __GST_PNM_SRC_H__ */ diff --git a/gst/realmedia/rademux.c b/gst/realmedia/rademux.c index 5c368cf038..99251c002e 100644 --- a/gst/realmedia/rademux.c +++ b/gst/realmedia/rademux.c @@ -964,3 +964,10 @@ gst_real_audio_demux_change_state (GstElement * element, return ret; } + +gboolean +gst_rademux_plugin_init (GstPlugin * plugin) +{ + return gst_element_register (plugin, "rademux", + GST_RANK_SECONDARY, GST_TYPE_REAL_AUDIO_DEMUX); +} diff --git a/gst/realmedia/rademux.h b/gst/realmedia/rademux.h index 342e0c92bf..6dab9c0985 100644 --- a/gst/realmedia/rademux.h +++ b/gst/realmedia/rademux.h @@ -94,6 +94,8 @@ struct _GstRealAudioDemuxClass { GType gst_real_audio_demux_get_type (void); +gboolean gst_rademux_plugin_init (GstPlugin * plugin); + G_END_DECLS #endif /* __GST_REAL_AUDIO_DEMUX_H__ */ diff --git a/gst/realmedia/realmedia.c b/gst/realmedia/realmedia.c new file mode 100644 index 0000000000..29a92505b9 --- /dev/null +++ b/gst/realmedia/realmedia.c @@ -0,0 +1,59 @@ +/* GStreamer + * Copyright (C) <2009> Wim Taymans + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "rmdemux.h" +#include "rademux.h" +#include "rdtdepay.h" +#include "rdtmanager.h" +#include "rtspreal.h" +#include "pnmsrc.h" + +static gboolean +plugin_init (GstPlugin * plugin) +{ + if (!gst_rmdemux_plugin_init (plugin)) + return FALSE; + + if (!gst_rademux_plugin_init (plugin)) + return FALSE; + + if (!gst_rdt_depay_plugin_init (plugin)) + return FALSE; + + if (!gst_rdt_manager_plugin_init (plugin)) + return FALSE; + + if (!gst_rtsp_real_plugin_init (plugin)) + return FALSE; + + if (!gst_pnm_src_plugin_init (plugin)) + return FALSE; + + return TRUE; +} + +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "realmedia", + "RealMedia support plugins", + plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN); diff --git a/gst/realmedia/rmdemux.c b/gst/realmedia/rmdemux.c index fa8ac26c24..fe174350df 100644 --- a/gst/realmedia/rmdemux.c +++ b/gst/realmedia/rmdemux.c @@ -29,11 +29,7 @@ #endif #include "rmdemux.h" -#include "rdtdepay.h" -#include "rdtmanager.h" -#include "rtspreal.h" #include "rmutils.h" -#include "rademux.h" #include #include @@ -2591,36 +2587,9 @@ unknown_stream: } } -static gboolean +gboolean gst_rmdemux_plugin_init (GstPlugin * plugin) { return gst_element_register (plugin, "rmdemux", - GST_RANK_PRIMARY, GST_TYPE_RMDEMUX) && - gst_element_register (plugin, "rademux", - GST_RANK_SECONDARY, GST_TYPE_REAL_AUDIO_DEMUX); + GST_RANK_PRIMARY, GST_TYPE_RMDEMUX); } - - -static gboolean -plugin_init (GstPlugin * plugin) -{ - if (!gst_rmdemux_plugin_init (plugin)) - return FALSE; - - if (!gst_rdt_depay_plugin_init (plugin)) - return FALSE; - - if (!gst_rdt_manager_plugin_init (plugin)) - return FALSE; - - if (!gst_rtsp_real_plugin_init (plugin)) - return FALSE; - - return TRUE; -} - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "realmedia", - "RealMedia demuxer and depayloader", - plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN); diff --git a/gst/realmedia/rmdemux.h b/gst/realmedia/rmdemux.h index 0ca0101628..4ebe6b0690 100644 --- a/gst/realmedia/rmdemux.h +++ b/gst/realmedia/rmdemux.h @@ -148,6 +148,8 @@ struct _GstRMDemuxClass { #define GST_RM_AUD_xRA4 GST_MAKE_FOURCC('.','r','a','4') // Not a real audio codec #define GST_RM_AUD_xRA5 GST_MAKE_FOURCC('.','r','a','5') // Not a real audio codec +gboolean gst_rmdemux_plugin_init (GstPlugin * plugin); + G_END_DECLS #endif /* __GST_RMDEMUX_H__ */