From 42b8b3a37f5ab9cda3dc63b362d4f59ec0b8109a Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Tue, 9 Jan 2007 12:23:48 +0000 Subject: [PATCH] gst/rtp/: Added RFC 2250 MPEG Video Depayloader. Original commit message from CVS: * gst/rtp/Makefile.am: * gst/rtp/gstrtp.c: (plugin_init): * gst/rtp/gstrtpmpvdepay.c: (gst_rtp_mpv_depay_base_init), (gst_rtp_mpv_depay_class_init), (gst_rtp_mpv_depay_init), (gst_rtp_mpv_depay_setcaps), (gst_rtp_mpv_depay_process), (gst_rtp_mpv_depay_set_property), (gst_rtp_mpv_depay_get_property), (gst_rtp_mpv_depay_change_state), (gst_rtp_mpv_depay_plugin_init): * gst/rtp/gstrtpmpvdepay.h: Added RFC 2250 MPEG Video Depayloader. * gst/rtp/gstrtpL16depay.h: * gst/rtp/gstrtph263pdepay.c: (gst_rtp_h263p_depay_setcaps), (gst_rtp_h263p_depay_process): Fix Header file. Small cleanups. * gst/rtp/gstrtpmp4gdepay.c: (gst_rtp_mp4g_depay_class_init), (gst_rtp_mp4g_depay_init), (gst_rtp_mp4g_depay_finalize), (gst_rtp_mp4g_depay_process), (gst_rtp_mp4g_depay_change_state): * gst/rtp/gstrtpmp4vdepay.c: (gst_rtp_mp4v_depay_class_init), (gst_rtp_mp4v_depay_init), (gst_rtp_mp4v_depay_finalize), (gst_rtp_mp4v_depay_setcaps), (gst_rtp_mp4v_depay_process), (gst_rtp_mp4v_depay_change_state): Remove usused code. Remove Adapter from state Change. Added debug. * gst/rtp/gstrtpmpadepay.c: (gst_rtp_mpa_depay_base_init), (gst_rtp_mpa_depay_class_init), (gst_rtp_mpa_depay_init), (gst_rtp_mpa_depay_setcaps), (gst_rtp_mpa_depay_process): * gst/rtp/gstrtpmpadepay.h: Subclass base depayloader. Added debug. Support static payload type assignment as well. * gst/rtp/gstrtpmpapay.c: Fix caps. --- ChangeLog | 37 ++++++ gst/rtp/Makefile.am | 2 + gst/rtp/gstrtp.c | 4 + gst/rtp/gstrtpL16depay.h | 41 +++---- gst/rtp/gstrtph263pdepay.c | 28 +---- gst/rtp/gstrtpmp4gdepay.c | 36 +++--- gst/rtp/gstrtpmp4vdepay.c | 43 ++++--- gst/rtp/gstrtpmpadepay.c | 127 +++++++++---------- gst/rtp/gstrtpmpadepay.h | 10 +- gst/rtp/gstrtpmpapay.c | 2 +- gst/rtp/gstrtpmpvdepay.c | 298 +++++++++++++++++++++++++++++++++++++++++++++ gst/rtp/gstrtpmpvdepay.h | 56 +++++++++ 12 files changed, 529 insertions(+), 155 deletions(-) create mode 100644 gst/rtp/gstrtpmpvdepay.c create mode 100644 gst/rtp/gstrtpmpvdepay.h diff --git a/ChangeLog b/ChangeLog index 20d3a7a..d254100 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,40 @@ +2007-01-09 Wim Taymans + + * gst/rtp/Makefile.am: + * gst/rtp/gstrtp.c: (plugin_init): + * gst/rtp/gstrtpmpvdepay.c: (gst_rtp_mpv_depay_base_init), + (gst_rtp_mpv_depay_class_init), (gst_rtp_mpv_depay_init), + (gst_rtp_mpv_depay_setcaps), (gst_rtp_mpv_depay_process), + (gst_rtp_mpv_depay_set_property), (gst_rtp_mpv_depay_get_property), + (gst_rtp_mpv_depay_change_state), (gst_rtp_mpv_depay_plugin_init): + * gst/rtp/gstrtpmpvdepay.h: + Added RFC 2250 MPEG Video Depayloader. + + * gst/rtp/gstrtpL16depay.h: + * gst/rtp/gstrtph263pdepay.c: (gst_rtp_h263p_depay_setcaps), + (gst_rtp_h263p_depay_process): + Fix Header file. Small cleanups. + + * gst/rtp/gstrtpmp4gdepay.c: (gst_rtp_mp4g_depay_class_init), + (gst_rtp_mp4g_depay_init), (gst_rtp_mp4g_depay_finalize), + (gst_rtp_mp4g_depay_process), (gst_rtp_mp4g_depay_change_state): + * gst/rtp/gstrtpmp4vdepay.c: (gst_rtp_mp4v_depay_class_init), + (gst_rtp_mp4v_depay_init), (gst_rtp_mp4v_depay_finalize), + (gst_rtp_mp4v_depay_setcaps), (gst_rtp_mp4v_depay_process), + (gst_rtp_mp4v_depay_change_state): + Remove usused code. Remove Adapter from state Change. Added debug. + + * gst/rtp/gstrtpmpadepay.c: (gst_rtp_mpa_depay_base_init), + (gst_rtp_mpa_depay_class_init), (gst_rtp_mpa_depay_init), + (gst_rtp_mpa_depay_setcaps), (gst_rtp_mpa_depay_process): + * gst/rtp/gstrtpmpadepay.h: + Subclass base depayloader. + Added debug. + Support static payload type assignment as well. + + * gst/rtp/gstrtpmpapay.c: + Fix caps. + 2007-01-08 Tim-Philipp Müller Patch by: Vincent Torri diff --git a/gst/rtp/Makefile.am b/gst/rtp/Makefile.am index 0e903a7..b12f2f9 100644 --- a/gst/rtp/Makefile.am +++ b/gst/rtp/Makefile.am @@ -7,6 +7,7 @@ libgstrtp_la_SOURCES = \ gstrtpilbcpay.c \ gstrtpmpadepay.c \ gstrtpmpapay.c \ + gstrtpmpvdepay.c \ gstrtppcmadepay.c \ gstrtppcmudepay.c \ gstrtppcmupay.c \ @@ -62,6 +63,7 @@ noinst_HEADERS = \ gstrtpgsmpay.h \ gstrtpmpadepay.h \ gstrtpmpapay.h \ + gstrtpmpvdepay.h \ gstrtph263pdepay.h \ gstrtph263ppay.h \ gstrtph263pay.h \ diff --git a/gst/rtp/gstrtp.c b/gst/rtp/gstrtp.c index 01ead5d..2433c8f 100644 --- a/gst/rtp/gstrtp.c +++ b/gst/rtp/gstrtp.c @@ -34,6 +34,7 @@ #include "gstrtpamrdepay.h" #include "gstrtpmpapay.h" #include "gstrtpmpadepay.h" +#include "gstrtpmpvdepay.h" #include "gstrtph263pdepay.h" #include "gstrtph263ppay.h" #include "gstrtph263pay.h" @@ -94,6 +95,9 @@ plugin_init (GstPlugin * plugin) if (!gst_rtp_mpa_pay_plugin_init (plugin)) return FALSE; + if (!gst_rtp_mpv_depay_plugin_init (plugin)) + return FALSE; + if (!gst_rtp_h263p_pay_plugin_init (plugin)) return FALSE; diff --git a/gst/rtp/gstrtpL16depay.h b/gst/rtp/gstrtpL16depay.h index fa27711..d90924e 100644 --- a/gst/rtp/gstrtpL16depay.h +++ b/gst/rtp/gstrtpL16depay.h @@ -24,13 +24,24 @@ #include "rtp-packet.h" #include "gstrtp-common.h" -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ +G_BEGIN_DECLS + +/* Standard macros for defining types for this element. */ +#define GST_TYPE_RTP_L16_DEPAY \ + (gst_rtp_L16depay_get_type()) +#define GST_RTP_L16_DEPAY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_L16_DEPAY,GstRtpL16Depay)) +#define GST_RTP_L16_DEPAY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_L16_DEPAY,GstRtpL16DepayClass)) +#define GST_IS_RTP_L16_DEPAY(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_L16_DEPAY)) +#define GST_IS_RTP_L16_DEPAY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_L16_DEPAY)) -/* Definition of structure storing data for this element. */ typedef struct _GstRtpL16Depay GstRtpL16Depay; +typedef struct _GstRtpL16DepayClass GstRtpL16DepayClass; + +/* Definition of structure storing data for this element. */ struct _GstRtpL16Depay { GstElement element; @@ -45,29 +56,13 @@ struct _GstRtpL16Depay }; /* Standard definition defining a class for this element. */ -typedef struct _GstRtpL16DepayClass GstRtpL16DepayClass; struct _GstRtpL16DepayClass { GstElementClass parent_class; }; -/* Standard macros for defining types for this element. */ -#define GST_TYPE_RTP_L16_DEPAY \ - (gst_rtp_L16depay_get_type()) -#define GST_RTP_L16_DEPAY(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_L16_DEPAY,GstRtpL16Depay)) -#define GST_RTP_L16_DEPAY_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_L16_DEPAY,GstRtpL16DepayClass)) -#define GST_IS_RTP_L16_DEPAY(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_L16_DEPAY)) -#define GST_IS_RTP_L16_DEPAY_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_L16_DEPAY)) - gboolean gst_rtp_L16depay_plugin_init (GstPlugin * plugin); -#ifdef __cplusplus -} -#endif /* __cplusplus */ - +G_END_DECLS -#endif /* __GST_RTP_L16_DEPAY_H__ */ +#endif /* __GST_RTP_L16_DEPAY_H__ */ diff --git a/gst/rtp/gstrtph263pdepay.c b/gst/rtp/gstrtph263pdepay.c index b0b2dcf..999fda7 100644 --- a/gst/rtp/gstrtph263pdepay.c +++ b/gst/rtp/gstrtph263pdepay.c @@ -138,18 +138,14 @@ gst_rtp_h263p_depay_finalize (GObject * object) G_OBJECT_CLASS (parent_class)->finalize (object); } -// only on the sink gboolean gst_rtp_h263p_depay_setcaps (GstBaseRTPDepayload * filter, GstCaps * caps) { GstStructure *structure = gst_caps_get_structure (caps, 0); - gint clock_rate = 90000; // default - - if (gst_structure_has_field (structure, "clock-rate")) { - gst_structure_get_int (structure, "clock-rate", &clock_rate); - } + gint clock_rate = 90000; /* default */ + gst_structure_get_int (structure, "clock-rate", &clock_rate); filter->clock_rate = clock_rate; return TRUE; @@ -163,18 +159,11 @@ gst_rtp_h263p_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf) GstRtpH263PDepay *rtph263pdepay; GstBuffer *outbuf; - /* GstRTPPayload pt; */ - rtph263pdepay = GST_RTP_H263P_DEPAY (depayload); if (!gst_rtp_buffer_validate (buf)) goto bad_packet; - /* - if ((pt = gst_rtp_buffer_get_payload_type (buf)) != 0) - goto bad_payload; - */ - { gint payload_len; guint8 *payload; @@ -249,29 +238,16 @@ gst_rtp_h263p_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf) memcpy (GST_BUFFER_DATA (outbuf), payload, payload_len); gst_adapter_push (rtph263pdepay->adapter, outbuf); - } - } - return NULL; bad_packet: { GST_ELEMENT_WARNING (rtph263pdepay, STREAM, DECODE, ("Packet did not validate"), (NULL)); - return NULL; } - /* - bad_payload: - { - GST_DEBUG ("Unexpected payload type %u", pt); - - gst_buffer_unref (buf); - return GST_FLOW_ERROR; - } - */ } static void diff --git a/gst/rtp/gstrtpmp4gdepay.c b/gst/rtp/gstrtpmp4gdepay.c index 1157e34..8593f21 100644 --- a/gst/rtp/gstrtpmp4gdepay.c +++ b/gst/rtp/gstrtpmp4gdepay.c @@ -46,7 +46,6 @@ enum enum { ARG_0, - ARG_FREQUENCY }; static GstStaticPadTemplate gst_rtp_mp4g_depay_src_template = @@ -92,6 +91,8 @@ GST_STATIC_PAD_TEMPLATE ("sink", GST_BOILERPLATE (GstRtpMP4GDepay, gst_rtp_mp4g_depay, GstBaseRTPDepayload, GST_TYPE_BASE_RTP_DEPAYLOAD); +static void gst_rtp_mp4g_depay_finalize (GObject * object); + static gboolean gst_rtp_mp4g_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps); static GstBuffer *gst_rtp_mp4g_depay_process (GstBaseRTPDepayload * depayload, @@ -132,14 +133,15 @@ gst_rtp_mp4g_depay_class_init (GstRtpMP4GDepayClass * klass) parent_class = g_type_class_peek_parent (klass); - gstbasertpdepayload_class->process = gst_rtp_mp4g_depay_process; - gstbasertpdepayload_class->set_caps = gst_rtp_mp4g_depay_setcaps; - + gobject_class->finalize = gst_rtp_mp4g_depay_finalize; gobject_class->set_property = gst_rtp_mp4g_depay_set_property; gobject_class->get_property = gst_rtp_mp4g_depay_get_property; gstelement_class->change_state = gst_rtp_mp4g_depay_change_state; + gstbasertpdepayload_class->process = gst_rtp_mp4g_depay_process; + gstbasertpdepayload_class->set_caps = gst_rtp_mp4g_depay_setcaps; + GST_DEBUG_CATEGORY_INIT (rtpmp4gdepay_debug, "rtpmp4gdepay", 0, "MP4-generic RTP Depayloader"); } @@ -148,6 +150,20 @@ static void gst_rtp_mp4g_depay_init (GstRtpMP4GDepay * rtpmp4gdepay, GstRtpMP4GDepayClass * klass) { + rtpmp4gdepay->adapter = gst_adapter_new (); +} + +static void +gst_rtp_mp4g_depay_finalize (GObject * object) +{ + GstRtpMP4GDepay *rtpmp4gdepay; + + rtpmp4gdepay = GST_RTP_MP4G_DEPAY (object); + + g_object_unref (rtpmp4gdepay->adapter); + rtpmp4gdepay->adapter = NULL; + + G_OBJECT_CLASS (parent_class)->finalize (object); } static gboolean @@ -299,14 +315,13 @@ gst_rtp_mp4g_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf) return NULL; } } - return NULL; + /* ERRORS */ bad_packet: { GST_ELEMENT_WARNING (rtpmp4gdepay, STREAM, DECODE, - ("Packet did not validate"), (NULL)); - + ("Packet did not validate."), (NULL)); return NULL; } } @@ -351,9 +366,6 @@ gst_rtp_mp4g_depay_change_state (GstElement * element, rtpmp4gdepay = GST_RTP_MP4G_DEPAY (element); switch (transition) { - case GST_STATE_CHANGE_NULL_TO_READY: - rtpmp4gdepay->adapter = gst_adapter_new (); - break; case GST_STATE_CHANGE_READY_TO_PAUSED: gst_adapter_clear (rtpmp4gdepay->adapter); break; @@ -364,10 +376,6 @@ gst_rtp_mp4g_depay_change_state (GstElement * element, ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); switch (transition) { - case GST_STATE_CHANGE_READY_TO_NULL: - g_object_unref (rtpmp4gdepay->adapter); - rtpmp4gdepay->adapter = NULL; - break; default: break; } diff --git a/gst/rtp/gstrtpmp4vdepay.c b/gst/rtp/gstrtpmp4vdepay.c index 993187c..f98644c 100644 --- a/gst/rtp/gstrtpmp4vdepay.c +++ b/gst/rtp/gstrtpmp4vdepay.c @@ -26,6 +26,9 @@ #include #include "gstrtpmp4vdepay.h" +GST_DEBUG_CATEGORY_STATIC (rtpmp4vdepay_debug); +#define GST_CAT_DEFAULT (rtpmp4vdepay_debug) + /* elementfactory information */ static const GstElementDetails gst_rtp_mp4vdepay_details = GST_ELEMENT_DETAILS ("RTP packet depayloader", @@ -72,6 +75,8 @@ GST_STATIC_PAD_TEMPLATE ("sink", GST_BOILERPLATE (GstRtpMP4VDepay, gst_rtp_mp4v_depay, GstBaseRTPDepayload, GST_TYPE_BASE_RTP_DEPAYLOAD); +static void gst_rtp_mp4v_depay_finalize (GObject * object); + static gboolean gst_rtp_mp4v_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps); static GstBuffer *gst_rtp_mp4v_depay_process (GstBaseRTPDepayload * depayload, @@ -108,22 +113,39 @@ gst_rtp_mp4v_depay_class_init (GstRtpMP4VDepayClass * klass) gobject_class = (GObjectClass *) klass; gstelement_class = (GstElementClass *) klass; - gstbasertpdepayload_class = (GstBaseRTPDepayloadClass *) klass; - gstbasertpdepayload_class->process = gst_rtp_mp4v_depay_process; - gstbasertpdepayload_class->set_caps = gst_rtp_mp4v_depay_setcaps; - + gobject_class->finalize = gst_rtp_mp4v_depay_finalize; gobject_class->set_property = gst_rtp_mp4v_depay_set_property; gobject_class->get_property = gst_rtp_mp4v_depay_get_property; gstelement_class->change_state = gst_rtp_mp4v_depay_change_state; + + gstbasertpdepayload_class->process = gst_rtp_mp4v_depay_process; + gstbasertpdepayload_class->set_caps = gst_rtp_mp4v_depay_setcaps; + + GST_DEBUG_CATEGORY_INIT (rtpmp4vdepay_debug, "rtpmp4vdepay", 0, + "MPEG4 video RTP Depayloader"); } static void gst_rtp_mp4v_depay_init (GstRtpMP4VDepay * rtpmp4vdepay, GstRtpMP4VDepayClass * klass) { + rtpmp4vdepay->adapter = gst_adapter_new (); +} + +static void +gst_rtp_mp4v_depay_finalize (GObject * object) +{ + GstRtpMP4VDepay *rtpmp4vdepay; + + rtpmp4vdepay = GST_RTP_MP4V_DEPAY (object); + + g_object_unref (rtpmp4vdepay->adapter); + rtpmp4vdepay->adapter = NULL; + + G_OBJECT_CLASS (parent_class)->finalize (object); } static gboolean @@ -140,10 +162,7 @@ gst_rtp_mp4v_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps) structure = gst_caps_get_structure (caps, 0); - if (gst_structure_has_field (structure, "clock-rate")) { - gst_structure_get_int (structure, "clock-rate", &clock_rate); - } - + gst_structure_get_int (structure, "clock-rate", &clock_rate); depayload->clock_rate = clock_rate; srccaps = gst_caps_new_simple ("video/mpeg", @@ -230,7 +249,6 @@ bad_packet: { GST_ELEMENT_WARNING (rtpmp4vdepay, STREAM, DECODE, ("Packet did not validate"), (NULL)); - return NULL; } } @@ -275,9 +293,6 @@ gst_rtp_mp4v_depay_change_state (GstElement * element, rtpmp4vdepay = GST_RTP_MP4V_DEPAY (element); switch (transition) { - case GST_STATE_CHANGE_NULL_TO_READY: - rtpmp4vdepay->adapter = gst_adapter_new (); - break; case GST_STATE_CHANGE_READY_TO_PAUSED: gst_adapter_clear (rtpmp4vdepay->adapter); break; @@ -288,10 +303,6 @@ gst_rtp_mp4v_depay_change_state (GstElement * element, ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); switch (transition) { - case GST_STATE_CHANGE_READY_TO_NULL: - g_object_unref (rtpmp4vdepay->adapter); - rtpmp4vdepay->adapter = NULL; - break; default: break; } diff --git a/gst/rtp/gstrtpmpadepay.c b/gst/rtp/gstrtpmpadepay.c index bce5e00..0fb9409 100644 --- a/gst/rtp/gstrtpmpadepay.c +++ b/gst/rtp/gstrtpmpadepay.c @@ -26,6 +26,9 @@ #include #include "gstrtpmpadepay.h" +GST_DEBUG_CATEGORY_STATIC (rtpmpadepay_debug); +#define GST_CAT_DEFAULT (rtpmpadepay_debug) + /* elementfactory information */ static const GstElementDetails gst_rtp_mpadepay_details = GST_ELEMENT_DETAILS ("RTP packet depayloader", @@ -43,7 +46,6 @@ enum enum { ARG_0, - ARG_FREQUENCY }; static GstStaticPadTemplate gst_rtp_mpa_depay_src_template = @@ -54,20 +56,25 @@ GST_STATIC_PAD_TEMPLATE ("src", ); static GstStaticPadTemplate gst_rtp_mpa_depay_sink_template = -GST_STATIC_PAD_TEMPLATE ("sink", + GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_CAPS ("application/x-rtp, " "media = (string) \"audio\", " - "clock-rate = (int) 90000, " "encoding-name = (string) \"MPA\"") + "clock-rate = (int) 90000, " "encoding-name = (string) \"MPA\";" + "application/x-rtp, " + "media = (string) \"audio\", " + "payload = (int) " GST_RTP_PAYLOAD_MPA_STRING ", " + "clock-rate = (int) 90000") ); +GST_BOILERPLATE (GstRtpMPADepay, gst_rtp_mpa_depay, GstBaseRTPDepayload, + GST_TYPE_BASE_RTP_DEPAYLOAD); -static void gst_rtp_mpa_depay_class_init (GstRtpMPADepayClass * klass); -static void gst_rtp_mpa_depay_base_init (GstRtpMPADepayClass * klass); -static void gst_rtp_mpa_depay_init (GstRtpMPADepay * rtpmpadepay); - -static GstFlowReturn gst_rtp_mpa_depay_chain (GstPad * pad, GstBuffer * buffer); +static gboolean gst_rtp_mpa_depay_setcaps (GstBaseRTPDepayload * depayload, + GstCaps * caps); +static GstBuffer *gst_rtp_mpa_depay_process (GstBaseRTPDepayload * depayload, + GstBuffer * buf); static void gst_rtp_mpa_depay_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); @@ -77,35 +84,8 @@ static void gst_rtp_mpa_depay_get_property (GObject * object, guint prop_id, static GstStateChangeReturn gst_rtp_mpa_depay_change_state (GstElement * element, GstStateChange transition); -static GstElementClass *parent_class = NULL; - -static GType -gst_rtp_mpa_depay_get_type (void) -{ - static GType rtpmpadepay_type = 0; - - if (!rtpmpadepay_type) { - static const GTypeInfo rtpmpadepay_info = { - sizeof (GstRtpMPADepayClass), - (GBaseInitFunc) gst_rtp_mpa_depay_base_init, - NULL, - (GClassInitFunc) gst_rtp_mpa_depay_class_init, - NULL, - NULL, - sizeof (GstRtpMPADepay), - 0, - (GInstanceInitFunc) gst_rtp_mpa_depay_init, - }; - - rtpmpadepay_type = - g_type_register_static (GST_TYPE_ELEMENT, "GstRtpMPADepay", - &rtpmpadepay_info, 0); - } - return rtpmpadepay_type; -} - static void -gst_rtp_mpa_depay_base_init (GstRtpMPADepayClass * klass) +gst_rtp_mpa_depay_base_init (gpointer klass) { GstElementClass *element_class = GST_ELEMENT_CLASS (klass); @@ -122,9 +102,11 @@ gst_rtp_mpa_depay_class_init (GstRtpMPADepayClass * klass) { GObjectClass *gobject_class; GstElementClass *gstelement_class; + GstBaseRTPDepayloadClass *gstbasertpdepayload_class; gobject_class = (GObjectClass *) klass; gstelement_class = (GstElementClass *) klass; + gstbasertpdepayload_class = (GstBaseRTPDepayloadClass *) klass; parent_class = g_type_class_peek_parent (klass); @@ -132,39 +114,48 @@ gst_rtp_mpa_depay_class_init (GstRtpMPADepayClass * klass) gobject_class->get_property = gst_rtp_mpa_depay_get_property; gstelement_class->change_state = gst_rtp_mpa_depay_change_state; + + gstbasertpdepayload_class->set_caps = gst_rtp_mpa_depay_setcaps; + gstbasertpdepayload_class->process = gst_rtp_mpa_depay_process; + + GST_DEBUG_CATEGORY_INIT (rtpmpadepay_debug, "rtpmpadepay", 0, + "MPEG Audio RTP Depayloader"); } static void -gst_rtp_mpa_depay_init (GstRtpMPADepay * rtpmpadepay) +gst_rtp_mpa_depay_init (GstRtpMPADepay * rtpmpadepay, + GstRtpMPADepayClass * klass) { - rtpmpadepay->srcpad = - gst_pad_new_from_static_template (&gst_rtp_mpa_depay_src_template, "src"); - gst_element_add_pad (GST_ELEMENT (rtpmpadepay), rtpmpadepay->srcpad); - - rtpmpadepay->sinkpad = - gst_pad_new_from_static_template (&gst_rtp_mpa_depay_sink_template, - "sink"); - gst_pad_set_chain_function (rtpmpadepay->sinkpad, gst_rtp_mpa_depay_chain); - gst_element_add_pad (GST_ELEMENT (rtpmpadepay), rtpmpadepay->sinkpad); } -static GstFlowReturn -gst_rtp_mpa_depay_chain (GstPad * pad, GstBuffer * buf) +static gboolean +gst_rtp_mpa_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps) +{ + GstStructure *structure; + GstRtpMPADepay *rtpmpadepay; + gint clock_rate = 90000; /* default */ + + rtpmpadepay = GST_RTP_MPA_DEPAY (depayload); + + structure = gst_caps_get_structure (caps, 0); + + gst_structure_get_int (structure, "clock-rate", &clock_rate); + depayload->clock_rate = clock_rate; + + return TRUE; +} + +static GstBuffer * +gst_rtp_mpa_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf) { GstRtpMPADepay *rtpmpadepay; GstBuffer *outbuf; - guint8 pt; - GstFlowReturn ret; - rtpmpadepay = GST_RTP_MPA_DEPAY (GST_OBJECT_PARENT (pad)); + rtpmpadepay = GST_RTP_MPA_DEPAY (depayload); if (!gst_rtp_buffer_validate (buf)) goto bad_packet; - if ((pt = gst_rtp_buffer_get_payload_type (buf)) != GST_RTP_PAYLOAD_MPA) - goto bad_payload; - - { gint payload_len; guint8 *payload; @@ -202,32 +193,32 @@ gst_rtp_mpa_depay_chain (GstPad * pad, GstBuffer * buf) "gst_rtp_mpa_depay_chain: pushing buffer of size %d", GST_BUFFER_SIZE (outbuf)); - gst_buffer_unref (buf); - /* FIXME, we can push half mpeg frames when they are split over multiple * RTP packets */ - ret = gst_pad_push (rtpmpadepay->srcpad, outbuf); + return outbuf; } - return ret; + return NULL; bad_packet: { - GST_DEBUG_OBJECT (rtpmpadepay, "Packet did not validate"); - gst_buffer_unref (buf); - return GST_FLOW_ERROR; + GST_ELEMENT_WARNING (rtpmpadepay, STREAM, DECODE, + ("Packet did not validate."), (NULL)); + return NULL; } +#if 0 bad_payload: { - GST_DEBUG_OBJECT (rtpmpadepay, "Unexpected payload type %u", pt); - gst_buffer_unref (buf); - return GST_FLOW_ERROR; + GST_ELEMENT_WARNING (rtpmpadepay, STREAM, DECODE, + ("Unexpected payload type."), (NULL)); + return NULL; } +#endif empty_packet: { - GST_DEBUG_OBJECT (rtpmpadepay, "Empty payload"); - gst_buffer_unref (buf); - return GST_FLOW_OK; + GST_ELEMENT_WARNING (rtpmpadepay, STREAM, DECODE, + ("Empty Payload."), (NULL)); + return NULL; } } diff --git a/gst/rtp/gstrtpmpadepay.h b/gst/rtp/gstrtpmpadepay.h index ff665db..3d8b3eb 100644 --- a/gst/rtp/gstrtpmpadepay.h +++ b/gst/rtp/gstrtpmpadepay.h @@ -21,6 +21,7 @@ #define __GST_RTP_MPA_DEPAY_H__ #include +#include G_BEGIN_DECLS @@ -40,17 +41,12 @@ typedef struct _GstRtpMPADepayClass GstRtpMPADepayClass; struct _GstRtpMPADepay { - GstElement element; - - GstPad *sinkpad; - GstPad *srcpad; - - guint frequency; + GstBaseRTPDepayload depayload; }; struct _GstRtpMPADepayClass { - GstElementClass parent_class; + GstBaseRTPDepayloadClass parent_class; }; gboolean gst_rtp_mpa_depay_plugin_init (GstPlugin * plugin); diff --git a/gst/rtp/gstrtpmpapay.c b/gst/rtp/gstrtpmpapay.c index 156941b..2fe208d 100644 --- a/gst/rtp/gstrtpmpapay.c +++ b/gst/rtp/gstrtpmpapay.c @@ -48,7 +48,7 @@ static GstStaticPadTemplate gst_rtp_mpa_pay_src_template = GST_STATIC_CAPS ("application/x-rtp, " "media = (string) \"audio\", " "payload = (int) " GST_RTP_PAYLOAD_MPA_STRING ", " - "clock-rate = (int) 90000, " "encoding-name = (string) \"MPA\"; " + "clock-rate = (int) 90000; " "application/x-rtp, " "media = (string) \"audio\", " "payload = (int) " GST_RTP_PAYLOAD_DYNAMIC_STRING ", " diff --git a/gst/rtp/gstrtpmpvdepay.c b/gst/rtp/gstrtpmpvdepay.c new file mode 100644 index 0000000..99cfeb3 --- /dev/null +++ b/gst/rtp/gstrtpmpvdepay.c @@ -0,0 +1,298 @@ +/* GStreamer + * Copyright (C) <2006> 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 +#include "gstrtpmpvdepay.h" + +GST_DEBUG_CATEGORY_STATIC (rtpmpvdepay_debug); +#define GST_CAT_DEFAULT (rtpmpvdepay_debug) + +/* elementfactory information */ +static const GstElementDetails gst_rtp_mpvdepay_details = +GST_ELEMENT_DETAILS ("RTP packet depayloader", + "Codec/Depayloader/Network", + "Extracts MPEG video from RTP packets (RFC 2250)", + "Wim Taymans "); + +/* RtpMPVDepay signals and args */ +enum +{ + /* FILL ME */ + LAST_SIGNAL +}; + +enum +{ + ARG_0, +}; + +static GstStaticPadTemplate gst_rtp_mpv_depay_src_template = +GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("video/mpeg") + ); + +static GstStaticPadTemplate gst_rtp_mpv_depay_sink_template = + GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("application/x-rtp, " + "media = (string) \"video\", " + "clock-rate = (int) 90000, " "encoding-name = (string) \"MPV\";" + "application/x-rtp, " + "media = (string) \"video\", " + "payload = (int) " GST_RTP_PAYLOAD_MPV_STRING ", " + "clock-rate = (int) 90000") + ); + +GST_BOILERPLATE (GstRtpMPVDepay, gst_rtp_mpv_depay, GstBaseRTPDepayload, + GST_TYPE_BASE_RTP_DEPAYLOAD); + +static gboolean gst_rtp_mpv_depay_setcaps (GstBaseRTPDepayload * depayload, + GstCaps * caps); +static GstBuffer *gst_rtp_mpv_depay_process (GstBaseRTPDepayload * depayload, + GstBuffer * buf); + +static void gst_rtp_mpv_depay_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec); +static void gst_rtp_mpv_depay_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); + +static GstStateChangeReturn gst_rtp_mpv_depay_change_state (GstElement * + element, GstStateChange transition); + +static void +gst_rtp_mpv_depay_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_rtp_mpv_depay_src_template)); + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&gst_rtp_mpv_depay_sink_template)); + + gst_element_class_set_details (element_class, &gst_rtp_mpvdepay_details); +} + +static void +gst_rtp_mpv_depay_class_init (GstRtpMPVDepayClass * klass) +{ + GObjectClass *gobject_class; + GstElementClass *gstelement_class; + GstBaseRTPDepayloadClass *gstbasertpdepayload_class; + + gobject_class = (GObjectClass *) klass; + gstelement_class = (GstElementClass *) klass; + gstbasertpdepayload_class = (GstBaseRTPDepayloadClass *) klass; + + parent_class = g_type_class_peek_parent (klass); + + gobject_class->set_property = gst_rtp_mpv_depay_set_property; + gobject_class->get_property = gst_rtp_mpv_depay_get_property; + + gstelement_class->change_state = gst_rtp_mpv_depay_change_state; + + gstbasertpdepayload_class->set_caps = gst_rtp_mpv_depay_setcaps; + gstbasertpdepayload_class->process = gst_rtp_mpv_depay_process; + + GST_DEBUG_CATEGORY_INIT (rtpmpvdepay_debug, "rtpmpvdepay", 0, + "MPEG Video RTP Depayloader"); +} + +static void +gst_rtp_mpv_depay_init (GstRtpMPVDepay * rtpmpvdepay, + GstRtpMPVDepayClass * klass) +{ +} + +static gboolean +gst_rtp_mpv_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps) +{ + GstStructure *structure; + GstRtpMPVDepay *rtpmpvdepay; + gint clock_rate = 90000; /* default */ + + rtpmpvdepay = GST_RTP_MPV_DEPAY (depayload); + + structure = gst_caps_get_structure (caps, 0); + + gst_structure_get_int (structure, "clock-rate", &clock_rate); + depayload->clock_rate = clock_rate; + + return TRUE; +} + +static GstBuffer * +gst_rtp_mpv_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf) +{ + GstRtpMPVDepay *rtpmpvdepay; + GstBuffer *outbuf; + + rtpmpvdepay = GST_RTP_MPV_DEPAY (depayload); + + if (!gst_rtp_buffer_validate (buf)) + goto bad_packet; + + { + gint payload_len; + guint8 *payload; + guint8 T; + guint32 timestamp; + + payload_len = gst_rtp_buffer_get_payload_len (buf); + payload = gst_rtp_buffer_get_payload (buf); + + if (payload_len <= 4) + goto empty_packet; + + /* 3.4 MPEG Video-specific header + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | MBZ |T| TR | |N|S|B|E| P | | BFC | | FFC | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * AN FBV FFV + */ + T = (payload[0] & 0x04); + + payload_len -= 4; + payload += 4; + + if (T) { + /* + * 3.4.1 MPEG-2 Video-specific header extension + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |X|E|f_[0,0]|f_[0,1]|f_[1,0]|f_[1,1]| DC| PS|T|P|C|Q|V|A|R|H|G|D| + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + if (payload_len <= 4) + goto empty_packet; + + payload_len -= 4; + payload += 4; + } + + timestamp = gst_rtp_buffer_get_timestamp (buf); + + outbuf = gst_buffer_new_and_alloc (payload_len); + memcpy (GST_BUFFER_DATA (outbuf), payload, payload_len); + + GST_DEBUG_OBJECT (rtpmpvdepay, + "gst_rtp_mpv_depay_chain: pushing buffer of size %d", + GST_BUFFER_SIZE (outbuf)); + + return outbuf; + } + + return NULL; + +bad_packet: + { + GST_ELEMENT_WARNING (rtpmpvdepay, STREAM, DECODE, + ("Packet did not validate."), (NULL)); + return NULL; + } +#if 0 +bad_payload: + { + GST_DEBUG_OBJECT (rtpmpvdepay, "Unexpected payload type %u", pt); + return NULL; + } +#endif +empty_packet: + { + GST_ELEMENT_WARNING (rtpmpvdepay, STREAM, DECODE, + ("Empty payload."), (NULL)); + return NULL; + } +} + +static void +gst_rtp_mpv_depay_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstRtpMPVDepay *rtpmpvdepay; + + rtpmpvdepay = GST_RTP_MPV_DEPAY (object); + + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_rtp_mpv_depay_get_property (GObject * object, guint prop_id, GValue * value, + GParamSpec * pspec) +{ + GstRtpMPVDepay *rtpmpvdepay; + + rtpmpvdepay = GST_RTP_MPV_DEPAY (object); + + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GstStateChangeReturn +gst_rtp_mpv_depay_change_state (GstElement * element, GstStateChange transition) +{ + GstRtpMPVDepay *rtpmpvdepay; + GstStateChangeReturn ret; + + rtpmpvdepay = GST_RTP_MPV_DEPAY (element); + + switch (transition) { + case GST_STATE_CHANGE_NULL_TO_READY: + break; + default: + break; + } + + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); + + switch (transition) { + case GST_STATE_CHANGE_READY_TO_NULL: + break; + default: + break; + } + return ret; +} + +gboolean +gst_rtp_mpv_depay_plugin_init (GstPlugin * plugin) +{ + return gst_element_register (plugin, "rtpmpvdepay", + GST_RANK_MARGINAL, GST_TYPE_RTP_MPV_DEPAY); +} diff --git a/gst/rtp/gstrtpmpvdepay.h b/gst/rtp/gstrtpmpvdepay.h new file mode 100644 index 0000000..406cb48 --- /dev/null +++ b/gst/rtp/gstrtpmpvdepay.h @@ -0,0 +1,56 @@ +/* GStreamer + * Copyright (C) <2005> 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_RTP_MPV_DEPAY_H__ +#define __GST_RTP_MPV_DEPAY_H__ + +#include +#include + +G_BEGIN_DECLS + +#define GST_TYPE_RTP_MPV_DEPAY \ + (gst_rtp_mpv_depay_get_type()) +#define GST_RTP_MPV_DEPAY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_MPV_DEPAY,GstRtpMPVDepay)) +#define GST_RTP_MPV_DEPAY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_MPV_DEPAY,GstRtpMPVDepayClass)) +#define GST_IS_RTP_MPV_DEPAY(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_MPV_DEPAY)) +#define GST_IS_RTP_MPV_DEPAY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_MPV_DEPAY)) + +typedef struct _GstRtpMPVDepay GstRtpMPVDepay; +typedef struct _GstRtpMPVDepayClass GstRtpMPVDepayClass; + +struct _GstRtpMPVDepay +{ + GstBaseRTPDepayload depayload; +}; + +struct _GstRtpMPVDepayClass +{ + GstBaseRTPDepayloadClass parent_class; +}; + +gboolean gst_rtp_mpv_depay_plugin_init (GstPlugin * plugin); + +G_END_DECLS + +#endif /* __GST_RTP_MPV_DEPAY_H__ */ -- 2.7.4