mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 11:45:25 +00:00
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.
This commit is contained in:
parent
50638b8106
commit
4379ed1dee
2 changed files with 83 additions and 1 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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__ */
|
||||
|
|
Loading…
Reference in a new issue