gstreamer_core/plugins/elements/gstidentity.c
branchRCL_3
changeset 30 7e817e7e631c
parent 29 567bb019e3e3
equal deleted inserted replaced
29:567bb019e3e3 30:7e817e7e631c
    20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    21  * Boston, MA 02111-1307, USA.
    21  * Boston, MA 02111-1307, USA.
    22  */
    22  */
    23 /**
    23 /**
    24  * SECTION:element-identity
    24  * SECTION:element-identity
       
    25  * @short_description: pass data through without modification
    25  *
    26  *
    26  * Dummy element that passes incomming data through unmodified. It has some
    27  * Dummy element that passes incomming data through unmodified. I has some
    27  * useful diagnostic functions, such as offset and timestamp checking.
    28  * useful diagnostic functions, such as offset and timestamp checking.
    28  */
    29  */
    29 
    30 
    30 #ifdef HAVE_CONFIG_H
    31 #ifdef HAVE_CONFIG_H
    31 #  include "config.h"
    32 #  include "config.h"
    32 #endif
    33 #endif
    33 
    34 
       
    35 #ifdef __SYMBIAN32__
       
    36 #include <gst_global.h>
       
    37 #endif
    34 #include <stdlib.h>
    38 #include <stdlib.h>
    35 
    39 
    36 #include "../../gst/gst-i18n-lib.h"
    40 #include "../../gst/gst-i18n-lib.h"
    37 #include "gstidentity.h"
    41 #include "gstidentity.h"
    38 #include <gst/gstmarshal.h>
    42 #include <gst/gstmarshal.h>
       
    43 #ifdef __SYMBIAN32__
       
    44 #include <glib_global.h>
       
    45 #include <gobject_global.h>
       
    46 
       
    47 #endif
    39 
    48 
    40 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
    49 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
    41     GST_PAD_SINK,
    50     GST_PAD_SINK,
    42     GST_PAD_ALWAYS,
    51     GST_PAD_ALWAYS,
    43     GST_STATIC_CAPS_ANY);
    52     GST_STATIC_CAPS_ANY);
   104     GValue * value, GParamSpec * pspec);
   113     GValue * value, GParamSpec * pspec);
   105 
   114 
   106 static gboolean gst_identity_event (GstBaseTransform * trans, GstEvent * event);
   115 static gboolean gst_identity_event (GstBaseTransform * trans, GstEvent * event);
   107 static GstFlowReturn gst_identity_transform_ip (GstBaseTransform * trans,
   116 static GstFlowReturn gst_identity_transform_ip (GstBaseTransform * trans,
   108     GstBuffer * buf);
   117     GstBuffer * buf);
   109 static GstFlowReturn gst_identity_prepare_output_buffer (GstBaseTransform
       
   110     * trans, GstBuffer * in_buf, gint out_size, GstCaps * out_caps,
       
   111     GstBuffer ** out_buf);
       
   112 static gboolean gst_identity_start (GstBaseTransform * trans);
   118 static gboolean gst_identity_start (GstBaseTransform * trans);
   113 static gboolean gst_identity_stop (GstBaseTransform * trans);
   119 static gboolean gst_identity_stop (GstBaseTransform * trans);
   114 
   120 
   115 static guint gst_identity_signals[LAST_SIGNAL] = { 0 };
   121 static guint gst_identity_signals[LAST_SIGNAL] = { 0 };
   116 
   122 
   135   GstIdentity *identity;
   141   GstIdentity *identity;
   136 
   142 
   137   identity = GST_IDENTITY (object);
   143   identity = GST_IDENTITY (object);
   138 
   144 
   139   g_free (identity->last_message);
   145   g_free (identity->last_message);
   140   g_static_rec_mutex_free (&identity->notify_lock);
       
   141 
   146 
   142   G_OBJECT_CLASS (parent_class)->finalize (object);
   147   G_OBJECT_CLASS (parent_class)->finalize (object);
   143 }
   148 }
   144 
   149 
   145 /* fixme: do something about this */
   150 /* fixme: do something about this */
   162   } else {
   167   } else {
   163     data1 = g_value_peek_pointer (param_values + 0);
   168     data1 = g_value_peek_pointer (param_values + 0);
   164     data2 = closure->data;
   169     data2 = closure->data;
   165   }
   170   }
   166   callback =
   171   callback =
   167       (marshalfunc_VOID__MINIOBJECT) (marshal_data ? marshal_data :
   172       (marshalfunc_VOID__MINIOBJECT) (marshal_data ? marshal_data : cc->
   168       cc->callback);
   173       callback);
   169 
   174 
   170   callback (data1, gst_value_get_mini_object (param_values + 1), data2);
   175   callback (data1, gst_value_get_mini_object (param_values + 1), data2);
   171 }
   176 }
   172 
   177 
   173 static void
   178 static void
   174 gst_identity_class_init (GstIdentityClass * klass)
   179 gst_identity_class_init (GstIdentityClass * klass)
   175 {
   180 {
   176   GObjectClass *gobject_class;
   181   GObjectClass *gobject_class;
       
   182   GstElementClass *gstelement_class;
   177   GstBaseTransformClass *gstbasetrans_class;
   183   GstBaseTransformClass *gstbasetrans_class;
   178 
   184 
   179   gobject_class = G_OBJECT_CLASS (klass);
   185   gobject_class = G_OBJECT_CLASS (klass);
       
   186   gstelement_class = GST_ELEMENT_CLASS (klass);
   180   gstbasetrans_class = GST_BASE_TRANSFORM_CLASS (klass);
   187   gstbasetrans_class = GST_BASE_TRANSFORM_CLASS (klass);
   181 
   188 
   182   gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_identity_set_property);
   189   gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_identity_set_property);
   183   gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_identity_get_property);
   190   gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_identity_get_property);
   184 
   191 
   185   g_object_class_install_property (gobject_class, PROP_SLEEP_TIME,
   192   g_object_class_install_property (gobject_class, PROP_SLEEP_TIME,
   186       g_param_spec_uint ("sleep-time", "Sleep time",
   193       g_param_spec_uint ("sleep-time", "Sleep time",
   187           "Microseconds to sleep between processing", 0, G_MAXUINT,
   194           "Microseconds to sleep between processing", 0, G_MAXUINT,
   188           DEFAULT_SLEEP_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   195           DEFAULT_SLEEP_TIME, G_PARAM_READWRITE));
   189   g_object_class_install_property (gobject_class, PROP_ERROR_AFTER,
   196   g_object_class_install_property (gobject_class, PROP_ERROR_AFTER,
   190       g_param_spec_int ("error-after", "Error After", "Error after N buffers",
   197       g_param_spec_int ("error_after", "Error After", "Error after N buffers",
   191           G_MININT, G_MAXINT, DEFAULT_ERROR_AFTER,
   198           G_MININT, G_MAXINT, DEFAULT_ERROR_AFTER, G_PARAM_READWRITE));
   192           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   199   g_object_class_install_property (gobject_class,
   193   g_object_class_install_property (gobject_class, PROP_DROP_PROBABILITY,
   200       PROP_DROP_PROBABILITY, g_param_spec_float ("drop_probability",
   194       g_param_spec_float ("drop-probability", "Drop Probability",
   201           "Drop Probability",
   195           "The Probability a buffer is dropped", 0.0, 1.0,
   202           "The Probability a buffer is dropped", 0.0, 1.0,
   196           DEFAULT_DROP_PROBABILITY,
   203           DEFAULT_DROP_PROBABILITY, G_PARAM_READWRITE));
   197           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
       
   198   g_object_class_install_property (gobject_class, PROP_DATARATE,
   204   g_object_class_install_property (gobject_class, PROP_DATARATE,
   199       g_param_spec_int ("datarate", "Datarate",
   205       g_param_spec_int ("datarate", "Datarate",
   200           "(Re)timestamps buffers with number of bytes per second (0 = inactive)",
   206           "(Re)timestamps buffers with number of bytes per second (0 = inactive)",
   201           0, G_MAXINT, DEFAULT_DATARATE,
   207           0, G_MAXINT, DEFAULT_DATARATE, G_PARAM_READWRITE));
   202           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
       
   203   g_object_class_install_property (gobject_class, PROP_SILENT,
   208   g_object_class_install_property (gobject_class, PROP_SILENT,
   204       g_param_spec_boolean ("silent", "silent", "silent", DEFAULT_SILENT,
   209       g_param_spec_boolean ("silent", "silent", "silent", DEFAULT_SILENT,
   205           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   210           G_PARAM_READWRITE));
   206   g_object_class_install_property (gobject_class, PROP_SINGLE_SEGMENT,
   211   g_object_class_install_property (gobject_class, PROP_SINGLE_SEGMENT,
   207       g_param_spec_boolean ("single-segment", "Single Segment",
   212       g_param_spec_boolean ("single-segment", "Single Segment",
   208           "Timestamp buffers and eat newsegments so as to appear as one segment",
   213           "Timestamp buffers and eat newsegments so as to appear as one segment",
   209           DEFAULT_SINGLE_SEGMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   214           DEFAULT_SINGLE_SEGMENT, G_PARAM_READWRITE));
   210   g_object_class_install_property (gobject_class, PROP_LAST_MESSAGE,
   215   g_object_class_install_property (gobject_class, PROP_LAST_MESSAGE,
   211       g_param_spec_string ("last-message", "last-message", "last-message", NULL,
   216       g_param_spec_string ("last-message", "last-message", "last-message", NULL,
   212           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
   217           G_PARAM_READABLE));
   213   g_object_class_install_property (gobject_class, PROP_DUMP,
   218   g_object_class_install_property (gobject_class, PROP_DUMP,
   214       g_param_spec_boolean ("dump", "Dump", "Dump buffer contents to stdout",
   219       g_param_spec_boolean ("dump", "Dump", "Dump buffer contents to stdout",
   215           DEFAULT_DUMP, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   220           DEFAULT_DUMP, G_PARAM_READWRITE));
   216   g_object_class_install_property (gobject_class, PROP_SYNC,
   221   g_object_class_install_property (gobject_class, PROP_SYNC,
   217       g_param_spec_boolean ("sync", "Synchronize",
   222       g_param_spec_boolean ("sync", "Synchronize",
   218           "Synchronize to pipeline clock", DEFAULT_SYNC,
   223           "Synchronize to pipeline clock", DEFAULT_SYNC, G_PARAM_READWRITE));
   219           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
       
   220   g_object_class_install_property (gobject_class, PROP_CHECK_PERFECT,
   224   g_object_class_install_property (gobject_class, PROP_CHECK_PERFECT,
   221       g_param_spec_boolean ("check-perfect", "Check For Perfect Stream",
   225       g_param_spec_boolean ("check-perfect", "Check For Perfect Stream",
   222           "Verify that the stream is time- and data-contiguous. "
   226           "Verify that the stream is time- and data-contiguous. "
   223           "This only logs in the debug log.  This will be deprecated in favor "
   227           "This only logs in the debug log.  This will be deprecated in favor "
   224           "of the check-imperfect-timestamp/offset properties.",
   228           "of the check-imperfect-timestamp/offset properties.",
   225           DEFAULT_CHECK_PERFECT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   229           DEFAULT_CHECK_PERFECT, G_PARAM_READWRITE));
   226   g_object_class_install_property (gobject_class,
   230   g_object_class_install_property (gobject_class,
   227       PROP_CHECK_IMPERFECT_TIMESTAMP,
   231       PROP_CHECK_IMPERFECT_TIMESTAMP,
   228       g_param_spec_boolean ("check-imperfect-timestamp",
   232       g_param_spec_boolean ("check-imperfect-timestamp",
   229           "Check for discontiguous timestamps",
   233           "Check for discontiguous timestamps",
   230           "Send element messages if timestamps and durations do not match up",
   234           "Send element messages if timestamps and durations do not match up",
   231           DEFAULT_CHECK_IMPERFECT_TIMESTAMP,
   235           DEFAULT_CHECK_IMPERFECT_TIMESTAMP, G_PARAM_READWRITE));
   232           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
       
   233   g_object_class_install_property (gobject_class, PROP_CHECK_IMPERFECT_OFFSET,
   236   g_object_class_install_property (gobject_class, PROP_CHECK_IMPERFECT_OFFSET,
   234       g_param_spec_boolean ("check-imperfect-offset",
   237       g_param_spec_boolean ("check-imperfect-offset",
   235           "Check for discontiguous offset",
   238           "Check for discontiguous offset",
   236           "Send element messages if offset and offset_end do not match up",
   239           "Send element messages if offset and offset_end do not match up",
   237           DEFAULT_CHECK_IMPERFECT_OFFSET,
   240           DEFAULT_CHECK_IMPERFECT_OFFSET, G_PARAM_READWRITE));
   238           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
       
   239 
   241 
   240   /**
   242   /**
   241    * GstIdentity:signal-handoffs
   243    * GstIdentity:signal-handoffs
   242    *
   244    *
   243    * If set to #TRUE, the identity will emit a handoff signal when handling a buffer.
   245    * If set to #TRUE, the identity will emit a handoff signal when handling a buffer.
   246    * Since: 0.10.16
   248    * Since: 0.10.16
   247    */
   249    */
   248   g_object_class_install_property (gobject_class, PROP_SIGNAL_HANDOFFS,
   250   g_object_class_install_property (gobject_class, PROP_SIGNAL_HANDOFFS,
   249       g_param_spec_boolean ("signal-handoffs",
   251       g_param_spec_boolean ("signal-handoffs",
   250           "Signal handoffs", "Send a signal before pushing the buffer",
   252           "Signal handoffs", "Send a signal before pushing the buffer",
   251           DEFAULT_SIGNAL_HANDOFFS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   253           DEFAULT_SIGNAL_HANDOFFS, G_PARAM_READWRITE));
   252 
   254 
   253   /**
   255   /**
   254    * GstIdentity::handoff:
   256    * GstIdentity::handoff:
   255    * @identity: the identity instance
   257    * @identity: the identity instance
   256    * @buffer: the buffer that just has been received
   258    * @buffer: the buffer that just has been received
   266   gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_identity_finalize);
   268   gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_identity_finalize);
   267 
   269 
   268   gstbasetrans_class->event = GST_DEBUG_FUNCPTR (gst_identity_event);
   270   gstbasetrans_class->event = GST_DEBUG_FUNCPTR (gst_identity_event);
   269   gstbasetrans_class->transform_ip =
   271   gstbasetrans_class->transform_ip =
   270       GST_DEBUG_FUNCPTR (gst_identity_transform_ip);
   272       GST_DEBUG_FUNCPTR (gst_identity_transform_ip);
   271   gstbasetrans_class->prepare_output_buffer =
       
   272       GST_DEBUG_FUNCPTR (gst_identity_prepare_output_buffer);
       
   273   gstbasetrans_class->start = GST_DEBUG_FUNCPTR (gst_identity_start);
   273   gstbasetrans_class->start = GST_DEBUG_FUNCPTR (gst_identity_start);
   274   gstbasetrans_class->stop = GST_DEBUG_FUNCPTR (gst_identity_stop);
   274   gstbasetrans_class->stop = GST_DEBUG_FUNCPTR (gst_identity_stop);
   275 }
   275 }
   276 
   276 
   277 static void
   277 static void
   278 gst_identity_init (GstIdentity * identity, GstIdentityClass * g_class)
   278 gst_identity_init (GstIdentity * identity, GstIdentityClass * g_class)
   279 {
   279 {
       
   280   gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (identity), TRUE);
       
   281 
   280   identity->sleep_time = DEFAULT_SLEEP_TIME;
   282   identity->sleep_time = DEFAULT_SLEEP_TIME;
   281   identity->error_after = DEFAULT_ERROR_AFTER;
   283   identity->error_after = DEFAULT_ERROR_AFTER;
   282   identity->drop_probability = DEFAULT_DROP_PROBABILITY;
   284   identity->drop_probability = DEFAULT_DROP_PROBABILITY;
   283   identity->datarate = DEFAULT_DATARATE;
   285   identity->datarate = DEFAULT_DATARATE;
   284   identity->silent = DEFAULT_SILENT;
   286   identity->silent = DEFAULT_SILENT;
   288   identity->check_imperfect_timestamp = DEFAULT_CHECK_IMPERFECT_TIMESTAMP;
   290   identity->check_imperfect_timestamp = DEFAULT_CHECK_IMPERFECT_TIMESTAMP;
   289   identity->check_imperfect_offset = DEFAULT_CHECK_IMPERFECT_OFFSET;
   291   identity->check_imperfect_offset = DEFAULT_CHECK_IMPERFECT_OFFSET;
   290   identity->dump = DEFAULT_DUMP;
   292   identity->dump = DEFAULT_DUMP;
   291   identity->last_message = NULL;
   293   identity->last_message = NULL;
   292   identity->signal_handoffs = DEFAULT_SIGNAL_HANDOFFS;
   294   identity->signal_handoffs = DEFAULT_SIGNAL_HANDOFFS;
   293   g_static_rec_mutex_init (&identity->notify_lock);
       
   294 }
       
   295 
       
   296 static void
       
   297 gst_identity_notify_last_message (GstIdentity * identity)
       
   298 {
       
   299   /* FIXME: this hacks around a bug in GLib/GObject: doing concurrent
       
   300    * g_object_notify() on the same object might lead to crashes, see
       
   301    * http://bugzilla.gnome.org/show_bug.cgi?id=166020#c60 and follow-ups.
       
   302    * So we really don't want to do a g_object_notify() here for out-of-band
       
   303    * events with the streaming thread possibly also doing a g_object_notify()
       
   304    * for an in-band buffer or event. */
       
   305   g_static_rec_mutex_lock (&identity->notify_lock);
       
   306   g_object_notify ((GObject *) identity, "last_message");
       
   307   g_static_rec_mutex_unlock (&identity->notify_lock);
       
   308 }
   295 }
   309 
   296 
   310 static gboolean
   297 static gboolean
   311 gst_identity_event (GstBaseTransform * trans, GstEvent * event)
   298 gst_identity_event (GstBaseTransform * trans, GstEvent * event)
   312 {
   299 {
   332         GST_DEBUG_PAD_NAME (trans->sinkpad), GST_EVENT_TYPE (event), sstr,
   319         GST_DEBUG_PAD_NAME (trans->sinkpad), GST_EVENT_TYPE (event), sstr,
   333         event);
   320         event);
   334     g_free (sstr);
   321     g_free (sstr);
   335     GST_OBJECT_UNLOCK (identity);
   322     GST_OBJECT_UNLOCK (identity);
   336 
   323 
   337     gst_identity_notify_last_message (identity);
   324     g_object_notify (G_OBJECT (identity), "last_message");
   338   }
   325   }
   339 
   326 
   340   if (identity->single_segment
   327   if (identity->single_segment
   341       && (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT)) {
   328       && (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT)) {
   342     if (trans->have_newsegment == FALSE) {
   329     if (trans->have_newsegment == FALSE) {
   347           NULL);
   334           NULL);
   348 
   335 
   349       /* This is the first newsegment, send out a (0, -1) newsegment */
   336       /* This is the first newsegment, send out a (0, -1) newsegment */
   350       news = gst_event_new_new_segment (TRUE, 1.0, format, 0, -1, 0);
   337       news = gst_event_new_new_segment (TRUE, 1.0, format, 0, -1, 0);
   351 
   338 
   352       gst_pad_event_default (trans->sinkpad, news);
   339       if (!(gst_pad_event_default (trans->sinkpad, news)))
       
   340         return FALSE;
   353     }
   341     }
   354   }
   342   }
   355 
   343 
   356   /* Reset previous timestamp, duration and offsets on NEWSEGMENT
   344   GST_BASE_TRANSFORM_CLASS (parent_class)->event (trans, event);
   357    * to prevent false warnings when checking for perfect streams */
       
   358   if (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT) {
       
   359     identity->prev_timestamp = identity->prev_duration = GST_CLOCK_TIME_NONE;
       
   360     identity->prev_offset = identity->prev_offset_end = GST_BUFFER_OFFSET_NONE;
       
   361   }
       
   362 
       
   363   ret = parent_class->event (trans, event);
       
   364 
   345 
   365   if (identity->single_segment
   346   if (identity->single_segment
   366       && (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT)) {
   347       && (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT)) {
   367     /* eat up segments */
   348     /* eat up segments */
   368     ret = FALSE;
   349     ret = FALSE;
   369   }
   350   }
   370 
   351 
   371   return ret;
   352   return ret;
   372 }
       
   373 
       
   374 static GstFlowReturn
       
   375 gst_identity_prepare_output_buffer (GstBaseTransform * trans,
       
   376     GstBuffer * in_buf, gint out_size, GstCaps * out_caps, GstBuffer ** out_buf)
       
   377 {
       
   378   GstIdentity *identity = GST_IDENTITY (trans);
       
   379 
       
   380   /* only bother if we may have to alter metadata */
       
   381   if (identity->datarate > 0 || identity->single_segment) {
       
   382     if (gst_buffer_is_metadata_writable (in_buf))
       
   383       *out_buf = gst_buffer_ref (in_buf);
       
   384     else {
       
   385       /* make even less writable */
       
   386       gst_buffer_ref (in_buf);
       
   387       /* extra ref is dropped going through the official process */
       
   388       *out_buf = gst_buffer_make_metadata_writable (in_buf);
       
   389     }
       
   390   } else
       
   391     *out_buf = gst_buffer_ref (in_buf);
       
   392 
       
   393   return GST_FLOW_OK;
       
   394 }
   353 }
   395 
   354 
   396 static void
   355 static void
   397 gst_identity_check_perfect (GstIdentity * identity, GstBuffer * buf)
   356 gst_identity_check_perfect (GstIdentity * identity, GstBuffer * buf)
   398 {
   357 {
   421             GST_TIME_ARGS (t_expected), (dt < 0) ? '-' : '+',
   380             GST_TIME_ARGS (t_expected), (dt < 0) ? '-' : '+',
   422             GST_TIME_ARGS ((dt < 0) ? (GstClockTime) (-dt) : dt));
   381             GST_TIME_ARGS ((dt < 0) ? (GstClockTime) (-dt) : dt));
   423       }
   382       }
   424 
   383 
   425       offset = GST_BUFFER_OFFSET (buf);
   384       offset = GST_BUFFER_OFFSET (buf);
   426       if (identity->prev_offset_end != offset &&
   385       if (identity->prev_offset_end != offset) {
   427           identity->prev_offset_end != GST_BUFFER_OFFSET_NONE &&
       
   428           offset != GST_BUFFER_OFFSET_NONE) {
       
   429         GST_WARNING_OBJECT (identity,
   386         GST_WARNING_OBJECT (identity,
   430             "Buffer not data-contiguous with previous one: "
   387             "Buffer not data-contiguous with previous one: "
   431             "prev offset_end %" G_GINT64_FORMAT ", new offset %"
   388             "prev offset_end %" G_GINT64_FORMAT ", new offset %"
   432             G_GINT64_FORMAT, identity->prev_offset_end, offset);
   389             G_GINT64_FORMAT, identity->prev_offset_end, offset);
   433       }
   390       }
   446   /* invalid timestamp drops us out of check.  FIXME: maybe warn ? */
   403   /* invalid timestamp drops us out of check.  FIXME: maybe warn ? */
   447   if (timestamp != GST_CLOCK_TIME_NONE) {
   404   if (timestamp != GST_CLOCK_TIME_NONE) {
   448     /* check if we had a previous buffer to compare to */
   405     /* check if we had a previous buffer to compare to */
   449     if (identity->prev_timestamp != GST_CLOCK_TIME_NONE &&
   406     if (identity->prev_timestamp != GST_CLOCK_TIME_NONE &&
   450         identity->prev_duration != GST_CLOCK_TIME_NONE) {
   407         identity->prev_duration != GST_CLOCK_TIME_NONE) {
       
   408       guint64 offset;
   451       GstClockTime t_expected;
   409       GstClockTime t_expected;
   452       GstClockTimeDiff dt;
   410       GstClockTimeDiff dt;
   453 
   411 
       
   412       offset = GST_BUFFER_OFFSET (buf);
   454       t_expected = identity->prev_timestamp + identity->prev_duration;
   413       t_expected = identity->prev_timestamp + identity->prev_duration;
   455       dt = GST_CLOCK_DIFF (t_expected, timestamp);
   414       dt = GST_CLOCK_DIFF (t_expected, timestamp);
   456       if (dt != 0) {
   415       if (dt != 0) {
   457         /*
   416         /*
   458          * "imperfect-timestamp" bus message:
   417          * "imperfect-timestamp" bus message:
   575             ", flags: %d) %p", GST_DEBUG_PAD_NAME (trans->sinkpad),
   534             ", flags: %d) %p", GST_DEBUG_PAD_NAME (trans->sinkpad),
   576             GST_BUFFER_SIZE (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
   535             GST_BUFFER_SIZE (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
   577             GST_TIME_ARGS (GST_BUFFER_DURATION (buf)), GST_BUFFER_OFFSET (buf),
   536             GST_TIME_ARGS (GST_BUFFER_DURATION (buf)), GST_BUFFER_OFFSET (buf),
   578             GST_BUFFER_OFFSET_END (buf), GST_BUFFER_FLAGS (buf), buf);
   537             GST_BUFFER_OFFSET_END (buf), GST_BUFFER_FLAGS (buf), buf);
   579         GST_OBJECT_UNLOCK (identity);
   538         GST_OBJECT_UNLOCK (identity);
   580         gst_identity_notify_last_message (identity);
   539         g_object_notify (G_OBJECT (identity), "last-message");
   581       }
   540       }
   582       /* return DROPPED to basetransform. */
   541       /* return DROPPED to basetransform. */
   583       return GST_BASE_TRANSFORM_FLOW_DROPPED;
   542       return GST_BASE_TRANSFORM_FLOW_DROPPED;
   584     }
   543     }
   585   }
   544   }
   599         GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
   558         GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
   600         GST_TIME_ARGS (GST_BUFFER_DURATION (buf)),
   559         GST_TIME_ARGS (GST_BUFFER_DURATION (buf)),
   601         GST_BUFFER_OFFSET (buf), GST_BUFFER_OFFSET_END (buf),
   560         GST_BUFFER_OFFSET (buf), GST_BUFFER_OFFSET_END (buf),
   602         GST_BUFFER_FLAGS (buf), buf);
   561         GST_BUFFER_FLAGS (buf), buf);
   603     GST_OBJECT_UNLOCK (identity);
   562     GST_OBJECT_UNLOCK (identity);
   604     gst_identity_notify_last_message (identity);
   563     g_object_notify (G_OBJECT (identity), "last-message");
   605   }
   564   }
   606 
   565 
   607   if (identity->datarate > 0) {
   566   if (identity->datarate > 0) {
   608     GstClockTime time = gst_util_uint64_scale_int (identity->offset,
   567     GstClockTime time = gst_util_uint64_scale_int (identity->offset,
   609         GST_SECOND, identity->datarate);
   568         GST_SECOND, identity->datarate);
   779   identity = GST_IDENTITY (trans);
   738   identity = GST_IDENTITY (trans);
   780 
   739 
   781   identity->offset = 0;
   740   identity->offset = 0;
   782   identity->prev_timestamp = GST_CLOCK_TIME_NONE;
   741   identity->prev_timestamp = GST_CLOCK_TIME_NONE;
   783   identity->prev_duration = GST_CLOCK_TIME_NONE;
   742   identity->prev_duration = GST_CLOCK_TIME_NONE;
   784   identity->prev_offset_end = GST_BUFFER_OFFSET_NONE;
   743   identity->prev_offset_end = -1;
   785   identity->prev_offset = GST_BUFFER_OFFSET_NONE;
   744   identity->prev_offset = -1;
   786 
   745 
   787   return TRUE;
   746   return TRUE;
   788 }
   747 }
   789 
   748 
   790 static gboolean
   749 static gboolean