static void gst_identity_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { GstIdentity *identity; identity = GST_IDENTITY (object); switch (prop_id) { case PROP_SLEEP_TIME: g_value_set_uint (value, identity->sleep_time); break; case PROP_ERROR_AFTER: g_value_set_int (value, identity->error_after); break; case PROP_DROP_PROBABILITY: g_value_set_float (value, identity->drop_probability); break; case PROP_DATARATE: g_value_set_int (value, identity->datarate); break; 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; case PROP_LAST_MESSAGE: GST_OBJECT_LOCK (identity); g_value_set_string (value, identity->last_message); GST_OBJECT_UNLOCK (identity); break; case PROP_SYNC: g_value_set_boolean (value, identity->sync); break; case PROP_CHECK_PERFECT: g_value_set_boolean (value, identity->check_perfect); break; case PROP_CHECK_IMPERFECT_TIMESTAMP: g_value_set_boolean (value, identity->check_imperfect_timestamp); break; case PROP_CHECK_IMPERFECT_OFFSET: g_value_set_boolean (value, identity->check_imperfect_offset); break; case PROP_SIGNAL_HANDOFFS: g_value_set_boolean (value, identity->signal_handoffs); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static void gst_identity_finalize (GObject * object) { GstIdentity *identity; identity = GST_IDENTITY (object); g_free (identity->last_message); G_OBJECT_CLASS (parent_class)->finalize (object); }
static void gst_identity_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstIdentity *identity; identity = GST_IDENTITY (object); switch (prop_id) { case PROP_SLEEP_TIME: identity->sleep_time = g_value_get_uint (value); break; 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; case PROP_ERROR_AFTER: identity->error_after = g_value_get_int (value); break; case PROP_DROP_PROBABILITY: identity->drop_probability = g_value_get_float (value); break; case PROP_DROP_BUFFER_FLAGS: identity->drop_buffer_flags = g_value_get_flags (value); break; case PROP_DATARATE: identity->datarate = g_value_get_int (value); break; case PROP_SYNC: identity->sync = g_value_get_boolean (value); break; case PROP_CHECK_IMPERFECT_TIMESTAMP: identity->check_imperfect_timestamp = g_value_get_boolean (value); break; case PROP_CHECK_IMPERFECT_OFFSET: identity->check_imperfect_offset = g_value_get_boolean (value); break; case PROP_SIGNAL_HANDOFFS: identity->signal_handoffs = g_value_get_boolean (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } if (identity->datarate > 0 || identity->single_segment) gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (identity), FALSE); else gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (identity), TRUE); }
static gboolean gst_identity_stop (GstBaseTransform * trans) { GstIdentity *identity; identity = GST_IDENTITY (trans); GST_OBJECT_LOCK (identity); g_free (identity->last_message); identity->last_message = NULL; GST_OBJECT_UNLOCK (identity); return TRUE; }
static gboolean gst_identity_start (GstBaseTransform * trans) { GstIdentity *identity; identity = GST_IDENTITY (trans); 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; return TRUE; }
static void gst_identity_finalize (GObject * object) { GstIdentity *identity; identity = GST_IDENTITY (object); g_free (identity->last_message); #if !GLIB_CHECK_VERSION(2,26,0) g_static_rec_mutex_free (&identity->notify_lock); #endif G_OBJECT_CLASS (parent_class)->finalize (object); }
static GstStateChangeReturn gst_identity_change_state (GstElement * element, GstStateChange transition) { GstStateChangeReturn ret; GstIdentity *identity = GST_IDENTITY (element); switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: break; case GST_STATE_CHANGE_READY_TO_PAUSED: break; case GST_STATE_CHANGE_PAUSED_TO_PLAYING: break; case GST_STATE_CHANGE_PAUSED_TO_READY: GST_OBJECT_LOCK (identity); if (identity->clock_id) { GST_DEBUG_OBJECT (identity, "unlock clock wait"); gst_clock_id_unschedule (identity->clock_id); gst_clock_id_unref (identity->clock_id); identity->clock_id = NULL; } GST_OBJECT_UNLOCK (identity); break; default: break; } ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); switch (transition) { case GST_STATE_CHANGE_PLAYING_TO_PAUSED: break; case GST_STATE_CHANGE_PAUSED_TO_READY: break; case GST_STATE_CHANGE_READY_TO_NULL: break; default: break; } return ret; }
static GstFlowReturn gst_identity_prepare_output_buffer (GstBaseTransform * trans, GstBuffer * in_buf, gint out_size, GstCaps * out_caps, GstBuffer ** out_buf) { GstIdentity *identity = GST_IDENTITY (trans); /* only bother if we may have to alter metadata */ if (identity->datarate > 0 || identity->single_segment) { if (gst_buffer_is_metadata_writable (in_buf)) *out_buf = gst_buffer_ref (in_buf); else { /* make even less writable */ gst_buffer_ref (in_buf); /* extra ref is dropped going through the official process */ *out_buf = gst_buffer_make_metadata_writable (in_buf); } } else *out_buf = gst_buffer_ref (in_buf); return GST_FLOW_OK; }
static gboolean gst_identity_query (GstBaseTransform * base, GstPadDirection direction, GstQuery * query) { GstIdentity *identity; gboolean ret; identity = GST_IDENTITY (base); ret = GST_BASE_TRANSFORM_CLASS (parent_class)->query (base, direction, query); if (GST_QUERY_TYPE (query) == GST_QUERY_LATENCY) { gboolean live = FALSE; GstClockTime min = 0, max = 0; if (ret) { gst_query_parse_latency (query, &live, &min, &max); if (identity->sync && max < min) { GST_ELEMENT_WARNING (base, CORE, CLOCK, (NULL), ("Impossible to configure latency before identity sync=true:" " max %" GST_TIME_FORMAT " < min %" GST_TIME_FORMAT ". Add queues or other buffering elements.", GST_TIME_ARGS (max), GST_TIME_ARGS (min))); } } /* Ignore the upstream latency if it is not live */ GST_OBJECT_LOCK (identity); if (live) identity->upstream_latency = min; else identity->upstream_latency = 0; GST_OBJECT_UNLOCK (identity); gst_query_set_latency (query, live || identity->sync, min, max); ret = TRUE; } return ret; }
static GstFlowReturn gst_identity_transform_ip (GstBaseTransform * trans, GstBuffer * buf) { GstFlowReturn ret = GST_FLOW_OK; GstIdentity *identity = GST_IDENTITY (trans); GstClockTime runtimestamp = G_GINT64_CONSTANT (0); gsize size; size = gst_buffer_get_size (buf); if (identity->check_imperfect_timestamp) gst_identity_check_imperfect_timestamp (identity, buf); if (identity->check_imperfect_offset) gst_identity_check_imperfect_offset (identity, buf); /* update prev values */ identity->prev_timestamp = GST_BUFFER_TIMESTAMP (buf); identity->prev_duration = GST_BUFFER_DURATION (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) goto error_after; } if (identity->drop_probability > 0.0) { if ((gfloat) (1.0 * rand () / (RAND_MAX)) < identity->drop_probability) goto dropped; } if (identity->dump) { GstMapInfo info; gst_buffer_map (buf, &info, GST_MAP_READ); gst_util_dump_mem (info.data, info.size); gst_buffer_unmap (buf, &info); } if (!identity->silent) { gst_identity_update_last_message_for_buffer (identity, "chain", buf, size); } if (identity->datarate > 0) { GstClockTime time = gst_util_uint64_scale_int (identity->offset, GST_SECOND, identity->datarate); GST_BUFFER_TIMESTAMP (buf) = time; GST_BUFFER_DURATION (buf) = size * GST_SECOND / identity->datarate; } if (identity->signal_handoffs) g_signal_emit (identity, gst_identity_signals[SIGNAL_HANDOFF], 0, buf); if (trans->segment.format == GST_FORMAT_TIME) runtimestamp = gst_segment_to_running_time (&trans->segment, GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (buf)); if ((identity->sync) && (trans->segment.format == GST_FORMAT_TIME)) { GstClock *clock; GST_OBJECT_LOCK (identity); if ((clock = GST_ELEMENT (identity)->clock)) { GstClockReturn cret; GstClockTime timestamp; timestamp = runtimestamp + GST_ELEMENT (identity)->base_time; /* save id if we need to unlock */ identity->clock_id = gst_clock_new_single_shot_id (clock, timestamp); GST_OBJECT_UNLOCK (identity); cret = gst_clock_id_wait (identity->clock_id, NULL); GST_OBJECT_LOCK (identity); if (identity->clock_id) { gst_clock_id_unref (identity->clock_id); identity->clock_id = NULL; } if (cret == GST_CLOCK_UNSCHEDULED) ret = GST_FLOW_EOS; } GST_OBJECT_UNLOCK (identity); } identity->offset += size; if (identity->sleep_time && ret == GST_FLOW_OK) g_usleep (identity->sleep_time); if (identity->single_segment && (trans->segment.format == GST_FORMAT_TIME) && (ret == GST_FLOW_OK)) { GST_BUFFER_TIMESTAMP (buf) = runtimestamp; GST_BUFFER_OFFSET (buf) = GST_CLOCK_TIME_NONE; GST_BUFFER_OFFSET_END (buf) = GST_CLOCK_TIME_NONE; } return ret; /* ERRORS */ error_after: { GST_ELEMENT_ERROR (identity, CORE, FAILED, (_("Failed after iterations as requested.")), (NULL)); return GST_FLOW_ERROR; } dropped: { if (!identity->silent) { gst_identity_update_last_message_for_buffer (identity, "dropping", buf, size); } /* return DROPPED to basetransform. */ return GST_BASE_TRANSFORM_FLOW_DROPPED; } }
static gboolean gst_identity_sink_event (GstBaseTransform * trans, GstEvent * event) { GstIdentity *identity; gboolean ret = TRUE; identity = GST_IDENTITY (trans); if (!identity->silent) { const GstStructure *s; const gchar *tstr; gchar *sstr; GST_OBJECT_LOCK (identity); g_free (identity->last_message); tstr = gst_event_type_get_name (GST_EVENT_TYPE (event)); if ((s = gst_event_get_structure (event))) sstr = gst_structure_to_string (s); else sstr = g_strdup (""); identity->last_message = g_strdup_printf ("event ******* (%s:%s) E (type: %s (%d), %s) %p", GST_DEBUG_PAD_NAME (trans->sinkpad), tstr, GST_EVENT_TYPE (event), sstr, event); g_free (sstr); GST_OBJECT_UNLOCK (identity); gst_identity_notify_last_message (identity); } if (identity->single_segment && (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT)) { if (trans->have_segment == FALSE) { GstEvent *news; GstSegment segment; gst_event_copy_segment (event, &segment); gst_event_copy_segment (event, &trans->segment); trans->have_segment = TRUE; /* This is the first segment, send out a (0, -1) segment */ gst_segment_init (&segment, segment.format); news = gst_event_new_segment (&segment); gst_pad_event_default (trans->sinkpad, GST_OBJECT_CAST (trans), news); } } /* Reset previous timestamp, duration and offsets on NEWSEGMENT * to prevent false warnings when checking for perfect streams */ if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT) { identity->prev_timestamp = identity->prev_duration = GST_CLOCK_TIME_NONE; identity->prev_offset = identity->prev_offset_end = GST_BUFFER_OFFSET_NONE; } if (identity->single_segment && GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT) { /* eat up segments */ gst_event_unref (event); ret = TRUE; } else { if (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_START) { GST_OBJECT_LOCK (identity); if (identity->clock_id) { GST_DEBUG_OBJECT (identity, "unlock clock wait"); gst_clock_id_unschedule (identity->clock_id); gst_clock_id_unref (identity->clock_id); identity->clock_id = NULL; } GST_OBJECT_UNLOCK (identity); } ret = GST_BASE_TRANSFORM_CLASS (parent_class)->sink_event (trans, event); } return ret; }
static GstStateChangeReturn gst_identity_change_state (GstElement * element, GstStateChange transition) { GstStateChangeReturn ret; GstIdentity *identity = GST_IDENTITY (element); gboolean no_preroll = FALSE; switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: break; case GST_STATE_CHANGE_READY_TO_PAUSED: GST_OBJECT_LOCK (identity); identity->blocked = TRUE; GST_OBJECT_UNLOCK (identity); if (identity->sync) no_preroll = TRUE; break; case GST_STATE_CHANGE_PAUSED_TO_PLAYING: GST_OBJECT_LOCK (identity); identity->blocked = FALSE; g_cond_broadcast (&identity->blocked_cond); GST_OBJECT_UNLOCK (identity); break; case GST_STATE_CHANGE_PAUSED_TO_READY: GST_OBJECT_LOCK (identity); if (identity->clock_id) { GST_DEBUG_OBJECT (identity, "unlock clock wait"); gst_clock_id_unschedule (identity->clock_id); } identity->blocked = FALSE; g_cond_broadcast (&identity->blocked_cond); GST_OBJECT_UNLOCK (identity); break; default: break; } ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); switch (transition) { case GST_STATE_CHANGE_PLAYING_TO_PAUSED: GST_OBJECT_LOCK (identity); identity->upstream_latency = 0; identity->blocked = TRUE; GST_OBJECT_UNLOCK (identity); if (identity->sync) no_preroll = TRUE; break; case GST_STATE_CHANGE_PAUSED_TO_READY: break; case GST_STATE_CHANGE_READY_TO_NULL: break; default: break; } if (no_preroll && ret == GST_STATE_CHANGE_SUCCESS) ret = GST_STATE_CHANGE_NO_PREROLL; return ret; }
static GstFlowReturn gst_identity_transform_ip (GstBaseTransform * trans, GstBuffer * buf) { GstFlowReturn ret = GST_FLOW_OK; GstIdentity *identity = GST_IDENTITY (trans); GstClockTime rundts = GST_CLOCK_TIME_NONE; GstClockTime runpts = GST_CLOCK_TIME_NONE; GstClockTime ts, duration, runtimestamp; gsize size; size = gst_buffer_get_size (buf); if (identity->check_imperfect_timestamp) gst_identity_check_imperfect_timestamp (identity, buf); if (identity->check_imperfect_offset) gst_identity_check_imperfect_offset (identity, buf); /* update prev values */ identity->prev_timestamp = GST_BUFFER_TIMESTAMP (buf); identity->prev_duration = GST_BUFFER_DURATION (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) goto error_after; } if (identity->drop_probability > 0.0) { if ((gfloat) (1.0 * rand () / (RAND_MAX)) < identity->drop_probability) goto dropped; } if (identity->dump) { GstMapInfo info; gst_buffer_map (buf, &info, GST_MAP_READ); gst_util_dump_mem (info.data, info.size); gst_buffer_unmap (buf, &info); } if (!identity->silent) { gst_identity_update_last_message_for_buffer (identity, "chain", buf, size); } if (identity->datarate > 0) { GstClockTime time = gst_util_uint64_scale_int (identity->offset, GST_SECOND, identity->datarate); GST_BUFFER_PTS (buf) = GST_BUFFER_DTS (buf) = time; GST_BUFFER_DURATION (buf) = size * GST_SECOND / identity->datarate; } if (identity->signal_handoffs) g_signal_emit (identity, gst_identity_signals[SIGNAL_HANDOFF], 0, buf); if (trans->segment.format == GST_FORMAT_TIME) { rundts = gst_segment_to_running_time (&trans->segment, GST_FORMAT_TIME, GST_BUFFER_DTS (buf)); runpts = gst_segment_to_running_time (&trans->segment, GST_FORMAT_TIME, GST_BUFFER_PTS (buf)); } if (GST_CLOCK_TIME_IS_VALID (rundts)) runtimestamp = rundts; else if (GST_CLOCK_TIME_IS_VALID (runpts)) runtimestamp = runpts; else runtimestamp = 0; ret = gst_identity_do_sync (identity, runtimestamp); identity->offset += size; if (identity->sleep_time && ret == GST_FLOW_OK) g_usleep (identity->sleep_time); if (identity->single_segment && (trans->segment.format == GST_FORMAT_TIME) && (ret == GST_FLOW_OK)) { GST_BUFFER_DTS (buf) = rundts; GST_BUFFER_PTS (buf) = runpts; GST_BUFFER_OFFSET (buf) = GST_CLOCK_TIME_NONE; GST_BUFFER_OFFSET_END (buf) = GST_CLOCK_TIME_NONE; } return ret; /* ERRORS */ error_after: { GST_ELEMENT_ERROR (identity, CORE, FAILED, (_("Failed after iterations as requested.")), (NULL)); return GST_FLOW_ERROR; } dropped: { if (!identity->silent) { gst_identity_update_last_message_for_buffer (identity, "dropping", buf, size); } ts = GST_BUFFER_TIMESTAMP (buf); if (GST_CLOCK_TIME_IS_VALID (ts)) { duration = GST_BUFFER_DURATION (buf); gst_pad_push_event (GST_BASE_TRANSFORM_SRC_PAD (identity), gst_event_new_gap (ts, duration)); } /* return DROPPED to basetransform. */ return GST_BASE_TRANSFORM_FLOW_DROPPED; } }
static GstFlowReturn gst_identity_transform_ip (GstBaseTransform * trans, GstBuffer * buf) { GstFlowReturn ret = GST_FLOW_OK; GstIdentity *identity = GST_IDENTITY (trans); GstClockTime runtimestamp = G_GINT64_CONSTANT (0); if (identity->check_perfect) gst_identity_check_perfect (identity, buf); if (identity->check_imperfect_timestamp) gst_identity_check_imperfect_timestamp (identity, buf); if (identity->check_imperfect_offset) gst_identity_check_imperfect_offset (identity, buf); /* update prev values */ identity->prev_timestamp = GST_BUFFER_TIMESTAMP (buf); identity->prev_duration = GST_BUFFER_DURATION (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) { GST_ELEMENT_ERROR (identity, CORE, FAILED, (_("Failed after iterations as requested.")), (NULL)); return GST_FLOW_ERROR; } } if (identity->drop_probability > 0.0) { if ((gfloat) (1.0 * rand () / (RAND_MAX)) < identity->drop_probability) { if (!identity->silent) { GST_OBJECT_LOCK (identity); g_free (identity->last_message); identity->last_message = g_strdup_printf ("dropping ******* (%s:%s)i (%d bytes, timestamp: %" GST_TIME_FORMAT ", duration: %" GST_TIME_FORMAT ", offset: %" G_GINT64_FORMAT ", offset_end: % " G_GINT64_FORMAT ", flags: %d) %p", GST_DEBUG_PAD_NAME (trans->sinkpad), GST_BUFFER_SIZE (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), GST_TIME_ARGS (GST_BUFFER_DURATION (buf)), GST_BUFFER_OFFSET (buf), GST_BUFFER_OFFSET_END (buf), GST_BUFFER_FLAGS (buf), buf); GST_OBJECT_UNLOCK (identity); g_object_notify (G_OBJECT (identity), "last-message"); } /* return DROPPED to basetransform. */ return GST_BASE_TRANSFORM_FLOW_DROPPED; } } if (identity->dump) { gst_util_dump_mem (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf)); } if (!identity->silent) { GST_OBJECT_LOCK (identity); g_free (identity->last_message); identity->last_message = g_strdup_printf ("chain ******* (%s:%s)i (%d bytes, timestamp: %" GST_TIME_FORMAT ", duration: %" GST_TIME_FORMAT ", offset: %" G_GINT64_FORMAT ", offset_end: % " G_GINT64_FORMAT ", flags: %d) %p", GST_DEBUG_PAD_NAME (trans->sinkpad), GST_BUFFER_SIZE (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), GST_TIME_ARGS (GST_BUFFER_DURATION (buf)), GST_BUFFER_OFFSET (buf), GST_BUFFER_OFFSET_END (buf), GST_BUFFER_FLAGS (buf), buf); GST_OBJECT_UNLOCK (identity); g_object_notify (G_OBJECT (identity), "last-message"); } if (identity->datarate > 0) { GstClockTime time = gst_util_uint64_scale_int (identity->offset, GST_SECOND, identity->datarate); GST_BUFFER_TIMESTAMP (buf) = time; GST_BUFFER_DURATION (buf) = GST_BUFFER_SIZE (buf) * GST_SECOND / identity->datarate; } if (identity->signal_handoffs) g_signal_emit (G_OBJECT (identity), gst_identity_signals[SIGNAL_HANDOFF], 0, buf); if (trans->segment.format == GST_FORMAT_TIME) runtimestamp = gst_segment_to_running_time (&trans->segment, GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (buf)); if ((identity->sync) && (trans->segment.format == GST_FORMAT_TIME)) { GstClock *clock; GST_OBJECT_LOCK (identity); if ((clock = GST_ELEMENT (identity)->clock)) { GstClockReturn cret; GstClockTime timestamp; timestamp = runtimestamp + GST_ELEMENT (identity)->base_time; /* save id if we need to unlock */ /* FIXME: actually unlock this somewhere in the state changes */ identity->clock_id = gst_clock_new_single_shot_id (clock, timestamp); GST_OBJECT_UNLOCK (identity); cret = gst_clock_id_wait (identity->clock_id, NULL); GST_OBJECT_LOCK (identity); if (identity->clock_id) { gst_clock_id_unref (identity->clock_id); identity->clock_id = NULL; } if (cret == GST_CLOCK_UNSCHEDULED) ret = GST_FLOW_UNEXPECTED; } GST_OBJECT_UNLOCK (identity); } identity->offset += GST_BUFFER_SIZE (buf); if (identity->sleep_time && ret == GST_FLOW_OK) g_usleep (identity->sleep_time); if (identity->single_segment && (trans->segment.format == GST_FORMAT_TIME) && (ret == GST_FLOW_OK)) { GST_BUFFER_TIMESTAMP (buf) = runtimestamp; GST_BUFFER_OFFSET (buf) = GST_CLOCK_TIME_NONE; GST_BUFFER_OFFSET_END (buf) = GST_CLOCK_TIME_NONE; } return ret; }
static gboolean gst_identity_event (GstBaseTransform * trans, GstEvent * event) { GstIdentity *identity; gboolean ret = TRUE; identity = GST_IDENTITY (trans); if (!identity->silent) { const GstStructure *s; gchar *sstr; GST_OBJECT_LOCK (identity); g_free (identity->last_message); if ((s = gst_event_get_structure (event))) sstr = gst_structure_to_string (s); else sstr = g_strdup (""); identity->last_message = g_strdup_printf ("event ******* (%s:%s) E (type: %d, %s) %p", GST_DEBUG_PAD_NAME (trans->sinkpad), GST_EVENT_TYPE (event), sstr, event); g_free (sstr); GST_OBJECT_UNLOCK (identity); g_object_notify (G_OBJECT (identity), "last_message"); } 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; } } /* Reset previous timestamp, duration and offsets on NEWSEGMENT * to prevent false warnings when checking for perfect streams */ if (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT) { identity->prev_timestamp = identity->prev_duration = GST_CLOCK_TIME_NONE; identity->prev_offset = identity->prev_offset_end = GST_BUFFER_OFFSET_NONE; } ret = parent_class->event (trans, event); if (identity->single_segment && (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT)) { /* eat up segments */ ret = FALSE; } return ret; }