From: Wim Taymans Date: Mon, 5 Aug 2013 21:22:16 +0000 (+0200) Subject: source: add methods to register NACK X-Git-Tag: 1.1.4~92 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4379ed1dee8e09c15c77bc19d223772cf663ff74;p=platform%2Fupstream%2Fgst-plugins-good.git source: add methods to register NACK Add a method to register a missing packet for an ssrc along with methods to get the missing packets and clear them. --- diff --git a/gst/rtpmanager/rtpsource.c b/gst/rtpmanager/rtpsource.c index 185ea1c..48c6986 100644 --- a/gst/rtpmanager/rtpsource.c +++ b/gst/rtpmanager/rtpsource.c @@ -236,6 +236,7 @@ rtp_source_reset (RTPSource * src) src->stats.prev_rtcptime = GST_CLOCK_TIME_NONE; src->stats.last_rtptime = GST_CLOCK_TIME_NONE; src->stats.last_rtcptime = GST_CLOCK_TIME_NONE; + g_array_set_size (src->nacks, 0); } static void @@ -258,6 +259,7 @@ rtp_source_init (RTPSource * src) src->last_rtptime = -1; src->retained_feedback = g_queue_new (); + src->nacks = g_array_new (FALSE, FALSE, sizeof (guint32)); rtp_source_reset (src); } @@ -295,6 +297,8 @@ rtp_source_finalize (GObject * object) gst_buffer_unref (buffer); g_queue_free (src->retained_feedback); + g_array_free (src->nacks, TRUE); + if (src->rtp_from) g_object_unref (src->rtp_from); if (src->rtcp_from) @@ -1780,3 +1784,74 @@ rtp_source_has_retained (RTPSource * src, GCompareFunc func, gconstpointer data) else return FALSE; } + +/** + * @src: The #RTPSource + * @seqnum: a seqnum + * + * Register that @seqnum has not been received from @src. + */ +void +rtp_source_register_nack (RTPSource * src, guint16 seqnum) +{ + guint i, len; + guint32 dword = seqnum << 16; + gint diff = 16; + + len = src->nacks->len; + for (i = 0; i < len; i++) { + guint32 tdword; + guint16 tseq; + + tdword = g_array_index (src->nacks, guint32, i); + tseq = tdword >> 16; + + diff = gst_rtp_buffer_compare_seqnum (tseq, seqnum); + if (diff < 16) + break; + } + /* we already have this seqnum */ + if (diff == 0) + return; + /* it comes before the recorded seqnum, FIXME, we could merge it + * if not to far away */ + if (diff < 0) { + GST_DEBUG ("insert NACK #%u at %u", seqnum, i); + g_array_insert_val (src->nacks, i, dword); + } else if (diff < 16) { + /* we can merge it */ + dword = g_array_index (src->nacks, guint32, i); + dword |= 1 << (diff - 1); + GST_DEBUG ("merge NACK #%u at %u with NACK #%u -> 0x%08x", seqnum, i, + dword >> 16, dword); + g_array_index (src->nacks, guint32, i) = dword; + } else { + GST_DEBUG ("append NACK #%u", seqnum); + g_array_append_val (src->nacks, dword); + } + src->send_nack = TRUE; +} + +/** + * @src: The #RTPSource + * @n_nacks: result number of nacks + * + * Get the registered NACKS since the last rtp_source_clear_nacks(). + * + * Returns: an array of @n_nacks seqnum values. + */ +guint32 * +rtp_source_get_nacks (RTPSource * src, guint * n_nacks) +{ + if (n_nacks) + *n_nacks = src->nacks->len; + + return (guint32 *) src->nacks->data; +} + +void +rtp_source_clear_nacks (RTPSource * src) +{ + g_array_set_size (src->nacks, 0); + src->send_nack = FALSE; +} diff --git a/gst/rtpmanager/rtpsource.h b/gst/rtpmanager/rtpsource.h index bde29df..09a339b 100644 --- a/gst/rtpmanager/rtpsource.h +++ b/gst/rtpmanager/rtpsource.h @@ -187,6 +187,10 @@ struct _RTPSource { gboolean send_fir; guint8 current_send_fir_seqnum; gint last_fir_count; + + gboolean send_nack; + GArray *nacks; + }; struct _RTPSourceClass { @@ -268,10 +272,13 @@ void rtp_source_timeout (RTPSource * src, void rtp_source_retain_rtcp_packet (RTPSource * src, GstRTCPPacket *pkt, GstClockTime running_time); - gboolean rtp_source_has_retained (RTPSource * src, GCompareFunc func, gconstpointer data); +void rtp_source_register_nack (RTPSource * src, + guint16 seqnum); +guint32 * rtp_source_get_nacks (RTPSource * src, guint *n_nacks); +void rtp_source_clear_nacks (RTPSource * src); #endif /* __RTP_SOURCE_H__ */