Commit 66d7070e authored by Wim Taymans's avatar Wim Taymans

Some docs updates

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.
parent 4795d257
......@@ -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.
......
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),
......
......@@ -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
......
......@@ -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
----------
......
......@@ -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;
......
......@@ -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;
}
}
......
......@@ -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);
......
......@@ -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");
}
......
......@@ -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),
......
......@@ -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)