Some docs updates
authorWim Taymans <wim.taymans@gmail.com>
Wed, 27 Jul 2005 18:33:03 +0000 (18:33 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Wed, 27 Jul 2005 18:33:03 +0000 (18:33 +0000)
Original commit message from CVS:
* CHANGES-0.9:
* docs/design/part-TODO.txt:
* docs/design/part-events.txt:
Some docs updates

* gst/base/gstbasesink.c: (gst_base_sink_handle_object),
(gst_base_sink_event), (gst_base_sink_do_sync),
(gst_base_sink_activate_push), (gst_base_sink_activate_pull):
* gst/base/gstbasesrc.c: (gst_base_src_send_discont),
(gst_base_src_do_seek), (gst_base_src_event_handler),
(gst_base_src_loop):
* gst/base/gstbasetransform.c: (gst_base_transform_transform_caps),
(gst_base_transform_configure_caps), (gst_base_transform_setcaps),
(gst_base_transform_get_size), (gst_base_transform_buffer_alloc),
(gst_base_transform_event), (gst_base_transform_handle_buffer),
(gst_base_transform_set_passthrough),
(gst_base_transform_is_passthrough):
* gst/elements/gstfakesink.c: (gst_fake_sink_event):
* gst/elements/gstfilesink.c: (gst_file_sink_event):
Event updates.

* gst/gstbuffer.h:
Use faster casts.

* gst/gstelement.c: (gst_element_seek):
* gst/gstelement.h:
Update gst_element_seek.

* gst/gstevent.c: (gst_event_finalize), (_gst_event_copy),
(gst_event_new), (gst_event_new_custom), (gst_event_get_structure),
(gst_event_new_flush_start), (gst_event_new_flush_stop),
(gst_event_new_eos), (gst_event_new_newsegment),
(gst_event_parse_newsegment), (gst_event_new_tag),
(gst_event_parse_tag), (gst_event_new_filler), (gst_event_new_qos),
(gst_event_parse_qos), (gst_event_new_seek),
(gst_event_parse_seek), (gst_event_new_navigation):
* gst/gstevent.h:
Make GstEvent use GstStructure. Add parsing code, make sure the
API is sufficiently generic.
Mark possible directions of events and serialization.

* gst/gstmessage.c: (gst_message_init), (gst_message_finalize),
(_gst_message_copy), (gst_message_new_segment_start),
(gst_message_new_segment_done), (gst_message_new_custom),
(gst_message_parse_segment_start),
(gst_message_parse_segment_done):
Small cleanups.

* gst/gstpad.c: (gst_pad_get_caps_unlocked), (gst_pad_accept_caps),
(gst_pad_set_caps), (gst_pad_send_event):
Update for new events.
Catch events sent in wrong directions.

* gst/gstqueue.c: (gst_queue_link_src),
(gst_queue_handle_sink_event), (gst_queue_chain), (gst_queue_loop),
(gst_queue_handle_src_query):
Event updates.

* gst/gsttag.c:
* gst/gsttag.h:
Remove event code from this file.

* libs/gst/dataprotocol/dataprotocol.c: (gst_dp_packet_from_event),
(gst_dp_event_from_packet):
Event updates.

28 files changed:
CHANGES-0.9
ChangeLog
docs/design/part-TODO.txt
docs/design/part-events.txt
gst/base/gstbasesink.c
gst/base/gstbasesrc.c
gst/base/gstbasetransform.c
gst/elements/gstfakesink.c
gst/elements/gstfilesink.c
gst/gstbuffer.h
gst/gstelement.c
gst/gstelement.h
gst/gstevent.c
gst/gstevent.h
gst/gstmessage.c
gst/gstpad.c
gst/gstqueue.c
gst/gsttag.c
gst/gsttag.h
gst/gsttaglist.c
gst/gsttaglist.h
libs/gst/base/gstbasesink.c
libs/gst/base/gstbasesrc.c
libs/gst/base/gstbasetransform.c
libs/gst/dataprotocol/dataprotocol.c
plugins/elements/gstfakesink.c
plugins/elements/gstfilesink.c
plugins/elements/gstqueue.c

index 67acb54e07035b73a71044bd479ff4a7b3052f8a..239d8c27e31dcd98e555da37834b0b63f4ee266b 100644 (file)
@@ -17,7 +17,7 @@ Changes in the 0.9 version
    remains in this state.
 
  - GMainLoop integration. Information on the state of the pipeline
-   is now received in the mainloop.
+   is now received in the mainloop via the GstBus.
 
  - Events move separate from the datastream, this allows for both
    in and out of sync delivery of events.
index 149c472511400ad38eacd993c41b0ff108b17c67..5e9483f8c1100190518bd0a2e928f84f5f217425 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,71 @@
+2005-07-27  Wim Taymans  <wim@fluendo.com>
+
+       * CHANGES-0.9:
+       * docs/design/part-TODO.txt:
+       * docs/design/part-events.txt:
+       Some docs updates
+
+       * gst/base/gstbasesink.c: (gst_base_sink_handle_object),
+       (gst_base_sink_event), (gst_base_sink_do_sync),
+       (gst_base_sink_activate_push), (gst_base_sink_activate_pull):
+       * gst/base/gstbasesrc.c: (gst_base_src_send_discont),
+       (gst_base_src_do_seek), (gst_base_src_event_handler),
+       (gst_base_src_loop):
+       * gst/base/gstbasetransform.c: (gst_base_transform_transform_caps),
+       (gst_base_transform_configure_caps), (gst_base_transform_setcaps),
+       (gst_base_transform_get_size), (gst_base_transform_buffer_alloc),
+       (gst_base_transform_event), (gst_base_transform_handle_buffer),
+       (gst_base_transform_set_passthrough),
+       (gst_base_transform_is_passthrough):
+       * gst/elements/gstfakesink.c: (gst_fake_sink_event):
+       * gst/elements/gstfilesink.c: (gst_file_sink_event):
+       Event updates.
+
+       * gst/gstbuffer.h:
+       Use faster casts.
+
+       * gst/gstelement.c: (gst_element_seek):
+       * gst/gstelement.h:
+       Update gst_element_seek.
+
+       * gst/gstevent.c: (gst_event_finalize), (_gst_event_copy),
+       (gst_event_new), (gst_event_new_custom), (gst_event_get_structure),
+       (gst_event_new_flush_start), (gst_event_new_flush_stop),
+       (gst_event_new_eos), (gst_event_new_newsegment),
+       (gst_event_parse_newsegment), (gst_event_new_tag),
+       (gst_event_parse_tag), (gst_event_new_filler), (gst_event_new_qos),
+       (gst_event_parse_qos), (gst_event_new_seek),
+       (gst_event_parse_seek), (gst_event_new_navigation):
+       * gst/gstevent.h:
+       Make GstEvent use GstStructure. Add parsing code, make sure the
+       API is sufficiently generic.
+       Mark possible directions of events and serialization.
+
+       * gst/gstmessage.c: (gst_message_init), (gst_message_finalize),
+       (_gst_message_copy), (gst_message_new_segment_start),
+       (gst_message_new_segment_done), (gst_message_new_custom),
+       (gst_message_parse_segment_start),
+       (gst_message_parse_segment_done):
+       Small cleanups.
+
+       * gst/gstpad.c: (gst_pad_get_caps_unlocked), (gst_pad_accept_caps),
+       (gst_pad_set_caps), (gst_pad_send_event):
+       Update for new events. 
+       Catch events sent in wrong directions.
+
+       * gst/gstqueue.c: (gst_queue_link_src),
+       (gst_queue_handle_sink_event), (gst_queue_chain), (gst_queue_loop),
+       (gst_queue_handle_src_query):
+       Event updates.
+
+       * gst/gsttag.c:
+       * gst/gsttag.h:
+       Remove event code from this file.
+
+       * libs/gst/dataprotocol/dataprotocol.c: (gst_dp_packet_from_event),
+       (gst_dp_event_from_packet):
+       Event updates.
+
 2005-07-27  Ronald S. Bultje  <rbultje@ronald.bitfreak.net>
 
        * gst/base/gstbasetransform.c: (gst_base_transform_getcaps),
index fffa9051dd06069d5fdbe5ca66542ba55a8df7eb..1acb746a0055d90df4a7fc33afea7cfb502d6da1 100644 (file)
@@ -8,7 +8,8 @@
   done by making the event contain a GstStructure with input/output values, similar
   to GstMessage.
 
-- implement iterators for traversing elements upstream or dowstream.
+- implement iterators for traversing elements upstream or dowstream. Use more simple
+  algorithm using indegree topological sort.
 
 - unlinking pads in the PAUSED state needs to make sure the stream thread is not
   executing code. Can this be done with a flush to unlock all downstream chain
index 32f995e56b8b6bf639d284ba292bdb8caf07f594..ed671f4a1fcb368acd1580e0efe2d763f5c0c056 100644 (file)
@@ -10,15 +10,47 @@ others don't.
 
 Different types of events exist to implement various functionalities.
 
+  GST_EVENT_FLUSH_START:   data is to be discarded
+  GST_EVENT_FLUSH_STOP:    data is allowed again
   GST_EVENT_EOS:          no more data is to be expected on a pad.
-  GST_EVENT_FLUSH:         data is to be discarded or allowed again
-  GST_EVENT_DISCONTINUOUS: A new group of buffers with common start time  
+  GST_EVENT_NEWSEGMENT:    A new group of buffers with common start time  
+  GST_EVENT_TAG:           Stream metadata.
+  GST_EVENT_FILLER:        Filler for sparse data streams
   GST_EVENT_QOS:           A notification of the quality of service of the stream
   GST_EVENT_SEEK:          A seek should be performed to a new position in the stream
-  GST_EVENT_SIZE:          Notification of suggested buffer size.
-  GST_EVENT_RATE:          Notification to change the processing speed of a stream
   GST_EVENT_NAVIGATION:    A navigation event.
-  GST_EVENT_TAG:           Stream metadata.
+
+
+FLUSH_START/STOP
+----------------
+
+A flush event is sent both downstream and upstream to clear any pending data 
+from the pipeline. This might be needed to make the graph more responsive 
+when the normal dataflow gets interrupted by for example a seek event.
+
+Flushing happens in two stages.
+
+ 1) a source filter sends the FLUSH_START event to the downstream peer element. The
+    downstream element starts rejecting buffers from the upstream elements. It
+    sends the flush event further downstream and discards any buffers it is 
+    holding as well as return from the chain function as soon as possible.
+    This makes sure that all upstream elements get unblocked.
+    This event is not synchronized with the STREAM_LOCK and can be done in the 
+    application thread.
+
+ 2) a source filter sends the FLUSH_STOP event to indicate
+    that the downstream element can accept buffers again. The downstream 
+    element sends the flush event to its peer elements. After this step dataflow
+    continues. The FLUSH_STOP call is synchronized with the STREAM_LOCK so any
+    data used by the chain function can safely freed here if needed. Any 
+    pending EOS events should be discarded too.
+
+After the flush completes the second stage, data is flowing again in the pipeline
+and all buffers are more recent than those before the flush.
+
+For elements that use the pullregion function, they send both flush events to
+the upstream pads in the same way top make sure that the pullregion function
+unlocks and any pending buffers are cleared in the upstream elements.
 
 
 EOS
@@ -57,67 +89,39 @@ the EOS event is received in the PAUSED state, it is queued until the element
 goes to PLAYING.
 
 
-FLUSH
------
-
-A flush event is sent both downstream and upstream to clear any pending data 
-from the pipeline. This might be needed to make the graph more responsive 
-when the normal dataflow gets interrupted by for example a seek event.
-
-Flushing happens in two stages.
-
- 1) a source filter sends the flush event to the downstream peer element. The
-    downstream element starts rejecting buffers from the upstream elements. It
-    sends the flush event further downstream and discards any buffers it is 
-    holding as well as return from the chain function as soon as possible.
-    This makes sure that all upstream elements get unblocked.
-    This event is not synchronized with the STREAM_LOCK and can be done in the 
-    application thread.
-
- 2) a source filter sends the flush event with the done flag set to indicate
-    that the downstream element can accept buffers again. The downstream 
-    element sends the flush event to its peer elements. After this step dataflow
-    continues. The endflush call is synchronized with the STREAM_LOCK so any
-    data used by the chain function can safely freed here if needed. Any 
-    pending EOS events should be discarded too.
-
-After the flush completes the second stage, data is flowing again in the pipeline
-and all buffers are more recent than those before the flush.
-
-For elements that use the pullregion function, they send both flush events to
-the upstream pads in the same way top make sure that the pullregion function
-unlocks and any pending buffers are cleared in the upstream elements.
-
-
-DISCONTINUOUS
+NEWSEGMENT
 -------------
 
-A discont event is sent downstream by an element to indicate that the following
-group of buffers start and end at the specified time. The discont event
+A newsegment event is sent downstream by an element to indicate that the following
+group of buffers start and end at the specified positions. The newsegment event
 also contains the playback speed of the stream.
 
 Since the stream time is always set to 0 at start and after a seek, a 0
 point for all next buffer's timestamps has to be propagated through the
-pipeline using the DISCONT event.
+pipeline using the NEWSEGMENT event.
 
-Before sending buffers, an element must send a DISCONT event. An element is
-free to refuse buffers if they were not preceeded by a DISCONT event.
+Before sending buffers, an element must send a NEWSEGMENT event. An element is
+free to refuse buffers if they were not preceeded by a NEWSEGMENT event.
 
-Elements that sync to the clock should store the DISCONT start and end values
+Elements that sync to the clock should store the NEWSEGMENT start and end values
 and substract the start value from the buffer timestamp before comparing
 it against the stream time (see part-clocks.txt).
 
-An element is allowed to send out buffers with the DISCONT start time already
+An element is allowed to send out buffers with the NEWSEGMENT start time already
 substracted from the timestamp. If it does so, it needs to send a corrected
-DISCONT downstream, ie, one with start time 0.
+NEWSEGMENT downstream, ie, one with start time 0.
 
-A DISCONT event should be generated as soon as possible in the pipeline and
+A NEWSEGMENT event should be generated as soon as possible in the pipeline and
 is usually generated by a demuxer or source. The event is generated before 
 pushing the first buffer and after a seek, right before pushing the new buffer.
 
