diff options
-rw-r--r-- | gst/rtp/gstrtpgstpay.c | 146 | ||||
-rw-r--r-- | gst/rtp/gstrtpgstpay.h | 2 |
2 files changed, 110 insertions, 38 deletions
diff --git a/gst/rtp/gstrtpgstpay.c b/gst/rtp/gstrtpgstpay.c index 78148623d..14804591c 100644 --- a/gst/rtp/gstrtpgstpay.c +++ b/gst/rtp/gstrtpgstpay.c @@ -77,10 +77,13 @@ GST_STATIC_PAD_TEMPLATE ("src", static void gst_rtp_gst_pay_finalize (GObject * obj); +static GstStateChangeReturn +gst_rtp_gst_pay_change_state (GstElement * element, GstStateChange transition); + static gboolean gst_rtp_gst_pay_setcaps (GstBaseRTPPayload * payload, GstCaps * caps); -static GstFlowReturn gst_rtp_gst_pay_handle_buffer (GstBaseRTPPayload * payload, - GstBuffer * buffer); +static GstFlowReturn gst_rtp_gst_pay_handle_buffer (GstBaseRTPPayload * + payload, GstBuffer * buffer); static gboolean gst_rtp_gst_pay_handle_event (GstPad * pad, GstEvent * event); GST_BOILERPLATE (GstRtpGSTPay, gst_rtp_gst_pay, GstBaseRTPPayload, @@ -105,13 +108,17 @@ static void gst_rtp_gst_pay_class_init (GstRtpGSTPayClass * klass) { GObjectClass *gobject_class; + GstElementClass *gstelement_class; GstBaseRTPPayloadClass *gstbasertppayload_class; gobject_class = (GObjectClass *) klass; + gstelement_class = (GstElementClass *) klass; gstbasertppayload_class = (GstBaseRTPPayloadClass *) klass; gobject_class->finalize = gst_rtp_gst_pay_finalize; + gstelement_class->change_state = gst_rtp_gst_pay_change_state; + gstbasertppayload_class->set_caps = gst_rtp_gst_pay_setcaps; gstbasertppayload_class->handle_buffer = gst_rtp_gst_pay_handle_buffer; gstbasertppayload_class->handle_event = gst_rtp_gst_pay_handle_event; @@ -129,12 +136,22 @@ gst_rtp_gst_pay_init (GstRtpGSTPay * rtpgstpay, GstRtpGSTPayClass * klass) } static void +gst_rtp_gst_pay_reset (GstRtpGSTPay * rtpgstpay) +{ + g_list_foreach (rtpgstpay->events, (GFunc) gst_event_unref, NULL); + g_list_free (rtpgstpay->events); + rtpgstpay->events = NULL; + rtpgstpay->have_caps = FALSE; +} + +static void gst_rtp_gst_pay_finalize (GObject * obj) { GstRtpGSTPay *rtpgstpay; rtpgstpay = GST_RTP_GST_PAY (obj); + gst_rtp_gst_pay_reset (rtpgstpay); g_object_unref (rtpgstpay->adapter); G_OBJECT_CLASS (parent_class)->finalize (obj); @@ -253,6 +270,43 @@ make_data_buffer (GstRtpGSTPay * rtpgstpay, gchar * data, guint size) return outbuf; } +static void +process_event (GstRtpGSTPay * rtpgstpay, GstEvent * event) +{ + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_TAG: + rtpgstpay->etype = 1; + break; + case GST_EVENT_CUSTOM_DOWNSTREAM: + rtpgstpay->etype = 2; + break; + case GST_EVENT_CUSTOM_BOTH: + rtpgstpay->etype = 2; + break; + default: + break; + } + if (rtpgstpay->etype) { + const GstStructure *s; + gchar *estr; + guint elen; + GstBuffer *outbuf; + + GST_DEBUG_OBJECT (rtpgstpay, "make event type %d", rtpgstpay->etype); + s = gst_event_get_structure (event); + + estr = gst_structure_to_string (s); + elen = strlen (estr); + outbuf = make_data_buffer (rtpgstpay, estr, elen); + g_free (estr); + + gst_adapter_push (rtpgstpay->adapter, outbuf); + /* flush the adapter immediately */ + gst_rtp_gst_pay_flush (rtpgstpay, GST_CLOCK_TIME_NONE); + } +} + + static gboolean gst_rtp_gst_pay_setcaps (GstBaseRTPPayload * payload, GstCaps * caps) { @@ -261,6 +315,7 @@ gst_rtp_gst_pay_setcaps (GstBaseRTPPayload * payload, GstCaps * caps) gchar *capsstr, *capsenc, *capsver; guint capslen; GstBuffer *outbuf; + GList *walk; rtpgstpay = GST_RTP_GST_PAY (payload); @@ -275,6 +330,23 @@ gst_rtp_gst_pay_setcaps (GstBaseRTPPayload * payload, GstCaps * caps) /* for 0 byte */ capslen++; + /* make caps for SDP */ + capsver = g_strdup_printf ("%d", rtpgstpay->current_CV); + res = + gst_basertppayload_set_outcaps (payload, "caps", G_TYPE_STRING, capsenc, + "capsversion", G_TYPE_STRING, capsver, NULL); + + rtpgstpay->have_caps = TRUE; + + for (walk = rtpgstpay->events; walk; walk = g_list_next (walk)) { + GstEvent *event = walk->data; + + process_event (rtpgstpay, event); + gst_event_unref (event); + } + g_list_free (rtpgstpay->events); + rtpgstpay->events = NULL; + /* make a data buffer of it */ outbuf = make_data_buffer (rtpgstpay, capsstr, capslen); g_free (capsstr); @@ -284,11 +356,6 @@ gst_rtp_gst_pay_setcaps (GstBaseRTPPayload * payload, GstCaps * caps) rtpgstpay->next_CV = (rtpgstpay->next_CV + 1) & 0x7; gst_adapter_push (rtpgstpay->adapter, outbuf); - /* make caps for SDP */ - capsver = g_strdup_printf ("%d", rtpgstpay->current_CV); - res = - gst_basertppayload_set_outcaps (payload, "caps", G_TYPE_STRING, capsenc, - "capsversion", G_TYPE_STRING, capsver, NULL); g_free (capsenc); g_free (capsver); @@ -302,38 +369,12 @@ gst_rtp_gst_pay_handle_event (GstPad * pad, GstEvent * event) rtpgstpay = GST_RTP_GST_PAY (GST_PAD_PARENT (pad)); - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_TAG: - rtpgstpay->etype = 1; - break; - case GST_EVENT_CUSTOM_DOWNSTREAM: - rtpgstpay->etype = 2; - break; - case GST_EVENT_CUSTOM_BOTH: - rtpgstpay->etype = 2; - break; - default: - break; + if (!rtpgstpay->have_caps) { + rtpgstpay->events = + g_list_append (rtpgstpay->events, gst_event_ref (event)); + } else { + process_event (rtpgstpay, event); } - if (rtpgstpay->etype) { - const GstStructure *s; - gchar *estr; - guint elen; - GstBuffer *outbuf; - - GST_DEBUG_OBJECT (rtpgstpay, "make event type %d", rtpgstpay->etype); - s = gst_event_get_structure (event); - - estr = gst_structure_to_string (s); - elen = strlen (estr); - outbuf = make_data_buffer (rtpgstpay, estr, elen); - g_free (estr); - - gst_adapter_push (rtpgstpay->adapter, outbuf); - /* flush the adapter immediately */ - gst_rtp_gst_pay_flush (rtpgstpay, GST_CLOCK_TIME_NONE); - } - /* FALSE to let base class handle it as well */ return FALSE; } @@ -366,6 +407,35 @@ gst_rtp_gst_pay_handle_buffer (GstBaseRTPPayload * basepayload, return ret; } +static GstStateChangeReturn +gst_rtp_gst_pay_change_state (GstElement * element, GstStateChange transition) +{ + GstRtpGSTPay *rtpgstpay; + GstStateChangeReturn ret; + + rtpgstpay = GST_RTP_GST_PAY (element); + + switch (transition) { + case GST_STATE_CHANGE_READY_TO_PAUSED: + gst_rtp_gst_pay_reset (rtpgstpay); + break; + default: + break; + } + + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); + + switch (transition) { + case GST_STATE_CHANGE_PAUSED_TO_READY: + gst_rtp_gst_pay_reset (rtpgstpay); + break; + default: + break; + } + return ret; +} + + gboolean gst_rtp_gst_pay_plugin_init (GstPlugin * plugin) { diff --git a/gst/rtp/gstrtpgstpay.h b/gst/rtp/gstrtpgstpay.h index 999b42a3e..31cbd49bf 100644 --- a/gst/rtp/gstrtpgstpay.h +++ b/gst/rtp/gstrtpgstpay.h @@ -47,6 +47,8 @@ struct _GstRtpGSTPay GstAdapter *adapter; guint8 flags; guint8 etype; + gboolean have_caps; + GList *events; guint8 current_CV; /* CV field of incoming caps*/ guint8 next_CV; |