summaryrefslogtreecommitdiff
path: root/gst
diff options
context:
space:
mode:
authorHavard Graff <havard.graff@gmail.com>2016-11-01 16:03:00 +0100
committerTim-Philipp Müller <tim@centricular.com>2017-11-25 11:10:27 +0000
commitb8b4124c8b55d884ec0a01c48744285e78ad449e (patch)
tree7d5115a2e49ee303ae4ea4aec602bd15ec7d15e7 /gst
parentc9002e3dd52614a7df1a0992fe4a8453a74cda81 (diff)
downloadgstreamer-plugins-bad-b8b4124c8b55d884ec0a01c48744285e78ad449e.tar.gz
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.
Diffstat (limited to 'gst')
-rw-r--r--gst/netsim/gstnetsim.c53
-rw-r--r--gst/netsim/gstnetsim.h2
2 files changed, 52 insertions, 3 deletions
diff --git a/gst/netsim/gstnetsim.c b/gst/netsim/gstnetsim.c
index 29a2f7044..24ea04a68 100644
--- a/gst/netsim/gstnetsim.c
+++ b/gst/netsim/gstnetsim.c
@@ -65,6 +65,7 @@ enum
PROP_DROP_PACKETS,
PROP_MAX_KBPS,
PROP_MAX_BUCKET_SIZE,
+ PROP_ALLOW_REORDERING,
};
/* these numbers are nothing but wild guesses and dont reflect any reality */
@@ -77,6 +78,7 @@ enum
#define DEFAULT_DROP_PACKETS 0
#define DEFAULT_MAX_KBPS -1
#define DEFAULT_MAX_BUCKET_SIZE -1
+#define DEFAULT_ALLOW_REORDERING TRUE
static GstStaticPadTemplate gst_net_sim_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
@@ -92,6 +94,21 @@ GST_STATIC_PAD_TEMPLATE ("src",
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
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);
}
-
static GstFlowReturn
gst_net_sim_delay_buffer (GstNetSim * netsim, GstBuffer * buf)
{
@@ -321,6 +337,7 @@ gst_net_sim_delay_buffer (GstNetSim * netsim, GstBuffer * buf)
gint delay;
PushBufferCtx *ctx;
GSource *source;
+ gint64 ready_time;
switch (netsim->delay_distribution) {
case DISTRIBUTION_UNIFORM:
@@ -344,9 +361,17 @@ gst_net_sim_delay_buffer (GstNetSim * netsim, GstBuffer * buf)
delay = 0;
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,
ctx, (GDestroyNotify) push_buffer_ctx_free);
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)
netsim->bucket_size = netsim->max_bucket_size * 1000;
break;
+ case PROP_ALLOW_REORDERING:
+ netsim->allow_reordering = g_value_get_boolean (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -558,6 +586,9 @@ gst_net_sim_get_property (GObject * object,
case PROP_MAX_BUCKET_SIZE:
g_value_set_int (value, netsim->max_bucket_size);
break;
+ case PROP_ALLOW_REORDERING:
+ g_value_set_boolean (value, netsim->allow_reordering);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -714,6 +745,22 @@ gst_net_sim_class_init (GstNetSimClass * klass)
"(-1 = unlimited)", -1, G_MAXINT, DEFAULT_MAX_BUCKET_SIZE,
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");
}
diff --git a/gst/netsim/gstnetsim.h b/gst/netsim/gstnetsim.h
index c9e32d8fd..bfbfa3f9f 100644
--- a/gst/netsim/gstnetsim.h
+++ b/gst/netsim/gstnetsim.h
@@ -75,6 +75,7 @@ struct _GstNetSim
gsize bucket_size;
GstClockTime prev_time;
NormalDistributionState delay_state;
+ gint64 last_ready_time;
/* properties */
gint min_delay;
@@ -86,6 +87,7 @@ struct _GstNetSim
guint drop_packets;
gint max_kbps;
gint max_bucket_size;
+ gboolean allow_reordering;
};
struct _GstNetSimClass