mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +00:00
rtpjitterbuffer: rework packet insert
Rework the packet queue so that the most common action (insert a packet at the tail of the queue) goes very fast. Report if a packet was inserted at the head instead of the tail so that we can know when to retry _pop or _peek.
This commit is contained in:
parent
9994ff2c6c
commit
18b69419fd
2 changed files with 34 additions and 31 deletions
|
@ -626,23 +626,20 @@ queue_do_insert (RTPJitterBuffer * jbuf, GList * list, GList * item)
|
||||||
{
|
{
|
||||||
GQueue *queue = jbuf->packets;
|
GQueue *queue = jbuf->packets;
|
||||||
|
|
||||||
/* It's more likely that the packet was inserted in the front of the buffer */
|
/* It's more likely that the packet was inserted at the tail of the queue */
|
||||||
if (G_LIKELY (list)) {
|
if (G_LIKELY (list)) {
|
||||||
item->prev = list->prev;
|
item->prev = list;
|
||||||
item->next = list;
|
item->next = list->next;
|
||||||
list->prev = item;
|
list->next = item;
|
||||||
if (item->prev) {
|
|
||||||
item->prev->next = item;
|
|
||||||
} else {
|
|
||||||
queue->head = item;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
queue->tail = g_list_concat (queue->tail, item);
|
item->prev = NULL;
|
||||||
if (queue->tail->next)
|
item->next = queue->head;
|
||||||
queue->tail = queue->tail->next;
|
queue->head = item;
|
||||||
else
|
|
||||||
queue->head = queue->tail;
|
|
||||||
}
|
}
|
||||||
|
if (item->next)
|
||||||
|
item->next->prev = item;
|
||||||
|
else
|
||||||
|
queue->tail = item;
|
||||||
queue->length++;
|
queue->length++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -650,20 +647,24 @@ queue_do_insert (RTPJitterBuffer * jbuf, GList * list, GList * item)
|
||||||
* rtp_jitter_buffer_insert:
|
* rtp_jitter_buffer_insert:
|
||||||
* @jbuf: an #RTPJitterBuffer
|
* @jbuf: an #RTPJitterBuffer
|
||||||
* @item: an #RTPJitterBufferItem to insert
|
* @item: an #RTPJitterBufferItem to insert
|
||||||
* @tail: TRUE when the tail element changed.
|
* @head: TRUE when the head element changed.
|
||||||
* @percent: the buffering percent after insertion
|
* @percent: the buffering percent after insertion
|
||||||
*
|
*
|
||||||
* Inserts @item into the packet queue of @jbuf. The sequence number of the
|
* Inserts @item into the packet queue of @jbuf. The sequence number of the
|
||||||
* packet will be used to sort the packets. This function takes ownerhip of
|
* packet will be used to sort the packets. This function takes ownerhip of
|
||||||
* @buf when the function returns %TRUE.
|
* @buf when the function returns %TRUE.
|
||||||
*
|
*
|
||||||
|
* When @head is %TRUE, the new packet was added at the head of the queue and
|
||||||
|
* will be available with the next call to rtp_jitter_buffer_pop() and
|
||||||
|
* rtp_jitter_buffer_peek().
|
||||||
|
*
|
||||||
* Returns: %FALSE if a packet with the same number already existed.
|
* Returns: %FALSE if a packet with the same number already existed.
|
||||||
*/
|
*/
|
||||||
gboolean
|
gboolean
|
||||||
rtp_jitter_buffer_insert (RTPJitterBuffer * jbuf, RTPJitterBufferItem * item,
|
rtp_jitter_buffer_insert (RTPJitterBuffer * jbuf, RTPJitterBufferItem * item,
|
||||||
gboolean * tail, gint * percent)
|
gboolean * head, gint * percent)
|
||||||
{
|
{
|
||||||
GList *list = NULL;
|
GList *list;
|
||||||
guint32 rtptime;
|
guint32 rtptime;
|
||||||
guint16 seqnum;
|
guint16 seqnum;
|
||||||
GstClockTime dts;
|
GstClockTime dts;
|
||||||
|
@ -671,21 +672,22 @@ rtp_jitter_buffer_insert (RTPJitterBuffer * jbuf, RTPJitterBufferItem * item,
|
||||||
g_return_val_if_fail (jbuf != NULL, FALSE);
|
g_return_val_if_fail (jbuf != NULL, FALSE);
|
||||||
g_return_val_if_fail (item != NULL, FALSE);
|
g_return_val_if_fail (item != NULL, FALSE);
|
||||||
|
|
||||||
|
list = jbuf->packets->tail;
|
||||||
|
|
||||||
/* no seqnum, simply append then */
|
/* no seqnum, simply append then */
|
||||||
if (item->seqnum == -1) {
|
if (item->seqnum == -1)
|
||||||
goto append;
|
goto append;
|
||||||
}
|
|
||||||
|
|
||||||
seqnum = item->seqnum;
|
seqnum = item->seqnum;
|
||||||
|
|
||||||
/* loop the list to skip strictly smaller seqnum buffers */
|
/* loop the list to skip strictly larger seqnum buffers */
|
||||||
for (list = jbuf->packets->head; list; list = g_list_next (list)) {
|
for (; list; list = g_list_previous (list)) {
|
||||||
guint16 qseq;
|
guint16 qseq;
|
||||||
gint gap;
|
gint gap;
|
||||||
RTPJitterBufferItem *qitem = (RTPJitterBufferItem *) list;
|
RTPJitterBufferItem *qitem = (RTPJitterBufferItem *) list;
|
||||||
|
|
||||||
if (qitem->seqnum == -1)
|
if (qitem->seqnum == -1)
|
||||||
continue;
|
break;
|
||||||
|
|
||||||
qseq = qitem->seqnum;
|
qseq = qitem->seqnum;
|
||||||
|
|
||||||
|
@ -696,8 +698,8 @@ rtp_jitter_buffer_insert (RTPJitterBuffer * jbuf, RTPJitterBufferItem * item,
|
||||||
if (G_UNLIKELY (gap == 0))
|
if (G_UNLIKELY (gap == 0))
|
||||||
goto duplicate;
|
goto duplicate;
|
||||||
|
|
||||||
/* seqnum < qseq, we can stop looking */
|
/* seqnum > qseq, we can stop looking */
|
||||||
if (G_LIKELY (gap > 0))
|
if (G_LIKELY (gap < 0))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -762,10 +764,10 @@ append:
|
||||||
else if (percent)
|
else if (percent)
|
||||||
*percent = -1;
|
*percent = -1;
|
||||||
|
|
||||||
/* tail was changed when we did not find a previous packet, we set the return
|
/* head was changed when we did not find a previous packet, we set the return
|
||||||
* flag when requested. */
|
* flag when requested. */
|
||||||
if (G_LIKELY (tail))
|
if (G_LIKELY (head))
|
||||||
*tail = (list == NULL);
|
*head = (list == NULL);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
@ -821,9 +823,10 @@ rtp_jitter_buffer_pop (RTPJitterBuffer * jbuf, gint * percent)
|
||||||
* rtp_jitter_buffer_peek:
|
* rtp_jitter_buffer_peek:
|
||||||
* @jbuf: an #RTPJitterBuffer
|
* @jbuf: an #RTPJitterBuffer
|
||||||
*
|
*
|
||||||
* Peek the oldest buffer from the packet queue of @jbuf. Register a callback
|
* Peek the oldest buffer from the packet queue of @jbuf.
|
||||||
* with rtp_jitter_buffer_set_tail_changed() to be notified when an older packet
|
*
|
||||||
* was inserted in the queue.
|
* See rtp_jitter_buffer_insert() to check when an older packet was
|
||||||
|
* added.
|
||||||
*
|
*
|
||||||
* Returns: a #GstBuffer or %NULL when there was no packet in the queue.
|
* Returns: a #GstBuffer or %NULL when there was no packet in the queue.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -153,7 +153,7 @@ void rtp_jitter_buffer_reset_skew (RTPJitterBuffer *jbuf)
|
||||||
|
|
||||||
gboolean rtp_jitter_buffer_insert (RTPJitterBuffer *jbuf,
|
gboolean rtp_jitter_buffer_insert (RTPJitterBuffer *jbuf,
|
||||||
RTPJitterBufferItem *item,
|
RTPJitterBufferItem *item,
|
||||||
gboolean *tail, gint *percent);
|
gboolean *head, gint *percent);
|
||||||
|
|
||||||
void rtp_jitter_buffer_disable_buffering (RTPJitterBuffer *jbuf, gboolean disabled);
|
void rtp_jitter_buffer_disable_buffering (RTPJitterBuffer *jbuf, gboolean disabled);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue