gst/base/gstbasetransform.c: The event virtual method is now properly implemented, with a default handler

Original commit message from CVS:
* gst/base/gstbasetransform.c: (gst_base_transform_class_init),
(gst_base_transform_event), (gst_base_transform_eventfunc):
The event virtual method is now properly implemented, with a default
handler
Sub classes should call the parent_class event method. They should
return FALSE if they had a problem handling the given event, or don't
want GstBaseTransform to send that even downstream
* gst/elements/gstidentity.c: (gst_identity_class_init),
(gst_identity_init), (gst_identity_event),
(gst_identity_transform_ip), (gst_identity_set_property),
(gst_identity_get_property):
* gst/elements/gstidentity.h:
Added the single-segment boolean property.
If set to TRUE, it will output a single segment of data, starting from
0, will eat up all incoming newsegment, and modify the timestamp of the
buffers accordingly
This commit is contained in:
Edward Hervey 2005-11-29 14:47:07 +00:00
parent 2a1233001e
commit 33a15d5e67
7 changed files with 153 additions and 20 deletions

View file

@ -1,3 +1,22 @@
2005-11-29 Edward Hervey <edward@fluendo.com>
* gst/base/gstbasetransform.c: (gst_base_transform_class_init),
(gst_base_transform_event), (gst_base_transform_eventfunc):
The event virtual method is now properly implemented, with a default
handler
Sub classes should call the parent_class event method. They should
return FALSE if they had a problem handling the given event, or don't
want GstBaseTransform to send that even downstream
* gst/elements/gstidentity.c: (gst_identity_class_init),
(gst_identity_init), (gst_identity_event),
(gst_identity_transform_ip), (gst_identity_set_property),
(gst_identity_get_property):
* gst/elements/gstidentity.h:
Added the single-segment boolean property.
If set to TRUE, it will output a single segment of data, starting from
0, will eat up all incoming newsegment, and modify the timestamp of the
buffers accordingly
2005-11-29 Tim-Philipp Müller <tim at centricular dot net>
* gst/gstghostpad.c: (gst_proxy_pad_get_target):

View file

@ -256,6 +256,8 @@ static GstStateChangeReturn gst_base_transform_change_state (GstElement *
element, GstStateChange transition);
static gboolean gst_base_transform_event (GstPad * pad, GstEvent * event);
static gboolean gst_base_transform_eventfunc (GstBaseTransform * trans,
GstEvent * event);
static GstFlowReturn gst_base_transform_getrange (GstPad * pad, guint64 offset,
guint length, GstBuffer ** buffer);
static GstFlowReturn gst_base_transform_chain (GstPad * pad,
@ -308,6 +310,7 @@ gst_base_transform_class_init (GstBaseTransformClass * klass)
GST_DEBUG_FUNCPTR (gst_base_transform_change_state);
klass->passthrough_on_same_caps = FALSE;
klass->event = GST_DEBUG_FUNCPTR (gst_base_transform_eventfunc);
}
static void
@ -1039,14 +1042,25 @@ gst_base_transform_event (GstPad * pad, GstEvent * event)
{
GstBaseTransform *trans;
GstBaseTransformClass *bclass;
gboolean ret = FALSE;
gboolean ret = TRUE;
trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
bclass = GST_BASE_TRANSFORM_GET_CLASS (trans);
if (bclass->event)
bclass->event (trans, event);
ret = bclass->event (trans, event);
if (ret)
ret = gst_pad_event_default (pad, event);
gst_object_unref (trans);
return ret;
}
static gboolean
gst_base_transform_eventfunc (GstBaseTransform * trans, GstEvent * event)
{
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_FLUSH_START:
break;
@ -1093,11 +1107,8 @@ gst_base_transform_event (GstPad * pad, GstEvent * event)
default:
break;
}
ret = gst_pad_event_default (pad, event);
gst_object_unref (trans);
return ret;
return TRUE;
}
static GstFlowReturn

View file

