summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wtaymans@redhat.com>2014-07-18 15:55:27 +0200
committerWim Taymans <wtaymans@redhat.com>2014-07-18 15:55:27 +0200
commit41acb585d812a7e8d8045ce98c2671d3d8f04c41 (patch)
tree32b4ebc8d11e56b1ecb31a1e72e53d5e9ec0721f
parent638a700463a96b53dc92e9db4522ca861e5c72a1 (diff)
rtxsend: use MIXED capsmixed-caps
Use MIXED caps to specify the caps of the original and RTX buffers. We can now also set the extra RTX properties on the caps.
-rw-r--r--gst/rtpmanager/gstrtprtxsend.c100
1 files changed, 82 insertions, 18 deletions
diff --git a/gst/rtpmanager/gstrtprtxsend.c b/gst/rtpmanager/gstrtprtxsend.c
index 922fad3b2..2cde62c54 100644
--- a/gst/rtpmanager/gstrtprtxsend.c
+++ b/gst/rtpmanager/gstrtprtxsend.c
@@ -359,6 +359,25 @@ gst_rtp_rtx_send_get_ssrc_data (GstRtpRtxSend * rtx, guint32 ssrc)
return data;
}
+static guint
+gst_rtp_rtx_send_get_rtx_pt (GstRtpRtxSend * rtx, guint pt)
+{
+ guint rtx_pt;
+ gpointer val;
+
+ val = g_hash_table_lookup (rtx->rtx_pt_map, GUINT_TO_POINTER (pt));
+ if (val) {
+ rtx_pt = GPOINTER_TO_UINT (val);
+ } else {
+ /* make random free pt */
+ rtx_pt = g_random_int_range (96, 127);
+ g_hash_table_insert (rtx->rtx_pt_map, GUINT_TO_POINTER (pt),
+ GUINT_TO_POINTER (rtx_pt));
+ }
+ return rtx_pt;
+}
+
+
/* Copy fixed header and extension. Add OSN before to copy payload
* Copy memory to avoid to manually copy each rtp buffer field.
*/
@@ -383,8 +402,8 @@ gst_rtp_rtx_buffer_new (GstRtpRtxSend * rtx, GstBuffer * buffer)
data = gst_rtp_rtx_send_get_ssrc_data (rtx, ssrc);
ssrc = data->rtx_ssrc;
seqnum = data->next_seqnum++;
- fmtp = GPOINTER_TO_UINT (g_hash_table_lookup (rtx->rtx_pt_map,
- GUINT_TO_POINTER (gst_rtp_buffer_get_payload_type (&rtp))));
+ fmtp =
+ gst_rtp_rtx_send_get_rtx_pt (rtx, gst_rtp_buffer_get_payload_type (&rtp));
GST_DEBUG_OBJECT (rtx,
"retransmit seqnum: %" G_GUINT16_FORMAT ", ssrc: %" G_GUINT32_FORMAT,
@@ -561,6 +580,66 @@ gst_rtp_rtx_send_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
}
static gboolean
+handle_caps (GstRtpRtxSend * rtx, GstCaps * caps)
+{
+ guint i, len;
+ GstCaps *outcaps;
+
+ outcaps = gst_caps_copy (caps);
+ GST_CAPS_FLAG_SET (outcaps, GST_CAPS_FLAG_MIXED);
+
+ GST_OBJECT_LOCK (rtx);
+ len = gst_caps_get_size (caps);
+ for (i = 0; i < len; i++) {
+ GstStructure *s;
+ SSRCRtxData *data;
+ guint ssrc;
+ gint srcpt, rtxpt;
+ const gchar *media;
+ gchar *apt, *rtx_time;
+
+ s = gst_caps_get_structure (caps, i);
+
+ if (!gst_structure_get_uint (s, "ssrc", &ssrc))
+ ssrc = -1;
+ if (!(media = gst_structure_get_string (s, "media")))
+ media = "unknown";
+ if (gst_structure_get_int (s, "payload", &srcpt))
+ rtxpt = gst_rtp_rtx_send_get_rtx_pt (rtx, srcpt);
+ else
+ rtxpt = 0;
+
+ data = gst_rtp_rtx_send_get_ssrc_data (rtx, ssrc);
+ gst_structure_get_int (s, "clock-rate", &data->clock_rate);
+
+ apt = g_strdup_printf ("%d", srcpt);
+ s = gst_structure_new ("application/x-rtp",
+ "media", G_TYPE_STRING, media,
+ "clock-rate", G_TYPE_INT, data->clock_rate,
+ "encoding-name", G_TYPE_STRING, "rtx",
+ "payload", G_TYPE_INT, rtxpt,
+ "ssrc", G_TYPE_UINT, data->rtx_ssrc,
+ "seqnum-offset", G_TYPE_UINT, data->next_seqnum,
+ "apt", G_TYPE_STRING, apt, NULL);
+ g_free (apt);
+
+ if (rtx->max_size_time > 0) {
+ rtx_time = g_strdup_printf ("%d", rtx->max_size_time);
+ gst_structure_set (s, "rtx-time", G_TYPE_STRING, rtx_time, NULL);
+ g_free (rtx_time);
+ }
+ gst_caps_append_structure (outcaps, s);
+
+
+ GST_DEBUG_OBJECT (rtx, "got clock-rate from caps: %d for ssrc: %u",
+ data->clock_rate, ssrc);
+ }
+ GST_OBJECT_UNLOCK (rtx);
+
+ return gst_pad_set_caps (rtx->srcpad, outcaps);
+}
+
+static gboolean
gst_rtp_rtx_send_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
GstRtpRtxSend *rtx = GST_RTP_RTX_SEND (parent);
@@ -584,25 +663,10 @@ gst_rtp_rtx_send_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
case GST_EVENT_CAPS:
{
GstCaps *caps;
- GstStructure *s;
- guint ssrc;
- SSRCRtxData *data;
gst_event_parse_caps (event, &caps);
- g_assert (gst_caps_is_fixed (caps));
-
- s = gst_caps_get_structure (caps, 0);
- if (!gst_structure_get_uint (s, "ssrc", &ssrc))
- ssrc = -1;
-
- GST_OBJECT_LOCK (rtx);
- data = gst_rtp_rtx_send_get_ssrc_data (rtx, ssrc);
- gst_structure_get_int (s, "clock-rate", &data->clock_rate);
- GST_DEBUG_OBJECT (rtx, "got clock-rate from caps: %d for ssrc: %u",
- data->clock_rate, ssrc);
- GST_OBJECT_UNLOCK (rtx);
- break;
+ return handle_caps (rtx, caps);
}
default:
break;