summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@collabora.co.uk>2013-04-09 12:53:30 +0200
committerWim Taymans <wim.taymans@collabora.co.uk>2013-04-09 12:53:30 +0200
commitdfc722d7a499ff770ae0c6fb950b9c00b7340018 (patch)
tree949e246ff4d486396aae3da26318c042267dc079
parent16dfcbe706d8d3dddfbc00c60145a1381a77fdc3 (diff)
downloadgstreamer-plugins-good-dfc722d7a499ff770ae0c6fb950b9c00b7340018.tar.gz
pay: cache events until caps are known
We want to cache the events until we know the caps of the outgoing buffers and we can place those caps on the buffers generated from the events. Otherwise we and up with buffers without caps in the sink.
-rw-r--r--gst/rtp/gstrtpgstpay.c146
-rw-r--r--gst/rtp/gstrtpgstpay.h2
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;