gstreamer_core/gst/gstevent.c
changeset 0 0e761a78d257
child 7 567bb019e3e3
equal deleted inserted replaced
-1:000000000000 0:0e761a78d257
       
     1 /* GStreamer
       
     2  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
       
     3  *                    2000 Wim Taymans <wim.taymans@chello.be>
       
     4  *                    2005 Wim Taymans <wim@fluendo.com>
       
     5  *
       
     6  * gstevent.c: GstEvent subsystem
       
     7  *
       
     8  * This library is free software; you can redistribute it and/or
       
     9  * modify it under the terms of the GNU Library General Public
       
    10  * License as published by the Free Software Foundation; either
       
    11  * version 2 of the License, or (at your option) any later version.
       
    12  *
       
    13  * This library is distributed in the hope that it will be useful,
       
    14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    16  * Library General Public License for more details.
       
    17  *
       
    18  * You should have received a copy of the GNU Library General Public
       
    19  * License along with this library; if not, write to the
       
    20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
       
    21  * Boston, MA 02111-1307, USA.
       
    22  */
       
    23 
       
    24 /**
       
    25  * SECTION:gstevent
       
    26  * @short_description: Structure describing events that are passed up and down
       
    27  *                     a pipeline
       
    28  * @see_also: #GstPad, #GstElement
       
    29  *
       
    30  * The event class provides factory methods to construct and functions query
       
    31  * (parse) events.
       
    32  *
       
    33  * Events are usually created with gst_event_new_*() which takes event-type
       
    34  * specific parameters as arguments.
       
    35  * To send an event application will usually use gst_element_send_event() and
       
    36  * elements will use gst_pad_send_event() or gst_pad_push_event().
       
    37  * The event should be unreffed with gst_event_unref() if it has not been sent.
       
    38  *
       
    39  * Events that have been received can be parsed with their respective 
       
    40  * gst_event_parse_*() functions. It is valid to pass %NULL for unwanted details.
       
    41  *
       
    42  * Events are passed between elements in parallel to the data stream. Some events
       
    43  * are serialized with buffers, others are not. Some events only travel downstream,
       
    44  * others only upstream. Some events can travel both upstream and downstream. 
       
    45  * 
       
    46  * The events are used to signal special conditions in the datastream such as
       
    47  * EOS (end of stream) or the start of a new stream-segment.
       
    48  * Events are also used to flush the pipeline of any pending data.
       
    49  *
       
    50  * Most of the event API is used inside plugins. Applications usually only 
       
    51  * construct and use seek events. 
       
    52  * To do that gst_event_new_seek() is used to create a seek event. It takes
       
    53  * the needed parameters to specity seeking time and mode.
       
    54  * <example>
       
    55  * <title>performing a seek on a pipeline</title>
       
    56  *   <programlisting>
       
    57  *   GstEvent *event;
       
    58  *   gboolean result;
       
    59  *   ...
       
    60  *   // construct a seek event to play the media from second 2 to 5, flush
       
    61  *   // the pipeline to decrease latency.
       
    62  *   event = gst_event_new_seek (1.0, 
       
    63  *      GST_FORMAT_TIME, 
       
    64  *      GST_SEEK_FLAG_FLUSH,
       
    65  *      GST_SEEK_TYPE_SET, 2 * GST_SECOND,
       
    66  *      GST_SEEK_TYPE_SET, 5 * GST_SECOND);
       
    67  *   ...
       
    68  *   result = gst_element_send_event (pipeline, event);
       
    69  *   if (!result)
       
    70  *     g_warning ("seek failed");
       
    71  *   ...
       
    72  *   </programlisting>
       
    73  * </example>
       
    74  *
       
    75  * Last reviewed on 2006-09-6 (0.10.10)
       
    76  */
       
    77 
       
    78 
       
    79 #include "gst_private.h"
       
    80 #include <string.h>             /* memcpy */
       
    81 
       
    82 #include "gstinfo.h"
       
    83 #include "gstevent.h"
       
    84 #include "gstenumtypes.h"
       
    85 #include "gstutils.h"
       
    86 
       
    87 static void gst_event_init (GTypeInstance * instance, gpointer g_class);
       
    88 static void gst_event_class_init (gpointer g_class, gpointer class_data);
       
    89 static void gst_event_finalize (GstEvent * event);
       
    90 static GstEvent *_gst_event_copy (GstEvent * event);
       
    91 
       
    92 static GstMiniObjectClass *parent_class = NULL;
       
    93 #ifdef __SYMBIAN32__
       
    94 EXPORT_C
       
    95 #endif
       
    96 
       
    97 
       
    98 void
       
    99 _gst_event_initialize (void)
       
   100 {
       
   101   g_type_class_ref (gst_event_get_type ());
       
   102   g_type_class_ref (gst_seek_flags_get_type ());
       
   103   g_type_class_ref (gst_seek_type_get_type ());
       
   104 }
       
   105 
       
   106 typedef struct
       
   107 {
       
   108   const gint type;
       
   109   const gchar *name;
       
   110   GQuark quark;
       
   111 } GstEventQuarks;
       
   112 
       
   113 static GstEventQuarks event_quarks[] = {
       
   114   {GST_EVENT_UNKNOWN, "unknown", 0},
       
   115   {GST_EVENT_FLUSH_START, "flush-start", 0},
       
   116   {GST_EVENT_FLUSH_STOP, "flush-stop", 0},
       
   117   {GST_EVENT_EOS, "eos", 0},
       
   118   {GST_EVENT_NEWSEGMENT, "newsegment", 0},
       
   119   {GST_EVENT_TAG, "tag", 0},
       
   120   {GST_EVENT_BUFFERSIZE, "buffersize", 0},
       
   121   {GST_EVENT_QOS, "qos", 0},
       
   122   {GST_EVENT_SEEK, "seek", 0},
       
   123   {GST_EVENT_NAVIGATION, "navigation", 0},
       
   124   {GST_EVENT_LATENCY, "latency", 0},
       
   125   {GST_EVENT_CUSTOM_UPSTREAM, "custom-upstream", 0},
       
   126   {GST_EVENT_CUSTOM_DOWNSTREAM, "custom-downstream", 0},
       
   127   {GST_EVENT_CUSTOM_DOWNSTREAM_OOB, "custom-downstream-oob", 0},
       
   128   {GST_EVENT_CUSTOM_BOTH, "custom-both", 0},
       
   129   {GST_EVENT_CUSTOM_BOTH_OOB, "custom-both-oob", 0},
       
   130 
       
   131   {0, NULL, 0}
       
   132 };
       
   133 
       
   134 /**
       
   135  * gst_event_type_get_name:
       
   136  * @type: the event type
       
   137  *
       
   138  * Get a printable name for the given event type. Do not modify or free.
       
   139  *
       
   140  * Returns: a reference to the static name of the event.
       
   141  */
       
   142 #ifdef __SYMBIAN32__
       
   143 EXPORT_C
       
   144 #endif
       
   145 
       
   146 const gchar *
       
   147 gst_event_type_get_name (GstEventType type)
       
   148 {
       
   149   gint i;
       
   150 
       
   151   for (i = 0; event_quarks[i].name; i++) {
       
   152     if (type == event_quarks[i].type)
       
   153       return event_quarks[i].name;
       
   154   }
       
   155   return "unknown";
       
   156 }
       
   157 
       
   158 /**
       
   159  * gst_event_type_to_quark:
       
   160  * @type: the event type
       
   161  *
       
   162  * Get the unique quark for the given event type.
       
   163  *
       
   164  * Returns: the quark associated with the event type
       
   165  */
       
   166 #ifdef __SYMBIAN32__
       
   167 EXPORT_C
       
   168 #endif
       
   169 
       
   170 GQuark
       
   171 gst_event_type_to_quark (GstEventType type)
       
   172 {
       
   173   gint i;
       
   174 
       
   175   for (i = 0; event_quarks[i].name; i++) {
       
   176     if (type == event_quarks[i].type)
       
   177       return event_quarks[i].quark;
       
   178   }
       
   179   return 0;
       
   180 }
       
   181 
       
   182 /**
       
   183  * gst_event_type_get_flags:
       
   184  * @type: a #GstEventType
       
   185  *
       
   186  * Gets the #GstEventTypeFlags associated with @type.
       
   187  *
       
   188  * Returns: a #GstEventTypeFlags.
       
   189  */
       
   190 #ifdef __SYMBIAN32__
       
   191 EXPORT_C
       
   192 #endif
       
   193 
       
   194 GstEventTypeFlags
       
   195 gst_event_type_get_flags (GstEventType type)
       
   196 {
       
   197   GstEventTypeFlags ret;
       
   198 
       
   199   ret = type & ((1 << GST_EVENT_TYPE_SHIFT) - 1);
       
   200 
       
   201   return ret;
       
   202 }
       
   203 #ifdef __SYMBIAN32__
       
   204 EXPORT_C
       
   205 #endif
       
   206 
       
   207 
       
   208 GType
       
   209 gst_event_get_type (void)
       
   210 {
       
   211   static GType _gst_event_type = 0;
       
   212   int i;
       
   213 
       
   214   if (G_UNLIKELY (_gst_event_type == 0)) {
       
   215     static const GTypeInfo event_info = {
       
   216       sizeof (GstEventClass),
       
   217       NULL,
       
   218       NULL,
       
   219       gst_event_class_init,
       
   220       NULL,
       
   221       NULL,
       
   222       sizeof (GstEvent),
       
   223       0,
       
   224       gst_event_init,
       
   225       NULL
       
   226     };
       
   227 
       
   228     _gst_event_type = g_type_register_static (GST_TYPE_MINI_OBJECT,
       
   229         "GstEvent", &event_info, 0);
       
   230 
       
   231     for (i = 0; event_quarks[i].name; i++) {
       
   232       event_quarks[i].quark = g_quark_from_static_string (event_quarks[i].name);
       
   233     }
       
   234   }
       
   235 
       
   236   return _gst_event_type;
       
   237 }
       
   238 
       
   239 static void
       
   240 gst_event_class_init (gpointer g_class, gpointer class_data)
       
   241 {
       
   242   GstEventClass *event_class = GST_EVENT_CLASS (g_class);
       
   243 
       
   244   parent_class = g_type_class_peek_parent (g_class);
       
   245 
       
   246   event_class->mini_object_class.copy =
       
   247       (GstMiniObjectCopyFunction) _gst_event_copy;
       
   248   event_class->mini_object_class.finalize =
       
   249       (GstMiniObjectFinalizeFunction) gst_event_finalize;
       
   250 }
       
   251 
       
   252 static void
       
   253 gst_event_init (GTypeInstance * instance, gpointer g_class)
       
   254 {
       
   255   GstEvent *event;
       
   256 
       
   257   event = GST_EVENT (instance);
       
   258 
       
   259   GST_EVENT_TIMESTAMP (event) = GST_CLOCK_TIME_NONE;
       
   260 }
       
   261 
       
   262 static void
       
   263 gst_event_finalize (GstEvent * event)
       
   264 {
       
   265   g_return_if_fail (event != NULL);
       
   266   g_return_if_fail (GST_IS_EVENT (event));
       
   267 
       
   268   GST_CAT_LOG (GST_CAT_EVENT, "freeing event %p type %s", event,
       
   269       GST_EVENT_TYPE_NAME (event));
       
   270 
       
   271   if (GST_EVENT_SRC (event)) {
       
   272     gst_object_unref (GST_EVENT_SRC (event));
       
   273     GST_EVENT_SRC (event) = NULL;
       
   274   }
       
   275   if (event->structure) {
       
   276     gst_structure_set_parent_refcount (event->structure, NULL);
       
   277     gst_structure_free (event->structure);
       
   278   }
       
   279 
       
   280   GST_MINI_OBJECT_CLASS (parent_class)->finalize (GST_MINI_OBJECT (event));
       
   281 }
       
   282 
       
   283 static GstEvent *
       
   284 _gst_event_copy (GstEvent * event)
       
   285 {
       
   286   GstEvent *copy;
       
   287 
       
   288   copy = (GstEvent *) gst_mini_object_new (GST_TYPE_EVENT);
       
   289 
       
   290   GST_EVENT_TYPE (copy) = GST_EVENT_TYPE (event);
       
   291   GST_EVENT_TIMESTAMP (copy) = GST_EVENT_TIMESTAMP (event);
       
   292 
       
   293   if (GST_EVENT_SRC (event)) {
       
   294     GST_EVENT_SRC (copy) = gst_object_ref (GST_EVENT_SRC (event));
       
   295   }
       
   296   if (event->structure) {
       
   297     copy->structure = gst_structure_copy (event->structure);
       
   298     gst_structure_set_parent_refcount (copy->structure,
       
   299         &copy->mini_object.refcount);
       
   300   }
       
   301   return copy;
       
   302 }
       
   303 
       
   304 static GstEvent *
       
   305 gst_event_new (GstEventType type)
       
   306 {
       
   307   GstEvent *event;
       
   308 
       
   309   event = (GstEvent *) gst_mini_object_new (GST_TYPE_EVENT);
       
   310 
       
   311   GST_CAT_DEBUG (GST_CAT_EVENT, "creating new event %p %s %d", event,
       
   312       gst_event_type_get_name (type), type);
       
   313 
       
   314   event->type = type;
       
   315   event->src = NULL;
       
   316   event->structure = NULL;
       
   317 
       
   318   return event;
       
   319 }
       
   320 
       
   321 /**
       
   322  * gst_event_new_custom:
       
   323  * @type: The type of the new event
       
   324  * @structure: The structure for the event. The event will take ownership of
       
   325  * the structure.
       
   326  *
       
   327  * Create a new custom-typed event. This can be used for anything not
       
   328  * handled by other event-specific functions to pass an event to another
       
   329  * element.
       
   330  *
       
   331  * Make sure to allocate an event type with the #GST_EVENT_MAKE_TYPE macro,
       
   332  * assigning a free number and filling in the correct direction and
       
   333  * serialization flags.
       
   334  *
       
   335  * New custom events can also be created by subclassing the event type if
       
   336  * needed.
       
   337  *
       
   338  * Returns: The new custom event.
       
   339  */
       
   340 #ifdef __SYMBIAN32__
       
   341 EXPORT_C
       
   342 #endif
       
   343 
       
   344 GstEvent *
       
   345 gst_event_new_custom (GstEventType type, GstStructure * structure)
       
   346 {
       
   347   GstEvent *event;
       
   348 
       
   349   /* structure must not have a parent */
       
   350   if (structure)
       
   351     g_return_val_if_fail (structure->parent_refcount == NULL, NULL);
       
   352 
       
   353   event = gst_event_new (type);
       
   354   if (structure) {
       
   355     gst_structure_set_parent_refcount (structure, &event->mini_object.refcount);
       
   356     event->structure = structure;
       
   357   }
       
   358   return event;
       
   359 }
       
   360 
       
   361 /**
       
   362  * gst_event_get_structure:
       
   363  * @event: The #GstEvent.
       
   364  *
       
   365  * Access the structure of the event.
       
   366  *
       
   367  * Returns: The structure of the event. The structure is still
       
   368  * owned by the event, which means that you should not free it and
       
   369  * that the pointer becomes invalid when you free the event.
       
   370  *
       
   371  * MT safe.
       
   372  */
       
   373 #ifdef __SYMBIAN32__
       
   374 EXPORT_C
       
   375 #endif
       
   376 
       
   377 const GstStructure *
       
   378 gst_event_get_structure (GstEvent * event)
       
   379 {
       
   380   g_return_val_if_fail (GST_IS_EVENT (event), NULL);
       
   381 
       
   382   return event->structure;
       
   383 }
       
   384 
       
   385 /**
       
   386  * gst_event_new_flush_start:
       
   387  *
       
   388  * Allocate a new flush start event. The flush start event can be sent
       
   389  * upstream and downstream and travels out-of-bounds with the dataflow.
       
   390  *
       
   391  * It marks pads as being flushing and will make them return
       
   392  * #GST_FLOW_WRONG_STATE when used for data flow with gst_pad_push(),
       
   393  * gst_pad_chain(), gst_pad_alloc_buffer(), gst_pad_get_range() and
       
   394  * gst_pad_pull_range(). Any event (except a #GST_EVENT_FLUSH_STOP) received
       
   395  * on a flushing pad will return %FALSE immediately.
       
   396  *
       
   397  * Elements should unlock any blocking functions and exit their streaming
       
   398  * functions as fast as possible when this event is received.
       
   399  *
       
   400  * This event is typically generated after a seek to flush out all queued data
       
   401  * in the pipeline so that the new media is played as soon as possible.
       
   402  *
       
   403  * Returns: A new flush start event.
       
   404  */
       
   405 #ifdef __SYMBIAN32__
       
   406 EXPORT_C
       
   407 #endif
       
   408 
       
   409 GstEvent *
       
   410 gst_event_new_flush_start (void)
       
   411 {
       
   412   return gst_event_new (GST_EVENT_FLUSH_START);
       
   413 }
       
   414 
       
   415 /**
       
   416  * gst_event_new_flush_stop:
       
   417  *
       
   418  * Allocate a new flush stop event. The flush stop event can be sent
       
   419  * upstream and downstream and travels out-of-bounds with the dataflow.
       
   420  * It is typically sent after sending a FLUSH_START event to make the
       
   421  * pads accept data again.
       
   422  *
       
   423  * Elements can process this event synchronized with the dataflow since
       
   424  * the preceeding FLUSH_START event stopped the dataflow.
       
   425  *
       
   426  * This event is typically generated to complete a seek and to resume
       
   427  * dataflow.
       
   428  *
       
   429  * Returns: A new flush stop event.
       
   430  */
       
   431 #ifdef __SYMBIAN32__
       
   432 EXPORT_C
       
   433 #endif
       
   434 
       
   435 GstEvent *
       
   436 gst_event_new_flush_stop (void)
       
   437 {
       
   438   return gst_event_new (GST_EVENT_FLUSH_STOP);
       
   439 }
       
   440 
       
   441 /**
       
   442  * gst_event_new_eos:
       
   443  *
       
   444  * Create a new EOS event. The eos event can only travel downstream
       
   445  * synchronized with the buffer flow. Elements that receive the EOS
       
   446  * event on a pad can return #GST_FLOW_UNEXPECTED as a #GstFlowReturn
       
   447  * when data after the EOS event arrives.
       
   448  *
       
   449  * The EOS event will travel down to the sink elements in the pipeline
       
   450  * which will then post the #GST_MESSAGE_EOS on the bus after they have
       
   451  * finished playing any buffered data.
       
   452  *
       
   453  * When all sinks have posted an EOS message, an EOS message is
       
   454  * forwarded to the application.
       
   455  *
       
   456  * Returns: The new EOS event.
       
   457  */
       
   458 #ifdef __SYMBIAN32__
       
   459 EXPORT_C
       
   460 #endif
       
   461 
       
   462 GstEvent *
       
   463 gst_event_new_eos (void)
       
   464 {
       
   465   return gst_event_new (GST_EVENT_EOS);
       
   466 }
       
   467 
       
   468 /**
       
   469  * gst_event_new_new_segment:
       
   470  * @update: is this segment an update to a previous one
       
   471  * @rate: a new rate for playback
       
   472  * @format: The format of the segment values
       
   473  * @start: the start value of the segment
       
   474  * @stop: the stop value of the segment
       
   475  * @position: stream position
       
   476  *
       
   477  * Allocate a new newsegment event with the given format/
       
   478 #ifdef __SYMBIAN32__
       
   479 EXPORT_C
       
   480 #endif
       
   481 values tripplets
       
   482  *
       
   483  * This method calls gst_event_new_new_segment_full() passing a default
       
   484  * value of 1.0 for applied_rate
       
   485  *
       
   486  * Returns: A new newsegment event.
       
   487  */
       
   488 #ifdef __SYMBIAN32__
       
   489 EXPORT_C
       
   490 #endif
       
   491 
       
   492 GstEvent *
       
   493 gst_event_new_new_segment (gboolean update, gdouble rate, GstFormat format,
       
   494     gint64 start, gint64 stop, gint64 position)
       
   495 {
       
   496   return gst_event_new_new_segment_full (update, rate, 1.0, format, start,
       
   497       stop, position);
       
   498 }
       
   499 
       
   500 /**
       
   501  * gst_event_parse_new_segment:
       
   502  * @event: The event to query
       
   503  * @update: A pointer to the update flag of the segment
       
   504  * @rate: A pointer to the rate of the segment
       
   505  * @format: A pointer to the format of the newsegment values
       
   506  * @start: A pointer to store the start value in
       
   507  * @stop: A pointer to store the stop value in
       
   508  * @position: A pointer to store the stream time in
       
   509  *
       
   510  * Get the update flag, rate, format, start, stop and position in the 
       
   511  * newsegment event. In general, gst_event_parse_new_segment_full() should
       
   512  * be used instead of this, to also retrieve the applied_rate value of the
       
   513  * segment. See gst_event_new_new_segment_full() for a full description 
       
   514  * of the newsegment event.
       
   515  */
       
   516 #ifdef __SYMBIAN32__
       
   517 EXPORT_C
       
   518 #endif
       
   519 
       
   520 void
       
   521 gst_event_parse_new_segment (GstEvent * event, gboolean * update,
       
   522     gdouble * rate, GstFormat * format, gint64 * start,
       
   523     gint64 * stop, gint64 * position)
       
   524 {
       
   525   gst_event_parse_new_segment_full (event, update, rate, NULL, format, start,
       
   526       stop, position);
       
   527 }
       
   528 
       
   529 /**
       
   530  * gst_event_new_new_segment_full:
       
   531  * @update: Whether this segment is an update to a previous one
       
   532  * @rate: A new rate for playback
       
   533  * @applied_rate: The rate factor which has already been applied
       
   534  * @format: The format of the segment values
       
   535  * @start: The start value of the segment
       
   536  * @stop: The stop value of the segment
       
   537  * @position: stream position
       
   538  *
       
   539  * Allocate a new newsegment event with the given format/values triplets.
       
   540  *
       
   541  * The newsegment event marks the range of buffers to be processed. All
       
   542  * data not within the segment range is not to be processed. This can be
       
   543  * used intelligently by plugins to apply more efficient methods of skipping
       
   544  * unneeded data.
       
   545  *
       
   546  * The position value of the segment is used in conjunction with the start
       
   547  * value to convert the buffer timestamps into the stream time. This is 
       
   548  * usually done in sinks to report the current stream_time. 
       
   549  * @position represents the stream_time of a buffer carrying a timestamp of 
       
   550  * @start. @position cannot be -1.
       
   551  *
       
   552  * @start cannot be -1, @stop can be -1. If there
       
   553  * is a valid @stop given, it must be greater or equal the @start, including 
       
   554  * when the indicated playback @rate is < 0.
       
   555  *
       
   556  * The @applied_rate value provides information about any rate adjustment that
       
   557  * has already been made to the timestamps and content on the buffers of the 
       
   558  * stream. (@rate * @applied_rate) should always equal the rate that has been 
       
   559  * requested for playback. For example, if an element has an input segment 
       
   560  * with intended playback @rate of 2.0 and applied_rate of 1.0, it can adjust 
       
   561  * incoming timestamps and buffer content by half and output a newsegment event 
       
   562  * with @rate of 1.0 and @applied_rate of 2.0
       
   563  *
       
   564  * After a newsegment event, the buffer stream time is calculated with:
       
   565  *
       
   566  *   position + (TIMESTAMP(buf) - start) * ABS (rate * applied_rate)
       
   567  *
       
   568  * Returns: A new newsegment event.
       
   569  *
       
   570  * Since: 0.10.6
       
   571  */
       
   572 #ifdef __SYMBIAN32__
       
   573 EXPORT_C
       
   574 #endif
       
   575 GstEvent *
       
   576 gst_event_new_new_segment_full (gboolean update, gdouble rate,
       
   577     gdouble applied_rate, GstFormat format, gint64 start, gint64 stop,
       
   578     gint64 position)
       
   579 {
       
   580   g_return_val_if_fail (rate != 0.0, NULL);
       
   581   g_return_val_if_fail (applied_rate != 0.0, NULL);
       
   582 
       
   583   if (format == GST_FORMAT_TIME) {
       
   584     GST_CAT_INFO (GST_CAT_EVENT,
       
   585         "creating newsegment update %d, rate %lf, format GST_FORMAT_TIME, "
       
   586         "start %" GST_TIME_FORMAT ", stop %" GST_TIME_FORMAT
       
   587         ", position %" GST_TIME_FORMAT,
       
   588         update, rate, GST_TIME_ARGS (start),
       
   589         GST_TIME_ARGS (stop), GST_TIME_ARGS (position));
       
   590   } else {
       
   591     GST_CAT_INFO (GST_CAT_EVENT,
       
   592         "creating newsegment update %d, rate %lf, format %d, "
       
   593         "start %" G_GINT64_FORMAT ", stop %" G_GINT64_FORMAT ", position %"
       
   594         G_GINT64_FORMAT, update, rate, format, start, stop, position);
       
   595   }
       
   596 
       
   597   g_return_val_if_fail (position != -1, NULL);
       
   598   g_return_val_if_fail (start != -1, NULL);
       
   599   if (stop != -1)
       
   600     g_return_val_if_fail (start <= stop, NULL);
       
   601 
       
   602   return gst_event_new_custom (GST_EVENT_NEWSEGMENT,
       
   603       gst_structure_new ("GstEventNewsegment",
       
   604           "update", G_TYPE_BOOLEAN, update,
       
   605           "rate", G_TYPE_DOUBLE, rate,
       
   606           "applied_rate", G_TYPE_DOUBLE, applied_rate,
       
   607           "format", GST_TYPE_FORMAT, format,
       
   608           "start", G_TYPE_INT64, start,
       
   609           "stop", G_TYPE_INT64, stop,
       
   610           "position", G_TYPE_INT64, position, NULL));
       
   611 }
       
   612 
       
   613 /**
       
   614  * gst_event_parse_new_segment_full:
       
   615  * @event: The event to query
       
   616  * @update: A pointer to the update flag of the segment
       
   617  * @rate: A pointer to the rate of the segment
       
   618  * @applied_rate: A pointer to the applied_rate of the segment
       
   619  * @format: A pointer to the format of the newsegment values
       
   620  * @start: A pointer to store the start value in
       
   621  * @stop: A pointer to store the stop value in
       
   622  * @position: A pointer to store the stream time in
       
   623  *
       
   624  * Get the update, rate, applied_rate, format, start, stop and 
       
   625  * position in the newsegment event. See gst_event_new_new_segment_full() 
       
   626  * for a full description of the newsegment event.
       
   627  *
       
   628  * Since: 0.10.6
       
   629  */
       
   630 #ifdef __SYMBIAN32__
       
   631 EXPORT_C
       
   632 #endif
       
   633 
       
   634 void
       
   635 gst_event_parse_new_segment_full (GstEvent * event, gboolean * update,
       
   636     gdouble * rate, gdouble * applied_rate, GstFormat * format,
       
   637     gint64 * start, gint64 * stop, gint64 * position)
       
   638 {
       
   639   const GstStructure *structure;
       
   640 
       
   641   g_return_if_fail (GST_IS_EVENT (event));
       
   642   g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT);
       
   643 
       
   644   structure = gst_event_get_structure (event);
       
   645   if (G_LIKELY (update))
       
   646     *update =
       
   647         g_value_get_boolean (gst_structure_get_value (structure, "update"));
       
   648   if (G_LIKELY (rate))
       
   649     *rate = g_value_get_double (gst_structure_get_value (structure, "rate"));
       
   650   if (G_LIKELY (applied_rate))
       
   651     *applied_rate =
       
   652         g_value_get_double (gst_structure_get_value (structure,
       
   653             "applied_rate"));
       
   654   if (G_LIKELY (format))
       
   655     *format = g_value_get_enum (gst_structure_get_value (structure, "format"));
       
   656   if (G_LIKELY (start))
       
   657     *start = g_value_get_int64 (gst_structure_get_value (structure, "start"));
       
   658   if (G_LIKELY (stop))
       
   659     *stop = g_value_get_int64 (gst_structure_get_value (structure, "stop"));
       
   660   if (G_LIKELY (position))
       
   661     *position =
       
   662         g_value_get_int64 (gst_structure_get_value (structure, "position"));
       
   663 }
       
   664 
       
   665 /**
       
   666  * gst_event_new_tag:
       
   667  * @taglist: metadata list
       
   668  *
       
   669  * Generates a metadata tag event from the given @taglist.
       
   670  *
       
   671  * Returns: a new #GstEvent
       
   672  */
       
   673 #ifdef __SYMBIAN32__
       
   674 EXPORT_C
       
   675 #endif
       
   676 
       
   677 GstEvent *
       
   678 gst_event_new_tag (GstTagList * taglist)
       
   679 {
       
   680   g_return_val_if_fail (taglist != NULL, NULL);
       
   681 
       
   682   return gst_event_new_custom (GST_EVENT_TAG, (GstStructure *) taglist);
       
   683 }
       
   684 
       
   685 /**
       
   686  * gst_event_parse_tag:
       
   687  * @event: a tag event
       
   688  * @taglist: pointer to metadata list
       
   689  *
       
   690  * Parses a tag @event and stores the results in the given @taglist location.
       
   691  */
       
   692 #ifdef __SYMBIAN32__
       
   693 EXPORT_C
       
   694 #endif
       
   695 
       
   696 void
       
   697 gst_event_parse_tag (GstEvent * event, GstTagList ** taglist)
       
   698 {
       
   699   g_return_if_fail (GST_IS_EVENT (event));
       
   700   g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_TAG);
       
   701 
       
   702   if (taglist)
       
   703     *taglist = (GstTagList *) event->structure;
       
   704 }
       
   705 
       
   706 /* buffersize event */
       
   707 /**
       
   708  * gst_event_new_buffer_size:
       
   709  * @format: buffer format
       
   710  * @minsize: minimum buffer size
       
   711  * @maxsize: maximum buffer size
       
   712  * @async: thread behavior
       
   713  *
       
   714  * Create a new buffersize event. The event is sent downstream and notifies
       
   715  * elements that they should provide a buffer of the specified dimensions.
       
   716  *
       
   717  * When the @async flag is set, a thread boundary is prefered.
       
   718  *
       
   719  * Returns: a new #GstEvent
       
   720  */
       
   721 #ifdef __SYMBIAN32__
       
   722 EXPORT_C
       
   723 #endif
       
   724 
       
   725 GstEvent *
       
   726 gst_event_new_buffer_size (GstFormat format, gint64 minsize,
       
   727     gint64 maxsize, gboolean async)
       
   728 {
       
   729   GST_CAT_INFO (GST_CAT_EVENT,
       
   730       "creating buffersize format %d, minsize %" G_GINT64_FORMAT
       
   731       ", maxsize %" G_GINT64_FORMAT ", async %d", format,
       
   732       minsize, maxsize, async);
       
   733 
       
   734   return gst_event_new_custom (GST_EVENT_BUFFERSIZE,
       
   735       gst_structure_new ("GstEventBufferSize",
       
   736           "format", GST_TYPE_FORMAT, format,
       
   737           "minsize", G_TYPE_INT64, minsize,
       
   738           "maxsize", G_TYPE_INT64, maxsize,
       
   739           "async", G_TYPE_BOOLEAN, async, NULL));
       
   740 }
       
   741 
       
   742 /**
       
   743  * gst_event_parse_buffer_size:
       
   744  * @event: The event to query
       
   745  * @format: A pointer to store the format in
       
   746  * @minsize: A pointer to store the minsize in
       
   747  * @maxsize: A pointer to store the maxsize in
       
   748  * @async: A pointer to store the async-flag in
       
   749  *
       
   750  * Get the format, minsize, maxsize and async-flag in the buffersize event.
       
   751  */
       
   752 #ifdef __SYMBIAN32__
       
   753 EXPORT_C
       
   754 #endif
       
   755 
       
   756 void
       
   757 gst_event_parse_buffer_size (GstEvent * event, GstFormat * format,
       
   758     gint64 * minsize, gint64 * maxsize, gboolean * async)
       
   759 {
       
   760   const GstStructure *structure;
       
   761 
       
   762   g_return_if_fail (GST_IS_EVENT (event));
       
   763   g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_BUFFERSIZE);
       
   764 
       
   765   structure = gst_event_get_structure (event);
       
   766   if (format)
       
   767     *format = g_value_get_enum (gst_structure_get_value (structure, "format"));
       
   768   if (minsize)
       
   769     *minsize =
       
   770         g_value_get_int64 (gst_structure_get_value (structure, "minsize"));
       
   771   if (maxsize)
       
   772     *maxsize =
       
   773         g_value_get_int64 (gst_structure_get_value (structure, "maxsize"));
       
   774   if (async)
       
   775     *async = g_value_get_boolean (gst_structure_get_value (structure, "async"));
       
   776 }
       
   777 
       
   778 /**
       
   779  * gst_event_new_qos:
       
   780  * @proportion: the proportion of the qos message
       
   781  * @diff: The time difference of the last Clock sync
       
   782  * @timestamp: The timestamp of the buffer
       
   783  *
       
   784  * Allocate a new qos event with the given values.
       
   785  * The QOS event is generated in an element that wants an upstream
       
   786  * element to either reduce or increase its rate because of
       
   787  * high/low CPU load or other resource usage such as network performance.
       
   788  * Typically sinks generate these events for each buffer they receive.
       
   789  *
       
   790  * @proportion indicates the real-time performance of the streaming in the
       
   791  * element that generated the QoS event (usually the sink). The value is
       
   792  * generally computed based on more long term statistics about the streams
       
   793  * timestamps compared to the clock.
       
   794  * A value < 1.0 indicates that the upstream element is producing data faster
       
   795  * than real-time. A value > 1.0 indicates that the upstream element is not
       
   796  * producing data fast enough. 1.0 is the ideal @proportion value. The
       
   797  * proportion value can safely be used to lower or increase the quality of
       
   798  * the element.
       
   799  *
       
   800  * @diff is the difference against the clock in running time of the last
       
   801  * buffer that caused the element to generate the QOS event. A negative value
       
   802  * means that the buffer with @timestamp arrived in time. A positive value
       
   803  * indicates how late the buffer with @timestamp was.
       
   804  *
       
   805  * @timestamp is the timestamp of the last buffer that cause the element
       
   806  * to generate the QOS event. It is expressed in running time and thus an ever
       
   807  * increasing value.
       
   808  *
       
   809  * The upstream element can use the @diff and @timestamp values to decide
       
   810  * whether to process more buffers. For possitive @diff, all buffers with
       
   811  * timestamp <= @timestamp + @diff will certainly arrive late in the sink
       
   812  * as well. 
       
   813  *
       
   814  * The application can use general event probes to intercept the QoS
       
   815  * event and implement custom application specific QoS handling.
       
   816  *
       
   817  * Returns: A new QOS event.
       
   818  */
       
   819 #ifdef __SYMBIAN32__
       
   820 EXPORT_C
       
   821 #endif
       
   822 
       
   823 GstEvent *
       
   824 gst_event_new_qos (gdouble proportion, GstClockTimeDiff diff,
       
   825     GstClockTime timestamp)
       
   826 {
       
   827   GST_CAT_INFO (GST_CAT_EVENT,
       
   828       "creating qos proportion %lf, diff %" G_GINT64_FORMAT
       
   829       ", timestamp %" GST_TIME_FORMAT, proportion,
       
   830       diff, GST_TIME_ARGS (timestamp));
       
   831 
       
   832   return gst_event_new_custom (GST_EVENT_QOS,
       
   833       gst_structure_new ("GstEventQOS",
       
   834           "proportion", G_TYPE_DOUBLE, proportion,
       
   835           "diff", G_TYPE_INT64, diff,
       
   836           "timestamp", G_TYPE_UINT64, timestamp, NULL));
       
   837 }
       
   838 
       
   839 /**
       
   840  * gst_event_parse_qos:
       
   841  * @event: The event to query
       
   842  * @proportion: A pointer to store the proportion in
       
   843  * @diff: A pointer to store the diff in
       
   844  * @timestamp: A pointer to store the timestamp in
       
   845  *
       
   846  * Get the proportion, diff and timestamp in the qos event. See
       
   847  * gst_event_new_qos() for more information about the different QoS values.
       
   848  */
       
   849 #ifdef __SYMBIAN32__
       
   850 EXPORT_C
       
   851 #endif
       
   852 
       
   853 void
       
   854 gst_event_parse_qos (GstEvent * event, gdouble * proportion,
       
   855     GstClockTimeDiff * diff, GstClockTime * timestamp)
       
   856 {
       
   857   const GstStructure *structure;
       
   858 
       
   859   g_return_if_fail (GST_IS_EVENT (event));
       
   860   g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_QOS);
       
   861 
       
   862   structure = gst_event_get_structure (event);
       
   863   if (proportion)
       
   864     *proportion =
       
   865         g_value_get_double (gst_structure_get_value (structure, "proportion"));
       
   866   if (diff)
       
   867     *diff = g_value_get_int64 (gst_structure_get_value (structure, "diff"));
       
   868   if (timestamp)
       
   869     *timestamp =
       
   870         g_value_get_uint64 (gst_structure_get_value (structure, "timestamp"));
       
   871 }
       
   872 
       
   873 /**
       
   874  * gst_event_new_seek:
       
   875  * @rate: The new playback rate
       
   876  * @format: The format of the seek values
       
   877  * @flags: The optional seek flags
       
   878  * @start_type: The type and flags for the new start position
       
   879  * @start: The value of the new start position
       
   880  * @stop_type: The type and flags for the new stop position
       
   881  * @stop: The value of the new stop position
       
   882  *
       
   883  * Allocate a new seek event with the given parameters.
       
   884  *
       
   885  * The seek event configures playback of the pipeline between @start to @stop
       
   886  * at the speed given in @rate, also called a playback segment.
       
   887  * The @start and @stop values are expressed in @format.
       
   888  *
       
   889  * A @rate of 1.0 means normal playback rate, 2.0 means double speed.
       
   890  * Negatives values means backwards playback. A value of 0.0 for the
       
   891  * rate is not allowed and should be accomplished instead by PAUSING the
       
   892  * pipeline.
       
   893  *
       
   894  * A pipeline has a default playback segment configured with a start
       
   895  * position of 0, a stop position of -1 and a rate of 1.0. The currently
       
   896  * configured playback segment can be queried with #GST_QUERY_SEGMENT. 
       
   897  *
       
   898  * @start_type and @stop_type specify how to adjust the currently configured 
       
   899  * start and stop fields in @segment. Adjustments can be made relative or
       
   900  * absolute to the last configured values. A type of #GST_SEEK_TYPE_NONE means
       
   901  * that the position should not be updated.
       
   902  *
       
   903  * When the rate is positive and @start has been updated, playback will start
       
   904  * from the newly configured start position. 
       
   905  *
       
   906  * For negative rates, playback will start from the newly configured stop
       
   907  * position (if any). If the stop position if updated, it must be different from
       
   908  * -1 for negative rates.
       
   909  *
       
   910  * It is not possible to seek relative to the current playback position, to do
       
   911  * this, PAUSE the pipeline, query the current playback position with
       
   912  * #GST_QUERY_POSITION and update the playback segment current position with a
       
   913  * #GST_SEEK_TYPE_SET to the desired position.
       
   914  *
       
   915  * Returns: A new seek event.
       
   916  */
       
   917 #ifdef __SYMBIAN32__
       
   918 EXPORT_C
       
   919 #endif
       
   920 GstEvent *
       
   921 gst_event_new_seek (gdouble rate, GstFormat format, GstSeekFlags flags,
       
   922     GstSeekType start_type, gint64 start, GstSeekType stop_type, gint64 stop)
       
   923 {
       
   924   g_return_val_if_fail (rate != 0.0, NULL);
       
   925 
       
   926   if (format == GST_FORMAT_TIME) {
       
   927     GST_CAT_INFO (GST_CAT_EVENT,
       
   928         "creating seek rate %lf, format TIME, flags %d, "
       
   929         "start_type %d, start %" GST_TIME_FORMAT ", "
       
   930         "stop_type %d, stop %" GST_TIME_FORMAT,
       
   931         rate, flags, start_type, GST_TIME_ARGS (start),
       
   932         stop_type, GST_TIME_ARGS (stop));
       
   933   } else {
       
   934     GST_CAT_INFO (GST_CAT_EVENT,
       
   935         "creating seek rate %lf, format %d, flags %d, "
       
   936         "start_type %d, start %" G_GINT64_FORMAT ", "
       
   937         "stop_type %d, stop %" G_GINT64_FORMAT,
       
   938         rate, format, flags, start_type, start, stop_type, stop);
       
   939   }
       
   940 
       
   941   return gst_event_new_custom (GST_EVENT_SEEK,
       
   942       gst_structure_new ("GstEventSeek", "rate", G_TYPE_DOUBLE, rate,
       
   943           "format", GST_TYPE_FORMAT, format,
       
   944           "flags", GST_TYPE_SEEK_FLAGS, flags,
       
   945           "cur_type", GST_TYPE_SEEK_TYPE, start_type,
       
   946           "cur", G_TYPE_INT64, start,
       
   947           "stop_type", GST_TYPE_SEEK_TYPE, stop_type,
       
   948           "stop", G_TYPE_INT64, stop, NULL));
       
   949 }
       
   950 
       
   951 /**
       
   952  * gst_event_parse_seek:
       
   953  * @event: a seek event
       
   954  * @rate: result location for the rate
       
   955  * @format: result location for the stream format
       
   956  * @flags:  result location for the #GstSeekFlags
       
   957  * @start_type: result location for the #GstSeekType of the start position
       
   958  * @start: result location for the start postion expressed in @format
       
   959  * @stop_type:  result location for the #GstSeekType of the stop position
       
   960  * @stop: result location for the stop postion expressed in @format
       
   961  *
       
   962  * Parses a seek @event and stores the results in the given result locations.
       
   963  */
       
   964 #ifdef __SYMBIAN32__
       
   965 EXPORT_C
       
   966 #endif
       
   967 
       
   968 void
       
   969 gst_event_parse_seek (GstEvent * event, gdouble * rate,
       
   970     GstFormat * format, GstSeekFlags * flags, GstSeekType * start_type,
       
   971     gint64 * start, GstSeekType * stop_type, gint64 * stop)
       
   972 {
       
   973   const GstStructure *structure;
       
   974 
       
   975   g_return_if_fail (GST_IS_EVENT (event));
       
   976   g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_SEEK);
       
   977 
       
   978   structure = gst_event_get_structure (event);
       
   979   if (rate)
       
   980     *rate = g_value_get_double (gst_structure_get_value (structure, "rate"));
       
   981   if (format)
       
   982     *format = g_value_get_enum (gst_structure_get_value (structure, "format"));
       
   983   if (flags)
       
   984     *flags = g_value_get_flags (gst_structure_get_value (structure, "flags"));
       
   985   if (start_type)
       
   986     *start_type =
       
   987         g_value_get_enum (gst_structure_get_value (structure, "cur_type"));
       
   988   if (start)
       
   989     *start = g_value_get_int64 (gst_structure_get_value (structure, "cur"));
       
   990   if (stop_type)
       
   991     *stop_type =
       
   992         g_value_get_enum (gst_structure_get_value (structure, "stop_type"));
       
   993   if (stop)
       
   994     *stop = g_value_get_int64 (gst_structure_get_value (structure, "stop"));
       
   995 }
       
   996 
       
   997 /**
       
   998  * gst_event_new_navigation:
       
   999  * @structure: description of the event
       
  1000  *
       
  1001  * Create a new navigation event from the given description.
       
  1002  *
       
  1003  * Returns: a new #GstEvent
       
  1004  */
       
  1005 #ifdef __SYMBIAN32__
       
  1006 EXPORT_C
       
  1007 #endif
       
  1008 
       
  1009 GstEvent *
       
  1010 gst_event_new_navigation (GstStructure * structure)
       
  1011 {
       
  1012   g_return_val_if_fail (structure != NULL, NULL);
       
  1013 
       
  1014   return gst_event_new_custom (GST_EVENT_NAVIGATION, structure);
       
  1015 }
       
  1016 
       
  1017 /**
       
  1018  * gst_event_new_latency:
       
  1019  * @latency: the new latency value
       
  1020  *
       
  1021  * Create a new latency event. The event is sent upstream from the sinks and
       
  1022  * notifies elements that they should add an additional @latency to the
       
  1023  * timestamps before synchronising against the clock.
       
  1024  *
       
  1025  * The latency is mostly used in live sinks and is always expressed in
       
  1026  * the time format.
       
  1027  *
       
  1028  * Returns: a new #GstEvent
       
  1029  *
       
  1030  * Since: 0.10.12
       
  1031  */
       
  1032 #ifdef __SYMBIAN32__
       
  1033 EXPORT_C
       
  1034 #endif
       
  1035 
       
  1036 GstEvent *
       
  1037 gst_event_new_latency (GstClockTime latency)
       
  1038 {
       
  1039   GST_CAT_INFO (GST_CAT_EVENT,
       
  1040       "creating latency event %" GST_TIME_FORMAT, GST_TIME_ARGS (latency));
       
  1041 
       
  1042   return gst_event_new_custom (GST_EVENT_LATENCY,
       
  1043       gst_structure_new ("GstEventLatency",
       
  1044           "latency", G_TYPE_UINT64, latency, NULL));
       
  1045 }
       
  1046 
       
  1047 /**
       
  1048  * gst_event_parse_latency:
       
  1049  * @event: The event to query
       
  1050  * @latency: A pointer to store the latency in.
       
  1051  *
       
  1052  * Get the latency in the latency event.
       
  1053  *
       
  1054  * Since: 0.10.12
       
  1055  */
       
  1056 #ifdef __SYMBIAN32__
       
  1057 EXPORT_C
       
  1058 #endif
       
  1059 
       
  1060 void
       
  1061 gst_event_parse_latency (GstEvent * event, GstClockTime * latency)
       
  1062 {
       
  1063   const GstStructure *structure;
       
  1064 
       
  1065   g_return_if_fail (GST_IS_EVENT (event));
       
  1066   g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_LATENCY);
       
  1067 
       
  1068   structure = gst_event_get_structure (event);
       
  1069   if (latency)
       
  1070     *latency =
       
  1071         g_value_get_uint64 (gst_structure_get_value (structure, "latency"));
       
  1072 }