X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=plugins%2Felements%2Fgstidentity.c;h=bf6ba4026aac6eee528812e8936cc6aab718f088;hb=66e1ee5137b2964b27b4dd18fd61809cb261048b;hp=119fb5886b8ede2eca118f60b8eb06b5ad5e91bf;hpb=a87b4551a6090663a1714f263d4e20fe75eb46ca;p=platform%2Fupstream%2Fgstreamer.git diff --git a/plugins/elements/gstidentity.c b/plugins/elements/gstidentity.c index 119fb58..bf6ba40 100644 --- a/plugins/elements/gstidentity.c +++ b/plugins/elements/gstidentity.c @@ -74,6 +74,8 @@ enum #define DEFAULT_CHECK_IMPERFECT_OFFSET FALSE #define DEFAULT_SIGNAL_HANDOFFS TRUE #define DEFAULT_TS_OFFSET 0 +#define DEFAULT_DROP_ALLOCATION FALSE +#define DEFAULT_EOS_AFTER -1 enum { @@ -91,7 +93,9 @@ enum PROP_TS_OFFSET, PROP_CHECK_IMPERFECT_TIMESTAMP, PROP_CHECK_IMPERFECT_OFFSET, - PROP_SIGNAL_HANDOFFS + PROP_SIGNAL_HANDOFFS, + PROP_DROP_ALLOCATION, + PROP_EOS_AFTER }; @@ -157,7 +161,7 @@ gst_identity_class_init (GstIdentityClass * klass) DEFAULT_SLEEP_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_ERROR_AFTER, g_param_spec_int ("error-after", "Error After", "Error after N buffers", - G_MININT, G_MAXINT, DEFAULT_ERROR_AFTER, + -1, G_MAXINT, DEFAULT_ERROR_AFTER, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_DROP_PROBABILITY, g_param_spec_float ("drop-probability", "Drop Probability", @@ -222,14 +226,31 @@ gst_identity_class_init (GstIdentityClass * klass) /** * GstIdentity:signal-handoffs * - * If set to #TRUE, the identity will emit a handoff signal when handling a buffer. - * When set to #FALSE, no signal will be emitted, which might improve performance. + * If set to %TRUE, the identity will emit a handoff signal when handling a buffer. + * When set to %FALSE, no signal will be emitted, which might improve performance. */ g_object_class_install_property (gobject_class, PROP_SIGNAL_HANDOFFS, g_param_spec_boolean ("signal-handoffs", "Signal handoffs", "Send a signal before pushing the buffer", DEFAULT_SIGNAL_HANDOFFS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_DROP_ALLOCATION, + g_param_spec_boolean ("drop-allocation", "Drop allocation query", + "Don't forward allocation queries", DEFAULT_DROP_ALLOCATION, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstIdentity:eos-after + * + * EOS after N buffers. + * + * Since: 1.16 + **/ + g_object_class_install_property (gobject_class, PROP_EOS_AFTER, + g_param_spec_int ("eos-after", "EOS After", "EOS after N buffers", + -1, G_MAXINT, DEFAULT_EOS_AFTER, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** * GstIdentity::handoff: * @identity: the identity instance @@ -271,6 +292,7 @@ gst_identity_init (GstIdentity * identity) { identity->sleep_time = DEFAULT_SLEEP_TIME; identity->error_after = DEFAULT_ERROR_AFTER; + identity->error_after_counter = DEFAULT_ERROR_AFTER; identity->drop_probability = DEFAULT_DROP_PROBABILITY; identity->drop_buffer_flags = DEFAULT_DROP_BUFFER_FLAGS; identity->datarate = DEFAULT_DATARATE; @@ -284,6 +306,8 @@ gst_identity_init (GstIdentity * identity) identity->signal_handoffs = DEFAULT_SIGNAL_HANDOFFS; identity->ts_offset = DEFAULT_TS_OFFSET; g_cond_init (&identity->blocked_cond); + identity->eos_after = DEFAULT_EOS_AFTER; + identity->eos_after_counter = DEFAULT_EOS_AFTER; gst_base_transform_set_gap_aware (GST_BASE_TRANSFORM_CAST (identity), TRUE); } @@ -305,9 +329,18 @@ gst_identity_do_sync (GstIdentity * identity, GstClockTime running_time) GST_OBJECT_LOCK (identity); + if (identity->flushing) { + GST_OBJECT_UNLOCK (identity); + return GST_FLOW_FLUSHING; + } + while (identity->blocked) g_cond_wait (&identity->blocked_cond, GST_OBJECT_GET_LOCK (identity)); + if (identity->flushing) { + GST_OBJECT_UNLOCK (identity); + return GST_FLOW_FLUSHING; + } if ((clock = GST_ELEMENT (identity)->clock)) { GstClockReturn cret; @@ -336,8 +369,8 @@ gst_identity_do_sync (GstIdentity * identity, GstClockTime running_time) gst_clock_id_unref (identity->clock_id); identity->clock_id = NULL; } - if (cret == GST_CLOCK_UNSCHEDULED) - ret = GST_FLOW_EOS; + if (cret == GST_CLOCK_UNSCHEDULED || identity->flushing) + ret = GST_FLOW_FLUSHING; } GST_OBJECT_UNLOCK (identity); } @@ -430,11 +463,16 @@ gst_identity_sink_event (GstBaseTransform * trans, GstEvent * event) } else { if (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_START) { GST_OBJECT_LOCK (identity); + identity->flushing = TRUE; if (identity->clock_id) { GST_DEBUG_OBJECT (identity, "unlock clock wait"); gst_clock_id_unschedule (identity->clock_id); } GST_OBJECT_UNLOCK (identity); + } else if (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP) { + GST_OBJECT_LOCK (identity); + identity->flushing = FALSE; + GST_OBJECT_UNLOCK (identity); } ret = GST_BASE_TRANSFORM_CLASS (parent_class)->sink_event (trans, event); @@ -603,12 +641,18 @@ gst_identity_transform_ip (GstBaseTransform * trans, GstBuffer * buf) identity->prev_offset_end = GST_BUFFER_OFFSET_END (buf); identity->prev_offset = GST_BUFFER_OFFSET (buf); - if (identity->error_after >= 0) { - identity->error_after--; - if (identity->error_after == 0) + if (identity->error_after_counter >= 0) { + identity->error_after_counter--; + if (identity->error_after_counter == 0) goto error_after; } + if (identity->eos_after_counter >= 0) { + identity->eos_after_counter--; + if (identity->eos_after_counter == 0) + goto eos_after; + } + if (identity->drop_probability > 0.0) { if ((gfloat) (1.0 * rand () / (RAND_MAX)) < identity->drop_probability) goto dropped; @@ -678,6 +722,11 @@ error_after: (_("Failed after iterations as requested.")), (NULL)); return GST_FLOW_ERROR; } +eos_after: + { + GST_DEBUG_OBJECT (identity, "EOS after iterations as requested."); + return GST_FLOW_EOS; + } dropped: { if (!identity->silent) { @@ -745,6 +794,12 @@ gst_identity_set_property (GObject * object, guint prop_id, case PROP_SIGNAL_HANDOFFS: identity->signal_handoffs = g_value_get_boolean (value); break; + case PROP_DROP_ALLOCATION: + identity->drop_allocation = g_value_get_boolean (value); + break; + case PROP_EOS_AFTER: + identity->eos_after = g_value_get_int (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -797,7 +852,7 @@ gst_identity_get_property (GObject * object, guint prop_id, GValue * value, g_value_set_boolean (value, identity->sync); break; case PROP_TS_OFFSET: - identity->ts_offset = g_value_get_int64 (value); + g_value_set_int64 (value, identity->ts_offset); break; case PROP_CHECK_IMPERFECT_TIMESTAMP: g_value_set_boolean (value, identity->check_imperfect_timestamp); @@ -808,6 +863,12 @@ gst_identity_get_property (GObject * object, guint prop_id, GValue * value, case PROP_SIGNAL_HANDOFFS: g_value_set_boolean (value, identity->signal_handoffs); break; + case PROP_DROP_ALLOCATION: + g_value_set_boolean (value, identity->drop_allocation); + break; + case PROP_EOS_AFTER: + g_value_set_int (value, identity->eos_after); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -821,13 +882,27 @@ gst_identity_start (GstBaseTransform * trans) identity = GST_IDENTITY (trans); + if (identity->eos_after != DEFAULT_EOS_AFTER + && identity->error_after != DEFAULT_ERROR_AFTER) + goto both_afters_defined; + identity->offset = 0; identity->prev_timestamp = GST_CLOCK_TIME_NONE; identity->prev_duration = GST_CLOCK_TIME_NONE; identity->prev_offset_end = GST_BUFFER_OFFSET_NONE; identity->prev_offset = GST_BUFFER_OFFSET_NONE; + identity->error_after_counter = identity->error_after; + identity->eos_after_counter = identity->eos_after; return TRUE; + + /* ERROR */ +both_afters_defined: + { + GST_ELEMENT_ERROR (identity, CORE, FAILED, + (_("eos-after and error-after can't both be defined.")), (NULL)); + return FALSE; + } } static gboolean @@ -873,6 +948,12 @@ gst_identity_query (GstBaseTransform * base, GstPadDirection direction, identity = GST_IDENTITY (base); + if (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION && + identity->drop_allocation) { + GST_DEBUG_OBJECT (identity, "Dropping allocation query."); + return FALSE; + } + ret = GST_BASE_TRANSFORM_CLASS (parent_class)->query (base, direction, query); if (GST_QUERY_TYPE (query) == GST_QUERY_LATENCY) { @@ -917,6 +998,7 @@ gst_identity_change_state (GstElement * element, GstStateChange transition) break; case GST_STATE_CHANGE_READY_TO_PAUSED: GST_OBJECT_LOCK (identity); + identity->flushing = FALSE; identity->blocked = TRUE; GST_OBJECT_UNLOCK (identity); if (identity->sync) @@ -930,6 +1012,7 @@ gst_identity_change_state (GstElement * element, GstStateChange transition) break; case GST_STATE_CHANGE_PAUSED_TO_READY: GST_OBJECT_LOCK (identity); + identity->flushing = TRUE; if (identity->clock_id) { GST_DEBUG_OBJECT (identity, "unlock clock wait"); gst_clock_id_unschedule (identity->clock_id);