-
- /* when in probation, we require consecutive seqnums */
- if (seqnr == expected) {
- /* expected packet */
- GST_DEBUG ("probation: seqnr %d == expected %d", seqnr, expected);
- src->curr_probation--;
- src->stats.max_seq = seqnr;
- if (src->curr_probation == 0) {
- GST_DEBUG ("probation done!");
+ 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 < 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 < -max_misorder || delta >= 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). */