mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-23 06:26:23 +00:00
rtprtxsend: keep important buffer information in a private structure
This is to avoid mapping a buffer every time we need to read a seqnum or a timestamp.
This commit is contained in:
parent
f7277db9e4
commit
920a55532c
1 changed files with 42 additions and 24 deletions
|
@ -91,6 +91,20 @@ static void gst_rtp_rtx_send_finalize (GObject * object);
|
||||||
|
|
||||||
G_DEFINE_TYPE (GstRtpRtxSend, gst_rtp_rtx_send, GST_TYPE_ELEMENT);
|
G_DEFINE_TYPE (GstRtpRtxSend, gst_rtp_rtx_send, GST_TYPE_ELEMENT);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
guint16 seqnum;
|
||||||
|
guint32 timestamp;
|
||||||
|
GstBuffer *buffer;
|
||||||
|
} BufferQueueItem;
|
||||||
|
|
||||||
|
static void
|
||||||
|
buffer_queue_item_free (BufferQueueItem * item)
|
||||||
|
{
|
||||||
|
gst_buffer_unref (item->buffer);
|
||||||
|
g_free (item);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_rtp_rtx_send_class_init (GstRtpRtxSendClass * klass)
|
gst_rtp_rtx_send_class_init (GstRtpRtxSendClass * klass)
|
||||||
{
|
{
|
||||||
|
@ -149,7 +163,7 @@ static void
|
||||||
gst_rtp_rtx_send_reset (GstRtpRtxSend * rtx, gboolean full)
|
gst_rtp_rtx_send_reset (GstRtpRtxSend * rtx, gboolean full)
|
||||||
{
|
{
|
||||||
g_mutex_lock (&rtx->lock);
|
g_mutex_lock (&rtx->lock);
|
||||||
g_queue_foreach (rtx->queue, (GFunc) gst_buffer_unref, NULL);
|
g_queue_foreach (rtx->queue, (GFunc) buffer_queue_item_free, NULL);
|
||||||
g_queue_clear (rtx->queue);
|
g_queue_clear (rtx->queue);
|
||||||
g_list_foreach (rtx->pending, (GFunc) gst_buffer_unref, NULL);
|
g_list_foreach (rtx->pending, (GFunc) gst_buffer_unref, NULL);
|
||||||
g_list_free (rtx->pending);
|
g_list_free (rtx->pending);
|
||||||
|
@ -233,26 +247,18 @@ typedef struct
|
||||||
/* traverse queue history and try to find the buffer that the
|
/* traverse queue history and try to find the buffer that the
|
||||||
* requested seqnum */
|
* requested seqnum */
|
||||||
static void
|
static void
|
||||||
push_seqnum (GstBuffer * buffer, RTXData * data)
|
push_seqnum (BufferQueueItem * item, RTXData * data)
|
||||||
{
|
{
|
||||||
GstRtpRtxSend *rtx = data->rtx;
|
GstRtpRtxSend *rtx = data->rtx;
|
||||||
GstRTPBuffer rtpbuffer = GST_RTP_BUFFER_INIT;
|
|
||||||
guint16 seqnum;
|
|
||||||
|
|
||||||
if (data->found)
|
if (data->found)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtpbuffer))
|
|
||||||
return;
|
|
||||||
|
|
||||||
seqnum = gst_rtp_buffer_get_seq (&rtpbuffer);
|
|
||||||
gst_rtp_buffer_unmap (&rtpbuffer);
|
|
||||||
|
|
||||||
/* data->seqnum comes from the request */
|
/* data->seqnum comes from the request */
|
||||||
if (seqnum == data->seqnum) {
|
if (item->seqnum == data->seqnum) {
|
||||||
data->found = TRUE;
|
data->found = TRUE;
|
||||||
GST_DEBUG_OBJECT (rtx, "found %" G_GUINT16_FORMAT, seqnum);
|
GST_DEBUG_OBJECT (rtx, "found %" G_GUINT16_FORMAT, item->seqnum);
|
||||||
rtx->pending = g_list_prepend (rtx->pending, gst_buffer_ref (buffer));
|
rtx->pending = g_list_prepend (rtx->pending, gst_buffer_ref (item->buffer));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -431,42 +437,54 @@ gst_rtp_rtx_send_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
|
||||||
GstFlowReturn ret = GST_FLOW_ERROR;
|
GstFlowReturn ret = GST_FLOW_ERROR;
|
||||||
GList *pending = NULL;
|
GList *pending = NULL;
|
||||||
GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
|
GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
|
||||||
guint seqnum = 0;
|
BufferQueueItem *item;
|
||||||
|
guint16 seqnum;
|
||||||
|
guint32 ssrc, rtptime;
|
||||||
|
|
||||||
|
rtx = GST_RTP_RTX_SEND (parent);
|
||||||
|
|
||||||
|
/* read the information we want from the buffer */
|
||||||
|
gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp);
|
||||||
|
seqnum = gst_rtp_buffer_get_seq (&rtp);
|
||||||
|
ssrc = gst_rtp_buffer_get_ssrc (&rtp);
|
||||||
|
rtptime = gst_rtp_buffer_get_timestamp (&rtp);
|
||||||
|
gst_rtp_buffer_unmap (&rtp);
|
||||||
|
|
||||||
g_mutex_lock (&rtx->lock);
|
g_mutex_lock (&rtx->lock);
|
||||||
|
|
||||||
/* retrievemaster stream ssrc */
|
/* retrieve master stream ssrc */
|
||||||
gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp);
|
rtx->master_ssrc = ssrc;
|
||||||
rtx->master_ssrc = gst_rtp_buffer_get_ssrc (&rtp);
|
|
||||||
seqnum = gst_rtp_buffer_get_seq (&rtp);
|
|
||||||
gst_rtp_buffer_unmap (&rtp);
|
|
||||||
|
|
||||||
/* check if our initial aux ssrc is equal to master */
|
/* check if our initial aux ssrc is equal to master */
|
||||||
if (rtx->rtx_ssrc == rtx->master_ssrc)
|
if (rtx->rtx_ssrc == rtx->master_ssrc)
|
||||||
choose_ssrc (rtx);
|
choose_ssrc (rtx);
|
||||||
|
|
||||||
/* add current rtp buffer to queue history */
|
/* add current rtp buffer to queue history */
|
||||||
g_queue_push_head (rtx->queue, gst_buffer_ref (buffer));
|
item = g_new0 (BufferQueueItem, 1);
|
||||||
|
item->seqnum = seqnum;
|
||||||
|
item->timestamp = rtptime;
|
||||||
|
item->buffer = gst_buffer_ref (buffer);
|
||||||
|
g_queue_push_head (rtx->queue, item);
|
||||||
|
|
||||||
/* remove oldest packets from history if they are too many */
|
/* remove oldest packets from history if they are too many */
|
||||||
if (rtx->max_size_packets) {
|
if (rtx->max_size_packets) {
|
||||||
while (g_queue_get_length (rtx->queue) > rtx->max_size_packets)
|
while (g_queue_get_length (rtx->queue) > rtx->max_size_packets)
|
||||||
gst_buffer_unref (g_queue_pop_tail (rtx->queue));
|
buffer_queue_item_free (g_queue_pop_tail (rtx->queue));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* within lock, get packets that have to be retransmited */
|
/* within lock, get packets that have to be retransmited */
|
||||||
pending = rtx->pending;
|
pending = rtx->pending;
|
||||||
rtx->pending = NULL;
|
rtx->pending = NULL;
|
||||||
|
|
||||||
/* assume we will succeed to retransmit those packets */
|
/* update statistics - assume we will succeed to retransmit those packets */
|
||||||
rtx->num_rtx_packets += g_list_length (pending);
|
rtx->num_rtx_packets += g_list_length (pending);
|
||||||
|
|
||||||
/* transfer payload type while holding the lock */
|
/* transfer payload type while holding the lock */
|
||||||
rtx->rtx_payload_type = rtx->rtx_payload_type_pending;
|
rtx->rtx_payload_type = rtx->rtx_payload_type_pending;
|
||||||
|
|
||||||
|
/* no need to hold the lock to push rtx packets */
|
||||||
g_mutex_unlock (&rtx->lock);
|
g_mutex_unlock (&rtx->lock);
|
||||||
|
|
||||||
/* no need to hold the lock to push rtx packets */
|
/* retransmit requested packets */
|
||||||
g_list_foreach (pending, (GFunc) do_push, rtx);
|
g_list_foreach (pending, (GFunc) do_push, rtx);
|
||||||
g_list_foreach (pending, (GFunc) gst_buffer_unref, NULL);
|
g_list_foreach (pending, (GFunc) gst_buffer_unref, NULL);
|
||||||
g_list_free (pending);
|
g_list_free (pending);
|
||||||
|
|
Loading…
Reference in a new issue