+2004-09-03 Wim Taymans <wim@fluendo.com>
+
+ * gst/elements/gstfakesrc.c: (gst_fakesrc_class_init),
+ (gst_fakesrc_init), (gst_fakesrc_set_clock),
+ (gst_fakesrc_set_property), (gst_fakesrc_get_property),
+ (gst_fakesrc_get), (gst_fakesrc_change_state):
+ * gst/elements/gstfakesrc.h:
+ * gst/elements/gstidentity.c: (gst_identity_class_init),
+ (gst_identity_init), (gst_identity_chain),
+ (gst_identity_set_property), (gst_identity_get_property),
+ (gst_identity_change_state):
+ * gst/elements/gstidentity.h:
+ Added datarate properties to limit the datarate.
+
2004-08-25 Benjamin Otte <in7y118@public.uni-hamburg.de>
* gst/autoplug/gstspider.c: (plugin_init):
#define DEFAULT_SIZEMIN 0
#define DEFAULT_SIZEMAX 4096
#define DEFAULT_PARENTSIZE 4096*10
+#define DEFAULT_DATARATE 0
+#define DEFAULT_SYNC FALSE
static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
ARG_SIZEMIN,
ARG_SIZEMAX,
ARG_FILLTYPE,
+ ARG_DATARATE,
+ ARG_SYNC,
ARG_PATTERN,
ARG_NUM_BUFFERS,
ARG_EOS,
const GValue * value, GParamSpec * pspec);
static void gst_fakesrc_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
+static void gst_fakesrc_set_clock (GstElement * element, GstClock * clock);
static GstElementStateReturn gst_fakesrc_change_state (GstElement * element);
g_param_spec_enum ("filltype", "filltype",
"How to fill the buffer, if at all", GST_TYPE_FAKESRC_FILLTYPE,
FAKESRC_FILLTYPE_NULL, G_PARAM_READWRITE));
+ g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DATARATE,
+ g_param_spec_int ("datarate", "Datarate",
+ "Timestamps buffers with number of bytes per second (0 = none)", 0,
+ G_MAXINT, DEFAULT_DATARATE, G_PARAM_READWRITE));
+ g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SYNC,
+ g_param_spec_boolean ("sync", "Sync", "Sync to the clock to the datarate",
+ DEFAULT_SYNC, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PATTERN,
g_param_spec_string ("pattern", "pattern", "pattern", NULL,
G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NUM_BUFFERS,
g_param_spec_int ("num-buffers", "num-buffers",
- "Number of buffers to output before sending EOS", -1, G_MAXINT,
- 0, G_PARAM_READWRITE));
+ "Number of buffers to output before sending EOS", -1, G_MAXINT, 0,
+ G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_EOS,
g_param_spec_boolean ("eos", "eos", "Send out the EOS event?", TRUE,
G_PARAM_READWRITE));
gstelement_class->request_new_pad =
GST_DEBUG_FUNCPTR (gst_fakesrc_request_new_pad);
gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_fakesrc_change_state);
+ gstelement_class->set_clock = GST_DEBUG_FUNCPTR (gst_fakesrc_set_clock);
}
static void
fakesrc->parent = NULL;
fakesrc->parentsize = DEFAULT_PARENTSIZE;
fakesrc->last_message = NULL;
+ fakesrc->datarate = DEFAULT_DATARATE;
+ fakesrc->sync = DEFAULT_SYNC;
+}
+
+static void
+gst_fakesrc_set_clock (GstElement * element, GstClock * clock)
+{
+ GstFakeSrc *src;
+
+ src = GST_FAKESRC (element);
+
+ src->clock = clock;
}
+
static GstPad *
gst_fakesrc_request_new_pad (GstElement * element, GstPadTemplate * templ,
const gchar * unused)
case ARG_FILLTYPE:
src->filltype = g_value_get_enum (value);
break;
+ case ARG_DATARATE:
+ src->datarate = g_value_get_int (value);
+ break;
+ case ARG_SYNC:
+ src->sync = g_value_get_boolean (value);
+ break;
case ARG_PATTERN:
break;
case ARG_NUM_BUFFERS:
case ARG_FILLTYPE:
g_value_set_enum (value, src->filltype);
break;
+ case ARG_DATARATE:
+ g_value_set_int (value, src->datarate);
+ break;
+ case ARG_SYNC:
+ g_value_set_boolean (value, src->sync);
+ break;
case ARG_PATTERN:
g_value_set_string (value, src->pattern);
break;
}
buf = gst_fakesrc_create_buffer (src);
- GST_BUFFER_TIMESTAMP (buf) = src->buffer_count++;
+ GST_BUFFER_OFFSET (buf) = src->buffer_count++;
+
+ GstClockTime time = GST_CLOCK_TIME_NONE;
+
+ if (src->datarate > 0) {
+ time = (src->bytes_sent * GST_SECOND) / src->datarate;
+ if (src->sync) {
+ gst_element_wait (GST_ELEMENT (src), time);
+ }
+
+ GST_BUFFER_DURATION (buf) =
+ GST_BUFFER_SIZE (buf) * GST_SECOND / src->datarate;
+ }
+ GST_BUFFER_TIMESTAMP (buf) = time;
if (!src->silent) {
g_free (src->last_message);
GST_LOG_OBJECT (src, "post handoff emit");
}
+ src->bytes_sent += GST_BUFFER_SIZE (buf);
+
return GST_DATA (buf);
}
fakesrc->pattern_byte = 0x00;
fakesrc->need_flush = FALSE;
fakesrc->eos = FALSE;
+ fakesrc->bytes_sent = 0;
fakesrc->rt_num_buffers = fakesrc->num_buffers;
break;
case GST_STATE_PAUSED_TO_PLAYING:
guint8 pattern_byte;
gchar *pattern;
GList *patternlist;
+ gint datarate;
+ gboolean sync;
+ GstClock *clock;
gint64 segment_start;
gint64 segment_end;
gboolean segment_loop;
gboolean dump;
gboolean need_flush;
+ guint64 bytes_sent;
+
gchar *last_message;
};
LAST_SIGNAL
};
+#define DEFAULT_LOOP_BASED FALSE
+#define DEFAULT_SLEEP_TIME 0
+#define DEFAULT_DUPLICATE 1
+#define DEFAULT_ERROR_AFTER -1
+#define DEFAULT_DROP_PROBABILITY 0.0
+#define DEFAULT_DATARATE 0
+#define DEFAULT_SILENT FALSE
+#define DEFAULT_DUMP FALSE
+#define DEFAULT_SYNC FALSE
+#define DEFAULT_CHECK_PERFECT FALSE
+
enum
{
ARG_0,
ARG_DUPLICATE,
ARG_ERROR_AFTER,
ARG_DROP_PROBABILITY,
+ ARG_DATARATE,
ARG_SILENT,
ARG_LAST_MESSAGE,
ARG_DUMP,
const GValue * value, GParamSpec * pspec);
static void gst_identity_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
+static GstElementStateReturn gst_identity_change_state (GstElement * element);
static void gst_identity_chain (GstPad * pad, GstData * _data);
static void gst_identity_set_clock (GstElement * element, GstClock * clock);
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LOOP_BASED,
g_param_spec_boolean ("loop-based", "Loop-based",
"Set to TRUE to use loop-based rather than chain-based scheduling",
- TRUE, G_PARAM_READWRITE));
+ DEFAULT_LOOP_BASED, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SLEEP_TIME,
g_param_spec_uint ("sleep-time", "Sleep time",
- "Microseconds to sleep between processing", 0, G_MAXUINT, 0,
- G_PARAM_READWRITE));
+ "Microseconds to sleep between processing", 0, G_MAXUINT,
+ DEFAULT_SLEEP_TIME, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DUPLICATE,
g_param_spec_uint ("duplicate", "Duplicate Buffers",
- "Push the buffers N times", 0, G_MAXUINT, 1, G_PARAM_READWRITE));
+ "Push the buffers N times", 0, G_MAXUINT, DEFAULT_DUPLICATE,
+ G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ERROR_AFTER,
g_param_spec_int ("error_after", "Error After", "Error after N buffers",
- G_MININT, G_MAXINT, -1, G_PARAM_READWRITE));
+ G_MININT, G_MAXINT, DEFAULT_ERROR_AFTER, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DROP_PROBABILITY,
g_param_spec_float ("drop_probability", "Drop Probability",
- "The Probability a buffer is dropped", 0.0, 1.0, 0.0,
- G_PARAM_READWRITE));
+ "The Probability a buffer is dropped", 0.0, 1.0,
+ DEFAULT_DROP_PROBABILITY, G_PARAM_READWRITE));
+ g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DATARATE,
+ g_param_spec_int ("datarate", "Datarate",
+ "(Re)timestamps buffers with number of bytes per second (0 = inactive)",
+ 0, G_MAXINT, DEFAULT_DATARATE, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SILENT,
- g_param_spec_boolean ("silent", "silent", "silent", FALSE,
+ g_param_spec_boolean ("silent", "silent", "silent", DEFAULT_SILENT,
G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LAST_MESSAGE,
g_param_spec_string ("last-message", "last-message", "last-message", NULL,
G_PARAM_READABLE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DUMP,
- g_param_spec_boolean ("dump", "Dump", "Dump buffer contents", FALSE,
- G_PARAM_READWRITE));
+ g_param_spec_boolean ("dump", "Dump", "Dump buffer contents",
+ DEFAULT_DUMP, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SYNC,
g_param_spec_boolean ("sync", "Synchronize",
- "Synchronize to pipeline clock", FALSE, G_PARAM_READWRITE));
+ "Synchronize to pipeline clock", DEFAULT_SYNC, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_CHECK_PERFECT,
g_param_spec_boolean ("check-perfect", "Check For Perfect Stream",
- "Verify that the stream is time- and data-contiguous", FALSE,
- G_PARAM_READWRITE));
+ "Verify that the stream is time- and data-contiguous",
+ DEFAULT_CHECK_PERFECT, G_PARAM_READWRITE));
gst_identity_signals[SIGNAL_HANDOFF] =
g_signal_new ("handoff", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_identity_get_property);
gstelement_class->set_clock = GST_DEBUG_FUNCPTR (gst_identity_set_clock);
+ gstelement_class->change_state =
+ GST_DEBUG_FUNCPTR (gst_identity_change_state);
}
gst_pad_set_link_function (identity->srcpad, gst_pad_proxy_pad_link);
gst_pad_set_getcaps_function (identity->srcpad, gst_pad_proxy_getcaps);
- identity->loop_based = FALSE;
- identity->sleep_time = 0;
- identity->duplicate = 1;
- identity->error_after = -1;
- identity->drop_probability = 0.0;
- identity->silent = FALSE;
- identity->sync = FALSE;
- identity->check_perfect = FALSE;
- identity->prev_timestamp = GST_CLOCK_TIME_NONE;
- identity->prev_duration = GST_CLOCK_TIME_NONE;
- identity->prev_offset_end = -1;
- identity->dump = FALSE;
+ identity->loop_based = DEFAULT_LOOP_BASED;
+ identity->sleep_time = DEFAULT_SLEEP_TIME;
+ identity->duplicate = DEFAULT_DUPLICATE;
+ identity->error_after = DEFAULT_ERROR_AFTER;
+ identity->drop_probability = DEFAULT_DROP_PROBABILITY;
+ identity->datarate = DEFAULT_DATARATE;
+ identity->silent = DEFAULT_SILENT;
+ identity->sync = DEFAULT_SYNC;
+ identity->check_perfect = DEFAULT_CHECK_PERFECT;
+ identity->dump = DEFAULT_DUMP;
identity->last_message = NULL;
identity->srccaps = NULL;
g_object_notify (G_OBJECT (identity), "last-message");
}
+ GstClockTime time = GST_BUFFER_TIMESTAMP (buf);
+
+ if (identity->datarate > 0) {
+ time = identity->bytes_handled * GST_SECOND / identity->datarate;
+
+ GST_BUFFER_TIMESTAMP (buf) = time;
+ GST_BUFFER_DURATION (buf) =
+ GST_BUFFER_SIZE (buf) * GST_SECOND / identity->datarate;
+ }
+
g_signal_emit (G_OBJECT (identity), gst_identity_signals[SIGNAL_HANDOFF], 0,
buf);
if (identity->sync) {
if (identity->clock) {
- gst_element_wait (GST_ELEMENT (identity), GST_BUFFER_TIMESTAMP (buf));
+ gst_element_wait (GST_ELEMENT (identity), time);
}
}
+
+ identity->bytes_handled += GST_BUFFER_SIZE (buf);
gst_pad_push (identity->srcpad, GST_DATA (buf));
if (identity->sleep_time)
case ARG_DROP_PROBABILITY:
identity->drop_probability = g_value_get_float (value);
break;
+ case ARG_DATARATE:
+ identity->datarate = g_value_get_int (value);
+ break;
case ARG_SYNC:
identity->sync = g_value_get_boolean (value);
break;
case ARG_DROP_PROBABILITY:
g_value_set_float (value, identity->drop_probability);
break;
+ case ARG_DATARATE:
+ g_value_set_int (value, identity->datarate);
+ break;
case ARG_SILENT:
g_value_set_boolean (value, identity->silent);
break;
break;
}
}
+
+static GstElementStateReturn
+gst_identity_change_state (GstElement * element)
+{
+ GstIdentity *identity;
+
+ g_return_val_if_fail (GST_IS_IDENTITY (element), GST_STATE_FAILURE);
+
+ identity = GST_IDENTITY (element);
+
+ switch (GST_STATE_TRANSITION (element)) {
+ case GST_STATE_NULL_TO_READY:
+ break;
+ case GST_STATE_READY_TO_PAUSED:
+ identity->bytes_handled = 0;
+ identity->prev_timestamp = GST_CLOCK_TIME_NONE;
+ identity->prev_duration = GST_CLOCK_TIME_NONE;
+ identity->prev_offset_end = -1;
+ break;
+ case GST_STATE_PAUSED_TO_PLAYING:
+ case GST_STATE_PLAYING_TO_PAUSED:
+ break;
+ case GST_STATE_PAUSED_TO_READY:
+ g_free (identity->last_message);
+ identity->last_message = NULL;
+ break;
+ case GST_STATE_READY_TO_NULL:
+ break;
+ default:
+ break;
+ }
+
+ if (GST_ELEMENT_CLASS (parent_class)->change_state)
+ return GST_ELEMENT_CLASS (parent_class)->change_state (element);
+
+ return GST_STATE_SUCCESS;
+}
guint duplicate;
gint error_after;
gfloat drop_probability;
+ gint datarate;
guint sleep_time;
gboolean silent;
gboolean dump;
GstClock *clock;
gchar *last_message;
GstCaps *srccaps;
+
+ guint64 bytes_handled;
};
struct _GstIdentityClass {
#define DEFAULT_SIZEMIN 0
#define DEFAULT_SIZEMAX 4096
#define DEFAULT_PARENTSIZE 4096*10
+#define DEFAULT_DATARATE 0
+#define DEFAULT_SYNC FALSE
static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
ARG_SIZEMIN,
ARG_SIZEMAX,
ARG_FILLTYPE,
+ ARG_DATARATE,
+ ARG_SYNC,
ARG_PATTERN,
ARG_NUM_BUFFERS,
ARG_EOS,
const GValue * value, GParamSpec * pspec);
static void gst_fakesrc_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
+static void gst_fakesrc_set_clock (GstElement * element, GstClock * clock);
static GstElementStateReturn gst_fakesrc_change_state (GstElement * element);
g_param_spec_enum ("filltype", "filltype",
"How to fill the buffer, if at all", GST_TYPE_FAKESRC_FILLTYPE,
FAKESRC_FILLTYPE_NULL, G_PARAM_READWRITE));
+ g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DATARATE,
+ g_param_spec_int ("datarate", "Datarate",
+ "Timestamps buffers with number of bytes per second (0 = none)", 0,
+ G_MAXINT, DEFAULT_DATARATE, G_PARAM_READWRITE));
+ g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SYNC,
+ g_param_spec_boolean ("sync", "Sync", "Sync to the clock to the datarate",
+ DEFAULT_SYNC, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PATTERN,
g_param_spec_string ("pattern", "pattern", "pattern", NULL,
G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NUM_BUFFERS,
g_param_spec_int ("num-buffers", "num-buffers",
- "Number of buffers to output before sending EOS", -1, G_MAXINT,
- 0, G_PARAM_READWRITE));
+ "Number of buffers to output before sending EOS", -1, G_MAXINT, 0,
+ G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_EOS,
g_param_spec_boolean ("eos", "eos", "Send out the EOS event?", TRUE,
G_PARAM_READWRITE));
gstelement_class->request_new_pad =
GST_DEBUG_FUNCPTR (gst_fakesrc_request_new_pad);
gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_fakesrc_change_state);
+ gstelement_class->set_clock = GST_DEBUG_FUNCPTR (gst_fakesrc_set_clock);
}
static void
fakesrc->parent = NULL;
fakesrc->parentsize = DEFAULT_PARENTSIZE;
fakesrc->last_message = NULL;
+ fakesrc->datarate = DEFAULT_DATARATE;
+ fakesrc->sync = DEFAULT_SYNC;
+}
+
+static void
+gst_fakesrc_set_clock (GstElement * element, GstClock * clock)
+{
+ GstFakeSrc *src;
+
+ src = GST_FAKESRC (element);
+
+ src->clock = clock;
}
+
static GstPad *
gst_fakesrc_request_new_pad (GstElement * element, GstPadTemplate * templ,
const gchar * unused)
case ARG_FILLTYPE:
src->filltype = g_value_get_enum (value);
break;
+ case ARG_DATARATE:
+ src->datarate = g_value_get_int (value);
+ break;
+ case ARG_SYNC:
+ src->sync = g_value_get_boolean (value);
+ break;
case ARG_PATTERN:
break;
case ARG_NUM_BUFFERS:
case ARG_FILLTYPE:
g_value_set_enum (value, src->filltype);
break;
+ case ARG_DATARATE:
+ g_value_set_int (value, src->datarate);
+ break;
+ case ARG_SYNC:
+ g_value_set_boolean (value, src->sync);
+ break;
case ARG_PATTERN:
g_value_set_string (value, src->pattern);
break;
}
buf = gst_fakesrc_create_buffer (src);
- GST_BUFFER_TIMESTAMP (buf) = src->buffer_count++;
+ GST_BUFFER_OFFSET (buf) = src->buffer_count++;
+
+ GstClockTime time = GST_CLOCK_TIME_NONE;
+
+ if (src->datarate > 0) {
+ time = (src->bytes_sent * GST_SECOND) / src->datarate;
+ if (src->sync) {
+ gst_element_wait (GST_ELEMENT (src), time);
+ }
+
+ GST_BUFFER_DURATION (buf) =
+ GST_BUFFER_SIZE (buf) * GST_SECOND / src->datarate;
+ }
+ GST_BUFFER_TIMESTAMP (buf) = time;
if (!src->silent) {
g_free (src->last_message);
GST_LOG_OBJECT (src, "post handoff emit");
}
+ src->bytes_sent += GST_BUFFER_SIZE (buf);
+
return GST_DATA (buf);
}
fakesrc->pattern_byte = 0x00;
fakesrc->need_flush = FALSE;
fakesrc->eos = FALSE;
+ fakesrc->bytes_sent = 0;
fakesrc->rt_num_buffers = fakesrc->num_buffers;
break;
case GST_STATE_PAUSED_TO_PLAYING:
guint8 pattern_byte;
gchar *pattern;
GList *patternlist;
+ gint datarate;
+ gboolean sync;
+ GstClock *clock;
gint64 segment_start;
gint64 segment_end;
gboolean segment_loop;
gboolean dump;
gboolean need_flush;
+ guint64 bytes_sent;
+
gchar *last_message;
};
LAST_SIGNAL
};
+#define DEFAULT_LOOP_BASED FALSE
+#define DEFAULT_SLEEP_TIME 0
+#define DEFAULT_DUPLICATE 1
+#define DEFAULT_ERROR_AFTER -1
+#define DEFAULT_DROP_PROBABILITY 0.0
+#define DEFAULT_DATARATE 0
+#define DEFAULT_SILENT FALSE
+#define DEFAULT_DUMP FALSE
+#define DEFAULT_SYNC FALSE
+#define DEFAULT_CHECK_PERFECT FALSE
+
enum
{
ARG_0,
ARG_DUPLICATE,
ARG_ERROR_AFTER,
ARG_DROP_PROBABILITY,
+ ARG_DATARATE,
ARG_SILENT,
ARG_LAST_MESSAGE,
ARG_DUMP,
const GValue * value, GParamSpec * pspec);
static void gst_identity_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
+static GstElementStateReturn gst_identity_change_state (GstElement * element);
static void gst_identity_chain (GstPad * pad, GstData * _data);
static void gst_identity_set_clock (GstElement * element, GstClock * clock);
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LOOP_BASED,
g_param_spec_boolean ("loop-based", "Loop-based",
"Set to TRUE to use loop-based rather than chain-based scheduling",
- TRUE, G_PARAM_READWRITE));
+ DEFAULT_LOOP_BASED, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SLEEP_TIME,
g_param_spec_uint ("sleep-time", "Sleep time",
- "Microseconds to sleep between processing", 0, G_MAXUINT, 0,
- G_PARAM_READWRITE));
+ "Microseconds to sleep between processing", 0, G_MAXUINT,
+ DEFAULT_SLEEP_TIME, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DUPLICATE,
g_param_spec_uint ("duplicate", "Duplicate Buffers",
- "Push the buffers N times", 0, G_MAXUINT, 1, G_PARAM_READWRITE));
+ "Push the buffers N times", 0, G_MAXUINT, DEFAULT_DUPLICATE,
+ G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ERROR_AFTER,
g_param_spec_int ("error_after", "Error After", "Error after N buffers",
- G_MININT, G_MAXINT, -1, G_PARAM_READWRITE));
+ G_MININT, G_MAXINT, DEFAULT_ERROR_AFTER, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DROP_PROBABILITY,
g_param_spec_float ("drop_probability", "Drop Probability",
- "The Probability a buffer is dropped", 0.0, 1.0, 0.0,
- G_PARAM_READWRITE));
+ "The Probability a buffer is dropped", 0.0, 1.0,
+ DEFAULT_DROP_PROBABILITY, G_PARAM_READWRITE));
+ g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DATARATE,
+ g_param_spec_int ("datarate", "Datarate",
+ "(Re)timestamps buffers with number of bytes per second (0 = inactive)",
+ 0, G_MAXINT, DEFAULT_DATARATE, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SILENT,
- g_param_spec_boolean ("silent", "silent", "silent", FALSE,
+ g_param_spec_boolean ("silent", "silent", "silent", DEFAULT_SILENT,
G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LAST_MESSAGE,
g_param_spec_string ("last-message", "last-message", "last-message", NULL,
G_PARAM_READABLE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DUMP,
- g_param_spec_boolean ("dump", "Dump", "Dump buffer contents", FALSE,
- G_PARAM_READWRITE));
+ g_param_spec_boolean ("dump", "Dump", "Dump buffer contents",
+ DEFAULT_DUMP, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SYNC,
g_param_spec_boolean ("sync", "Synchronize",
- "Synchronize to pipeline clock", FALSE, G_PARAM_READWRITE));
+ "Synchronize to pipeline clock", DEFAULT_SYNC, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_CHECK_PERFECT,
g_param_spec_boolean ("check-perfect", "Check For Perfect Stream",
- "Verify that the stream is time- and data-contiguous", FALSE,
- G_PARAM_READWRITE));
+ "Verify that the stream is time- and data-contiguous",
+ DEFAULT_CHECK_PERFECT, G_PARAM_READWRITE));
gst_identity_signals[SIGNAL_HANDOFF] =
g_signal_new ("handoff", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_identity_get_property);
gstelement_class->set_clock = GST_DEBUG_FUNCPTR (gst_identity_set_clock);
+ gstelement_class->change_state =
+ GST_DEBUG_FUNCPTR (gst_identity_change_state);
}
gst_pad_set_link_function (identity->srcpad, gst_pad_proxy_pad_link);
gst_pad_set_getcaps_function (identity->srcpad, gst_pad_proxy_getcaps);
- identity->loop_based = FALSE;
- identity->sleep_time = 0;
- identity->duplicate = 1;
- identity->error_after = -1;
- identity->drop_probability = 0.0;
- identity->silent = FALSE;
- identity->sync = FALSE;
- identity->check_perfect = FALSE;
- identity->prev_timestamp = GST_CLOCK_TIME_NONE;
- identity->prev_duration = GST_CLOCK_TIME_NONE;
- identity->prev_offset_end = -1;
- identity->dump = FALSE;
+ identity->loop_based = DEFAULT_LOOP_BASED;
+ identity->sleep_time = DEFAULT_SLEEP_TIME;
+ identity->duplicate = DEFAULT_DUPLICATE;
+ identity->error_after = DEFAULT_ERROR_AFTER;
+ identity->drop_probability = DEFAULT_DROP_PROBABILITY;
+ identity->datarate = DEFAULT_DATARATE;
+ identity->silent = DEFAULT_SILENT;
+ identity->sync = DEFAULT_SYNC;
+ identity->check_perfect = DEFAULT_CHECK_PERFECT;
+ identity->dump = DEFAULT_DUMP;
identity->last_message = NULL;
identity->srccaps = NULL;
g_object_notify (G_OBJECT (identity), "last-message");
}
+ GstClockTime time = GST_BUFFER_TIMESTAMP (buf);
+
+ if (identity->datarate > 0) {
+ time = identity->bytes_handled * GST_SECOND / identity->datarate;
+
+ GST_BUFFER_TIMESTAMP (buf) = time;
+ GST_BUFFER_DURATION (buf) =
+ GST_BUFFER_SIZE (buf) * GST_SECOND / identity->datarate;
+ }
+
g_signal_emit (G_OBJECT (identity), gst_identity_signals[SIGNAL_HANDOFF], 0,
buf);
if (identity->sync) {
if (identity->clock) {
- gst_element_wait (GST_ELEMENT (identity), GST_BUFFER_TIMESTAMP (buf));
+ gst_element_wait (GST_ELEMENT (identity), time);
}
}
+
+ identity->bytes_handled += GST_BUFFER_SIZE (buf);
gst_pad_push (identity->srcpad, GST_DATA (buf));
if (identity->sleep_time)
case ARG_DROP_PROBABILITY:
identity->drop_probability = g_value_get_float (value);
break;
+ case ARG_DATARATE:
+ identity->datarate = g_value_get_int (value);
+ break;
case ARG_SYNC:
identity->sync = g_value_get_boolean (value);
break;
case ARG_DROP_PROBABILITY:
g_value_set_float (value, identity->drop_probability);
break;
+ case ARG_DATARATE:
+ g_value_set_int (value, identity->datarate);
+ break;
case ARG_SILENT:
g_value_set_boolean (value, identity->silent);
break;
break;
}
}
+
+static GstElementStateReturn
+gst_identity_change_state (GstElement * element)
+{
+ GstIdentity *identity;
+
+ g_return_val_if_fail (GST_IS_IDENTITY (element), GST_STATE_FAILURE);
+
+ identity = GST_IDENTITY (element);
+
+ switch (GST_STATE_TRANSITION (element)) {
+ case GST_STATE_NULL_TO_READY:
+ break;
+ case GST_STATE_READY_TO_PAUSED:
+ identity->bytes_handled = 0;
+ identity->prev_timestamp = GST_CLOCK_TIME_NONE;
+ identity->prev_duration = GST_CLOCK_TIME_NONE;
+ identity->prev_offset_end = -1;
+ break;
+ case GST_STATE_PAUSED_TO_PLAYING:
+ case GST_STATE_PLAYING_TO_PAUSED:
+ break;
+ case GST_STATE_PAUSED_TO_READY:
+ g_free (identity->last_message);
+ identity->last_message = NULL;
+ break;
+ case GST_STATE_READY_TO_NULL:
+ break;
+ default:
+ break;
+ }
+
+ if (GST_ELEMENT_CLASS (parent_class)->change_state)
+ return GST_ELEMENT_CLASS (parent_class)->change_state (element);
+
+ return GST_STATE_SUCCESS;
+}
guint duplicate;
gint error_after;
gfloat drop_probability;
+ gint datarate;
guint sleep_time;
gboolean silent;
gboolean dump;
GstClock *clock;
gchar *last_message;
GstCaps *srccaps;
+
+ guint64 bytes_handled;
};
struct _GstIdentityClass {