-The DISCONT event can be send from both the application and the streaming
+The NEWSEGMENT event can be send from both the application and the streaming
 thread and should be serialized with the buffers.
 
+Buffers should be clipped within the range indicated by the newsegment event
+start and stop values. Sinks are allowed to drop buffers with timestamps out
+of the indicated newsegment range.
+
 
 SEEK
 ----
@@ -149,7 +153,7 @@ the STREAM_LOCK so that the streaming thread and the seek gets serialized.
 The general flow of executing the seek with FLUSH is as follows:
 
  1) unblock the streaming threads, they could be blocked in a chain 
-    function. This is done by sending a flush on all srcpads.
+    function. This is done by sending a FLUSH_START on all srcpads.
     The flush will make sure that all downstream elements unlock and
     that control will return to this element chain/loop function.
     We cannot lock the STREAM_LOCK before doing this since it might
@@ -162,9 +166,9 @@ The general flow of executing the seek with FLUSH is as follows:
     will wait for the seek to complete. Most likely, the stream thread
     will pause because the peer elements are flushing.
 
- 4) send a flush event with the done flag set to allow streaming again.
+ 4) send a FLUSH_STOP event to all peer elements to allow streaming again.
 
- 5) send a DISCONT event to signal the new buffer timestamp base time.
+ 5) send a NEWSEGMENT event to signal the new buffer timestamp base time.
 
  6) start stopped tasks and unlock the STREAM_LOCK, dataflow will continue
     now from the new position.
@@ -173,29 +177,6 @@ More information about the different seek types can be found in
 part-seeking.txt.
 
 
-SIZE
-----
-
-Some demuxers know an optimal size for any downstream buffers. They can 
-use this event to signal this fact. Similary an element can signal an
-upstream element for a prefered buffer size.
-
-
-RATE
-----
-
-When the application wants to change the playback rate of the stream, it
-issues a rate event on the sinks. A rate of 1.0 is the normal playback rate, 
-2.0 plays at twice the speed and negative values play backwards.
-
-The rate event travels upstream. After the rate event reaches an element
-that can handle the rate event, it issues a flush and generates a new 
-DISCONT event with the updated rate.
-
-Note that the clock speed does not change. More specific information about
-changing the playback rate are to be thought out and written down.
-
-
 NAVIGATION
 ----------
 
index 91063b7278b7d46469fcc3e077a5fd60d3e543c5..098bf15daa070b86f1aed65f0bc42d1db1d342a6 100644 (file)
@@ -468,11 +468,17 @@ gst_base_sink_handle_object (GstBaseSink * basesink, GstPad * pad,
         basesink->preroll_queued++;
         basesink->eos = TRUE;
         break;
-      case GST_EVENT_DISCONTINUOUS:
-        /* the discont event is needed to bring the buffer timestamps to the
+      case GST_EVENT_NEWSEGMENT:
+      {
+        GstFormat format;
+        gdouble rate;
+
+        /* the newsegment event is needed to bring the buffer timestamps to the
          * stream time */
-        if (!gst_event_discont_get_value (event, GST_FORMAT_TIME,
-                &basesink->discont_start, &basesink->discont_stop)) {
+        gst_event_parse_newsegment (event, &rate, &format,
+            &basesink->discont_start, &basesink->discont_stop, NULL);
+
+        if (format != GST_FORMAT_TIME) {
           /* this means this sink will not be able to sync to the clock */
           basesink->discont_start = 0;
           basesink->discont_stop = 0;
@@ -483,6 +489,7 @@ gst_base_sink_handle_object (GstBaseSink * basesink, GstPad * pad,
             GST_TIME_ARGS (basesink->discont_start),
             GST_TIME_ARGS (basesink->discont_stop));
         break;
+      }
       default:
         break;
     }
@@ -664,7 +671,7 @@ gst_base_sink_event (GstPad * pad, GstEvent * event)
       GST_STREAM_UNLOCK (pad);
       break;
     }
-    case GST_EVENT_DISCONTINUOUS:
+    case GST_EVENT_NEWSEGMENT:
     {
       GstFlowReturn ret;
 
@@ -674,39 +681,44 @@ gst_base_sink_event (GstPad * pad, GstEvent * event)
       GST_STREAM_UNLOCK (pad);
       break;
     }
-    case GST_EVENT_FLUSH:
+    case GST_EVENT_FLUSH_START:
       /* make sure we are not blocked on the clock also clear any pending
        * eos state. */
       if (bclass->event)
         bclass->event (basesink, event);
 
-      if (!GST_EVENT_FLUSH_DONE (event)) {
-        GST_PREROLL_LOCK (pad);
-        /* we need preroll after the flush */
-        basesink->need_preroll = TRUE;
-        /* unlock from a possible state change/preroll */
-        gst_base_sink_preroll_queue_flush (basesink, pad);
+      GST_PREROLL_LOCK (pad);
+      /* we need preroll after the flush */
+      basesink->need_preroll = TRUE;
+      /* unlock from a possible state change/preroll */
+      gst_base_sink_preroll_queue_flush (basesink, pad);
 
-        GST_LOCK (basesink);
-        if (basesink->clock_id) {
-          gst_clock_id_unschedule (basesink->clock_id);
-        }
-        GST_UNLOCK (basesink);
-        GST_PREROLL_UNLOCK (pad);
-
-        /* and we need to commit our state again on the next
-         * prerolled buffer */
-        GST_STATE_LOCK (basesink);
-        GST_STREAM_LOCK (pad);
-        gst_element_lost_state (GST_ELEMENT (basesink));
-        GST_STREAM_UNLOCK (pad);
-        GST_STATE_UNLOCK (basesink);
-      } else {
-        /* now we are completely unblocked and the _chain method
-         * will return */
-        GST_STREAM_LOCK (pad);
-        GST_STREAM_UNLOCK (pad);
+      GST_LOCK (basesink);
+      if (basesink->clock_id) {
+        gst_clock_id_unschedule (basesink->clock_id);
       }
+      GST_UNLOCK (basesink);
+      GST_PREROLL_UNLOCK (pad);
+
+      /* and we need to commit our state again on the next
+       * prerolled buffer */
+      GST_STATE_LOCK (basesink);
+      GST_STREAM_LOCK (pad);
+      gst_element_lost_state (GST_ELEMENT (basesink));
+      GST_STREAM_UNLOCK (pad);
+      GST_STATE_UNLOCK (basesink);
+      GST_DEBUG ("event unref %p %p", basesink, event);
+      gst_event_unref (event);
+      break;
+    case GST_EVENT_FLUSH_STOP:
+      if (bclass->event)
+        bclass->event (basesink, event);
+
+      /* now we are completely unblocked and the _chain method
+       * will return */
+      GST_STREAM_LOCK (pad);
+      GST_STREAM_UNLOCK (pad);
+
       GST_DEBUG ("event unref %p %p", basesink, event);
       gst_event_unref (event);
       break;
index 77b1e2088a2d6037cd5d65877031e8d774c0513e..c42e6aa35596d7bf9909e152fd317fd2b453e5b5 100644 (file)
@@ -362,9 +362,9 @@ gst_base_src_send_discont (GstBaseSrc * src)
 {
   GstEvent *event;
 
-  event = gst_event_new_discontinuous (1.0,
+  event = gst_event_new_newsegment (1.0,
       GST_FORMAT_BYTES,
-      (gint64) src->segment_start, (gint64) src->segment_end, NULL);
+      (gint64) src->segment_start, (gint64) src->segment_end, (gint64) 0);
 
   return gst_pad_push_event (src->srcpad, event);
 }
@@ -372,10 +372,14 @@ gst_base_src_send_discont (GstBaseSrc * src)
 static gboolean
 gst_base_src_do_seek (GstBaseSrc * src, GstEvent * event)
 {
+  gdouble rate;
   GstFormat format;
-  gint64 offset;
+  GstSeekFlags flags;
+  GstSeekType cur_type, stop_type;
+  gint64 cur, stop;
 
-  format = GST_EVENT_SEEK_FORMAT (event);
+  gst_event_parse_seek (event, &rate, &format, &flags,
+      &cur_type, &cur, &stop_type, &stop);
 
   /* get seek format */
   if (format == GST_FORMAT_DEFAULT)
@@ -385,11 +389,10 @@ gst_base_src_do_seek (GstBaseSrc * src, GstEvent * event)
     return FALSE;
 
   /* get seek positions */
-  offset = GST_EVENT_SEEK_OFFSET (event);
-  src->segment_loop = GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_SEGMENT_LOOP;
+  src->segment_loop = flags & GST_SEEK_FLAG_SEGMENT;
 
   /* send flush start */
-  gst_pad_push_event (src->srcpad, gst_event_new_flush (FALSE));
+  gst_pad_push_event (src->srcpad, gst_event_new_flush_start ());
 
   /* unblock streaming thread */
   gst_base_src_unlock (src);
@@ -397,35 +400,35 @@ gst_base_src_do_seek (GstBaseSrc * src, GstEvent * event)
   /* grab streaming lock */
   GST_STREAM_LOCK (src->srcpad);
 
-  /* send flush end */
-  gst_pad_push_event (src->srcpad, gst_event_new_flush (TRUE));
+  /* send flush stop */
+  gst_pad_push_event (src->srcpad, gst_event_new_flush_stop ());
 
   /* perform the seek */
-  switch (GST_EVENT_SEEK_METHOD (event)) {
-    case GST_SEEK_METHOD_SET:
-      if (offset < 0)
+  switch (cur_type) {
+    case GST_SEEK_TYPE_SET:
+      if (cur < 0)
         goto error;
-      src->offset = MIN (offset, src->size);
+      src->offset = MIN (cur, src->size);
       src->segment_start = src->offset;
-      src->segment_end = MIN (GST_EVENT_SEEK_ENDOFFSET (event), src->size);
+      src->segment_end = MIN (stop, src->size);
       GST_DEBUG_OBJECT (src, "seek set pending to %" G_GINT64_FORMAT,
           src->offset);
       break;
-    case GST_SEEK_METHOD_CUR:
-      offset += src->offset;
-      src->offset = CLAMP (offset, 0, src->size);
+    case GST_SEEK_TYPE_CUR:
+      cur += src->offset;
+      src->offset = CLAMP (cur, 0, src->size);
       src->segment_start = src->offset;
-      src->segment_end = GST_EVENT_SEEK_ENDOFFSET (event);
+      src->segment_end = stop;
       GST_DEBUG_OBJECT (src, "seek cur pending to %" G_GINT64_FORMAT,
           src->offset);
       break;
-    case GST_SEEK_METHOD_END:
-      if (offset > 0)
+    case GST_SEEK_TYPE_END:
+      if (cur > 0)
         goto error;
-      offset = src->size + offset;
-      src->offset = MAX (0, offset);
+      cur = src->size + cur;
+      src->offset = MAX (0, cur);
       src->segment_start = src->offset;
-      src->segment_end = GST_EVENT_SEEK_ENDOFFSET (event);
+      src->segment_end = stop;
       GST_DEBUG_OBJECT (src, "seek end pending to %" G_GINT64_FORMAT,
           src->offset);
       break;
@@ -471,25 +474,11 @@ gst_base_src_event_handler (GstPad * pad, GstEvent * event)
   switch (GST_EVENT_TYPE (event)) {
     case GST_EVENT_SEEK:
       return gst_base_src_do_seek (src, event);
-    case GST_EVENT_SIZE:
-    {
-      GstFormat format;
-
-      format = GST_EVENT_SIZE_FORMAT (event);
-      if (format == GST_FORMAT_DEFAULT)
-        format = GST_FORMAT_BYTES;
-      /* we can only accept bytes */
-      if (format != GST_FORMAT_BYTES)
-        return FALSE;
-
-      src->blocksize = GST_EVENT_SIZE_VALUE (event);
-      g_object_notify (G_OBJECT (src), "blocksize");
-      break;
-    }
-    case GST_EVENT_FLUSH:
+    case GST_EVENT_FLUSH_START:
       /* cancel any blocking getrange */
-      if (!GST_EVENT_FLUSH_DONE (event))
-        gst_base_src_unlock (src);
+      gst_base_src_unlock (src);
+      break;
+    case GST_EVENT_FLUSH_STOP:
       break;
     default:
       break;
@@ -695,7 +684,7 @@ eos:
   {
     GST_DEBUG_OBJECT (src, "going to EOS");
     gst_pad_pause_task (pad);
-    gst_pad_push_event (pad, gst_event_new (GST_EVENT_EOS));
+    gst_pad_push_event (pad, gst_event_new_eos ());
     return;
   }
 pause:
@@ -707,7 +696,7 @@ pause:
       GST_ELEMENT_ERROR (src, STREAM, STOPPED,
           ("streaming stopped, reason %s", gst_flow_get_name (ret)),
           ("streaming stopped, reason %s", gst_flow_get_name (ret)));
-      gst_pad_push_event (pad, gst_event_new (GST_EVENT_EOS));
+      gst_pad_push_event (pad, gst_event_new_eos ());
     }
     return;
   }
@@ -717,7 +706,7 @@ error:
         ("internal: element returned NULL buffer"),
         ("internal: element returned NULL buffer"));
     gst_pad_pause_task (pad);
-    gst_pad_push_event (pad, gst_event_new (GST_EVENT_EOS));
+    gst_pad_push_event (pad, gst_event_new_eos ());
     return;
   }
 }