@ -65,6 +65,7 @@ enum
#define DEFAULT_DROP_PROBABILITY 0.0
#define DEFAULT_DATARATE 0
#define DEFAULT_SILENT FALSE
#define DEFAULT_SINGLE_SEGMENT FALSE
#define DEFAULT_DUMP FALSE
#define DEFAULT_SYNC FALSE
#define DEFAULT_CHECK_PERFECT FALSE
@ -77,6 +78,7 @@ enum
PROP_DROP_PROBABILITY,
PROP_DATARATE,
PROP_SILENT,
PROP_SINGLE_SEGMENT,
PROP_LAST_MESSAGE,
PROP_DUMP,
PROP_SYNC,
@ -188,6 +190,10 @@ gst_identity_class_init (GstIdentityClass * klass)
g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SILENT,
g_param_spec_boolean ("silent", "silent", "silent", DEFAULT_SILENT,
G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SINGLE_SEGMENT,
g_param_spec_boolean ("single-segment", "Single Segment",
"Timestamp buffers and eat newsegments so as to appear as one segment",
DEFAULT_SINGLE_SEGMENT, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_LAST_MESSAGE,
g_param_spec_string ("last-message", "last-message", "last-message", NULL,
G_PARAM_READABLE));
@ -226,6 +232,7 @@ gst_identity_init (GstIdentity * identity, GstIdentityClass * g_class)
identity->drop_probability = DEFAULT_DROP_PROBABILITY;
identity->datarate = DEFAULT_DATARATE;
identity->silent = DEFAULT_SILENT;
identity->single_segment = DEFAULT_SINGLE_SEGMENT;
identity->sync = DEFAULT_SYNC;
identity->check_perfect = DEFAULT_CHECK_PERFECT;
identity->dump = DEFAULT_DUMP;
@ -236,6 +243,7 @@ static gboolean
gst_identity_event (GstBaseTransform * trans, GstEvent * event)
{
GstIdentity *identity;
gboolean ret = TRUE;
identity = GST_IDENTITY (trans);
@ -260,7 +268,33 @@ gst_identity_event (GstBaseTransform * trans, GstEvent * event)
g_object_notify (G_OBJECT (identity), "last_message");
}
return TRUE;
if (identity->single_segment
&& (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT)) {
if (trans->have_newsegment == FALSE) {
GstEvent *news;
GstFormat format;
gst_event_parse_new_segment (event, NULL, NULL, &format, NULL, NULL,
NULL);
/* This is the first newsegment, send out a (0, -1) newsegment */
news = gst_event_new_new_segment (TRUE, 1.0, format, 0, -1, 0);
if (!(gst_pad_event_default (trans->sinkpad, news)))
return FALSE;
}
}
GST_BASE_TRANSFORM_CLASS (parent_class)->event (trans, event);
if (identity->single_segment
&& (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT)) {
/* eat up segments */
ret = FALSE;
}
return ret;
}
static void
@ -305,6 +339,7 @@ gst_identity_transform_ip (GstBaseTransform * trans, GstBuffer * buf)
{
GstFlowReturn ret = GST_FLOW_OK;
GstIdentity *identity = GST_IDENTITY (trans);
GstClockTime runtimestamp;
if (identity->check_perfect)
gst_identity_check_perfect (identity, buf);
@ -368,6 +403,9 @@ gst_identity_transform_ip (GstBaseTransform * trans, GstBuffer * buf)
g_signal_emit (G_OBJECT (identity), gst_identity_signals[SIGNAL_HANDOFF], 0,
buf);
runtimestamp = gst_segment_to_running_time (&trans->segment,
GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (buf));
if (identity->sync) {
GstClock *clock;
@ -376,9 +414,7 @@ gst_identity_transform_ip (GstBaseTransform * trans, GstBuffer * buf)
GstClockReturn cret;
GstClockTime timestamp;
timestamp = gst_segment_to_running_time (&trans->segment,
GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (buf));
timestamp += GST_ELEMENT (identity)->base_time;
timestamp = runtimestamp + GST_ELEMENT (identity)->base_time;
/* save id if we need to unlock */
/* FIXME: actually unlock this somewhere in the state changes */
@ -403,6 +439,9 @@ gst_identity_transform_ip (GstBaseTransform * trans, GstBuffer * buf)
if (identity->sleep_time && ret == GST_FLOW_OK)
g_usleep (identity->sleep_time);
if (identity->single_segment && ret == GST_FLOW_OK)
GST_BUFFER_TIMESTAMP (buf) = runtimestamp;
return ret;
}
@ -421,6 +460,9 @@ gst_identity_set_property (GObject * object, guint prop_id,
case PROP_SILENT:
identity->silent = g_value_get_boolean (value);
break;
case PROP_SINGLE_SEGMENT:
identity->single_segment = g_value_get_boolean (value);
break;
case PROP_DUMP:
identity->dump = g_value_get_boolean (value);
break;
@ -469,6 +511,9 @@ gst_identity_get_property (GObject * object, guint prop_id, GValue * value,
case PROP_SILENT:
g_value_set_boolean (value, identity->silent);
break;
case PROP_SINGLE_SEGMENT:
g_value_set_boolean (value, identity->single_segment);
break;
case PROP_DUMP:
g_value_set_boolean (value, identity->dump);
break;

View file

@ -57,6 +57,7 @@ struct _GstIdentity {
gboolean dump;
gboolean sync;
gboolean check_perfect;
gboolean single_segment;
GstClockTime prev_timestamp;
GstClockTime prev_duration;
guint64 prev_offset_end;

View file

@ -256,6 +256,8 @@ static GstStateChangeReturn gst_base_transform_change_state (GstElement *
element, GstStateChange transition);
static gboolean gst_base_transform_event (GstPad * pad, GstEvent * event);
static gboolean gst_base_transform_eventfunc (GstBaseTransform * trans,
GstEvent * event);
static GstFlowReturn gst_base_transform_getrange (GstPad * pad, guint64 offset,
guint length, GstBuffer ** buffer);
static GstFlowReturn gst_base_transform_chain (GstPad * pad,
@ -308,6 +310,7 @@ gst_base_transform_class_init (GstBaseTransformClass * klass)
GST_DEBUG_FUNCPTR (gst_base_transform_change_state);
klass->passthrough_on_same_caps = FALSE;
klass->event = GST_DEBUG_FUNCPTR (gst_base_transform_eventfunc);
}
static void
@ -1039,14 +1042,25 @@ gst_base_transform_event (GstPad * pad, GstEvent * event)
{
GstBaseTransform *trans;
GstBaseTransformClass *bclass;
gboolean ret = FALSE;
gboolean ret = TRUE;
trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
bclass = GST_BASE_TRANSFORM_GET_CLASS (trans);
if (bclass->event)
bclass->event (trans, event);
ret = bclass->event (trans, event);
if (ret)
ret = gst_pad_event_default (pad, event);
gst_object_unref (trans);
return ret;
}
static gboolean
gst_base_transform_eventfunc (GstBaseTransform * trans, GstEvent * event)
{
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_FLUSH_START:
break;
@ -1093,11 +1107,8 @@ gst_base_transform_event (GstPad * pad, GstEvent * event)
default:
break;
}
ret = gst_pad_event_default (pad, event);
gst_object_unref (trans);
return ret;
return TRUE;
}
static GstFlowReturn

View file

@ -65,6 +65,7 @@ enum
#define DEFAULT_DROP_PROBABILITY 0.0
#define DEFAULT_DATARATE 0
#define DEFAULT_SILENT FALSE
#define DEFAULT_SINGLE_SEGMENT FALSE
#define DEFAULT_DUMP FALSE
#define DEFAULT_SYNC FALSE
#define DEFAULT_CHECK_PERFECT FALSE
@ -77,6 +78,7 @@ enum
PROP_DROP_PROBABILITY,
PROP_DATARATE,
PROP_SILENT,
PROP_SINGLE_SEGMENT,
PROP_LAST_MESSAGE,
PROP_DUMP,
PROP_SYNC,
@ -188,6 +190,10 @@ gst_identity_class_init (GstIdentityClass * klass)
g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SILENT,
g_param_spec_boolean ("silent", "silent", "silent", DEFAULT_SILENT,
G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SINGLE_SEGMENT,
g_param_spec_boolean ("single-segment", "Single Segment",
"Timestamp buffers and eat newsegments so as to appear as one segment",
DEFAULT_SINGLE_SEGMENT, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_LAST_MESSAGE,
g_param_spec_string ("last-message", "last-message", "last-message", NULL,
G_PARAM_READABLE));
@ -226,6 +232,7 @@ gst_identity_init (GstIdentity * identity, GstIdentityClass * g_class)
identity->drop_probability = DEFAULT_DROP_PROBABILITY;
identity->datarate = DEFAULT_DATARATE;
identity->silent = DEFAULT_SILENT;
identity->single_segment = DEFAULT_SINGLE_SEGMENT;
identity->sync = DEFAULT_SYNC;
identity->check_perfect = DEFAULT_CHECK_PERFECT;
identity->dump = DEFAULT_DUMP;
@ -236,6 +243,7 @@ static gboolean
gst_identity_event (GstBaseTransform * trans, GstEvent * event)
{
GstIdentity *identity;
gboolean ret = TRUE;
identity = GST_IDENTITY (trans);
@ -260,7 +268,33 @@ gst_identity_event (GstBaseTransform * trans, GstEvent * event)
g_object_notify (G_OBJECT (identity), "last_message");
}
return TRUE;
if (identity->single_segment
&& (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT)) {
if (trans->have_newsegment == FALSE) {
GstEvent *news;
GstFormat format;
gst_event_parse_new_segment (event, NULL, NULL, &format, NULL, NULL,
NULL);
/* This is the first newsegment, send out a (0, -1) newsegment */
news = gst_event_new_new_segment (TRUE, 1.0, format, 0, -1, 0);
if (!(gst_pad_event_default (trans->sinkpad, news)))
return FALSE;
}
}
GST_BASE_TRANSFORM_CLASS (parent_class)->event (trans, event);
if (identity->single_segment
&& (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT)) {
/* eat up segments */
ret = FALSE;
}
return ret;
}
static void
@ -305,6 +339,7 @@ gst_identity_transform_ip (GstBaseTransform * trans, GstBuffer * buf)
{
GstFlowReturn ret = GST_FLOW_OK;
GstIdentity *identity = GST_IDENTITY (trans);
GstClockTime runtimestamp;
if (identity->check_perfect)
gst_identity_check_perfect (identity, buf);
@ -368,6 +403,9 @@ gst_identity_transform_ip (GstBaseTransform * trans, GstBuffer * buf)
g_signal_emit (G_OBJECT (identity), gst_identity_signals[SIGNAL_HANDOFF], 0,
buf);
runtimestamp = gst_segment_to_running_time (&trans->segment,
GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (buf));
if (identity->sync) {
GstClock *clock;
@ -376,9 +414,7 @@ gst_identity_transform_ip (GstBaseTransform * trans, GstBuffer * buf)
GstClockReturn cret;
GstClockTime timestamp;
timestamp = gst_segment_to_running_time (&trans->segment,
GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (buf));
timestamp += GST_ELEMENT (identity)->base_time;
timestamp = runtimestamp + GST_ELEMENT (identity)->base_time;
/* save id if we need to unlock */
/* FIXME: actually unlock this somewhere in the state changes */
@ -403,6 +439,9 @@ gst_identity_transform_ip (GstBaseTransform * trans, GstBuffer * buf)
if (identity->sleep_time && ret == GST_FLOW_OK)
g_usleep (identity->sleep_time);
if (identity->single_segment && ret == GST_FLOW_OK)
GST_BUFFER_TIMESTAMP (buf) = runtimestamp;
return ret;
}
@ -421,6 +460,9 @@ gst_identity_set_property (GObject * object, guint prop_id,
case PROP_SILENT:
identity->silent = g_value_get_boolean (value);
break;
case PROP_SINGLE_SEGMENT:
identity->single_segment = g_value_get_boolean (value);
break;
case PROP_DUMP:
identity->dump = g_value_get_boolean (value);
break;
@ -469,6 +511,9 @@ gst_identity_get_property (GObject * object, guint prop_id, GValue * value,
case PROP_SILENT:
g_value_set_boolean (value, identity->silent);
break;
case PROP_SINGLE_SEGMENT:
g_value_set_boolean (value, identity->single_segment);
break;
case PROP_DUMP:
g_value_set_boolean (value, identity->dump);
break;

View file

@ -57,6 +57,7 @@ struct _GstIdentity {
gboolean dump;
gboolean sync;
gboolean check_perfect;
gboolean single_segment;
GstClockTime prev_timestamp;
GstClockTime prev_duration;
guint64 prev_offset_end;