From b814d7ed250239e57da2387ec9535852de06749f Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Fri, 2 Oct 2015 16:18:15 +0900 Subject: [PATCH] rtpsource: doesn't handle probation and rtp gap in case of sender https://bugzilla.gnome.org/show_bug.cgi?id=754548 --- gst/rtpmanager/rtpsource.c | 131 +++++++++++++++++++------------------ 1 file changed, 67 insertions(+), 64 deletions(-) diff --git a/gst/rtpmanager/rtpsource.c b/gst/rtpmanager/rtpsource.c index 5aabe41468..6373bc3a3c 100644 --- a/gst/rtpmanager/rtpsource.c +++ b/gst/rtpmanager/rtpsource.c @@ -1005,7 +1005,8 @@ do_bitrate_estimation (RTPSource * src, GstClockTime running_time, } static gboolean -update_receiver_stats (RTPSource * src, RTPPacketInfo * pinfo) +update_receiver_stats (RTPSource * src, RTPPacketInfo * pinfo, + gboolean is_receive) { guint16 seqnr, expected; RTPSourceStats *stats; @@ -1023,80 +1024,82 @@ update_receiver_stats (RTPSource * src, RTPPacketInfo * pinfo) src->curr_probation = src->probation; } - expected = src->stats.max_seq + 1; - delta = gst_rtp_buffer_compare_seqnum (expected, seqnr); + if (is_receive) { + expected = src->stats.max_seq + 1; + delta = gst_rtp_buffer_compare_seqnum (expected, seqnr); - /* if we are still on probation, check seqnum */ - if (src->curr_probation) { - /* when in probation, we require consecutive seqnums */ - if (delta == 0) { - /* expected packet */ - GST_DEBUG ("probation: seqnr %d == expected %d", seqnr, expected); - src->curr_probation--; + /* if we are still on probation, check seqnum */ + if (src->curr_probation) { + /* when in probation, we require consecutive seqnums */ + if (delta == 0) { + /* expected packet */ + GST_DEBUG ("probation: seqnr %d == expected %d", seqnr, expected); + src->curr_probation--; + if (seqnr < stats->max_seq) { + /* sequence number wrapped - count another 64K cycle. */ + stats->cycles += RTP_SEQ_MOD; + } + src->stats.max_seq = seqnr; + + if (src->curr_probation == 0) { + GST_DEBUG ("probation done!"); + init_seq (src, seqnr); + } else { + GstBuffer *q; + + GST_DEBUG ("probation %d: queue packet", src->curr_probation); + /* when still in probation, keep packets in a list. */ + g_queue_push_tail (src->packets, pinfo->data); + pinfo->data = NULL; + /* remove packets from queue if there are too many */ + while (g_queue_get_length (src->packets) > RTP_MAX_PROBATION_LEN) { + q = g_queue_pop_head (src->packets); + gst_buffer_unref (q); + } + goto done; + } + } else { + /* unexpected seqnum in probation */ + goto probation_seqnum; + } + } else if (delta >= 0 && delta < RTP_MAX_DROPOUT) { + /* Clear bad packets */ + stats->bad_seq = RTP_SEQ_MOD + 1; /* so seq == bad_seq is false */ + g_queue_foreach (src->packets, (GFunc) gst_buffer_unref, NULL); + g_queue_clear (src->packets); + + /* in order, with permissible gap */ if (seqnr < stats->max_seq) { /* sequence number wrapped - count another 64K cycle. */ stats->cycles += RTP_SEQ_MOD; } - src->stats.max_seq = seqnr; - - if (src->curr_probation == 0) { - GST_DEBUG ("probation done!"); + stats->max_seq = seqnr; + } else if (delta < -RTP_MAX_MISORDER || delta >= RTP_MAX_DROPOUT) { + /* the sequence number made a very large jump */ + if (seqnr == stats->bad_seq && src->packets->head) { + /* two sequential packets -- assume that the other side + * restarted without telling us so just re-sync + * (i.e., pretend this was the first packet). */ init_seq (src, seqnr); } else { - GstBuffer *q; - - GST_DEBUG ("probation %d: queue packet", src->curr_probation); - /* when still in probation, keep packets in a list. */ + /* unacceptable jump */ + stats->bad_seq = (seqnr + 1) & (RTP_SEQ_MOD - 1); + g_queue_foreach (src->packets, (GFunc) gst_buffer_unref, NULL); + g_queue_clear (src->packets); g_queue_push_tail (src->packets, pinfo->data); pinfo->data = NULL; - /* remove packets from queue if there are too many */ - while (g_queue_get_length (src->packets) > RTP_MAX_PROBATION_LEN) { - q = g_queue_pop_head (src->packets); - gst_buffer_unref (q); - } - goto done; + goto bad_sequence; } - } else { - /* unexpected seqnum in probation */ - goto probation_seqnum; - } - } else if (delta >= 0 && delta < RTP_MAX_DROPOUT) { - /* Clear bad packets */ - stats->bad_seq = RTP_SEQ_MOD + 1; /* so seq == bad_seq is false */ - g_queue_foreach (src->packets, (GFunc) gst_buffer_unref, NULL); - g_queue_clear (src->packets); - - /* in order, with permissible gap */ - if (seqnr < stats->max_seq) { - /* sequence number wrapped - count another 64K cycle. */ - stats->cycles += RTP_SEQ_MOD; - } - stats->max_seq = seqnr; - } else if (delta < -RTP_MAX_MISORDER || delta >= RTP_MAX_DROPOUT) { - /* the sequence number made a very large jump */ - if (seqnr == stats->bad_seq && src->packets->head) { - /* two sequential packets -- assume that the other side - * restarted without telling us so just re-sync - * (i.e., pretend this was the first packet). */ - init_seq (src, seqnr); - } else { - /* unacceptable jump */ - stats->bad_seq = (seqnr + 1) & (RTP_SEQ_MOD - 1); + } else { /* delta < 0 && delta >= -RTP_MAX_MISORDER */ + /* Clear bad packets */ + stats->bad_seq = RTP_SEQ_MOD + 1; /* so seq == bad_seq is false */ g_queue_foreach (src->packets, (GFunc) gst_buffer_unref, NULL); g_queue_clear (src->packets); - g_queue_push_tail (src->packets, pinfo->data); - pinfo->data = NULL; - goto bad_sequence; - } - } else { /* delta < 0 && delta >= -RTP_MAX_MISORDER */ - /* Clear bad packets */ - stats->bad_seq = RTP_SEQ_MOD + 1; /* so seq == bad_seq is false */ - g_queue_foreach (src->packets, (GFunc) gst_buffer_unref, NULL); - g_queue_clear (src->packets); - /* duplicate or reordered packet, will be filtered by jitterbuffer. */ - GST_WARNING ("duplicate or reordered packet (seqnr %u, expected %u)", seqnr, - expected); + /* duplicate or reordered packet, will be filtered by jitterbuffer. */ + GST_WARNING ("duplicate or reordered packet (seqnr %u, expected %u)", + seqnr, expected); + } } src->stats.octets_received += pinfo->payload_len; @@ -1146,7 +1149,7 @@ rtp_source_process_rtp (RTPSource * src, RTPPacketInfo * pinfo) g_return_val_if_fail (RTP_IS_SOURCE (src), GST_FLOW_ERROR); g_return_val_if_fail (pinfo != NULL, GST_FLOW_ERROR); - if (!update_receiver_stats (src, pinfo)) + if (!update_receiver_stats (src, pinfo, TRUE)) return GST_FLOW_OK; /* the source that sent the packet must be a sender */ @@ -1217,7 +1220,7 @@ rtp_source_send_rtp (RTPSource * src, RTPPacketInfo * pinfo) src->is_sender = TRUE; /* we are also a receiver of our packets */ - if (!update_receiver_stats (src, pinfo)) + if (!update_receiver_stats (src, pinfo, FALSE)) return GST_FLOW_OK; /* update stats for the SR */