mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 10:11:08 +00:00
srtpdec: Make sure that stream-id/caps/segment are sent before buffers
It may be possible that only one of the two sink pads is linked in that case, the events need to be created from the other pad.
This commit is contained in:
parent
de1fb842e6
commit
2b75eb85c4
2 changed files with 108 additions and 12 deletions
|
@ -685,31 +685,50 @@ gst_srtp_dec_sink_setcaps (GstPad * pad, GstObject * parent,
|
|||
}
|
||||
|
||||
static gboolean
|
||||
gst_srtp_dec_sink_event (GstPad * pad, GstObject * parent,
|
||||
GstEvent * event, gboolean is_rtcp)
|
||||
gst_srtp_dec_sink_event_rtp (GstPad * pad, GstObject * parent, GstEvent * event)
|
||||
{
|
||||
GstCaps *caps;
|
||||
GstSrtpDec *filter = GST_SRTP_DEC (parent);
|
||||
|
||||
switch (GST_EVENT_TYPE (event)) {
|
||||
case GST_EVENT_CAPS:
|
||||
gst_event_parse_caps (event, &caps);
|
||||
return gst_srtp_dec_sink_setcaps (pad, parent, caps, is_rtcp);
|
||||
return gst_srtp_dec_sink_setcaps (pad, parent, caps, FALSE);
|
||||
case GST_EVENT_SEGMENT:
|
||||
filter->rtp_has_segment = TRUE;
|
||||
break;
|
||||
case GST_EVENT_FLUSH_STOP:
|
||||
filter->rtp_has_segment = FALSE;
|
||||
break;
|
||||
default:
|
||||
return gst_pad_event_default (pad, parent, event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_srtp_dec_sink_event_rtp (GstPad * pad, GstObject * parent, GstEvent * event)
|
||||
{
|
||||
return gst_srtp_dec_sink_event (pad, parent, event, FALSE);
|
||||
return gst_pad_event_default (pad, parent, event);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_srtp_dec_sink_event_rtcp (GstPad * pad, GstObject * parent,
|
||||
GstEvent * event)
|
||||
{
|
||||
return gst_srtp_dec_sink_event (pad, parent, event, TRUE);
|
||||
GstCaps *caps;
|
||||
GstSrtpDec *filter = GST_SRTP_DEC (parent);
|
||||
|
||||
switch (GST_EVENT_TYPE (event)) {
|
||||
case GST_EVENT_CAPS:
|
||||
gst_event_parse_caps (event, &caps);
|
||||
return gst_srtp_dec_sink_setcaps (pad, parent, caps, TRUE);
|
||||
case GST_EVENT_SEGMENT:
|
||||
filter->rtcp_has_segment = TRUE;
|
||||
break;
|
||||
case GST_EVENT_FLUSH_STOP:
|
||||
filter->rtcp_has_segment = FALSE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return gst_pad_event_default (pad, parent, event);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -842,6 +861,71 @@ gst_srtp_dec_iterate_internal_links_rtcp (GstPad * pad, GstObject * parent)
|
|||
return gst_srtp_dec_iterate_internal_links (pad, parent, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_srtp_dec_push_early_events (GstSrtpDec * filter, GstPad * pad,
|
||||
GstPad * otherpad, gboolean is_rtcp)
|
||||
{
|
||||
GstEvent *otherev, *ev;
|
||||
|
||||
ev = gst_pad_get_sticky_event (pad, GST_EVENT_STREAM_START, 0);
|
||||
if (ev) {
|
||||
gst_event_unref (ev);
|
||||
} else {
|
||||
gchar *new_stream_id;
|
||||
|
||||
otherev = gst_pad_get_sticky_event (otherpad, GST_EVENT_STREAM_START, 0);
|
||||
|
||||
if (otherev) {
|
||||
const gchar *other_stream_id;
|
||||
|
||||
gst_event_parse_stream_start (otherev, &other_stream_id);
|
||||
|
||||
new_stream_id = g_strdup_printf ("%s/%s", other_stream_id,
|
||||
is_rtcp ? "rtcp" : "rtp");
|
||||
gst_event_unref (otherev);
|
||||
} else {
|
||||
new_stream_id = gst_pad_create_stream_id (pad, GST_ELEMENT (filter),
|
||||
is_rtcp ? "rtcp" : "rtp");
|
||||
}
|
||||
|
||||
ev = gst_event_new_stream_start (new_stream_id);
|
||||
g_free (new_stream_id);
|
||||
|
||||
gst_pad_push_event (pad, ev);
|
||||
}
|
||||
|
||||
ev = gst_pad_get_sticky_event (pad, GST_EVENT_CAPS, 0);
|
||||
if (ev) {
|
||||
gst_event_unref (ev);
|
||||
} else {
|
||||
GstCaps *caps;
|
||||
|
||||
if (is_rtcp)
|
||||
caps = gst_caps_new_empty_simple ("application/x-rtcp");
|
||||
else
|
||||
caps = gst_caps_new_empty_simple ("application/x-rtp");
|
||||
|
||||
gst_pad_set_caps (pad, caps);
|
||||
gst_caps_unref (caps);
|
||||
}
|
||||
|
||||
ev = gst_pad_get_sticky_event (pad, GST_EVENT_SEGMENT, 0);
|
||||
if (ev) {
|
||||
gst_event_unref (ev);
|
||||
} else {
|
||||
ev = gst_pad_get_sticky_event (otherpad, GST_EVENT_SEGMENT, 0);
|
||||
|
||||
if (ev)
|
||||
gst_pad_push_event (pad, ev);
|
||||
}
|
||||
|
||||
if (is_rtcp)
|
||||
filter->rtcp_has_segment = TRUE;
|
||||
else
|
||||
filter->rtp_has_segment = TRUE;
|
||||
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_srtp_dec_chain (GstPad * pad, GstObject * parent, GstBuffer * buf,
|
||||
gboolean is_rtcp)
|
||||
|
@ -939,10 +1023,17 @@ unprotect:
|
|||
|
||||
push_out:
|
||||
/* Push buffer to source pad */
|
||||
if (is_rtcp)
|
||||
if (is_rtcp) {
|
||||
otherpad = filter->rtcp_srcpad;
|
||||
else
|
||||
if (!filter->rtcp_has_segment)
|
||||
gst_srtp_dec_push_early_events (filter, filter->rtcp_srcpad,
|
||||
filter->rtp_srcpad, TRUE);
|
||||
} else {
|
||||
otherpad = filter->rtp_srcpad;
|
||||
if (!filter->rtp_has_segment)
|
||||
gst_srtp_dec_push_early_events (filter, filter->rtp_srcpad,
|
||||
filter->rtcp_srcpad, FALSE);
|
||||
}
|
||||
ret = gst_pad_push (otherpad, buf);
|
||||
|
||||
return ret;
|
||||
|
@ -980,6 +1071,8 @@ gst_srtp_dec_change_state (GstElement * element, GstStateChange transition)
|
|||
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
||||
filter->streams = g_hash_table_new_full (g_direct_hash, g_direct_equal,
|
||||
NULL, (GDestroyNotify) clear_stream);
|
||||
filter->rtp_has_segment = FALSE;
|
||||
filter->rtcp_has_segment = FALSE;
|
||||
break;
|
||||
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
|
||||
break;
|
||||
|
|
|
@ -78,6 +78,9 @@ struct _GstSrtpDec
|
|||
srtp_t session;
|
||||
gboolean first_session;
|
||||
GHashTable *streams;
|
||||
|
||||
gboolean rtp_has_segment;
|
||||
gboolean rtcp_has_segment;
|
||||
};
|
||||
|
||||
struct _GstSrtpDecClass
|
||||
|
|
Loading…
Reference in a new issue