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