mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
netsim: add "allow-reordering" property
Reordering of packets is not very common in networks, and the delay functions will always introduce reordering if delay > packet-spacing, so by setting allow-reordering to FALSE you guarantee that the packets are in order, while at the same time introducing delay/jitter to them.
This commit is contained in:
parent
c9002e3dd5
commit
b8b4124c8b
2 changed files with 52 additions and 3 deletions
|
@ -65,6 +65,7 @@ enum
|
||||||
PROP_DROP_PACKETS,
|
PROP_DROP_PACKETS,
|
||||||
PROP_MAX_KBPS,
|
PROP_MAX_KBPS,
|
||||||
PROP_MAX_BUCKET_SIZE,
|
PROP_MAX_BUCKET_SIZE,
|
||||||
|
PROP_ALLOW_REORDERING,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* these numbers are nothing but wild guesses and dont reflect any reality */
|
/* these numbers are nothing but wild guesses and dont reflect any reality */
|
||||||
|
@ -77,6 +78,7 @@ enum
|
||||||
#define DEFAULT_DROP_PACKETS 0
|
#define DEFAULT_DROP_PACKETS 0
|
||||||
#define DEFAULT_MAX_KBPS -1
|
#define DEFAULT_MAX_KBPS -1
|
||||||
#define DEFAULT_MAX_BUCKET_SIZE -1
|
#define DEFAULT_MAX_BUCKET_SIZE -1
|
||||||
|
#define DEFAULT_ALLOW_REORDERING TRUE
|
||||||
|
|
||||||
static GstStaticPadTemplate gst_net_sim_sink_template =
|
static GstStaticPadTemplate gst_net_sim_sink_template =
|
||||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||||
|
@ -92,6 +94,21 @@ GST_STATIC_PAD_TEMPLATE ("src",
|
||||||
|
|
||||||
G_DEFINE_TYPE (GstNetSim, gst_net_sim, GST_TYPE_ELEMENT);
|
G_DEFINE_TYPE (GstNetSim, gst_net_sim, GST_TYPE_ELEMENT);
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_net_sim_source_dispatch (GSource * source,
|
||||||
|
GSourceFunc callback, gpointer user_data)
|
||||||
|
{
|
||||||
|
callback (user_data);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
GSourceFuncs gst_net_sim_source_funcs = {
|
||||||
|
NULL, /* prepare */
|
||||||
|
NULL, /* check */
|
||||||
|
gst_net_sim_source_dispatch,
|
||||||
|
NULL /* finalize */
|
||||||
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_net_sim_loop (GstNetSim * netsim)
|
gst_net_sim_loop (GstNetSim * netsim)
|
||||||
{
|
{
|
||||||
|
@ -309,7 +326,6 @@ get_random_value_gamma (GRand * rand_seed, gint32 low, gint32 high,
|
||||||
return round (x + low);
|
return round (x + low);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_net_sim_delay_buffer (GstNetSim * netsim, GstBuffer * buf)
|
gst_net_sim_delay_buffer (GstNetSim * netsim, GstBuffer * buf)
|
||||||
{
|
{
|
||||||
|
@ -321,6 +337,7 @@ gst_net_sim_delay_buffer (GstNetSim * netsim, GstBuffer * buf)
|
||||||
gint delay;
|
gint delay;
|
||||||
PushBufferCtx *ctx;
|
PushBufferCtx *ctx;
|
||||||
GSource *source;
|
GSource *source;
|
||||||
|
gint64 ready_time;
|
||||||
|
|
||||||
switch (netsim->delay_distribution) {
|
switch (netsim->delay_distribution) {
|
||||||
case DISTRIBUTION_UNIFORM:
|
case DISTRIBUTION_UNIFORM:
|
||||||
|
@ -344,9 +361,17 @@ gst_net_sim_delay_buffer (GstNetSim * netsim, GstBuffer * buf)
|
||||||
delay = 0;
|
delay = 0;
|
||||||
|
|
||||||
ctx = push_buffer_ctx_new (netsim->srcpad, buf);
|
ctx = push_buffer_ctx_new (netsim->srcpad, buf);
|
||||||
source = g_timeout_source_new (delay);
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (netsim, "Delaying packet by %d", delay);
|
source = g_source_new (&gst_net_sim_source_funcs, sizeof (GSource));
|
||||||
|
ready_time = g_get_monotonic_time () + delay * 1000;
|
||||||
|
if (!netsim->allow_reordering && ready_time < netsim->last_ready_time)
|
||||||
|
ready_time = netsim->last_ready_time + 1;
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (netsim, "Delaying packet by %ldms",
|
||||||
|
(ready_time - netsim->last_ready_time) / 1000);
|
||||||
|
netsim->last_ready_time = ready_time;
|
||||||
|
|
||||||
|
g_source_set_ready_time (source, ready_time);
|
||||||
g_source_set_callback (source, (GSourceFunc) push_buffer_ctx_push,
|
g_source_set_callback (source, (GSourceFunc) push_buffer_ctx_push,
|
||||||
ctx, (GDestroyNotify) push_buffer_ctx_free);
|
ctx, (GDestroyNotify) push_buffer_ctx_free);
|
||||||
g_source_attach (source, g_main_loop_get_context (netsim->main_loop));
|
g_source_attach (source, g_main_loop_get_context (netsim->main_loop));
|
||||||
|
@ -518,6 +543,9 @@ gst_net_sim_set_property (GObject * object,
|
||||||
if (netsim->max_bucket_size != -1)
|
if (netsim->max_bucket_size != -1)
|
||||||
netsim->bucket_size = netsim->max_bucket_size * 1000;
|
netsim->bucket_size = netsim->max_bucket_size * 1000;
|
||||||
break;
|
break;
|
||||||
|
case PROP_ALLOW_REORDERING:
|
||||||
|
netsim->allow_reordering = g_value_get_boolean (value);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -558,6 +586,9 @@ gst_net_sim_get_property (GObject * object,
|
||||||
case PROP_MAX_BUCKET_SIZE:
|
case PROP_MAX_BUCKET_SIZE:
|
||||||
g_value_set_int (value, netsim->max_bucket_size);
|
g_value_set_int (value, netsim->max_bucket_size);
|
||||||
break;
|
break;
|
||||||
|
case PROP_ALLOW_REORDERING:
|
||||||
|
g_value_set_boolean (value, netsim->allow_reordering);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -714,6 +745,22 @@ gst_net_sim_class_init (GstNetSimClass * klass)
|
||||||
"(-1 = unlimited)", -1, G_MAXINT, DEFAULT_MAX_BUCKET_SIZE,
|
"(-1 = unlimited)", -1, G_MAXINT, DEFAULT_MAX_BUCKET_SIZE,
|
||||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstNetSim:allow-reordering:
|
||||||
|
*
|
||||||
|
* When delaying packets, are they allowed to be reordered or not. By
|
||||||
|
* default this is enabled, but in the real world packet reordering is
|
||||||
|
* fairly uncommon, yet the delay functions will always introduce reordering
|
||||||
|
* if delay > packet-spacing, This property allows switching that off.
|
||||||
|
*
|
||||||
|
* Since: 1.14
|
||||||
|
*/
|
||||||
|
g_object_class_install_property (gobject_class, PROP_ALLOW_REORDERING,
|
||||||
|
g_param_spec_boolean ("allow-reordering", "Allow Reordering",
|
||||||
|
"When delaying packets, are they allowed to be reordered or not",
|
||||||
|
DEFAULT_ALLOW_REORDERING,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_INIT (netsim_debug, "netsim", 0, "Network simulator");
|
GST_DEBUG_CATEGORY_INIT (netsim_debug, "netsim", 0, "Network simulator");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,6 +75,7 @@ struct _GstNetSim
|
||||||
gsize bucket_size;
|
gsize bucket_size;
|
||||||
GstClockTime prev_time;
|
GstClockTime prev_time;
|
||||||
NormalDistributionState delay_state;
|
NormalDistributionState delay_state;
|
||||||
|
gint64 last_ready_time;
|
||||||
|
|
||||||
/* properties */
|
/* properties */
|
||||||
gint min_delay;
|
gint min_delay;
|
||||||
|
@ -86,6 +87,7 @@ struct _GstNetSim
|
||||||
guint drop_packets;
|
guint drop_packets;
|
||||||
gint max_kbps;
|
gint max_kbps;
|
||||||
gint max_bucket_size;
|
gint max_bucket_size;
|
||||||
|
gboolean allow_reordering;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstNetSimClass
|
struct _GstNetSimClass
|
||||||
|
|
Loading…
Reference in a new issue