}
static gboolean
-update_receiver_stats (RTPSource * src, RTPPacketInfo * pinfo)
+update_receiver_stats (RTPSource * src, RTPPacketInfo * pinfo,
+ gboolean is_receive)
{
guint16 seqnr, expected;
RTPSourceStats *stats;
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;
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 */
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 */