rtpsource: doesn't handle probation and rtp gap in case of sender
authorHyunjun Ko <zzoon.ko@samsung.com>
Fri, 2 Oct 2015 07:18:15 +0000 (16:18 +0900)
committerSebastian Dröge <sebastian@centricular.com>
Fri, 2 Oct 2015 13:42:36 +0000 (16:42 +0300)
https://bugzilla.gnome.org/show_bug.cgi?id=754548

gst/rtpmanager/rtpsource.c

index 5aabe41468ef29db05ed376cd3c18d2463435bbd..6373bc3a3c6b6c7afab6a8541edef3a7fcfb1369 100644 (file)
@@ -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 (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);
 
-  /* 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--;
+      /* 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;
+
+      /* duplicate or reordered packet, will be filtered by jitterbuffer. */
+      GST_WARNING ("duplicate or reordered packet (seqnr %u, expected %u)",
+          seqnr, expected);
     }
-  } 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);
   }
 
   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 */