index 52aa8a68bf5187b35efaa7789afc05a176d002c2..3aba064ebe15fc4380c29523cd50ae69df687da6 100644 (file)
@@ -497,11 +497,11 @@ gst_base_transform_event (GstPad * pad, GstEvent * event)
   unlock = FALSE;
 
   switch (GST_EVENT_TYPE (event)) {
-    case GST_EVENT_FLUSH:
-      if (GST_EVENT_FLUSH_DONE (event)) {
-        GST_STREAM_LOCK (pad);
-        unlock = TRUE;
-      }
+    case GST_EVENT_FLUSH_START:
+      break;
+    case GST_EVENT_FLUSH_STOP:
+      GST_STREAM_LOCK (pad);
+      unlock = TRUE;
       break;
     case GST_EVENT_EOS:
       GST_STREAM_LOCK (pad);
index 8853b4a89ddf7bd8767dca54c5453f1107d57f19..1ba00b14e902cb44d8d7b9205e40ef180870c236 100644 (file)
@@ -273,13 +273,20 @@ static gboolean
 gst_fake_sink_event (GstBaseSink * bsink, GstEvent * event)
 {
   GstFakeSink *sink = GST_FAKE_SINK (bsink);
+  const GstStructure *s;
 
   if (!sink->silent) {
+    gchar *sstr;
+
     g_free (sink->last_message);
 
+    s = gst_event_get_structure (event);
+    sstr = gst_structure_to_string (s);
+
     sink->last_message =
-        g_strdup_printf ("event   ******* E (type: %d) %p",
-        GST_EVENT_TYPE (event), event);
+        g_strdup_printf ("event   ******* E (type: %d, %s) %p",
+        GST_EVENT_TYPE (event), sstr, event);
+    g_free (sstr);
 
     g_object_notify (G_OBJECT (sink), "last_message");
   }
index 531758d62f6bce8662fbfef7568cb028a03e9fdf..b2bc2e17d1e2b1f28348717ad38db5ec94e51c11 100644 (file)
@@ -291,48 +291,23 @@ gst_file_sink_event (GstBaseSink * sink, GstEvent * event)
 
   filesink = GST_FILE_SINK (sink);
 
-  type = event ? GST_EVENT_TYPE (event) : GST_EVENT_UNKNOWN;
+  type = GST_EVENT_TYPE (event);
 
   switch (type) {
-    case GST_EVENT_SEEK:
-      if (GST_EVENT_SEEK_FORMAT (event) != GST_FORMAT_BYTES) {
-        return FALSE;
-      }
-
-      if (GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_FLUSH) {
-        if (fflush (filesink->file)) {
-          GST_ELEMENT_ERROR (filesink, RESOURCE, WRITE,
-              (_("Error while writing to file \"%s\"."), filesink->filename),
-              GST_ERROR_SYSTEM);
-          return FALSE;
-        }
-      }
-
-      switch (GST_EVENT_SEEK_METHOD (event)) {
-        case GST_SEEK_METHOD_SET:
-          fseek (filesink->file, GST_EVENT_SEEK_OFFSET (event), SEEK_SET);
-          break;
-        case GST_SEEK_METHOD_CUR:
-          fseek (filesink->file, GST_EVENT_SEEK_OFFSET (event), SEEK_CUR);
-          break;
-        case GST_SEEK_METHOD_END:
-          fseek (filesink->file, GST_EVENT_SEEK_OFFSET (event), SEEK_END);
-          break;
-        default:
-          g_warning ("unknown seek method!");
-          break;
-      }
-      break;
-    case GST_EVENT_DISCONTINUOUS:
+    case GST_EVENT_NEWSEGMENT:
     {
       gint64 soffset, eoffset;
+      GstFormat format;
 
-      if (gst_event_discont_get_value (event, GST_FORMAT_BYTES, &soffset,
-              &eoffset))
+      gst_event_parse_newsegment (event, NULL, &format, &soffset, &eoffset,
+          NULL);
+
+      if (format == GST_FORMAT_BYTES) {
         fseek (filesink->file, soffset, SEEK_SET);
+      }
       break;
     }
-    case GST_EVENT_FLUSH:
+    case GST_EVENT_EOS:
       if (fflush (filesink->file)) {
         GST_ELEMENT_ERROR (filesink, RESOURCE, WRITE,
             (_("Error while writing to file \"%s\"."), filesink->filename),
index 2f226f145e8810ebce1d5013ddfbf40c2efbca6a..fc648ac462a33e388d28ecc5afc7539ee4c76031 100644 (file)
@@ -48,14 +48,14 @@ typedef struct _GstBufferClass GstBufferClass;
 #define GST_BUFFER_FLAG_SET(buf,flag)           GST_MINI_OBJECT_FLAG_SET (buf, flag)
 #define GST_BUFFER_FLAG_UNSET(buf,flag)         GST_MINI_OBJECT_FLAG_UNSET (buf, flag)
 
-#define GST_BUFFER_DATA(buf)                   (GST_BUFFER(buf)->data)
-#define GST_BUFFER_SIZE(buf)                   (GST_BUFFER(buf)->size)
-#define GST_BUFFER_TIMESTAMP(buf)              (GST_BUFFER(buf)->timestamp)
-#define GST_BUFFER_DURATION(buf)               (GST_BUFFER(buf)->duration)
-#define GST_BUFFER_CAPS(buf)                   (GST_BUFFER(buf)->caps)
-#define GST_BUFFER_OFFSET(buf)                 (GST_BUFFER(buf)->offset)
-#define GST_BUFFER_OFFSET_END(buf)             (GST_BUFFER(buf)->offset_end)
-#define GST_BUFFER_MALLOCDATA(buf)             (GST_BUFFER(buf)->malloc_data)
+#define GST_BUFFER_DATA(buf)                   (GST_BUFFER_CAST(buf)->data)
+#define GST_BUFFER_SIZE(buf)                   (GST_BUFFER_CAST(buf)->size)
+#define GST_BUFFER_TIMESTAMP(buf)              (GST_BUFFER_CAST(buf)->timestamp)
+#define GST_BUFFER_DURATION(buf)               (GST_BUFFER_CAST(buf)->duration)
+#define GST_BUFFER_CAPS(buf)                   (GST_BUFFER_CAST(buf)->caps)
+#define GST_BUFFER_OFFSET(buf)                 (GST_BUFFER_CAST(buf)->offset)
+#define GST_BUFFER_OFFSET_END(buf)             (GST_BUFFER_CAST(buf)->offset_end)
+#define GST_BUFFER_MALLOCDATA(buf)             (GST_BUFFER_CAST(buf)->malloc_data)
 
 #define GST_BUFFER_OFFSET_NONE ((guint64)-1)
 
@@ -138,12 +138,12 @@ G_STMT_START {                                            \
 } G_STMT_END
 
 /* refcounting */
-#define                gst_buffer_ref(buf)             GST_BUFFER (gst_mini_object_ref (GST_MINI_OBJECT (buf)))
+#define                gst_buffer_ref(buf)             GST_BUFFER_CAST (gst_mini_object_ref (GST_MINI_OBJECT (buf)))
 #define                gst_buffer_unref(buf)           gst_mini_object_unref (GST_MINI_OBJECT (buf))
 /* copy buffer */
-#define                gst_buffer_copy(buf)            GST_BUFFER (gst_mini_object_copy (GST_MINI_OBJECT (buf)))
+#define                gst_buffer_copy(buf)            GST_BUFFER_CAST (gst_mini_object_copy (GST_MINI_OBJECT (buf)))
 #define                gst_buffer_is_writable(buf)     gst_mini_object_is_writable (GST_MINI_OBJECT (buf))
-#define                gst_buffer_make_writable(buf)   GST_BUFFER (gst_mini_object_make_writable (GST_MINI_OBJECT (buf)))
+#define                gst_buffer_make_writable(buf)   GST_BUFFER_CAST (gst_mini_object_make_writable (GST_MINI_OBJECT (buf)))
 
 #define                gst_buffer_replace(obuf,nbuf)   gst_mini_object_replace ((GstMiniObject **)(obuf), GST_MINI_OBJECT (nbuf))
 
index 577673db9c3d5bdb692f3ce2f31fc761639d6b88..a4e341733e8f9940683a1b21dfad2343b30c3699 100644 (file)
@@ -1160,15 +1160,17 @@ gst_element_send_event (GstElement * element, GstEvent * event)
  * MT safe.
  */
 gboolean
-gst_element_seek (GstElement * element, GstSeekType seek_method,
-    GstFormat seek_format, GstSeekType seek_flags, guint64 offset)
+gst_element_seek (GstElement * element, gdouble rate, GstFormat format,
+    GstSeekFlags flags, GstSeekType cur_type, gint64 cur,
+    GstSeekType stop_type, gint64 stop)
 {
   GstEvent *event;
   gboolean result;
 
   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
 
-  event = gst_event_new_seek (seek_method | seek_format | seek_flags, offset);
+  event =
+      gst_event_new_seek (rate, format, flags, cur_type, cur, stop_type, stop);
   result = gst_element_send_event (element, event);
 
   return result;
index baa02812f3fb1f29209313fc63eb5fa7d7f75a19..39d99652e9c00f5a3c4a55fe30392674fabe8509 100644 (file)
@@ -302,11 +302,10 @@ GstIterator *             gst_element_iterate_sink_pads   (GstElement * element);
 
 /* event/query/format stuff */
 gboolean               gst_element_send_event          (GstElement *element, GstEvent *event);
-gboolean               gst_element_seek                (GstElement *element,
-                                                        GstSeekType seek_method,
-                                                        GstFormat   seek_format,
-                                                        GstSeekType seek_flags,
-                                                        guint64 offset);
+gboolean               gst_element_seek                (GstElement *element, gdouble rate,
+                                                        GstFormat format, GstSeekFlags flags,
+                                                        GstSeekType cur_type, gint64 cur,
+                                                        GstSeekType stop_type, gint64 stop);
 G_CONST_RETURN GstQueryType*
                        gst_element_get_query_types     (GstElement *element);
 gboolean               gst_element_query               (GstElement *element, GstQuery *query);
index 8aec18858c3dbf4ca9db105362d03f31889a172a..fd5571d65313853eb7062ffb77259f29e749bf0c 100644 (file)
 #include "gst_private.h"
 
 #include "gstinfo.h"
-#include "gstmemchunk.h"
 #include "gstevent.h"
-#include "gsttag.h"
+#include "gstenumtypes.h"
 #include "gstutils.h"
 
-
 static void gst_event_init (GTypeInstance * instance, gpointer g_class);
 static void gst_event_class_init (gpointer g_class, gpointer class_data);
 static void gst_event_finalize (GstEvent * event);
@@ -101,298 +99,400 @@ gst_event_finalize (GstEvent * event)
     gst_object_unref (GST_EVENT_SRC (event));
     GST_EVENT_SRC (event) = NULL;
   }
-  switch (GST_EVENT_TYPE (event)) {
-    case GST_EVENT_TAG:
-      if (GST_IS_TAG_LIST (event->event_data.structure.structure)) {
-        gst_tag_list_free (event->event_data.structure.structure);
-      } else {
-        g_warning ("tag event %p didn't contain a valid tag list!", event);
-        GST_ERROR ("tag event %p didn't contain a valid tag list!", event);
-      }
-      break;
-    case GST_EVENT_NAVIGATION:
-      gst_structure_free (event->event_data.structure.structure);
-      break;
-    default:
-      break;
+  if (event->structure) {
+    gst_structure_set_parent_refcount (event->structure, NULL);
+    gst_structure_free (event->structure);
   }
 }
 
-
 static GstEvent *
 _gst_event_copy (GstEvent * event)
 {
   GstEvent *copy;
 
-  copy = gst_event_new (event->type);
+  copy = (GstEvent *) gst_mini_object_new (GST_TYPE_EVENT);
 
-  copy->timestamp = event->timestamp;
-  if (event->src) {
-    copy->src = gst_object_ref (event->src);
-  }
+  GST_EVENT_TYPE (copy) = GST_EVENT_TYPE (event);
+  GST_EVENT_TIMESTAMP (copy) = GST_EVENT_TIMESTAMP (event);
 
-  memcpy (&copy->event_data, &event->event_data, sizeof (event->event_data));
-
-  /* FIXME copy/ref additional fields */
-  switch (GST_EVENT_TYPE (event)) {
-    case GST_EVENT_TAG:
-      copy->event_data.structure.structure =
-          gst_tag_list_copy ((GstTagList *) event->event_data.structure.
-          structure);
-      break;
-    case GST_EVENT_NAVIGATION:
-      copy->event_data.structure.structure =
-          gst_structure_copy (event->event_data.structure.structure);
-    default:
-      break;
+  if (GST_EVENT_SRC (event)) {
+    GST_EVENT_SRC (copy) = gst_object_ref (GST_EVENT_SRC (event));
+  }
+  if (event->structure) {
+    copy->structure = gst_structure_copy (event->structure);
+    gst_structure_set_parent_refcount (copy->structure,
+        &event->mini_object.refcount);
   }
-
   return copy;
 }
 
-/**
- * gst_event_masks_contains:
- * @masks: The eventmask array to search
- * @mask: the event mask to find
- *
- * See if the given eventmask is inside the eventmask array.
- *
- * Returns: TRUE if the eventmask is found inside the array
- */
-gboolean
-gst_event_masks_contains (const GstEventMask * masks, GstEventMask * mask)
+static GstEvent *
+gst_event_new (GstEventType type)
 {
-  g_return_val_if_fail (mask != NULL, FALSE);
+  GstEvent *event;
 
-  if (!masks)
-    return FALSE;
+  event = (GstEvent *) gst_mini_object_new (GST_TYPE_EVENT);
 
-  while (masks->type) {
-    if (masks->type == mask->type &&
-        (masks->flags & mask->flags) == mask->flags)
-      return TRUE;
+  GST_CAT_INFO (GST_CAT_EVENT, "creating new event %p %d", event, type);
 
-    masks++;
-  }
+  event->type = type;
+  event->src = NULL;
+  event->structure = NULL;
 
-  return FALSE;
+  return event;
 }
 
 /**
- * gst_event_new:
+ * gst_event_new_custom:
  * @type: The type of the new event
+ * @structure: The structure for the event. The event will take ownership of
+ * the structure.
  *
- * Allocate a new event of the given type.
+ * Create a new custom-typed event. This can be used for anything not
+ * handled by other event-specific functions to pass an event to another
+ * element.
  *
- * Returns: A new event.
+ * Make sure to allocate an event type with the #GST_EVENT_MAKE_TYPE macro,
+ * assigning a free number and filling in the correct direction and
+ * serialization flags.
+ *
+ * New custom events can also be created by subclassing the event type if
+ * needed.
+ *
+ * Returns: The new custom event.
  */
 GstEvent *
-gst_event_new (GstEventType type)
+gst_event_new_custom (GstEventType type, GstStructure * structure)
 {
   GstEvent *event;
 
-  event = (GstEvent *) gst_mini_object_new (GST_TYPE_EVENT);
-
-  GST_CAT_INFO (GST_CAT_EVENT, "creating new event type %d: %p", type, event);
-
-  GST_EVENT_TYPE (event) = type;
-
+  event = gst_event_new (type);
+  if (structure) {
+    gst_structure_set_parent_refcount (structure, &event->mini_object.refcount);
+    event->structure = structure;
+  }
   return event;
 }
 
 /**
- * gst_event_new_seek:
- * @type: The type of the seek event
- * @offset: The offset of the seek
+ * gst_event_get_structure:
+ * @event: The #GstEvent.
  *
- * Allocate a new seek event with the given parameters.
+ * Access the structure of the event.
  *
- * Returns: A new seek event.
+ * Returns: The structure of the event. The structure is still
+ * owned by the event, which means that you should not free it and
+ * that the pointer becomes invalid when you free the event.
+ *
+ * MT safe.
  */
-GstEvent *
-gst_event_new_seek (GstSeekType type, gint64 offset)
+const GstStructure *
+gst_event_get_structure (GstEvent * event)
 {
-  GstEvent *event;
-
-  event = gst_event_new (GST_EVENT_SEEK);
+  g_return_val_if_fail (GST_IS_EVENT (event), NULL);
 
-  GST_EVENT_SEEK_TYPE (event) = type;
-  GST_EVENT_SEEK_OFFSET (event) = offset;
-  GST_EVENT_SEEK_ENDOFFSET (event) = -1;
-
-  return event;
+  return event->structure;
 }
 
 /**
- * gst_event_new_discontinuous_valist:
- * @new_media: A flag indicating a new media type starts
- * @format1: The format of the discont value
- * @var_args: more discont values and formats
+ * gst_event_new_flush_start:
+ *
+ * Allocate a new flush start event. The flush start event can be send
+ * upstream and downstream and travels out-of-bounds with the dataflow.
+ * It marks pads as being in a WRONG_STATE to process more data.
+ *
+ * Elements unlock and blocking functions and exit their streaming functions
+ * as fast as possible. 
  *
- * Allocate a new discontinuous event with the given format/value pairs. Note
- * that the values are of type gint64 - you may not use simple integers such
- * as "0" when calling this function, always cast them like "(gint64) 0".
- * Terminate the list with #GST_FORMAT_UNDEFINED.
+ * This event is typically generated after a seek to minimize the latency
+ * after the seek.
  *
- * Returns: A new discontinuous event.
+ * Returns: A new flush start event.
  */
 GstEvent *
-gst_event_new_discontinuous_valist (gdouble rate, GstFormat format1,
-    va_list var_args)
+gst_event_new_flush_start (void)
 {
-  GstEvent *event;
-  gint count = 0;
-
-  event = gst_event_new (GST_EVENT_DISCONTINUOUS);
-  GST_EVENT_DISCONT_RATE (event) = rate;
-
-  while (format1 != GST_FORMAT_UNDEFINED && count < 8) {
-
-    GST_EVENT_DISCONT_OFFSET (event, count).format =
-        format1 & GST_SEEK_FORMAT_MASK;
-    GST_EVENT_DISCONT_OFFSET (event, count).start_value =
-        va_arg (var_args, gint64);
-    GST_EVENT_DISCONT_OFFSET (event, count).end_value =
-        va_arg (var_args, gint64);
-
-    format1 = va_arg (var_args, GstFormat);
-
-    count++;
-  }
-
-  GST_EVENT_DISCONT_OFFSET_LEN (event) = count;
-
-  return event;
+  return gst_event_new (GST_EVENT_FLUSH_START);
 }
 
 /**
- * gst_event_new_discontinuous:
- * @new_media: A flag indicating a new media type starts
- * @format1: The format of the discont value
- * @...: more discont values and formats
+ * gst_event_new_flush_stop:
+ *
+ * Allocate a new flush stop event. The flush start event can be send
+ * upstream and downstream and travels out-of-bounds with the dataflow.
+ * It is typically send after sending a FLUSH_START event to make the
+ * pads accept data again.
  *
- * Allocate a new discontinuous event with the given format/value pairs. Note
- * that the values are of type gint64 - you may not use simple integers such
- * as "0" when calling this function, always cast them like "(gint64) 0".
- * Terminate the list with #GST_FORMAT_UNDEFINED.
+ * Elements can process this event synchronized with the dataflow since
+ * the preceeding FLUSH_START event stopped the dataflow.
  *
- * Returns: A new discontinuous event.
+ * This event is typically generated to complete a seek and to resume
+ * dataflow.
+ *
+ * Returns: A new flush stop event.
  */
 GstEvent *
-gst_event_new_discontinuous (gdouble rate, GstFormat format1, ...)
+gst_event_new_flush_stop (void)
 {
-  va_list var_args;
-  GstEvent *event;
-
-  va_start (var_args, format1);
-
-  event = gst_event_new_discontinuous_valist (rate, format1, var_args);
-
-  va_end (var_args);
-
-  return event;
+  return gst_event_new (GST_EVENT_FLUSH_STOP);
 }
 
 /**
- * gst_event_discont_get_value:
- * @event: The event to query
- * @format: The format of the discontinuous value
- * @start_value: A pointer to store the end value in
- * @end_value: A pointer to store the end value in
+ * gst_event_new_eos:
  *
- * Get the start and end value for the given format in the discontinous event.
+ * Create a new EOS event. The eos event can only travel downstream
+ * synchronized with the buffer flow. Elements that receive the EOS
+ * event on a pad can return UNEXPECTED as a GstFlowReturn when data
+ * after the EOS event arrives.
  *
- * Returns: TRUE if the discontinuous event carries the specified
- * format/value pair.
+ * The EOS event will travel up to the sink elements in the pipeline
+ * which will then post the GST_MESSAGE_EOS on the bus.
+ *
+ * When all sinks have posted an EOS message, the EOS message is
+ * forwarded to the application.
+ *
+ * Returns: The new EOS event.
  */
-gboolean
-gst_event_discont_get_value (GstEvent * event, GstFormat format,
-    gint64 * start_value, gint64 * end_value)
+GstEvent *
+gst_event_new_eos (void)
 {
-  gint i, n;
-
-  g_return_val_if_fail (event != NULL, FALSE);
-
-  n = GST_EVENT_DISCONT_OFFSET_LEN (event);
-
-  for (i = 0; i < n; i++) {
-    if (GST_EVENT_DISCONT_OFFSET (event, i).format == format) {
-      if (start_value)
-        *start_value = GST_EVENT_DISCONT_OFFSET (event, i).start_value;
-      if (end_value)
-        *end_value = GST_EVENT_DISCONT_OFFSET (event, i).end_value;
-      return TRUE;
-    }
-  }
-
-  return FALSE;
+  return gst_event_new (GST_EVENT_EOS);
 }
 
-
 /**
- * gst_event_new_size:
- * @format: The format of the size value
- * @value: The value of the size event
+ * gst_event_new_newsegment:
+ * @rate: a new rate for playback
+ * @format: The format of the segment values
+ * @start_val: the start value of the segment
+ * @stop_val: the stop value of the segment
+ * @base: base value for buffer timestamps.
+ *
+ * Allocate a new newsegment event with the given format/values tripplets.
+ *
+ * The newsegment event marks the range of buffers to be processed. All
+ * data not within the segment range is not to be processed.
  *
- * Create a new size event with the given values.
+ * The base time of the segment is used to convert the buffer timestamps
+ * into the stream time again.
  *
- * Returns: The new size event.
+ * After a newsegment event, the buffer stream time is calculated with:
+ *
+ *   TIMESTAMP(buf) - start_time + base
+ *
+ * Returns: A new newsegment event.
  */
 GstEvent *
-gst_event_new_size (GstFormat format, gint64 value)
+gst_event_new_newsegment (gdouble rate, GstFormat format,
+    gint64 start_val, gint64 stop_val, gint64 base)
 {
-  GstEvent *event;
+  return gst_event_new_custom (GST_EVENT_NEWSEGMENT,
+      gst_structure_new ("GstEventNewsegment", "rate", G_TYPE_DOUBLE, rate,
+          "format", GST_TYPE_FORMAT, format,
+          "start_val", G_TYPE_INT64, start_val,
+          "stop_val", G_TYPE_INT64, stop_val,
+          "base", G_TYPE_INT64, base, NULL));
+}
 
-  event = gst_event_new (GST_EVENT_SIZE);
+/**
+ * gst_event_parse_newsegment:
+ * @event: The event to query
+ * @rate: A pointer to the rate of the segment
+ * @format: A pointer to the format of the newsegment values
+ * @start_value: A pointer to store the start value in
+ * @stop_value: A pointer to store the stop value in
+ * @base: A pointer to store the base time in
+ *
+ * Get the start, stop and format in the newsegment event.
+ */
+void
+gst_event_parse_newsegment (GstEvent * event, gdouble * rate,
+    GstFormat * format, gint64 * start_value, gint64 * stop_value,
+    gint64 * base)
+{
+  const GstStructure *structure;
 
-  GST_EVENT_SIZE_FORMAT (event) = format;
-  GST_EVENT_SIZE_VALUE (event) = value;
+  g_return_if_fail (GST_IS_EVENT (event));
+  g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT);
+
+  structure = gst_event_get_structure (event);
+  if (rate)
+    *rate = g_value_get_double (gst_structure_get_value (structure, "rate"));
+  if (format)
+    *format = g_value_get_enum (gst_structure_get_value (structure, "format"));
+  if (start_value)
+    *start_value =
+        g_value_get_int64 (gst_structure_get_value (structure, "start_val"));
+  if (stop_value)
+    *stop_value =
+        g_value_get_int64 (gst_structure_get_value (structure, "stop_val"));
+  if (base)
+    *base = g_value_get_int64 (gst_structure_get_value (structure, "base"));
+}
 
-  return event;
+/* tag event */
+GstEvent *
+gst_event_new_tag (GstTagList * taglist)
+{
+  g_return_val_if_fail (taglist != NULL, NULL);
+
+  return gst_event_new_custom (GST_EVENT_TAG, (GstStructure *) taglist);
 }
 
+void
+gst_event_parse_tag (GstEvent * event, GstTagList ** taglist)
+{
+  g_return_if_fail (GST_IS_EVENT (event));
+  g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_TAG);
+
+  if (taglist)
+    *taglist = (GstTagList *) event->structure;
+}
+
+/* filler event */
+GstEvent *
+gst_event_new_filler (void)
+{
+  return gst_event_new (GST_EVENT_FILLER);
+}
 
 /**
- * gst_event_new_segment_seek:
- * @type: The type of the seek event
- * @start: The start offset of the seek
- * @stop: The stop offset of the seek
+ * gst_event_new_qos:
+ * @proportion: the proportion of the qos message
+ * @diff: The time difference of the last Clock sync
+ * @timestamp: The timestamp of the buffer
+ *
+ * Allocate a new qos event with the given values.
+ * The QOS event is generated in an element that wants an upstream
+ * element to either reduce or increase its rate because of
+ * high/low CPU load.
+ *
+ * proportion is the requested adjustment in datarate, 1.0 is the normal
+ * datarate, 0.75 means increase datarate by 75%, 1.5 is 150%. Negative
+ * values request a slow down, so -0.75 means a decrease by 75%.
  *
- * Allocate a new segment seek event with the given parameters. 
+ * diff is the difference against the clock in stream time of the last 
+ * buffer that caused the element to generate the QOS event.
  *
- * Returns: A new segment seek event.
+ * timestamp is the timestamp of the last buffer that cause the element
+ * to generate the QOS event.
+ *
+ * Returns: A new QOS event.
  */
 GstEvent *
-gst_event_new_segment_seek (GstSeekType type, gint64 start, gint64 stop)
+gst_event_new_qos (gdouble proportion, GstClockTimeDiff diff,
+    GstClockTime timestamp)
 {
-  GstEvent *event;
-
-  g_return_val_if_fail (start < stop || stop == -1, NULL);
-
-  event = gst_event_new (GST_EVENT_SEEK);
+  return gst_event_new_custom (GST_EVENT_QOS,
+      gst_structure_new ("GstEventQOS",
+          "proportion", G_TYPE_DOUBLE, proportion,
+          "diff", G_TYPE_INT64, diff,
+          "timestamp", G_TYPE_UINT64, timestamp, NULL));
+}
 
-  GST_EVENT_SEEK_TYPE (event) = type;
-  GST_EVENT_SEEK_OFFSET (event) = start;
-  GST_EVENT_SEEK_ENDOFFSET (event) = stop;
+/**
+ * gst_event_parse_qos:
+ * @event: The event to query
+ * @proportion: A pointer to store the proportion in
+ * @diff: A pointer to store the diff in
+ * @timestamp: A pointer to store the timestamp in
+ *
+ * Get the proportion, diff and timestamp in the qos event.
+ */
+void
+gst_event_parse_qos (GstEvent * event, gdouble * proportion,
+    GstClockTimeDiff * diff, GstClockTime * timestamp)
+{
+  const GstStructure *structure;
 
-  return event;
+  g_return_if_fail (GST_IS_EVENT (event));
+  g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_QOS);
+
+  structure = gst_event_get_structure (event);
+  if (proportion)
+    *proportion =
+        g_value_get_double (gst_structure_get_value (structure, "proportion"));
+  if (diff)
+    *diff = g_value_get_int64 (gst_structure_get_value (structure, "diff"));
+  if (timestamp)
+    *timestamp =
+        g_value_get_uint64 (gst_structure_get_value (structure, "timestamp"));
 }
 
 /**
- * gst_event_new_flush:
- * @done: Indicates the end of the flush
+ * gst_event_new_seek:
+ * @rate: The new playback rate
+ * @format: The format of the seek values
+ * @flags: The optional seek flags.
+ * @cur_type: The type and flags for the new current position
+ * @cur: The value of the new current position
+ * @stop_type: The type and flags for the new stop position
+ * @stop: The value of the new stop position
+ *
+ * Allocate a new seek event with the given parameters.
+ *
+ * The seek event configures playback of the pipeline from 
+ * @cur to @stop at the speed given in @rate.
+ * The @cur and @stop values are expressed in format @format.
  *
- * Allocate a new flush event.
+ * A @rate of 1.0 means normal playback rate, 2.0 means double speed.
+ * Negatives values means backwards playback. A value of 0.0 for the
+ * rate is not allowed.
  *
- * Returns: A new flush event.
+ * @cur_type and @stop_type specify how to adjust the current and stop
+ * time, relative or absolute. A type of #GST_EVENT_TYPE_NONE means that
+ * the position should not be updated.
+ *
+ * Returns: A new seek event.
  */
 GstEvent *
-gst_event_new_flush (gboolean done)
+gst_event_new_seek (gdouble rate, GstFormat format, GstSeekFlags flags,
+    GstSeekType cur_type, gint64 cur, GstSeekType stop_type, gint64 stop)
 {
-  GstEvent *event;
+  return gst_event_new_custom (GST_EVENT_SEEK,
+      gst_structure_new ("GstEventSeek", "rate", G_TYPE_DOUBLE, rate,
+          "format", GST_TYPE_FORMAT, format,
+          "flags", GST_TYPE_SEEK_FLAGS, flags,
+          "cur_type", GST_TYPE_SEEK_TYPE, cur_type,
+          "cur", G_TYPE_INT64, cur,
+          "stop_type", GST_TYPE_SEEK_TYPE, stop_type,
+          "stop", G_TYPE_INT64, stop, NULL));
+}
 
-  event = gst_event_new (GST_EVENT_FLUSH);
-  GST_EVENT_FLUSH_DONE (event) = done;
+void
+gst_event_parse_seek (GstEvent * event, gdouble * rate, GstFormat * format,
+    GstSeekFlags * flags,
+    GstSeekType * cur_type, gint64 * cur,
+    GstSeekType * stop_type, gint64 * stop)
+{
+  const GstStructure *structure;
 
-  return event;
+  g_return_if_fail (GST_IS_EVENT (event));
+  g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_SEEK);
+
+  structure = gst_event_get_structure (event);
+  if (rate)
+    *rate = g_value_get_double (gst_structure_get_value (structure, "rate"));
+  if (format)
+    *format = g_value_get_enum (gst_structure_get_value (structure, "format"));
+  if (flags)
+    *flags = g_value_get_flags (gst_structure_get_value (structure, "flags"));
+  if (cur_type)
+    *cur_type =
+        g_value_get_enum (gst_structure_get_value (structure, "cur_type"));
+  if (cur)
+    *cur = g_value_get_int64 (gst_structure_get_value (structure, "cur"));
+  if (stop_type)
+    *stop_type =
+        g_value_get_enum (gst_structure_get_value (structure, "stop_type"));
+  if (stop)
+    *stop = g_value_get_int64 (gst_structure_get_value (structure, "stop"));
+}
+
+/* navigation event */
+GstEvent *
+gst_event_new_navigation (GstStructure * structure)
+{
+  g_return_val_if_fail (structure != NULL, NULL);
+
+  return gst_event_new_custom (GST_EVENT_NAVIGATION, structure);
 }
index 5427232aedf7bd9c55d820ae21d8af93ef27bde2..ef7bf3d42f45f72bc914e0ab7da5f3d11df1693d 100644 (file)
@@ -1,6 +1,7 @@
 /* GStreamer
  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
  *                    2000 Wim Taymans <wim.taymans@chello.be>
+ *                    2005 Wim Taymans <wim@fluendo.com>
  *
  * gstevent.h: Header for GstEvent subsystem
  *
 #include <gst/gstminiobject.h>
 #include <gst/gstformat.h>
 #include <gst/gstobject.h>
+#include <gst/gstclock.h>
 #include <gst/gststructure.h>
+#include <gst/gsttag.h>
 
 G_BEGIN_DECLS
 
+/* bitmaks defining the direction */
+#define GST_EVDIR_US   (1 << 0)        
+#define GST_EVDIR_DS   (1 << 1)        
+#define GST_EVDIR_BOTH GST_EVDIR_US | GST_EVDIR_DS
+/* mask defining event is serialized with data */
+#define GST_EVSER      (1 << 2)        
+#define GST_EVSHIFT    4       
+
+/* when making custom event types, use this macro with the num and
+ * the given flags */
+#define GST_EVENT_MAKE_TYPE(num,flags) (((num) << GST_EVSHIFT) | (flags))
+
 /**
  * GstEventType:
- * @GST_EVENT_UNKNOWN: 
- * @GST_EVENT_EOS:
- * @GST_EVENT_FLUSH:
- * @GST_EVENT_DISCONTINUOUS:
- * @GST_EVENT_QOS:
- * @GST_EVENT_SEEK:
- * @GST_EVENT_SIZE:
- * @GST_EVENT_RATE:
- * @GST_EVENT_NAVIGATION:
- * @GST_EVENT_TAG:
+ * @GST_EVENT_UNKNOWN: unknown event.
+ * @GST_EVENT_FLUSH_START: start a flush operation
+ * @GST_EVENT_FLUSH_STOP: stop a flush operation
+ * @GST_EVENT_EOS: no more data is to be expected.
+ * @GST_EVENT_NEWSEGMENT: a new segment started
+ * @GST_EVENT_TAG: a new tag
+ * @GST_EVENT_FILLER: filler for sparse data streams.
+ * @GST_EVENT_QOS: a quality message
+ * @GST_EVENT_SEEK: a request for a new playback position and rate.
+ * @GST_EVENT_NAVIGATION: a navigation event
  */
 typedef enum {
-  GST_EVENT_UNKNOWN            = 0,
-  GST_EVENT_EOS                        = 1,
-  GST_EVENT_FLUSH              = 2,
-  GST_EVENT_DISCONTINUOUS      = 3,
-  GST_EVENT_QOS                        = 4,
-  GST_EVENT_SEEK               = 5,
-  GST_EVENT_SIZE               = 8,
-  GST_EVENT_RATE               = 9,
-  GST_EVENT_NAVIGATION         = 10,
-  GST_EVENT_TAG                        = 11
+  GST_EVENT_UNKNOWN            = GST_EVENT_MAKE_TYPE (0, 0),
+  /* bidirectional events */
+  GST_EVENT_FLUSH_START                = GST_EVENT_MAKE_TYPE (1, GST_EVDIR_BOTH),
+  GST_EVENT_FLUSH_STOP         = GST_EVENT_MAKE_TYPE (2, GST_EVDIR_BOTH),
+  /* downstream serialized events */
+  GST_EVENT_EOS                        = GST_EVENT_MAKE_TYPE (3, GST_EVDIR_DS | GST_EVSER),
+  GST_EVENT_NEWSEGMENT         = GST_EVENT_MAKE_TYPE (4, GST_EVDIR_DS | GST_EVSER),
+  GST_EVENT_TAG                        = GST_EVENT_MAKE_TYPE (5, GST_EVDIR_DS | GST_EVSER),
+  GST_EVENT_FILLER             = GST_EVENT_MAKE_TYPE (6, GST_EVDIR_DS | GST_EVSER),
+  /* upstream events */
+  GST_EVENT_QOS                        = GST_EVENT_MAKE_TYPE (7, GST_EVDIR_US),
+  GST_EVENT_SEEK               = GST_EVENT_MAKE_TYPE (8, GST_EVDIR_US),
+  GST_EVENT_NAVIGATION         = GST_EVENT_MAKE_TYPE (9, GST_EVDIR_US),
+
+  /* custom events start here */
+  GST_EVENT_CUSTOM_START       = 32
 } GstEventType;
-#define GST_EVENT_ANY GST_EVENT_NAVIGATION
 
 #define GST_EVENT_TRACE_NAME   "GstEvent"
 
 typedef struct _GstEvent GstEvent;
 typedef struct _GstEventClass GstEventClass;
 
-#define GST_TYPE_EVENT                        (gst_event_get_type())
-#define GST_IS_EVENT(obj)                      (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_EVENT))
-#define GST_IS_EVENT_CLASS(klass)              (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_EVENT))
-#define GST_EVENT_GET_CLASS(obj)               (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_EVENT, GstEventClass))
-#define GST_EVENT(obj)                         (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_EVENT, GstEvent))
-#define GST_EVENT_CLASS(klass)                 (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_EVENT, GstEventClass))
+#define GST_TYPE_EVENT                 (gst_event_get_type())
+#define GST_IS_EVENT(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_EVENT))
+#define GST_IS_EVENT_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_EVENT))
+#define GST_EVENT_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_EVENT, GstEventClass))
+#define GST_EVENT(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_EVENT, GstEvent))
+#define GST_EVENT_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_EVENT, GstEventClass))
 
 #define GST_EVENT_TYPE(event)          (GST_EVENT(event)->type)
 #define GST_EVENT_TIMESTAMP(event)     (GST_EVENT(event)->timestamp)
 #define GST_EVENT_SRC(event)           (GST_EVENT(event)->src)
 
-#define GST_EVENT_IS_INTERRUPT(event) (GST_EVENT_TYPE (event) == GST_EVENT_INTERRUPT)
-
-#define GST_SEEK_FORMAT_SHIFT  0
-#define GST_SEEK_METHOD_SHIFT  16
-#define GST_SEEK_FLAGS_SHIFT   20
-#define GST_SEEK_FORMAT_MASK   0x0000ffff
-#define GST_SEEK_METHOD_MASK   0x000f0000
-#define GST_SEEK_FLAGS_MASK    0xfff00000
-
-typedef enum {
-  GST_EVENT_FLAG_NONE          = 0,
-
-  /* indicates negative rates are supported */
-  GST_RATE_FLAG_NEGATIVE       = (1 << 1)
-} GstEventFlag;
-
-typedef struct
-{
-  GstEventType type;
-  GstEventFlag flags;
-} GstEventMask;
+#define GST_EVENT_IS_UPSTREAM(ev)      !!(GST_EVENT_TYPE (ev) & GST_EVDIR_US)
+#define GST_EVENT_IS_DOWNSTREAM(ev)    !!(GST_EVENT_TYPE (ev) & GST_EVDIR_DS)
+#define GST_EVENT_IS_SERIALIZED(ev)    !!(GST_EVENT_TYPE (ev) & GST_EVSER)
 
-/* seek events, extends GstEventFlag */
+/**
+ * GstSeekType:
+ * @GST_SEEK_TYPE_NONE: no change in position is required
+ * @GST_SEEK_TYPE_CUR: change relative to current position
+ * @GST_SEEK_TYPE_SET: absolute position is requested
+ * @GST_SEEK_TYPE_END: relative position to duration is requested
+ */
 typedef enum {
-  /* | with some format */
-  /* | with one of these */
-  GST_SEEK_METHOD_CUR          = (1 << (GST_SEEK_METHOD_SHIFT + 0)),
-  GST_SEEK_METHOD_SET          = (1 << (GST_SEEK_METHOD_SHIFT + 1)),
-  GST_SEEK_METHOD_END          = (1 << (GST_SEEK_METHOD_SHIFT + 2)),
-
-  /* | with optional seek flags */
-  /* seek flags */
-  GST_SEEK_FLAG_FLUSH          = (1 << (GST_SEEK_FLAGS_SHIFT + 0)),
-  GST_SEEK_FLAG_ACCURATE       = (1 << (GST_SEEK_FLAGS_SHIFT + 1)),
-  GST_SEEK_FLAG_KEY_UNIT       = (1 << (GST_SEEK_FLAGS_SHIFT + 2)),
-  GST_SEEK_FLAG_SEGMENT_LOOP   = (1 << (GST_SEEK_FLAGS_SHIFT + 3))
-       
+  /* one of these */
+  GST_SEEK_TYPE_NONE           = 0,
+  GST_SEEK_TYPE_CUR            = 1,
+  GST_SEEK_TYPE_SET            = 2,
+  GST_SEEK_TYPE_END            = 3
 } GstSeekType;
 
+/**
+ * GstSeekFlags:
+ * @GST_SEEK_FLAG_NONE: no flag
+ * @GST_SEEK_FLAG_FLUSH: flush pipeline
+ * @GST_SEEK_FLAG_ACCURATE: accurate position is requested, this might
+ *                     be slower for some formats.
+ * @GST_SEEK_FLAG_KEY_UNIT: seek to the nearest keyframe. This might be
+ *                    faster but less accurate.
+ * @GST_SEEK_FLAG_SEGMENT: perform a segment seek. After the playback
+ *            of the segment completes, no EOS will be emmited but a
+ *            SEGMENT_DONE message will be posted on the bus.
+ */
 typedef enum {
-  GST_SEEK_CERTAIN,
-  GST_SEEK_FUZZY
-} GstSeekAccuracy;
-
-typedef struct
-{
-  GstFormat    format;
-  gint64       start_value;
-  gint64       end_value;
-} GstFormatValue;
-
-#define GST_EVENT_SEEK_TYPE(event)             (GST_EVENT(event)->event_data.seek.type)
-#define GST_EVENT_SEEK_FORMAT(event)           (GST_EVENT_SEEK_TYPE(event) & GST_SEEK_FORMAT_MASK)
-#define GST_EVENT_SEEK_METHOD(event)           (GST_EVENT_SEEK_TYPE(event) & GST_SEEK_METHOD_MASK)
-#define GST_EVENT_SEEK_FLAGS(event)            (GST_EVENT_SEEK_TYPE(event) & GST_SEEK_FLAGS_MASK)
-#define GST_EVENT_SEEK_OFFSET(event)           (GST_EVENT(event)->event_data.seek.offset)
-#define GST_EVENT_SEEK_ENDOFFSET(event)                (GST_EVENT(event)->event_data.seek.endoffset)
-#define GST_EVENT_SEEK_ACCURACY(event)         (GST_EVENT(event)->event_data.seek.accuracy)
-
-#define GST_EVENT_DISCONT_RATE(event)          (GST_EVENT(event)->event_data.discont.rate)
-#define GST_EVENT_DISCONT_OFFSET(event,i)      (GST_EVENT(event)->event_data.discont.offsets[i])
-#define GST_EVENT_DISCONT_OFFSET_LEN(event)    (GST_EVENT(event)->event_data.discont.noffsets)
-
-#define GST_EVENT_FLUSH_DONE(event)            (GST_EVENT(event)->event_data.flush.done)
-
-#define GST_EVENT_SIZE_FORMAT(event)           (GST_EVENT(event)->event_data.size.format)
-#define GST_EVENT_SIZE_VALUE(event)            (GST_EVENT(event)->event_data.size.value)
-
-#define GST_EVENT_RATE_VALUE(event)            (GST_EVENT(event)->event_data.rate.value)
+  GST_SEEK_FLAG_NONE           = 0,
+  GST_SEEK_FLAG_FLUSH          = (1 << 0),
+  GST_SEEK_FLAG_ACCURATE       = (1 << 1),
+  GST_SEEK_FLAG_KEY_UNIT       = (1 << 2),
+  GST_SEEK_FLAG_SEGMENT                = (1 << 3)
+} GstSeekFlags;
 
 struct _GstEvent {
   GstMiniObject mini_object;
@@ -152,32 +141,7 @@ struct _GstEvent {
   guint64      timestamp;
   GstObject    *src;
 
-  union {
-    struct {
-      GstSeekType      type;
-      gint64           offset;
-      gint64           endoffset;
-      GstSeekAccuracy  accuracy;
-    } seek;
-    struct {
-      GstFormatValue   offsets[8];
-      gint             noffsets;
-      gdouble          rate;
-    } discont;
-    struct {
-      gboolean         done;
-    } flush;
-    struct {
-      GstFormat                format;
-      gint64           value;
-    } size;
-    struct {
-      gdouble          value;
-    } rate;
-    struct {
-      GstStructure     *structure;
-    } structure;
-  } event_data;
+  GstStructure *structure;
 
   /*< private >*/
   gpointer _gst_reserved[GST_PADDING];
@@ -193,39 +157,54 @@ struct _GstEventClass {
 void           _gst_event_initialize           (void);
        
 GType          gst_event_get_type              (void);
-GstEvent*      gst_event_new                   (GstEventType type);
-
 /* refcounting */
 #define         gst_event_ref(ev)              GST_EVENT (gst_mini_object_ref (GST_MINI_OBJECT (ev)))
 #define         gst_event_unref(ev)            gst_mini_object_unref (GST_MINI_OBJECT (ev))
-/* copy buffer */
+/* copy event */
 #define         gst_event_copy(ev)             GST_EVENT (gst_mini_object_copy (GST_MINI_OBJECT (ev)))
 
-gboolean       gst_event_masks_contains        (const GstEventMask *masks, GstEventMask *mask);
+/* custom event */
+GstEvent*      gst_event_new_custom            (GstEventType type, GstStructure *structure);
 
-/* seek event */
-GstEvent*      gst_event_new_seek              (GstSeekType type, gint64 offset);
-
-GstEvent*      gst_event_new_segment_seek      (GstSeekType type, gint64 start, gint64 stop);
-
-
-/* size events */
-GstEvent*      gst_event_new_size              (GstFormat format, gint64 value);
-
-/* discontinous event */
-GstEvent*      gst_event_new_discontinuous     (gdouble rate,
-                                                GstFormat format1, ...);
-GstEvent*      gst_event_new_discontinuous_valist      (gdouble rate,
-                                                GstFormat format1,
-                                                va_list var_args);
-gboolean       gst_event_discont_get_value     (GstEvent *event, GstFormat format, 
-                                                gint64 *start_value, gint64 *end_value);
-
-#define                gst_event_new_filler()          gst_event_new(GST_EVENT_FILLER)
-#define                gst_event_new_eos()             gst_event_new(GST_EVENT_EOS)
+const GstStructure *  
+               gst_event_get_structure         (GstEvent *event);
 
 /* flush events */
-GstEvent*      gst_event_new_flush             (gboolean done);
+GstEvent *     gst_event_new_flush_start       (void);
+GstEvent *     gst_event_new_flush_stop        (void);
+
+/* EOS event */
+GstEvent *     gst_event_new_eos               (void);
+
+/* newsegment events */
+GstEvent*      gst_event_new_newsegment        (gdouble rate,
+                                                GstFormat format, gint64 start_value, gint64 stop_value,
+                                                gint64 base);
+void           gst_event_parse_newsegment      (GstEvent *event, gdouble *rate, GstFormat *format, 
+                                                gint64 *start_value, gint64 *end_value, gint64 *base);
+/* tag event */
+GstEvent*      gst_event_new_tag               (GstTagList *taglist);
+void           gst_event_parse_tag             (GstEvent *event, GstTagList **taglist);
+
+/* filler event */
+GstEvent *     gst_event_new_filler            (void);
+
+
+/* QOS events */
+GstEvent*      gst_event_new_qos               (gdouble proportion, GstClockTimeDiff diff,
+                                                GstClockTime timestamp);
+void           gst_event_parse_qos             (GstEvent *event, gdouble *proportion, GstClockTimeDiff *diff,
+                                                GstClockTime *timestamp);
+/* seek event */
+GstEvent*      gst_event_new_seek              (gdouble rate, GstFormat format, GstSeekFlags flags,
+                                                GstSeekType cur_type, gint64 cur, 
+                                                GstSeekType stop_type, gint64 stop);
+void           gst_event_parse_seek            (GstEvent *event, gdouble *rate, GstFormat *format, 
+                                                GstSeekFlags *flags,
+                                                GstSeekType *cur_type, gint64 *cur, 
+                                                GstSeekType *stop_type, gint64 *stop);
+/* navigation event */
+GstEvent*      gst_event_new_navigation        (GstStructure *structure);
 
 G_END_DECLS
 
index e0e0d5e480b9c3fb8d77d1abfd01fda1a5131c59..8c5329d9fa51170c70b43b5f5a2188c801d59c60 100644 (file)
@@ -94,7 +94,7 @@ gst_message_init (GTypeInstance * instance, gpointer g_class)
 {
   GstMessage *message = GST_MESSAGE (instance);
 
-  message->timestamp = GST_CLOCK_TIME_NONE;
+  GST_MESSAGE_TIMESTAMP (message) = GST_CLOCK_TIME_NONE;
 }
 
 static void
@@ -106,6 +106,7 @@ gst_message_finalize (GstMessage * message)
 
   if (GST_MESSAGE_SRC (message)) {
     gst_object_unref (GST_MESSAGE_SRC (message));
+    GST_MESSAGE_SRC (message) = NULL;
   }
 
   if (message->lock) {
@@ -132,10 +133,10 @@ _gst_message_copy (GstMessage * message)
   /* FIXME, need to copy relevant data from the miniobject. */
   //memcpy (copy, message, sizeof (GstMessage));
 
-  copy->lock = message->lock;
-  copy->cond = message->cond;
-  copy->type = message->type;
-  copy->timestamp = message->timestamp;
+  GST_MESSAGE_GET_LOCK (copy) = GST_MESSAGE_GET_LOCK (message);
+  GST_MESSAGE_COND (copy) = GST_MESSAGE_COND (message);
+  GST_MESSAGE_TYPE (copy) = GST_MESSAGE_TYPE (message);
+  GST_MESSAGE_TIMESTAMP (copy) = GST_MESSAGE_TIMESTAMP (message);
 
   if (GST_MESSAGE_SRC (message)) {
     GST_MESSAGE_SRC (copy) = gst_object_ref (GST_MESSAGE_SRC (message));
@@ -150,16 +151,6 @@ _gst_message_copy (GstMessage * message)
   return copy;
 }
 
-/**
- * gst_message_new:
- * @type: The type of the new message
- *
- * Allocate a new message of the given type.
- *
- * Returns: A new message.
- *
- * MT safe.
- */
 static GstMessage *
 gst_message_new (GstMessageType type, GstObject * src)
 {
@@ -386,7 +377,7 @@ gst_message_new_segment_done (GstObject * src, GstClockTime timestamp)
  *
  * Create a new custom-typed message. This can be used for anything not
  * handled by other message-specific functions to pass a message to the
- * app.
+ * app. The structure field can be NULL.
  *
  * Returns: The new message.
  *
@@ -398,12 +389,12 @@ gst_message_new_custom (GstMessageType type, GstObject * src,
 {
   GstMessage *message;
 
-  g_return_val_if_fail (GST_IS_STRUCTURE (structure), NULL);
-
   message = gst_message_new (type, src);
-  gst_structure_set_parent_refcount (structure, &message->mini_object.refcount);
-  message->structure = structure;
-
+  if (structure) {
+    gst_structure_set_parent_refcount (structure,
+        &message->mini_object.refcount);
+    message->structure = structure;
+  }
   return message;
 }
 
index 651e11ba7fa7a4fe6e0f1b3597c6ce2cb2833870..f1794dabd0185725e264aee0bb4cb15fd16243bd 100644 (file)
@@ -3255,24 +3255,29 @@ gst_pad_send_event (GstPad * pad, GstEvent * event)
 
   GST_LOCK (pad);
 
+  if (GST_PAD_IS_SINK (pad) && !GST_EVENT_IS_DOWNSTREAM (event))
+    goto wrong_direction;
+  if (GST_PAD_IS_SRC (pad) && !GST_EVENT_IS_UPSTREAM (event))
+    goto wrong_direction;
+
   if (GST_EVENT_SRC (event) == NULL)
     GST_EVENT_SRC (event) = gst_object_ref (pad);
 
   switch (GST_EVENT_TYPE (event)) {
-    case GST_EVENT_FLUSH:
-      GST_CAT_DEBUG (GST_CAT_EVENT, "have event type %d (FLUSH) on pad %s:%s",
+    case GST_EVENT_FLUSH_START:
+      GST_CAT_DEBUG (GST_CAT_EVENT,
+          "have event type %d (FLUSH_START) on pad %s:%s",
           GST_EVENT_TYPE (event), GST_DEBUG_PAD_NAME (pad));
 
-      if (GST_EVENT_FLUSH_DONE (event)) {
-        GST_PAD_UNSET_FLUSHING (pad);
-        GST_CAT_DEBUG (GST_CAT_EVENT, "cleared flush flag");
-      } else {
-        /* can't even accept a flush begin event when flushing */
-        if (GST_PAD_IS_FLUSHING (pad))
-          goto flushing;
-        GST_PAD_SET_FLUSHING (pad);
-        GST_CAT_DEBUG (GST_CAT_EVENT, "set flush flag");
-      }
+      /* can't even accept a flush begin event when flushing */
+      if (GST_PAD_IS_FLUSHING (pad))
+        goto flushing;
+      GST_PAD_SET_FLUSHING (pad);
+      GST_CAT_DEBUG (GST_CAT_EVENT, "set flush flag");
+      break;
+    case GST_EVENT_FLUSH_STOP:
+      GST_PAD_UNSET_FLUSHING (pad);
+      GST_CAT_DEBUG (GST_CAT_EVENT, "cleared flush flag");
       break;
     default:
       GST_CAT_DEBUG (GST_CAT_EVENT, "have event type %d on pad %s:%s",
@@ -3303,6 +3308,14 @@ gst_pad_send_event (GstPad * pad, GstEvent * event)
   return result;
 
   /* ERROR handling */
+wrong_direction:
+  {
+    g_warning ("pad %s:%s sending event in wrong direction",
+        GST_DEBUG_PAD_NAME (pad));
+    GST_UNLOCK (pad);
+    gst_event_unref (event);
+    return FALSE;
+  }
 no_function:
   {
     g_warning ("pad %s:%s has no event handler, file a bug.",
index 74bbd7040bd7250b53c46807a0614fda347f228a..325bd1c233ed63d006de4bb8a190c79a647f42c0 100644 (file)
@@ -491,32 +491,38 @@ gst_queue_handle_sink_event (GstPad * pad, GstEvent * event)
   queue = GST_QUEUE (GST_OBJECT_PARENT (pad));
 
   switch (GST_EVENT_TYPE (event)) {
-    case GST_EVENT_FLUSH:
-      STATUS (queue, "received flush event");
+    case GST_EVENT_FLUSH_START:
+      STATUS (queue, "received flush start event");
       /* forward event, re first as we're going to use it still */
       gst_event_ref (event);
       gst_pad_push_event (queue->srcpad, event);
-      if (GST_EVENT_FLUSH_DONE (event)) {
-        GST_QUEUE_MUTEX_LOCK (queue);
-        gst_queue_locked_flush (queue);
-        queue->srcresult = GST_FLOW_OK;
-        gst_pad_start_task (queue->srcpad, (GstTaskFunction) gst_queue_loop,
-            queue->srcpad);
-        GST_QUEUE_MUTEX_UNLOCK (queue);
 
-        STATUS (queue, "after flush");
-      } else {
-        /* now unblock the chain function */
-        GST_QUEUE_MUTEX_LOCK (queue);
-        queue->srcresult = GST_FLOW_WRONG_STATE;
-        /* unblock the loop function */
-        g_cond_signal (queue->item_add);
-        GST_QUEUE_MUTEX_UNLOCK (queue);
+      /* now unblock the chain function */
+      GST_QUEUE_MUTEX_LOCK (queue);
+      queue->srcresult = GST_FLOW_WRONG_STATE;
+      /* unblock the loop function */
+      g_cond_signal (queue->item_add);
+      GST_QUEUE_MUTEX_UNLOCK (queue);
 
-        /* make sure it pauses */
-        gst_pad_pause_task (queue->srcpad);
-        GST_CAT_LOG_OBJECT (queue_dataflow, queue, "loop stopped");
-      }
+      /* make sure it pauses */
+      gst_pad_pause_task (queue->srcpad);
+      GST_CAT_LOG_OBJECT (queue_dataflow, queue, "loop stopped");
+      gst_event_unref (event);
+      goto done;
+    case GST_EVENT_FLUSH_STOP:
+      STATUS (queue, "received flush stop event");
+      /* forward event, re first as we're going to use it still */
+      gst_event_ref (event);
+      gst_pad_push_event (queue->srcpad, event);
+
+      GST_QUEUE_MUTEX_LOCK (queue);
+      gst_queue_locked_flush (queue);
+      queue->srcresult = GST_FLOW_OK;
+      gst_pad_start_task (queue->srcpad, (GstTaskFunction) gst_queue_loop,
+          queue->srcpad);
+      GST_QUEUE_MUTEX_UNLOCK (queue);
+
+      STATUS (queue, "after flush");
       gst_event_unref (event);
       goto done;
     case GST_EVENT_EOS:
@@ -775,7 +781,7 @@ restart:
         GST_ELEMENT_ERROR (queue, STREAM, STOPPED,
             ("streaming stopped, reason %s", flowname),
             ("streaming stopped, reason %s", flowname));
-        gst_pad_push_event (queue->srcpad, gst_event_new (GST_EVENT_EOS));
+        gst_pad_push_event (queue->srcpad, gst_event_new_eos ());
       }
       GST_DEBUG ("pausing queue, reason %s", flowname);
       gst_pad_pause_task (queue->srcpad);
index 20542f1cfd47ec571edca0eda4dbab0db0cbd918..0b7fb0923c09608ccd63a7472a0d7387c5e65be6 100644 (file)
@@ -804,48 +804,6 @@ gst_tag_list_foreach (GstTagList * list, GstTagForeachFunc func,
       &data);
 }
 
-/***** tag events *****/
-
-/**
- * gst_event_new_tag:
- * @list: the tag list to put into the event or NULL for an empty list
- *
- * Creates a new tag event with the given list and takes ownership of it.
- *
- * Returns: a new tag event
- */
-GstEvent *
-gst_event_new_tag (GstTagList * list)
-{
-  GstEvent *ret;
-
-  g_return_val_if_fail (list == NULL || GST_IS_TAG_LIST (list), NULL);
-
-  ret = gst_event_new (GST_EVENT_TAG);
-  if (!list)
-    list = gst_tag_list_new ();
-  ret->event_data.structure.structure = (GstStructure *) list;
-
-  return ret;
-}
-
-/**
- * gst_event_tag_get_list:
- * @tag_event: a tagging #GstEvent
- *
- * Gets the taglist from a given tagging event.
- *
- * Returns: The #GstTagList of the event
- */
-GstTagList *
-gst_event_tag_get_list (GstEvent * tag_event)
-{
-  g_return_val_if_fail (GST_IS_EVENT (tag_event), NULL);
-  g_return_val_if_fail (GST_EVENT_TYPE (tag_event) == GST_EVENT_TAG, NULL);
-
-  return GST_TAG_LIST (tag_event->event_data.structure.structure);
-}
-
 /**
  * gst_tag_list_get_value_index:
  * @list: a #GStTagList
index 5651178e60dd25390a1c5ce39ca6350ccd8ae1c3..a58665e7bb031025cda2100384573574a996df61 100644 (file)
@@ -24,7 +24,6 @@
 #define __GST_TAG_H__
 
 #include <gst/gststructure.h>
-#include <gst/gstevent.h>
 
 G_BEGIN_DECLS
 
@@ -220,11 +219,6 @@ gboolean   gst_tag_list_get_pointer_index  (const GstTagList *     list,
                                                 guint                  index,
                                                 gpointer *             value);
 
-/* tag events */
-GstEvent *     gst_event_new_tag               (GstTagList *           list);
-GstTagList *   gst_event_tag_get_list          (GstEvent *             tag_event);
-
-
 /* GStreamer core tags (need to be discussed) */
 /**
  * GST_TAG_TITLE:
index 20542f1cfd47ec571edca0eda4dbab0db0cbd918..0b7fb0923c09608ccd63a7472a0d7387c5e65be6 100644 (file)
@@ -804,48 +804,6 @@ gst_tag_list_foreach (GstTagList * list, GstTagForeachFunc func,
       &data);
 }
 
-/***** tag events *****/
-
-/**
- * gst_event_new_tag:
- * @list: the tag list to put into the event or NULL for an empty list
- *
- * Creates a new tag event with the given list and takes ownership of it.
- *
- * Returns: a new tag event
- */
-GstEvent *
-gst_event_new_tag (GstTagList * list)
-{
-  GstEvent *ret;
-
-  g_return_val_if_fail (list == NULL || GST_IS_TAG_LIST (list), NULL);
-
-  ret = gst_event_new (GST_EVENT_TAG);
-  if (!list)
-    list = gst_tag_list_new ();
-  ret->event_data.structure.structure = (GstStructure *) list;
-
-  return ret;
-}
-
-/**
- * gst_event_tag_get_list:
- * @tag_event: a tagging #GstEvent
- *
- * Gets the taglist from a given tagging event.
- *
- * Returns: The #GstTagList of the event
- */
-GstTagList *
-gst_event_tag_get_list (GstEvent * tag_event)
-{
-  g_return_val_if_fail (GST_IS_EVENT (tag_event), NULL);
-  g_return_val_if_fail (GST_EVENT_TYPE (tag_event) == GST_EVENT_TAG, NULL);
-
-  return GST_TAG_LIST (tag_event->event_data.structure.structure);
-}
-
 /**
  * gst_tag_list_get_value_index:
  * @list: a #GStTagList
index 5651178e60dd25390a1c5ce39ca6350ccd8ae1c3..a58665e7bb031025cda2100384573574a996df61 100644 (file)
@@ -24,7 +24,6 @@
 #define __GST_TAG_H__
 
 #include <gst/gststructure.h>
-#include <gst/gstevent.h>
 
 G_BEGIN_DECLS
 
@@ -220,11 +219,6 @@ gboolean   gst_tag_list_get_pointer_index  (const GstTagList *     list,
                                                 guint                  index,
                                                 gpointer *             value);
 
-/* tag events */
-GstEvent *     gst_event_new_tag               (GstTagList *           list);
-GstTagList *   gst_event_tag_get_list          (GstEvent *             tag_event);
-
-
 /* GStreamer core tags (need to be discussed) */
 /**
  * GST_TAG_TITLE:
index 91063b7278b7d46469fcc3e077a5fd60d3e543c5..098bf15daa070b86f1aed65f0bc42d1db1d342a6 100644 (file)
@@ -468,11 +468,17 @@ gst_base_sink_handle_object (GstBaseSink * basesink, GstPad * pad,
         basesink->preroll_queued++;
         basesink->eos = TRUE;
         break;
-      case GST_EVENT_DISCONTINUOUS:
-        /* the discont event is needed to bring the buffer timestamps to the
+      case GST_EVENT_NEWSEGMENT:
+      {
+        GstFormat format;
+        gdouble rate;
+
+        /* the newsegment event is needed to bring the buffer timestamps to the
          * stream time */
-        if (!gst_event_discont_get_value (event, GST_FORMAT_TIME,
-                &basesink->discont_start, &basesink->discont_stop)) {
+        gst_event_parse_newsegment (event, &rate, &format,
+            &basesink->discont_start, &basesink->discont_stop, NULL);
+
+        if (format != GST_FORMAT_TIME) {
           /* this means this sink will not be able to sync to the clock */
           basesink->discont_start = 0;
           basesink->discont_stop = 0;
@@ -483,6 +489,7 @@ gst_base_sink_handle_object (GstBaseSink * basesink, GstPad * pad,
             GST_TIME_ARGS (basesink->discont_start),
             GST_TIME_ARGS (basesink->discont_stop));
         break;
+      }
       default:
         break;
     }
@@ -664,7 +671,7 @@ gst_base_sink_event (GstPad * pad, GstEvent * event)
       GST_STREAM_UNLOCK (pad);
       break;
     }
-    case GST_EVENT_DISCONTINUOUS:
+    case GST_EVENT_NEWSEGMENT:
     {
       GstFlowReturn ret;
 
@@ -674,39 +681,44 @@ gst_base_sink_event (GstPad * pad, GstEvent * event)
       GST_STREAM_UNLOCK (pad);
       break;
     }
-    case GST_EVENT_FLUSH:
+    case GST_EVENT_FLUSH_START:
       /* make sure we are not blocked on the clock also clear any pending
        * eos state. */
       if (bclass->event)
         bclass->event (basesink, event);
 
-      if (!GST_EVENT_FLUSH_DONE (event)) {
-        GST_PREROLL_LOCK (pad);
-        /* we need preroll after the flush */
-        basesink->need_preroll = TRUE;
-        /* unlock from a possible state change/preroll */
-        gst_base_sink_preroll_queue_flush (basesink, pad);
+      GST_PREROLL_LOCK (pad);
+      /* we need preroll after the flush */
+      basesink->need_preroll = TRUE;
+      /* unlock from a possible state change/preroll */
+      gst_base_sink_preroll_queue_flush (basesink, pad);
 
-        GST_LOCK (basesink);
-        if (basesink->clock_id) {
-          gst_clock_id_unschedule (basesink->clock_id);
-        }
-        GST_UNLOCK (basesink);
-        GST_PREROLL_UNLOCK (pad);
-
-        /* and we need to commit our state again on the next
-         * prerolled buffer */
-        GST_STATE_LOCK (basesink);
-        GST_STREAM_LOCK (pad);
-        gst_element_lost_state (GST_ELEMENT (basesink));
-        GST_STREAM_UNLOCK (pad);
-        GST_STATE_UNLOCK (basesink);
-      } else {
-        /* now we are completely unblocked and the _chain method
-         * will return */
-        GST_STREAM_LOCK (pad);
-        GST_STREAM_UNLOCK (pad);
+      GST_LOCK (basesink);
+      if (basesink->clock_id) {
+        gst_clock_id_unschedule (basesink->clock_id);
       }
+      GST_UNLOCK (basesink);
+      GST_PREROLL_UNLOCK (pad);
+
+      /* and we need to commit our state again on the next
+       * prerolled buffer */
+      GST_STATE_LOCK (basesink);
+      GST_STREAM_LOCK (pad);
+      gst_element_lost_state (GST_ELEMENT (basesink));
+      GST_STREAM_UNLOCK (pad);
+      GST_STATE_UNLOCK (basesink);
+      GST_DEBUG ("event unref %p %p", basesink, event);
+      gst_event_unref (event);
+      break;
+    case GST_EVENT_FLUSH_STOP:
+      if (bclass->event)
+        bclass->event (basesink, event);
+
+      /* now we are completely unblocked and the _chain method
+       * will return */
+      GST_STREAM_LOCK (pad);
+      GST_STREAM_UNLOCK (pad);
+
       GST_DEBUG ("event unref %p %p", basesink, event);
       gst_event_unref (event);
       break;
index 77b1e2088a2d6037cd5d65877031e8d774c0513e..c42e6aa35596d7bf9909e152fd317fd2b453e5b5 100644 (file)
@@ -362,9 +362,9 @@ gst_base_src_send_discont (GstBaseSrc * src)
 {
   GstEvent *event;
 
-  event = gst_event_new_discontinuous (1.0,
+  event = gst_event_new_newsegment (1.0,
       GST_FORMAT_BYTES,
-      (gint64) src->segment_start, (gint64) src->segment_end, NULL);
+      (gint64) src->segment_start, (gint64) src->segment_end, (gint64) 0);
 
   return gst_pad_push_event (src->srcpad, event);
 }
@@ -372,10 +372,14 @@ gst_base_src_send_discont (GstBaseSrc * src)
 static gboolean
 gst_base_src_do_seek (GstBaseSrc * src, GstEvent * event)
 {
+  gdouble rate;
   GstFormat format;
-  gint64 offset;
+  GstSeekFlags flags;
+  GstSeekType cur_type, stop_type;
+  gint64 cur, stop;
 
-  format = GST_EVENT_SEEK_FORMAT (event);
+  gst_event_parse_seek (event, &rate, &format, &flags,
+      &cur_type, &cur, &stop_type, &stop);
 
   /* get seek format */
   if (format == GST_FORMAT_DEFAULT)
@@ -385,11 +389,10 @@ gst_base_src_do_seek (GstBaseSrc * src, GstEvent * event)
     return FALSE;
 
   /* get seek positions */
-  offset = GST_EVENT_SEEK_OFFSET (event);
-  src->segment_loop = GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_SEGMENT_LOOP;
+  src->segment_loop = flags & GST_SEEK_FLAG_SEGMENT;
 
   /* send flush start */
-  gst_pad_push_event (src->srcpad, gst_event_new_flush (FALSE));
+  gst_pad_push_event (src->srcpad, gst_event_new_flush_start ());
 
   /* unblock streaming thread */
   gst_base_src_unlock (src);
@@ -397,35 +400,35 @@ gst_base_src_do_seek (GstBaseSrc * src, GstEvent * event)
   /* grab streaming lock */
   GST_STREAM_LOCK (src->srcpad);
 
-  /* send flush end */
-  gst_pad_push_event (src->srcpad, gst_event_new_flush (TRUE));
+  /* send flush stop */
+  gst_pad_push_event (src->srcpad, gst_event_new_flush_stop ());
 
   /* perform the seek */
-  switch (GST_EVENT_SEEK_METHOD (event)) {
-    case GST_SEEK_METHOD_SET:
-      if (offset < 0)
+  switch (cur_type) {
+    case GST_SEEK_TYPE_SET:
+      if (cur < 0)
         goto error;
-      src->offset = MIN (offset, src->size);
+      src->offset = MIN (cur, src->size);
       src->segment_start = src->offset;
-      src->segment_end = MIN (GST_EVENT_SEEK_ENDOFFSET (event), src->size);
+      src->segment_end = MIN (stop, src->size);
       GST_DEBUG_OBJECT (src, "seek set pending to %" G_GINT64_FORMAT,
           src->offset);
       break;
-    case GST_SEEK_METHOD_CUR:
-      offset += src->offset;
-      src->offset = CLAMP (offset, 0, src->size);
+    case GST_SEEK_TYPE_CUR:
+      cur += src->offset;
+      src->offset = CLAMP (cur, 0, src->size);
       src->segment_start = src->offset;
-      src->segment_end = GST_EVENT_SEEK_ENDOFFSET (event);
+      src->segment_end = stop;
       GST_DEBUG_OBJECT (src, "seek cur pending to %" G_GINT64_FORMAT,
           src->offset);
       break;
-    case GST_SEEK_METHOD_END:
-      if (offset > 0)
+    case GST_SEEK_TYPE_END:
+      if (cur > 0)
         goto error;
-      offset = src->size + offset;
-      src->offset = MAX (0, offset);
+      cur = src->size + cur;
+      src->offset = MAX (0, cur);
       src->segment_start = src->offset;
-      src->segment_end = GST_EVENT_SEEK_ENDOFFSET (event);
+      src->segment_end = stop;
       GST_DEBUG_OBJECT (src, "seek end pending to %" G_GINT64_FORMAT,
           src->offset);
       break;
@@ -471,25 +474,11 @@ gst_base_src_event_handler (GstPad * pad, GstEvent * event)
   switch (GST_EVENT_TYPE (event)) {
     case GST_EVENT_SEEK:
       return gst_base_src_do_seek (src, event);
-    case GST_EVENT_SIZE:
-    {
-      GstFormat format;
-
-      format = GST_EVENT_SIZE_FORMAT (event);
-      if (format == GST_FORMAT_DEFAULT)
-        format = GST_FORMAT_BYTES;
-      /* we can only accept bytes */
-      if (format != GST_FORMAT_BYTES)
-        return FALSE;
-
-      src->blocksize = GST_EVENT_SIZE_VALUE (event);
-      g_object_notify (G_OBJECT (src), "blocksize");
-      break;
-    }
-    case GST_EVENT_FLUSH:
+    case GST_EVENT_FLUSH_START:
       /* cancel any blocking getrange */
-      if (!GST_EVENT_FLUSH_DONE (event))
-        gst_base_src_unlock (src);
+      gst_base_src_unlock (src);
+      break;
+    case GST_EVENT_FLUSH_STOP:
       break;
     default:
       break;
@@ -695,7 +684,7 @@ eos:
   {
     GST_DEBUG_OBJECT (src, "going to EOS");
     gst_pad_pause_task (pad);
-    gst_pad_push_event (pad, gst_event_new (GST_EVENT_EOS));
+    gst_pad_push_event (pad, gst_event_new_eos ());
     return;
   }
 pause:
@@ -707,7 +696,7 @@ pause:
       GST_ELEMENT_ERROR (src, STREAM, STOPPED,
           ("streaming stopped, reason %s", gst_flow_get_name (ret)),
           ("streaming stopped, reason %s", gst_flow_get_name (ret)));
-      gst_pad_push_event (pad, gst_event_new (GST_EVENT_EOS));
+      gst_pad_push_event (pad, gst_event_new_eos ());
     }
     return;
   }
@@ -717,7 +706,7 @@ error:
         ("internal: element returned NULL buffer"),
         ("internal: element returned NULL buffer"));
     gst_pad_pause_task (pad);
-    gst_pad_push_event (pad, gst_event_new (GST_EVENT_EOS));
+    gst_pad_push_event (pad, gst_event_new_eos ());
     return;
   }
 }
index 52aa8a68bf5187b35efaa7789afc05a176d002c2..3aba064ebe15fc4380c29523cd50ae69df687da6 100644 (file)
@@ -497,11 +497,11 @@ gst_base_transform_event (GstPad * pad, GstEvent * event)
   unlock = FALSE;
 
   switch (GST_EVENT_TYPE (event)) {
-    case GST_EVENT_FLUSH:
-      if (GST_EVENT_FLUSH_DONE (event)) {
-        GST_STREAM_LOCK (pad);
-        unlock = TRUE;
-      }
+    case GST_EVENT_FLUSH_START:
+      break;
+    case GST_EVENT_FLUSH_STOP:
+      GST_STREAM_LOCK (pad);
+      unlock = TRUE;
       break;
     case GST_EVENT_EOS:
       GST_STREAM_LOCK (pad);
index d83e649f8d221b0eb9af009fe3e05e1d36d957cd..babefbd3c4e9a2567fe783c41c99a940b85dd9b4 100644 (file)
@@ -321,8 +321,9 @@ gst_dp_packet_from_event (const GstEvent * event, GstDPHeaderFlag flags,
       g_free (h);
       return FALSE;
     case GST_EVENT_EOS:
-    case GST_EVENT_FLUSH:
-    case GST_EVENT_DISCONTINUOUS:
+    case GST_EVENT_FLUSH_START:
+    case GST_EVENT_FLUSH_STOP:
+    case GST_EVENT_NEWSEGMENT:
       GST_WRITE_UINT64_BE (h + 8, GST_EVENT_TIMESTAMP (event));
       pl_length = 0;
       *payload = NULL;
@@ -330,17 +331,17 @@ gst_dp_packet_from_event (const GstEvent * event, GstDPHeaderFlag flags,
     case GST_EVENT_SEEK:
       pl_length = 4 + 8 + 8 + 4;
       *payload = g_malloc0 (pl_length);
-      GST_WRITE_UINT32_BE (*payload, (guint32) GST_EVENT_SEEK_TYPE (event));
-      GST_WRITE_UINT64_BE (*payload + 4,
-          (guint64) GST_EVENT_SEEK_OFFSET (event));
-      GST_WRITE_UINT64_BE (*payload + 12,
-          (guint64) GST_EVENT_SEEK_ENDOFFSET (event));
-      GST_WRITE_UINT32_BE (*payload + 20,
-          (guint32) GST_EVENT_SEEK_ACCURACY (event));
+      /*
+         GST_WRITE_UINT32_BE (*payload, (guint32) GST_EVENT_SEEK_TYPE (event));
+         GST_WRITE_UINT64_BE (*payload + 4,
+         (guint64) GST_EVENT_SEEK_OFFSET (event));
+         GST_WRITE_UINT64_BE (*payload + 12,
+         (guint64) GST_EVENT_SEEK_ENDOFFSET (event));
+         GST_WRITE_UINT32_BE (*payload + 20,
+         (guint32) GST_EVENT_SEEK_ACCURACY (event));
+       */
       break;
     case GST_EVENT_QOS:
-    case GST_EVENT_SIZE:
-    case GST_EVENT_RATE:
     case GST_EVENT_NAVIGATION:
     case GST_EVENT_TAG:
       g_warning ("Unhandled event type %d, ignoring", GST_EVENT_TYPE (event));
@@ -472,29 +473,30 @@ gst_dp_event_from_packet (guint header_length, const guint8 * header,
       g_warning ("Unknown event, ignoring");
       return FALSE;
     case GST_EVENT_EOS:
-    case GST_EVENT_FLUSH:
-    case GST_EVENT_DISCONTINUOUS:
-      event = gst_event_new (type);
+    case GST_EVENT_FLUSH_START:
+    case GST_EVENT_FLUSH_STOP:
+    case GST_EVENT_NEWSEGMENT:
+      event = gst_event_new_custom (type, NULL);
       GST_EVENT_TIMESTAMP (event) = GST_DP_HEADER_TIMESTAMP (header);
       break;
     case GST_EVENT_SEEK:
     {
-      GstSeekType type;
-      gint64 offset, endoffset;
-      GstSeekAccuracy accuracy;
-
-      type = (GstSeekType) GST_READ_UINT32_BE (payload);
-      offset = (gint64) GST_READ_UINT64_BE (payload + 4);
-      endoffset = (gint64) GST_READ_UINT64_BE (payload + 12);
-      accuracy = (GstSeekAccuracy) GST_READ_UINT32_BE (payload + 20);
-      event = gst_event_new_segment_seek (type, offset, endoffset);
-      GST_EVENT_TIMESTAMP (event) = GST_DP_HEADER_TIMESTAMP (header);
-      GST_EVENT_SEEK_ACCURACY (event) = accuracy;
+      /*
+         GstSeekType type;
+         gint64 offset, endoffset;
+         GstSeekAccuracy accuracy;
+
+         type = (GstSeekType) GST_READ_UINT32_BE (payload);
+         offset = (gint64) GST_READ_UINT64_BE (payload + 4);
+         endoffset = (gint64) GST_READ_UINT64_BE (payload + 12);
+         accuracy = (GstSeekAccuracy) GST_READ_UINT32_BE (payload + 20);
+         event = gst_event_new_segment_seek (type, offset, endoffset);
+         GST_EVENT_TIMESTAMP (event) = GST_DP_HEADER_TIMESTAMP (header);
+         GST_EVENT_SEEK_ACCURACY (event) = accuracy;
+       */
       break;
     }
     case GST_EVENT_QOS:
-    case GST_EVENT_SIZE:
-    case GST_EVENT_RATE:
     case GST_EVENT_NAVIGATION:
     case GST_EVENT_TAG:
       g_warning ("Unhandled event type %d, ignoring", GST_EVENT_TYPE (event));
index 8853b4a89ddf7bd8767dca54c5453f1107d57f19..1ba00b14e902cb44d8d7b9205e40ef180870c236 100644 (file)
@@ -273,13 +273,20 @@ static gboolean
 gst_fake_sink_event (GstBaseSink * bsink, GstEvent * event)
 {
   GstFakeSink *sink = GST_FAKE_SINK (bsink);
+  const GstStructure *s;
 
   if (!sink->silent) {
+    gchar *sstr;
+
     g_free (sink->last_message);
 
+    s = gst_event_get_structure (event);
+    sstr = gst_structure_to_string (s);
+
     sink->last_message =
-        g_strdup_printf ("event   ******* E (type: %d) %p",
-        GST_EVENT_TYPE (event), event);
+        g_strdup_printf ("event   ******* E (type: %d, %s) %p",
+        GST_EVENT_TYPE (event), sstr, event);
+    g_free (sstr);
 
     g_object_notify (G_OBJECT (sink), "last_message");
   }
index 531758d62f6bce8662fbfef7568cb028a03e9fdf..b2bc2e17d1e2b1f28348717ad38db5ec94e51c11 100644 (file)
@@ -291,48 +291,23 @@ gst_file_sink_event (GstBaseSink * sink, GstEvent * event)
 
   filesink = GST_FILE_SINK (sink);
 
-  type = event ? GST_EVENT_TYPE (event) : GST_EVENT_UNKNOWN;
+  type = GST_EVENT_TYPE (event);
 
   switch (type) {
-    case GST_EVENT_SEEK:
-      if (GST_EVENT_SEEK_FORMAT (event) != GST_FORMAT_BYTES) {
-        return FALSE;
-      }
-
-      if (GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_FLUSH) {
-        if (fflush (filesink->file)) {
-          GST_ELEMENT_ERROR (filesink, RESOURCE, WRITE,
-              (_("Error while writing to file \"%s\"."), filesink->filename),
-              GST_ERROR_SYSTEM);
-          return FALSE;
-        }
-      }
-
-      switch (GST_EVENT_SEEK_METHOD (event)) {
-        case GST_SEEK_METHOD_SET:
-          fseek (filesink->file, GST_EVENT_SEEK_OFFSET (event), SEEK_SET);
-          break;
-        case GST_SEEK_METHOD_CUR:
-          fseek (filesink->file, GST_EVENT_SEEK_OFFSET (event), SEEK_CUR);
-          break;
-        case GST_SEEK_METHOD_END:
-          fseek (filesink->file, GST_EVENT_SEEK_OFFSET (event), SEEK_END);
-          break;
-        default:
-          g_warning ("unknown seek method!");
-          break;
-      }
-      break;
-    case GST_EVENT_DISCONTINUOUS:
+    case GST_EVENT_NEWSEGMENT:
     {
       gint64 soffset, eoffset;
+      GstFormat format;
 
-      if (gst_event_discont_get_value (event, GST_FORMAT_BYTES, &soffset,
-              &eoffset))
+      gst_event_parse_newsegment (event, NULL, &format, &soffset, &eoffset,
+          NULL);
+
+      if (format == GST_FORMAT_BYTES) {
         fseek (filesink->file, soffset, SEEK_SET);
+      }
       break;
     }
-    case GST_EVENT_FLUSH:
+    case GST_EVENT_EOS:
       if (fflush (filesink->file)) {
         GST_ELEMENT_ERROR (filesink, RESOURCE, WRITE,
             (_("Error while writing to file \"%s\"."), filesink->filename),
index 74bbd7040bd7250b53c46807a0614fda347f228a..325bd1c233ed63d006de4bb8a190c79a647f42c0 100644 (file)
@@ -491,32 +491,38 @@ gst_queue_handle_sink_event (GstPad * pad, GstEvent * event)
   queue = GST_QUEUE (GST_OBJECT_PARENT (pad));
 
   switch (GST_EVENT_TYPE (event)) {
-    case GST_EVENT_FLUSH:
-      STATUS (queue, "received flush event");
+    case GST_EVENT_FLUSH_START:
+      STATUS (queue, "received flush start event");
       /* forward event, re first as we're going to use it still */
       gst_event_ref (event);
       gst_pad_push_event (queue->srcpad, event);
-      if (GST_EVENT_FLUSH_DONE (event)) {
-        GST_QUEUE_MUTEX_LOCK (queue);
-        gst_queue_locked_flush (queue);
-        queue->srcresult = GST_FLOW_OK;
-        gst_pad_start_task (queue->srcpad, (GstTaskFunction) gst_queue_loop,
-            queue->srcpad);
-        GST_QUEUE_MUTEX_UNLOCK (queue);
 
-        STATUS (queue, "after flush");
-      } else {
-        /* now unblock the chain function */
-        GST_QUEUE_MUTEX_LOCK (queue);
-        queue->srcresult = GST_FLOW_WRONG_STATE;
-        /* unblock the loop function */
-        g_cond_signal (queue->item_add);
-        GST_QUEUE_MUTEX_UNLOCK (queue);
+      /* now unblock the chain function */
+      GST_QUEUE_MUTEX_LOCK (queue);
+      queue->srcresult = GST_FLOW_WRONG_STATE;
+      /* unblock the loop function */
+      g_cond_signal (queue->item_add);
+      GST_QUEUE_MUTEX_UNLOCK (queue);
 
-        /* make sure it pauses */
-        gst_pad_pause_task (queue->srcpad);
-        GST_CAT_LOG_OBJECT (queue_dataflow, queue, "loop stopped");
-      }
+      /* make sure it pauses */
+      gst_pad_pause_task (queue->srcpad);
+      GST_CAT_LOG_OBJECT (queue_dataflow, queue, "loop stopped");
+      gst_event_unref (event);
+      goto done;
+    case GST_EVENT_FLUSH_STOP:
+      STATUS (queue, "received flush stop event");
+      /* forward event, re first as we're going to use it still */
+      gst_event_ref (event);
+      gst_pad_push_event (queue->srcpad, event);
+
+      GST_QUEUE_MUTEX_LOCK (queue);
+      gst_queue_locked_flush (queue);
+      queue->srcresult = GST_FLOW_OK;
+      gst_pad_start_task (queue->srcpad, (GstTaskFunction) gst_queue_loop,
+          queue->srcpad);
+      GST_QUEUE_MUTEX_UNLOCK (queue);
+
+      STATUS (queue, "after flush");
       gst_event_unref (event);
       goto done;
     case GST_EVENT_EOS:
@@ -775,7 +781,7 @@ restart:
         GST_ELEMENT_ERROR (queue, STREAM, STOPPED,
             ("streaming stopped, reason %s", flowname),
             ("streaming stopped, reason %s", flowname));
-        gst_pad_push_event (queue->srcpad, gst_event_new (GST_EVENT_EOS));
+        gst_pad_push_event (queue->srcpad, gst_event_new_eos ());
       }
       GST_DEBUG ("pausing queue, reason %s", flowname);
       gst_pad_pause_task (queue->srcpad);