mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 04:56:14 +00:00
rtprtxsend: Handle the max_size_time property
This property allows you to specify the amount of buffers to keep in the retransmission queue expressed as time (ms) instead of buffer count (which is the max_size_buffers property).
This commit is contained in:
parent
920a55532c
commit
7d530ab59f
2 changed files with 68 additions and 1 deletions
|
@ -77,6 +77,8 @@ static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
|
||||||
|
|
||||||
static gboolean gst_rtp_rtx_send_src_event (GstPad * pad, GstObject * parent,
|
static gboolean gst_rtp_rtx_send_src_event (GstPad * pad, GstObject * parent,
|
||||||
GstEvent * event);
|
GstEvent * event);
|
||||||
|
static gboolean gst_rtp_rtx_send_sink_event (GstPad * pad, GstObject * parent,
|
||||||
|
GstEvent * event);
|
||||||
static GstFlowReturn gst_rtp_rtx_send_chain (GstPad * pad, GstObject * parent,
|
static GstFlowReturn gst_rtp_rtx_send_chain (GstPad * pad, GstObject * parent,
|
||||||
GstBuffer * buffer);
|
GstBuffer * buffer);
|
||||||
|
|
||||||
|
@ -125,7 +127,7 @@ gst_rtp_rtx_send_class_init (GstRtpRtxSendClass * klass)
|
||||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
g_object_class_install_property (gobject_class, PROP_MAX_SIZE_TIME,
|
g_object_class_install_property (gobject_class, PROP_MAX_SIZE_TIME,
|
||||||
g_param_spec_uint ("max-size-time", "Max Size Times",
|
g_param_spec_uint ("max-size-time", "Max Size Time",
|
||||||
"Amount of ms to queue (0 = unlimited)", 0, G_MAXUINT,
|
"Amount of ms to queue (0 = unlimited)", 0, G_MAXUINT,
|
||||||
DEFAULT_MAX_SIZE_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
DEFAULT_MAX_SIZE_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
|
@ -207,6 +209,8 @@ gst_rtp_rtx_send_init (GstRtpRtxSend * rtx)
|
||||||
"sink"), "sink");
|
"sink"), "sink");
|
||||||
GST_PAD_SET_PROXY_CAPS (rtx->sinkpad);
|
GST_PAD_SET_PROXY_CAPS (rtx->sinkpad);
|
||||||
GST_PAD_SET_PROXY_ALLOCATION (rtx->sinkpad);
|
GST_PAD_SET_PROXY_ALLOCATION (rtx->sinkpad);
|
||||||
|
gst_pad_set_event_function (rtx->sinkpad,
|
||||||
|
GST_DEBUG_FUNCPTR (gst_rtp_rtx_send_sink_event));
|
||||||
gst_pad_set_chain_function (rtx->sinkpad,
|
gst_pad_set_chain_function (rtx->sinkpad,
|
||||||
GST_DEBUG_FUNCPTR (gst_rtp_rtx_send_chain));
|
GST_DEBUG_FUNCPTR (gst_rtp_rtx_send_chain));
|
||||||
gst_element_add_pad (GST_ELEMENT (rtx), rtx->sinkpad);
|
gst_element_add_pad (GST_ELEMENT (rtx), rtx->sinkpad);
|
||||||
|
@ -356,6 +360,61 @@ gst_rtp_rtx_send_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_rtp_rtx_send_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
|
||||||
|
{
|
||||||
|
GstRtpRtxSend *rtx = GST_RTP_RTX_SEND (parent);
|
||||||
|
|
||||||
|
switch (GST_EVENT_TYPE (event)) {
|
||||||
|
case GST_EVENT_CAPS:
|
||||||
|
{
|
||||||
|
GstCaps *caps;
|
||||||
|
GstStructure *s;
|
||||||
|
|
||||||
|
gst_event_parse_caps (event, &caps);
|
||||||
|
g_assert (gst_caps_is_fixed (caps));
|
||||||
|
|
||||||
|
s = gst_caps_get_structure (caps, 0);
|
||||||
|
gst_structure_get_int (s, "clock-rate", &rtx->clock_rate);
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (rtx, "got clock-rate from caps: %d", rtx->clock_rate);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return gst_pad_event_default (pad, parent, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* like rtp_jitter_buffer_get_ts_diff() */
|
||||||
|
static guint32
|
||||||
|
gst_rtp_rtx_send_get_ts_diff (GstRtpRtxSend * self)
|
||||||
|
{
|
||||||
|
guint64 high_ts, low_ts;
|
||||||
|
BufferQueueItem *high_buf, *low_buf;
|
||||||
|
guint32 result;
|
||||||
|
|
||||||
|
high_buf = g_queue_peek_head (self->queue);
|
||||||
|
low_buf = g_queue_peek_tail (self->queue);
|
||||||
|
|
||||||
|
if (!high_buf || !low_buf || high_buf == low_buf)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
high_ts = high_buf->timestamp;
|
||||||
|
low_ts = low_buf->timestamp;
|
||||||
|
|
||||||
|
/* it needs to work if ts wraps */
|
||||||
|
if (high_ts >= low_ts) {
|
||||||
|
result = (guint32) (high_ts - low_ts);
|
||||||
|
} else {
|
||||||
|
result = (guint32) (high_ts + G_MAXUINT32 + 1 - low_ts);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return value in ms instead of clock ticks */
|
||||||
|
return (guint32) gst_util_uint64_scale_int (result, 1000, self->clock_rate);
|
||||||
|
}
|
||||||
|
|
||||||
/* Copy fixed header and extension. Add OSN before to copy payload
|
/* Copy fixed header and extension. Add OSN before to copy payload
|
||||||
* Copy memory to avoid to manually copy each rtp buffer field.
|
* Copy memory to avoid to manually copy each rtp buffer field.
|
||||||
*/
|
*/
|
||||||
|
@ -470,6 +529,10 @@ gst_rtp_rtx_send_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
|
||||||
while (g_queue_get_length (rtx->queue) > rtx->max_size_packets)
|
while (g_queue_get_length (rtx->queue) > rtx->max_size_packets)
|
||||||
buffer_queue_item_free (g_queue_pop_tail (rtx->queue));
|
buffer_queue_item_free (g_queue_pop_tail (rtx->queue));
|
||||||
}
|
}
|
||||||
|
if (rtx->max_size_time) {
|
||||||
|
while (gst_rtp_rtx_send_get_ts_diff (rtx) > rtx->max_size_time)
|
||||||
|
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;
|
||||||
|
|
|
@ -57,8 +57,12 @@ struct _GstRtpRtxSend
|
||||||
guint16 next_seqnum;
|
guint16 next_seqnum;
|
||||||
guint8 rtx_payload_type;
|
guint8 rtx_payload_type;
|
||||||
|
|
||||||
|
gint clock_rate;
|
||||||
|
|
||||||
/* retreived from SDP */
|
/* retreived from SDP */
|
||||||
guint rtx_payload_type_pending;
|
guint rtx_payload_type_pending;
|
||||||
|
|
||||||
|
/* buffering control properties */
|
||||||
guint max_size_time;
|
guint max_size_time;
|
||||||
guint max_size_packets;
|
guint max_size_packets;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue