From: Wim Taymans Date: Sun, 12 Aug 2007 16:30:36 +0000 (+0000) Subject: gst-libs/gst/rtp/gstbasertppayload.*: Improve caps negotiation so that downstream... X-Git-Tag: RELEASE-0_10_15~167 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3b7071a16fa55c69893df27937be54fb328da40f;p=platform%2Fupstream%2Fgst-plugins-base.git gst-libs/gst/rtp/gstbasertppayload.*: Improve caps negotiation so that downstream elements can confiure certain RTP p... Original commit message from CVS: * gst-libs/gst/rtp/gstbasertppayload.c: (gst_basertppayload_set_outcaps): * gst-libs/gst/rtp/gstbasertppayload.h: Improve caps negotiation so that downstream elements can confiure certain RTP properties by fixing them on the caps. See #465146. Add docs. --- diff --git a/ChangeLog b/ChangeLog index ee628ff..6207390 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2007-08-12 Wim Taymans + + * gst-libs/gst/rtp/gstbasertppayload.c: + (gst_basertppayload_set_outcaps): + * gst-libs/gst/rtp/gstbasertppayload.h: + Improve caps negotiation so that downstream elements can confiure + certain RTP properties by fixing them on the caps. See #465146. + Add docs. + 2007-08-11 Tim-Philipp Müller * docs/libs/gst-plugins-base-libs-sections.txt: diff --git a/gst-libs/gst/rtp/gstbasertppayload.c b/gst-libs/gst/rtp/gstbasertppayload.c index a2a5a41..5f8c934 100644 --- a/gst-libs/gst/rtp/gstbasertppayload.c +++ b/gst-libs/gst/rtp/gstbasertppayload.c @@ -375,6 +375,18 @@ no_function: } } +/** + * gst_basertppayload_set_options: + * @payload: a #GstBaseRTPPayload + * @media: the media type (typically "audio" or "video") + * @dynamic: if the payload type is dynamic + * @encoding_name: the encoding name + * @clock_rate: the clock rate of the media + * + * Set the rtp options of the payloader. These options will be set in the caps + * of the payloader. Subclasses must call this method before calling + * gst_basertppayload_push() or gst_basertppayload_set_outcaps(). + */ void gst_basertppayload_set_options (GstBaseRTPPayload * payload, gchar * media, gboolean dynamic, gchar * encoding_name, guint32 clock_rate) @@ -390,37 +402,124 @@ gst_basertppayload_set_options (GstBaseRTPPayload * payload, payload->clock_rate = clock_rate; } +/** + * gst_basertppayload_set_outcaps: + * @payload: a #GstBaseRTPPayload + * @fieldname: the first field name or %NULL + * @...: field values + * + * Configure the output caps with the optional parameters. + * + * Variable arguments should be in the form field name, field type + * (as a GType), value(s). The last variable argument should be NULL. + * + * Returns: %TRUE if the caps could be set. + */ gboolean gst_basertppayload_set_outcaps (GstBaseRTPPayload * payload, gchar * fieldname, ...) { - GstCaps *srccaps; - GstStructure *s; + GstCaps *srccaps, *peercaps; + /* fill in the defaults, there properties cannot be negotiated. */ srccaps = gst_caps_new_simple ("application/x-rtp", "media", G_TYPE_STRING, payload->media, - "payload", G_TYPE_INT, GST_BASE_RTP_PAYLOAD_PT (payload), "clock-rate", G_TYPE_INT, payload->clock_rate, - "encoding-name", G_TYPE_STRING, payload->encoding_name, - "ssrc", G_TYPE_UINT, payload->current_ssrc, - "clock-base", G_TYPE_UINT, payload->ts_base, - "seqnum-base", G_TYPE_UINT, payload->seqnum_base, NULL); - s = gst_caps_get_structure (srccaps, 0); + "encoding-name", G_TYPE_STRING, payload->encoding_name, NULL); if (fieldname) { va_list varargs; va_start (varargs, fieldname); - gst_structure_set_valist (s, fieldname, varargs); + gst_caps_set_simple_valist (srccaps, fieldname, varargs); va_end (varargs); } + + /* the peer caps can override some of the defaults */ + peercaps = gst_pad_peer_get_caps (payload->srcpad); + if (peercaps == NULL) { + /* no peer caps, just add the other properties */ + gst_caps_set_simple (srccaps, + "payload", G_TYPE_INT, GST_BASE_RTP_PAYLOAD_PT (payload), + "ssrc", G_TYPE_UINT, payload->current_ssrc, + "clock-base", G_TYPE_UINT, payload->ts_base, + "seqnum-base", G_TYPE_UINT, payload->seqnum_base, NULL); + } else { + GstCaps *temp; + GstStructure *s; + const GValue *value; + gint pt; + + /* peer provides caps we can use to fixate, intersect. This always returns a + * writable caps. */ + temp = gst_caps_intersect (srccaps, peercaps); + gst_caps_unref (srccaps); + gst_caps_unref (peercaps); + + /* now fixate, start by taking the first caps */ + gst_caps_truncate (temp); + srccaps = temp; + + /* get first structure */ + s = gst_caps_get_structure (srccaps, 0); + + if (gst_structure_get_int (s, "payload", &pt)) + GST_BASE_RTP_PAYLOAD_PT (payload) = pt; + else { + if (gst_structure_has_field (s, "payload")) { + /* can only fixate if there is a field */ + gst_structure_fixate_field_nearest_int (s, "payload", + GST_BASE_RTP_PAYLOAD_PT (payload)); + } else { + gst_structure_set (s, "payload", G_TYPE_INT, + GST_BASE_RTP_PAYLOAD_PT (payload), NULL); + } + } + + if (gst_structure_has_field_typed (s, "ssrc", G_TYPE_UINT)) { + value = gst_structure_get_value (s, "ssrc"); + payload->current_ssrc = g_value_get_uint (value); + } else { + /* FIXME, fixate_nearest_uint would be even better */ + gst_structure_set (s, "ssrc", G_TYPE_UINT, payload->current_ssrc, NULL); + } + + if (gst_structure_has_field_typed (s, "clock-base", G_TYPE_UINT)) { + value = gst_structure_get_value (s, "clock-base"); + payload->ts_base = g_value_get_uint (value); + } else { + /* FIXME, fixate_nearest_uint would be even better */ + gst_structure_set (s, "clock-base", G_TYPE_UINT, payload->ts_base, NULL); + } + if (gst_structure_has_field_typed (s, "seqnum-base", G_TYPE_UINT)) { + value = gst_structure_get_value (s, "seqnum-base"); + payload->seqnum_base = g_value_get_uint (value); + } else { + /* FIXME, fixate_nearest_uint would be even better */ + gst_structure_set (s, "seqnum-base", G_TYPE_UINT, payload->seqnum_base, + NULL); + } + } + gst_pad_set_caps (GST_BASE_RTP_PAYLOAD_SRCPAD (payload), srccaps); gst_caps_unref (srccaps); return TRUE; } +/** + * gst_basertppayload_is_filled: + * @payload: a #GstBaseRTPPayload + * @size: the size of the packet + * @duration: the duration of the packet + * + * Check if the packet with @size and @duration would exceed the configure + * maximum size. + * + * Returns: %TRUE if the packet of @size and @duration would exceed the + * configured MTU or max_ptime. + */ gboolean gst_basertppayload_is_filled (GstBaseRTPPayload * payload, guint size, GstClockTime duration) @@ -434,6 +533,18 @@ gst_basertppayload_is_filled (GstBaseRTPPayload * payload, return FALSE; } +/** + * gst_basertppayload_push: + * @payload: a #GstBaseRTPPayload + * @buffer: a #GstBuffer + * + * Push @buffer to the peer element of the payloader. The SSRC, payload type, + * seqnum and timestamp of the RTP buffer will be updated first. + * + * This function takes ownership of @buffer. + * + * Returns: a #GstFlowReturn. + */ GstFlowReturn gst_basertppayload_push (GstBaseRTPPayload * payload, GstBuffer * buffer) { diff --git a/gst-libs/gst/rtp/gstbasertppayload.h b/gst-libs/gst/rtp/gstbasertppayload.h index 3f86dfb..bd16c13 100644 --- a/gst-libs/gst/rtp/gstbasertppayload.h +++ b/gst-libs/gst/rtp/gstbasertppayload.h @@ -41,10 +41,34 @@ typedef struct _GstBaseRTPPayload GstBaseRTPPayload; typedef struct _GstBaseRTPPayloadPrivate GstBaseRTPPayloadPrivate; typedef struct _GstBaseRTPPayloadClass GstBaseRTPPayloadClass; +/** + * GST_BASE_RTP_PAYLOAD_SINKPAD: + * @payload: a #GstBaseRTPPayload + * + * Get access to the sinkpad of @payload. + */ #define GST_BASE_RTP_PAYLOAD_SINKPAD(payload) (GST_BASE_RTP_PAYLOAD (payload)->sinkpad) +/** + * GST_BASE_RTP_PAYLOAD_SRCPAD: + * @payload: a #GstBaseRTPPayload + * + * Get access to the srcpad of @payload. + */ #define GST_BASE_RTP_PAYLOAD_SRCPAD(payload) (GST_BASE_RTP_PAYLOAD (payload)->srcpad) +/** + * GST_BASE_RTP_PAYLOAD_PT: + * @payload: a #GstBaseRTPPayload + * + * Get access to the configured payload type of @payload. + */ #define GST_BASE_RTP_PAYLOAD_PT(payload) (GST_BASE_RTP_PAYLOAD (payload)->pt) +/** + * GST_BASE_RTP_PAYLOAD_MTU: + * @payload: a #GstBaseRTPPayload + * + * Get access to the configured MTU of @payload. + */ #define GST_BASE_RTP_PAYLOAD_MTU(payload) (GST_BASE_RTP_PAYLOAD (payload)->mtu) struct _GstBaseRTPPayload