mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 05:16:13 +00:00
gst/realmedia/rdtdepay.*: Check seqnum gaps and drop duplicate packets or mark outgoing buffers with a DISCONT flag w...
Original commit message from CVS: * gst/realmedia/rdtdepay.c: (gst_rdt_depay_handle_data), (gst_rdt_depay_change_state): * gst/realmedia/rdtdepay.h: Check seqnum gaps and drop duplicate packets or mark outgoing buffers with a DISCONT flag when needed. * gst/realmedia/rdtmanager.c: (gst_rdt_manager_query_src): Report the configure latency instead of a hardcoded value.
This commit is contained in:
parent
541aad907e
commit
35b3e2b596
4 changed files with 68 additions and 5 deletions
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
||||||
|
2008-08-27 Wim Taymans <wim.taymans@collabora.co.uk>
|
||||||
|
|
||||||
|
* gst/realmedia/rdtdepay.c: (gst_rdt_depay_handle_data),
|
||||||
|
(gst_rdt_depay_change_state):
|
||||||
|
* gst/realmedia/rdtdepay.h:
|
||||||
|
Check seqnum gaps and drop duplicate packets or mark outgoing buffers
|
||||||
|
with a DISCONT flag when needed.
|
||||||
|
|
||||||
|
* gst/realmedia/rdtmanager.c: (gst_rdt_manager_query_src):
|
||||||
|
Report the configure latency instead of a hardcoded value.
|
||||||
|
|
||||||
2008-08-27 Wim Taymans <wim.taymans@collabora.co.uk>
|
2008-08-27 Wim Taymans <wim.taymans@collabora.co.uk>
|
||||||
|
|
||||||
* gst/realmedia/rdtmanager.c: (create_session), (activate_session),
|
* gst/realmedia/rdtmanager.c: (create_session), (activate_session),
|
||||||
|
|
|
@ -222,6 +222,9 @@ gst_rdt_depay_handle_data (GstRDTDepay * rdtdepay, GstClockTime outtime,
|
||||||
guint size;
|
guint size;
|
||||||
guint16 stream_id;
|
guint16 stream_id;
|
||||||
guint32 timestamp;
|
guint32 timestamp;
|
||||||
|
gint gap;
|
||||||
|
guint16 seqnum;
|
||||||
|
gboolean discont;
|
||||||
|
|
||||||
/* get pointers to the packet data */
|
/* get pointers to the packet data */
|
||||||
gst_rdt_packet_data_peek_data (packet, &data, &size);
|
gst_rdt_packet_data_peek_data (packet, &data, &size);
|
||||||
|
@ -236,6 +239,41 @@ gst_rdt_depay_handle_data (GstRDTDepay * rdtdepay, GstClockTime outtime,
|
||||||
stream_id = gst_rdt_packet_data_get_stream_id (packet);
|
stream_id = gst_rdt_packet_data_get_stream_id (packet);
|
||||||
timestamp = gst_rdt_packet_data_get_timestamp (packet);
|
timestamp = gst_rdt_packet_data_get_timestamp (packet);
|
||||||
|
|
||||||
|
seqnum = gst_rdt_packet_data_get_seq (packet);
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (rdtdepay, "stream_id %u, timestamp %u, seqnum %d",
|
||||||
|
stream_id, timestamp, seqnum);
|
||||||
|
|
||||||
|
if (rdtdepay->next_seqnum != -1) {
|
||||||
|
gap = gst_rdt_buffer_compare_seqnum (seqnum, rdtdepay->next_seqnum);
|
||||||
|
|
||||||
|
/* if we have no gap, all is fine */
|
||||||
|
if (G_UNLIKELY (gap != 0)) {
|
||||||
|
GST_LOG_OBJECT (rdtdepay, "got packet %u, expected %u, gap %d", seqnum,
|
||||||
|
rdtdepay->next_seqnum, gap);
|
||||||
|
if (gap < 0) {
|
||||||
|
/* seqnum > next_seqnum, we are missing some packets, this is always a
|
||||||
|
* DISCONT. */
|
||||||
|
GST_LOG_OBJECT (rdtdepay, "%d missing packets", gap);
|
||||||
|
rdtdepay->discont = TRUE;
|
||||||
|
} else {
|
||||||
|
/* seqnum < next_seqnum, we have seen this packet before or the sender
|
||||||
|
* could be restarted. If the packet is not too old, we throw it away as
|
||||||
|
* a duplicate, otherwise we mark discont and continue. 100 misordered
|
||||||
|
* packets is a good threshold. See also RFC 4737. */
|
||||||
|
if (gap < 100)
|
||||||
|
goto dropping;
|
||||||
|
|
||||||
|
GST_LOG_OBJECT (rdtdepay,
|
||||||
|
"%d > 100, packet too old, sender likely restarted", gap);
|
||||||
|
rdtdepay->discont = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rdtdepay->next_seqnum = (seqnum + 1);
|
||||||
|
if (rdtdepay->next_seqnum == 0xff00)
|
||||||
|
rdtdepay->next_seqnum = 0;
|
||||||
|
|
||||||
GST_WRITE_UINT16_BE (outdata + 0, 0); /* version */
|
GST_WRITE_UINT16_BE (outdata + 0, 0); /* version */
|
||||||
GST_WRITE_UINT16_BE (outdata + 2, size + 12); /* length */
|
GST_WRITE_UINT16_BE (outdata + 2, size + 12); /* length */
|
||||||
GST_WRITE_UINT16_BE (outdata + 4, stream_id); /* stream */
|
GST_WRITE_UINT16_BE (outdata + 4, stream_id); /* stream */
|
||||||
|
@ -243,13 +281,19 @@ gst_rdt_depay_handle_data (GstRDTDepay * rdtdepay, GstClockTime outtime,
|
||||||
GST_WRITE_UINT16_BE (outdata + 10, 0); /* flags */
|
GST_WRITE_UINT16_BE (outdata + 10, 0); /* flags */
|
||||||
memcpy (outdata + 12, data, size);
|
memcpy (outdata + 12, data, size);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (rdtdepay, "Passing on packet "
|
GST_DEBUG_OBJECT (rdtdepay, "Pushing packet, outtime %" GST_TIME_FORMAT,
|
||||||
"stream_id=%u timestamp=%u, outtime %" GST_TIME_FORMAT, stream_id,
|
GST_TIME_ARGS (outtime));
|
||||||
timestamp, GST_TIME_ARGS (outtime));
|
|
||||||
|
|
||||||
ret = gst_rdt_depay_push (rdtdepay, outbuf);
|
ret = gst_rdt_depay_push (rdtdepay, outbuf);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
/* ERRORS */
|
||||||
|
dropping:
|
||||||
|
{
|
||||||
|
GST_WARNING_OBJECT (rdtdepay, "%d <= 100, dropping old packet", gap);
|
||||||
|
return GST_FLOW_OK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
|
@ -355,6 +399,7 @@ gst_rdt_depay_change_state (GstElement * element, GstStateChange transition)
|
||||||
case GST_STATE_CHANGE_NULL_TO_READY:
|
case GST_STATE_CHANGE_NULL_TO_READY:
|
||||||
break;
|
break;
|
||||||
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
||||||
|
rdtdepay->next_seqnum = -1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -47,6 +47,7 @@ struct _GstRDTDepay
|
||||||
GstPad *srcpad;
|
GstPad *srcpad;
|
||||||
|
|
||||||
guint clock_rate;
|
guint clock_rate;
|
||||||
|
guint32 next_seqnum;
|
||||||
|
|
||||||
gboolean discont;
|
gboolean discont;
|
||||||
GstBuffer *header;
|
GstBuffer *header;
|
||||||
|
|
|
@ -528,9 +528,15 @@ gst_rdt_manager_query_src (GstPad * pad, GstQuery * query)
|
||||||
switch (GST_QUERY_TYPE (query)) {
|
switch (GST_QUERY_TYPE (query)) {
|
||||||
case GST_QUERY_LATENCY:
|
case GST_QUERY_LATENCY:
|
||||||
{
|
{
|
||||||
|
GstClockTime latency;
|
||||||
|
|
||||||
|
latency = rdtmanager->latency * GST_MSECOND;
|
||||||
|
|
||||||
/* we pretend to be live with a 3 second latency */
|
/* we pretend to be live with a 3 second latency */
|
||||||
gst_query_set_latency (query, TRUE, 5 * GST_SECOND, -1);
|
gst_query_set_latency (query, TRUE, latency, -1);
|
||||||
GST_DEBUG_OBJECT (rdtmanager, "reporting 5 seconds of latency");
|
|
||||||
|
GST_DEBUG_OBJECT (rdtmanager, "reporting %" GST_TIME_FORMAT " of latency",
|
||||||
|
GST_TIME_ARGS (latency));
|
||||||
res = TRUE;
|
res = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue