mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-04 13:32:29 +00:00
docs/design/part-TODO.txt: Remove item from the todo list because it was fixed with the latency state change rewrites.
Original commit message from CVS: * docs/design/part-TODO.txt: Remove item from the todo list because it was fixed with the latency state change rewrites. * docs/design/part-seeking.txt: * docs/design/part-segments.txt: Update some docs. * gst/gstevent.c: (gst_event_new_new_segment_full), (gst_event_parse_new_segment_full), (gst_event_new_buffer_size), (gst_event_parse_buffer_size), (gst_event_new_qos), (gst_event_parse_qos), (gst_event_new_seek), (gst_event_parse_seek), (gst_event_new_latency), (gst_event_parse_latency): Use quarks to construct and parse events. * gst/gstquark.c: (_priv_gst_quarks_initialize): * gst/gstquark.h: Add some more quarks to the table. Emit a warning when the quark tables are not in sync. * tests/check/gst/gstbus.c: (GST_START_TEST): Add an assert.
This commit is contained in:
parent
35a2a49c00
commit
97ec47cabb
8 changed files with 224 additions and 89 deletions
26
ChangeLog
26
ChangeLog
|
@ -1,3 +1,29 @@
|
||||||
|
2008-10-13 Wim Taymans <wim.taymans@collabora.co.uk>
|
||||||
|
|
||||||
|
* docs/design/part-TODO.txt:
|
||||||
|
Remove item from the todo list because it was fixed with the latency
|
||||||
|
state change rewrites.
|
||||||
|
|
||||||
|
* docs/design/part-seeking.txt:
|
||||||
|
* docs/design/part-segments.txt:
|
||||||
|
Update some docs.
|
||||||
|
|
||||||
|
* gst/gstevent.c: (gst_event_new_new_segment_full),
|
||||||
|
(gst_event_parse_new_segment_full), (gst_event_new_buffer_size),
|
||||||
|
(gst_event_parse_buffer_size), (gst_event_new_qos),
|
||||||
|
(gst_event_parse_qos), (gst_event_new_seek),
|
||||||
|
(gst_event_parse_seek), (gst_event_new_latency),
|
||||||
|
(gst_event_parse_latency):
|
||||||
|
Use quarks to construct and parse events.
|
||||||
|
|
||||||
|
* gst/gstquark.c: (_priv_gst_quarks_initialize):
|
||||||
|
* gst/gstquark.h:
|
||||||
|
Add some more quarks to the table.
|
||||||
|
Emit a warning when the quark tables are not in sync.
|
||||||
|
|
||||||
|
* tests/check/gst/gstbus.c: (GST_START_TEST):
|
||||||
|
Add an assert.
|
||||||
|
|
||||||
2008-10-13 Stefan Kost <ensonic@users.sf.net>
|
2008-10-13 Stefan Kost <ensonic@users.sf.net>
|
||||||
|
|
||||||
* plugins/elements/Makefile.am:
|
* plugins/elements/Makefile.am:
|
||||||
|
|
|
@ -59,12 +59,6 @@ API/ABI
|
||||||
|
|
||||||
- Make serialisation of structures more consistent, readable and nicer code-wise.
|
- Make serialisation of structures more consistent, readable and nicer code-wise.
|
||||||
|
|
||||||
- When a seekable live source does a flushing seek, it needs a new base_time to
|
|
||||||
timestamp new data. The pipeline however does not know that there is a live
|
|
||||||
source in the pipeline and thus does not select a new base_time automatically.
|
|
||||||
There needs to be a mechanism for a live source to request a new base_time or
|
|
||||||
pipeline restart.
|
|
||||||
|
|
||||||
- pad block has several issues:
|
- pad block has several issues:
|
||||||
* can't block on selected things, like push, pull, pad_alloc, events, ...
|
* can't block on selected things, like push, pull, pad_alloc, events, ...
|
||||||
* can't check why the block happened. We should also be able to get the item/
|
* can't check why the block happened. We should also be able to get the item/
|
||||||
|
|
|
@ -2,46 +2,63 @@ Seeking
|
||||||
-------
|
-------
|
||||||
|
|
||||||
Seeking in GStreamer means configuring the pipeline for playback of the
|
Seeking in GStreamer means configuring the pipeline for playback of the
|
||||||
media between a certain start and stop time, called a segment.
|
media between a certain start and stop time, called a segment. By default a
|
||||||
|
pipeline will play from position 0 to the total duration of the media at a rate
|
||||||
|
of 1.0.
|
||||||
|
|
||||||
Different kinds of seeking exist:
|
A seek is performed by sending a seek event to the sink elements of a
|
||||||
|
pipeline. Sending the seek event to a bin will by default forward
|
||||||
|
the event to all sinks in the bin.
|
||||||
|
|
||||||
- immediate seeking with low latency (FLUSH seek)
|
When performing a seek, the start and stop values of the segment can be
|
||||||
- seeking without flush, playback will start from the new
|
specified as absoulte positions or relative to the currently configured
|
||||||
position after all the queues are emptied with old data.
|
playback segment. Note that it is not possible to seek relative to the current
|
||||||
- segment seeking with and without FLUSH, this can be used to
|
playback position.
|
||||||
implement seamless looping or NLE functionality.
|
|
||||||
|
Feedback of the seek operation can be immediatly using the GST_SEEK_FLAG_FLUSH
|
||||||
|
flag. With this flag, all pending data in the pipeline is discarded and playback
|
||||||
|
starts from the new position immediatly.
|
||||||
|
|
||||||
|
When the FLUSH flag is not set, the seek will be queued and executed as
|
||||||
|
soon as possible, which might be after all queues are emptied.
|
||||||
|
|
||||||
Seeking can be performed in different formats such as time, frames
|
Seeking can be performed in different formats such as time, frames
|
||||||
or samples.
|
or samples.
|
||||||
|
|
||||||
Seeking can be performed to an absolute position or relative to the
|
The seeking can be performed to a nearby key unit or to the exact
|
||||||
currently configured segment.
|
(estimated) unit in the media (GST_SEEK_FLAG_KEY_UNIT).
|
||||||
|
|
||||||
For seeking to work reliably, all plugins in the pipeline need to follow
|
The seeking can be performed by using an estimated target position or in an
|
||||||
the well-defined rules in this document.
|
accurate way (GST_SEEK_FLAG_ACCURATE). For some formats this can result in
|
||||||
|
having to scan the complete file in order to accurately find the target unit.
|
||||||
|
|
||||||
Non segment seeking will make the pipeline emit EOS when the configured
|
Non segment seeking will make the pipeline emit EOS when the configured
|
||||||
segment has been played.
|
segment has been played.
|
||||||
|
|
||||||
Segment seeking will not emit an EOS at the end of the range but will
|
Segment seeking (using the GST_SEEK_FLAG_SEGMENT) will not emit an EOS at
|
||||||
post a SEGMENT_DONE message on the bus. This message is posted by the
|
the end of the playback segment but will post a SEGMENT_DONE message on the
|
||||||
earliest element in the pipeline, typically a demuxer. After receiving
|
bus. This message is posted by the element driving the playback in the
|
||||||
the message, the application can reconnect the pipeline or issue other
|
pipeline, typically a demuxer. After receiving the message, the application
|
||||||
seek events in the pipeline. Since the message is posted as early as
|
can reconnect the pipeline or issue other seek events in the pipeline.
|
||||||
possible in the pipeline, the application has some time to issue a new
|
Since the message is posted as early as possible in the pipeline, the
|
||||||
seek to make the transition seamless. Typically the allowed delay is
|
application has some time to issue a new seek to make the transition seamless.
|
||||||
defined by the buffer sizes of the sinks as well as the size of any
|
Typically the allowed delay is defined by the buffer sizes of the sinks as well
|
||||||
queues in the pipeline.
|
as the size of any queues in the pipeline.
|
||||||
|
|
||||||
The seek can also change the playback speed of the configured segment.
|
The seek can also change the playback speed of the configured segment.
|
||||||
A speed of 1.0 is normal speed, 2.0 is double speed. Negative values
|
A speed of 1.0 is normal speed, 2.0 is double speed. Negative values
|
||||||
mean backward playback.
|
mean backward playback.
|
||||||
|
|
||||||
|
When performing a seek with a playback rate different from 1.0, the
|
||||||
|
GST_SEEK_FLAG_SKIP flag can be used to instruct decoders and demuxers that they
|
||||||
|
are allowed to skip decoding. This can be useful when resource consumption is
|
||||||
|
more important than accurately producing all frames.
|
||||||
|
|
||||||
|
|
||||||
Generating seeking events
|
Generating seeking events
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
|
A seek event is created with gst_event_new_seek ().
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,13 @@ Use case: FLUSHING seek
|
||||||
When doing a seek in this pipeline for a segment 1 to 5 seconds, avidemux
|
When doing a seek in this pipeline for a segment 1 to 5 seconds, avidemux
|
||||||
will perform the seek.
|
will perform the seek.
|
||||||
|
|
||||||
|
Avidemux starts by sending a FLUSH_START event downstream and upstream. This
|
||||||
|
will cause its streaming task to PAUSED because _pad_pull_range() and
|
||||||
|
_pad_push() will return WRONG_STATE. It then waits for the STREAM_LOCK,
|
||||||
|
which will be unlocked when the streaming task pauses. At this point no
|
||||||
|
streaming is happening anymore in the pipeline and a FLUSH_STOP is sent
|
||||||
|
upstream and downstream.
|
||||||
|
|
||||||
When avidemux starts playback of the segment from second 1 to 5, it pushes
|
When avidemux starts playback of the segment from second 1 to 5, it pushes
|
||||||
out a newsegment with 1 and 5 as start and stop times. The stream_time in
|
out a newsegment with 1 and 5 as start and stop times. The stream_time in
|
||||||
the newsegment is also 1 as this is the position we seek to.
|
the newsegment is also 1 as this is the position we seek to.
|
||||||
|
@ -57,18 +64,21 @@ Use case: FLUSHING seek
|
||||||
When it reaches timestamp 5, it does not decode and push frames anymore.
|
When it reaches timestamp 5, it does not decode and push frames anymore.
|
||||||
|
|
||||||
The video sink receives a frame of timestamp 1. It takes the start value of
|
The video sink receives a frame of timestamp 1. It takes the start value of
|
||||||
the previous newsegment and aplies the folowing formula:
|
the previous newsegment and aplies the folowing (simplified) formula:
|
||||||
|
|
||||||
render_time = BUFFER_TIMESTAMP - segment_start + element->base_time
|
render_time = BUFFER_TIMESTAMP - segment_start + element->base_time
|
||||||
|
|
||||||
It then syncs against the clock with this render_time. Not that
|
It then syncs against the clock with this render_time. Note that
|
||||||
BUFFER_TIMESTAMP is always >= segment_start or else it would fall outside of
|
BUFFER_TIMESTAMP is always >= segment_start or else it would fall outside of
|
||||||
the configure segment.
|
the configure segment.
|
||||||
|
|
||||||
Videosink reports its current position as:
|
Videosink reports its current position as (simplified):
|
||||||
|
|
||||||
current_position = clock_time - element->base_time + segment_time
|
current_position = clock_time - element->base_time + segment_time
|
||||||
|
|
||||||
|
See part-synchronisation.txt for a more detailed and accurate explanation of
|
||||||
|
synchronisation and position reporting.
|
||||||
|
|
||||||
Since after a flushing seek the stream_time is reset to 0, the new buffer
|
Since after a flushing seek the stream_time is reset to 0, the new buffer
|
||||||
will be rendered immediatly after the seek and the current_position will be
|
will be rendered immediatly after the seek and the current_position will be
|
||||||
the stream_time of the seek that was performed.
|
the stream_time of the seek that was performed.
|
||||||
|
|
181
gst/gstevent.c
181
gst/gstevent.c
|
@ -83,6 +83,7 @@
|
||||||
#include "gstevent.h"
|
#include "gstevent.h"
|
||||||
#include "gstenumtypes.h"
|
#include "gstenumtypes.h"
|
||||||
#include "gstutils.h"
|
#include "gstutils.h"
|
||||||
|
#include "gstquark.h"
|
||||||
|
|
||||||
static void gst_event_init (GTypeInstance * instance, gpointer g_class);
|
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_class_init (gpointer g_class, gpointer class_data);
|
||||||
|
@ -545,6 +546,9 @@ gst_event_new_new_segment_full (gboolean update, gdouble rate,
|
||||||
gdouble applied_rate, GstFormat format, gint64 start, gint64 stop,
|
gdouble applied_rate, GstFormat format, gint64 start, gint64 stop,
|
||||||
gint64 position)
|
gint64 position)
|
||||||
{
|
{
|
||||||
|
GstEvent *event;
|
||||||
|
GstStructure *structure;
|
||||||
|
|
||||||
g_return_val_if_fail (rate != 0.0, NULL);
|
g_return_val_if_fail (rate != 0.0, NULL);
|
||||||
g_return_val_if_fail (applied_rate != 0.0, NULL);
|
g_return_val_if_fail (applied_rate != 0.0, NULL);
|
||||||
|
|
||||||
|
@ -568,15 +572,18 @@ gst_event_new_new_segment_full (gboolean update, gdouble rate,
|
||||||
if (stop != -1)
|
if (stop != -1)
|
||||||
g_return_val_if_fail (start <= stop, NULL);
|
g_return_val_if_fail (start <= stop, NULL);
|
||||||
|
|
||||||
return gst_event_new_custom (GST_EVENT_NEWSEGMENT,
|
structure = gst_structure_empty_new ("GstEventNewsegment");
|
||||||
gst_structure_new ("GstEventNewsegment",
|
gst_structure_id_set (structure,
|
||||||
"update", G_TYPE_BOOLEAN, update,
|
GST_QUARK (UPDATE), G_TYPE_BOOLEAN, update,
|
||||||
"rate", G_TYPE_DOUBLE, rate,
|
GST_QUARK (RATE), G_TYPE_DOUBLE, rate,
|
||||||
"applied_rate", G_TYPE_DOUBLE, applied_rate,
|
GST_QUARK (APPLIED_RATE), G_TYPE_DOUBLE, applied_rate,
|
||||||
"format", GST_TYPE_FORMAT, format,
|
GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
|
||||||
"start", G_TYPE_INT64, start,
|
GST_QUARK (START), G_TYPE_INT64, start,
|
||||||
"stop", G_TYPE_INT64, stop,
|
GST_QUARK (STOP), G_TYPE_INT64, stop,
|
||||||
"position", G_TYPE_INT64, position, NULL));
|
GST_QUARK (POSITION), G_TYPE_INT64, position, NULL);
|
||||||
|
event = gst_event_new_custom (GST_EVENT_NEWSEGMENT, structure);
|
||||||
|
|
||||||
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -609,22 +616,32 @@ gst_event_parse_new_segment_full (GstEvent * event, gboolean * update,
|
||||||
structure = gst_event_get_structure (event);
|
structure = gst_event_get_structure (event);
|
||||||
if (G_LIKELY (update))
|
if (G_LIKELY (update))
|
||||||
*update =
|
*update =
|
||||||
g_value_get_boolean (gst_structure_get_value (structure, "update"));
|
g_value_get_boolean (gst_structure_id_get_value (structure,
|
||||||
|
GST_QUARK (UPDATE)));
|
||||||
if (G_LIKELY (rate))
|
if (G_LIKELY (rate))
|
||||||
*rate = g_value_get_double (gst_structure_get_value (structure, "rate"));
|
*rate =
|
||||||
|
g_value_get_double (gst_structure_id_get_value (structure,
|
||||||
|
GST_QUARK (RATE)));
|
||||||
if (G_LIKELY (applied_rate))
|
if (G_LIKELY (applied_rate))
|
||||||
*applied_rate =
|
*applied_rate =
|
||||||
g_value_get_double (gst_structure_get_value (structure,
|
g_value_get_double (gst_structure_id_get_value (structure,
|
||||||
"applied_rate"));
|
GST_QUARK (APPLIED_RATE)));
|
||||||
if (G_LIKELY (format))
|
if (G_LIKELY (format))
|
||||||
*format = g_value_get_enum (gst_structure_get_value (structure, "format"));
|
*format =
|
||||||
|
g_value_get_enum (gst_structure_id_get_value (structure,
|
||||||
|
GST_QUARK (FORMAT)));
|
||||||
if (G_LIKELY (start))
|
if (G_LIKELY (start))
|
||||||
*start = g_value_get_int64 (gst_structure_get_value (structure, "start"));
|
*start =
|
||||||
|
g_value_get_int64 (gst_structure_id_get_value (structure,
|
||||||
|
GST_QUARK (START)));
|
||||||
if (G_LIKELY (stop))
|
if (G_LIKELY (stop))
|
||||||
*stop = g_value_get_int64 (gst_structure_get_value (structure, "stop"));
|
*stop =
|
||||||
|
g_value_get_int64 (gst_structure_id_get_value (structure,
|
||||||
|
GST_QUARK (STOP)));
|
||||||
if (G_LIKELY (position))
|
if (G_LIKELY (position))
|
||||||
*position =
|
*position =
|
||||||
g_value_get_int64 (gst_structure_get_value (structure, "position"));
|
g_value_get_int64 (gst_structure_id_get_value (structure,
|
||||||
|
GST_QUARK (POSITION)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -679,17 +696,23 @@ GstEvent *
|
||||||
gst_event_new_buffer_size (GstFormat format, gint64 minsize,
|
gst_event_new_buffer_size (GstFormat format, gint64 minsize,
|
||||||
gint64 maxsize, gboolean async)
|
gint64 maxsize, gboolean async)
|
||||||
{
|
{
|
||||||
|
GstEvent *event;
|
||||||
|
GstStructure *structure;
|
||||||
|
|
||||||
GST_CAT_INFO (GST_CAT_EVENT,
|
GST_CAT_INFO (GST_CAT_EVENT,
|
||||||
"creating buffersize format %s, minsize %" G_GINT64_FORMAT
|
"creating buffersize format %s, minsize %" G_GINT64_FORMAT
|
||||||
", maxsize %" G_GINT64_FORMAT ", async %d", gst_format_get_name (format),
|
", maxsize %" G_GINT64_FORMAT ", async %d", gst_format_get_name (format),
|
||||||
minsize, maxsize, async);
|
minsize, maxsize, async);
|
||||||
|
|
||||||
return gst_event_new_custom (GST_EVENT_BUFFERSIZE,
|
structure = gst_structure_empty_new ("GstEventBufferSize");
|
||||||
gst_structure_new ("GstEventBufferSize",
|
gst_structure_id_set (structure,
|
||||||
"format", GST_TYPE_FORMAT, format,
|
GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
|
||||||
"minsize", G_TYPE_INT64, minsize,
|
GST_QUARK (MINSIZE), G_TYPE_INT64, minsize,
|
||||||
"maxsize", G_TYPE_INT64, maxsize,
|
GST_QUARK (MAXSIZE), G_TYPE_INT64, maxsize,
|
||||||
"async", G_TYPE_BOOLEAN, async, NULL));
|
GST_QUARK (ASYNC), G_TYPE_BOOLEAN, async, NULL);
|
||||||
|
event = gst_event_new_custom (GST_EVENT_BUFFERSIZE, structure);
|
||||||
|
|
||||||
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -713,15 +736,21 @@ gst_event_parse_buffer_size (GstEvent * event, GstFormat * format,
|
||||||
|
|
||||||
structure = gst_event_get_structure (event);
|
structure = gst_event_get_structure (event);
|
||||||
if (format)
|
if (format)
|
||||||
*format = g_value_get_enum (gst_structure_get_value (structure, "format"));
|
*format =
|
||||||
|
g_value_get_enum (gst_structure_id_get_value (structure,
|
||||||
|
GST_QUARK (FORMAT)));
|
||||||
if (minsize)
|
if (minsize)
|
||||||
*minsize =
|
*minsize =
|
||||||
g_value_get_int64 (gst_structure_get_value (structure, "minsize"));
|
g_value_get_int64 (gst_structure_id_get_value (structure,
|
||||||
|
GST_QUARK (MINSIZE)));
|
||||||
if (maxsize)
|
if (maxsize)
|
||||||
*maxsize =
|
*maxsize =
|
||||||
g_value_get_int64 (gst_structure_get_value (structure, "maxsize"));
|
g_value_get_int64 (gst_structure_id_get_value (structure,
|
||||||
|
GST_QUARK (MAXSIZE)));
|
||||||
if (async)
|
if (async)
|
||||||
*async = g_value_get_boolean (gst_structure_get_value (structure, "async"));
|
*async =
|
||||||
|
g_value_get_boolean (gst_structure_id_get_value (structure,
|
||||||
|
GST_QUARK (ASYNC)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -770,6 +799,9 @@ GstEvent *
|
||||||
gst_event_new_qos (gdouble proportion, GstClockTimeDiff diff,
|
gst_event_new_qos (gdouble proportion, GstClockTimeDiff diff,
|
||||||
GstClockTime timestamp)
|
GstClockTime timestamp)
|
||||||
{
|
{
|
||||||
|
GstEvent *event;
|
||||||
|
GstStructure *structure;
|
||||||
|
|
||||||
/* diff must be positive or timestamp + diff must be positive */
|
/* diff must be positive or timestamp + diff must be positive */
|
||||||
g_return_val_if_fail (diff >= 0 || -diff <= timestamp, NULL);
|
g_return_val_if_fail (diff >= 0 || -diff <= timestamp, NULL);
|
||||||
|
|
||||||
|
@ -778,11 +810,14 @@ gst_event_new_qos (gdouble proportion, GstClockTimeDiff diff,
|
||||||
", timestamp %" GST_TIME_FORMAT, proportion,
|
", timestamp %" GST_TIME_FORMAT, proportion,
|
||||||
diff, GST_TIME_ARGS (timestamp));
|
diff, GST_TIME_ARGS (timestamp));
|
||||||
|
|
||||||
return gst_event_new_custom (GST_EVENT_QOS,
|
structure = gst_structure_empty_new ("GstEventQOS");
|
||||||
gst_structure_new ("GstEventQOS",
|
gst_structure_id_set (structure,
|
||||||
"proportion", G_TYPE_DOUBLE, proportion,
|
GST_QUARK (PROPORTION), G_TYPE_DOUBLE, proportion,
|
||||||
"diff", G_TYPE_INT64, diff,
|
GST_QUARK (DIFF), G_TYPE_INT64, diff,
|
||||||
"timestamp", G_TYPE_UINT64, timestamp, NULL));
|
GST_QUARK (TIMESTAMP), G_TYPE_UINT64, timestamp, NULL);
|
||||||
|
event = gst_event_new_custom (GST_EVENT_QOS, structure);
|
||||||
|
|
||||||
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -807,12 +842,16 @@ gst_event_parse_qos (GstEvent * event, gdouble * proportion,
|
||||||
structure = gst_event_get_structure (event);
|
structure = gst_event_get_structure (event);
|
||||||
if (proportion)
|
if (proportion)
|
||||||
*proportion =
|
*proportion =
|
||||||
g_value_get_double (gst_structure_get_value (structure, "proportion"));
|
g_value_get_double (gst_structure_id_get_value (structure,
|
||||||
|
GST_QUARK (PROPORTION)));
|
||||||
if (diff)
|
if (diff)
|
||||||
*diff = g_value_get_int64 (gst_structure_get_value (structure, "diff"));
|
*diff =
|
||||||
|
g_value_get_int64 (gst_structure_id_get_value (structure,
|
||||||
|
GST_QUARK (DIFF)));
|
||||||
if (timestamp)
|
if (timestamp)
|
||||||
*timestamp =
|
*timestamp =
|
||||||
g_value_get_uint64 (gst_structure_get_value (structure, "timestamp"));
|
g_value_get_uint64 (gst_structure_id_get_value (structure,
|
||||||
|
GST_QUARK (TIMESTAMP)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -841,9 +880,9 @@ gst_event_parse_qos (GstEvent * event, gdouble * proportion,
|
||||||
* configured playback segment can be queried with #GST_QUERY_SEGMENT.
|
* configured playback segment can be queried with #GST_QUERY_SEGMENT.
|
||||||
*
|
*
|
||||||
* @start_type and @stop_type specify how to adjust the currently configured
|
* @start_type and @stop_type specify how to adjust the currently configured
|
||||||
* start and stop fields in @segment. Adjustments can be made relative or
|
* start and stop fields in playback segment. Adjustments can be made relative
|
||||||
* absolute to the last configured values. A type of #GST_SEEK_TYPE_NONE means
|
* or absolute to the last configured values. A type of #GST_SEEK_TYPE_NONE
|
||||||
* that the position should not be updated.
|
* means that the position should not be updated.
|
||||||
*
|
*
|
||||||
* When the rate is positive and @start has been updated, playback will start
|
* When the rate is positive and @start has been updated, playback will start
|
||||||
* from the newly configured start position.
|
* from the newly configured start position.
|
||||||
|
@ -855,7 +894,7 @@ gst_event_parse_qos (GstEvent * event, gdouble * proportion,
|
||||||
* It is not possible to seek relative to the current playback position, to do
|
* It is not possible to seek relative to the current playback position, to do
|
||||||
* this, PAUSE the pipeline, query the current playback position with
|
* this, PAUSE the pipeline, query the current playback position with
|
||||||
* #GST_QUERY_POSITION and update the playback segment current position with a
|
* #GST_QUERY_POSITION and update the playback segment current position with a
|
||||||
* #GST_SEEK_TYPE_SET to the desired position.
|
* #GST_SEEK_TYPE_SET to the desired position.
|
||||||
*
|
*
|
||||||
* Returns: A new seek event.
|
* Returns: A new seek event.
|
||||||
*/
|
*/
|
||||||
|
@ -863,6 +902,9 @@ GstEvent *
|
||||||
gst_event_new_seek (gdouble rate, GstFormat format, GstSeekFlags flags,
|
gst_event_new_seek (gdouble rate, GstFormat format, GstSeekFlags flags,
|
||||||
GstSeekType start_type, gint64 start, GstSeekType stop_type, gint64 stop)
|
GstSeekType start_type, gint64 start, GstSeekType stop_type, gint64 stop)
|
||||||
{
|
{
|
||||||
|
GstEvent *event;
|
||||||
|
GstStructure *structure;
|
||||||
|
|
||||||
g_return_val_if_fail (rate != 0.0, NULL);
|
g_return_val_if_fail (rate != 0.0, NULL);
|
||||||
|
|
||||||
if (format == GST_FORMAT_TIME) {
|
if (format == GST_FORMAT_TIME) {
|
||||||
|
@ -881,14 +923,18 @@ gst_event_new_seek (gdouble rate, GstFormat format, GstSeekFlags flags,
|
||||||
stop);
|
stop);
|
||||||
}
|
}
|
||||||
|
|
||||||
return gst_event_new_custom (GST_EVENT_SEEK,
|
structure = gst_structure_empty_new ("GstEventSeek");
|
||||||
gst_structure_new ("GstEventSeek", "rate", G_TYPE_DOUBLE, rate,
|
gst_structure_id_set (structure,
|
||||||
"format", GST_TYPE_FORMAT, format,
|
GST_QUARK (RATE), G_TYPE_DOUBLE, rate,
|
||||||
"flags", GST_TYPE_SEEK_FLAGS, flags,
|
GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
|
||||||
"cur_type", GST_TYPE_SEEK_TYPE, start_type,
|
GST_QUARK (FLAGS), GST_TYPE_SEEK_FLAGS, flags,
|
||||||
"cur", G_TYPE_INT64, start,
|
GST_QUARK (CUR_TYPE), GST_TYPE_SEEK_TYPE, start_type,
|
||||||
"stop_type", GST_TYPE_SEEK_TYPE, stop_type,
|
GST_QUARK (CUR), G_TYPE_INT64, start,
|
||||||
"stop", G_TYPE_INT64, stop, NULL));
|
GST_QUARK (STOP_TYPE), GST_TYPE_SEEK_TYPE, stop_type,
|
||||||
|
GST_QUARK (STOP), G_TYPE_INT64, stop, NULL);
|
||||||
|
event = gst_event_new_custom (GST_EVENT_SEEK, structure);
|
||||||
|
|
||||||
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -916,21 +962,33 @@ gst_event_parse_seek (GstEvent * event, gdouble * rate,
|
||||||
|
|
||||||
structure = gst_event_get_structure (event);
|
structure = gst_event_get_structure (event);
|
||||||
if (rate)
|
if (rate)
|
||||||
*rate = g_value_get_double (gst_structure_get_value (structure, "rate"));
|
*rate =
|
||||||
|
g_value_get_double (gst_structure_id_get_value (structure,
|
||||||
|
GST_QUARK (RATE)));
|
||||||
if (format)
|
if (format)
|
||||||
*format = g_value_get_enum (gst_structure_get_value (structure, "format"));
|
*format =
|
||||||
|
g_value_get_enum (gst_structure_id_get_value (structure,
|
||||||
|
GST_QUARK (FORMAT)));
|
||||||
if (flags)
|
if (flags)
|
||||||
*flags = g_value_get_flags (gst_structure_get_value (structure, "flags"));
|
*flags =
|
||||||
|
g_value_get_flags (gst_structure_id_get_value (structure,
|
||||||
|
GST_QUARK (FLAGS)));
|
||||||
if (start_type)
|
if (start_type)
|
||||||
*start_type =
|
*start_type =
|
||||||
g_value_get_enum (gst_structure_get_value (structure, "cur_type"));
|
g_value_get_enum (gst_structure_id_get_value (structure,
|
||||||
|
GST_QUARK (CUR_TYPE)));
|
||||||
if (start)
|
if (start)
|
||||||
*start = g_value_get_int64 (gst_structure_get_value (structure, "cur"));
|
*start =
|
||||||
|
g_value_get_int64 (gst_structure_id_get_value (structure,
|
||||||
|
GST_QUARK (CUR)));
|
||||||
if (stop_type)
|
if (stop_type)
|
||||||
*stop_type =
|
*stop_type =
|
||||||
g_value_get_enum (gst_structure_get_value (structure, "stop_type"));
|
g_value_get_enum (gst_structure_id_get_value (structure,
|
||||||
|
GST_QUARK (STOP_TYPE)));
|
||||||
if (stop)
|
if (stop)
|
||||||
*stop = g_value_get_int64 (gst_structure_get_value (structure, "stop"));
|
*stop =
|
||||||
|
g_value_get_int64 (gst_structure_id_get_value (structure,
|
||||||
|
GST_QUARK (STOP)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -968,12 +1026,18 @@ gst_event_new_navigation (GstStructure * structure)
|
||||||
GstEvent *
|
GstEvent *
|
||||||
gst_event_new_latency (GstClockTime latency)
|
gst_event_new_latency (GstClockTime latency)
|
||||||
{
|
{
|
||||||
|
GstEvent *event;
|
||||||
|
GstStructure *structure;
|
||||||
|
|
||||||
GST_CAT_INFO (GST_CAT_EVENT,
|
GST_CAT_INFO (GST_CAT_EVENT,
|
||||||
"creating latency event %" GST_TIME_FORMAT, GST_TIME_ARGS (latency));
|
"creating latency event %" GST_TIME_FORMAT, GST_TIME_ARGS (latency));
|
||||||
|
|
||||||
return gst_event_new_custom (GST_EVENT_LATENCY,
|
structure = gst_structure_empty_new ("GstEventLatency");
|
||||||
gst_structure_new ("GstEventLatency",
|
gst_structure_id_set (structure,
|
||||||
"latency", G_TYPE_UINT64, latency, NULL));
|
GST_QUARK (LATENCY), G_TYPE_UINT64, latency, NULL);
|
||||||
|
event = gst_event_new_custom (GST_EVENT_LATENCY, structure);
|
||||||
|
|
||||||
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -996,5 +1060,6 @@ gst_event_parse_latency (GstEvent * event, GstClockTime * latency)
|
||||||
structure = gst_event_get_structure (event);
|
structure = gst_event_get_structure (event);
|
||||||
if (latency)
|
if (latency)
|
||||||
*latency =
|
*latency =
|
||||||
g_value_get_uint64 (gst_structure_get_value (structure, "latency"));
|
g_value_get_uint64 (gst_structure_id_get_value (structure,
|
||||||
|
GST_QUARK (LATENCY)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,10 @@ static const gchar *_quark_strings[] = {
|
||||||
"avg-in-rate", "avg-out-rate", "buffering-left",
|
"avg-in-rate", "avg-out-rate", "buffering-left",
|
||||||
"estimated-total", "old-state", "new-state", "pending-state",
|
"estimated-total", "old-state", "new-state", "pending-state",
|
||||||
"clock", "ready", "position", "new-base-time", "live", "min-latency",
|
"clock", "ready", "position", "new-base-time", "live", "min-latency",
|
||||||
"max-latency", "busy", "type", "owner"
|
"max-latency", "busy", "type", "owner", "update", "applied-rate",
|
||||||
|
"start", "stop", "minsize", "maxsize", "async", "proportion",
|
||||||
|
"diff", "timestamp", "flags", "cur-type", "cur", "stop-type",
|
||||||
|
"latency"
|
||||||
};
|
};
|
||||||
|
|
||||||
GQuark _priv_gst_quark_table[GST_QUARK_MAX];
|
GQuark _priv_gst_quark_table[GST_QUARK_MAX];
|
||||||
|
@ -44,6 +47,10 @@ _priv_gst_quarks_initialize (void)
|
||||||
{
|
{
|
||||||
gint i;
|
gint i;
|
||||||
|
|
||||||
|
if (G_N_ELEMENTS (_quark_strings) != GST_QUARK_MAX)
|
||||||
|
g_warning ("the quark table is not consistent! %ld != %d",
|
||||||
|
G_N_ELEMENTS (_quark_strings), GST_QUARK_MAX);
|
||||||
|
|
||||||
for (i = 0; i < GST_QUARK_MAX; i++) {
|
for (i = 0; i < GST_QUARK_MAX; i++) {
|
||||||
_priv_gst_quark_table[i] = g_quark_from_static_string (_quark_strings[i]);
|
_priv_gst_quark_table[i] = g_quark_from_static_string (_quark_strings[i]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,8 +62,23 @@ typedef enum _GstQuarkId
|
||||||
GST_QUARK_BUSY = 33,
|
GST_QUARK_BUSY = 33,
|
||||||
GST_QUARK_TYPE = 34,
|
GST_QUARK_TYPE = 34,
|
||||||
GST_QUARK_OWNER = 35,
|
GST_QUARK_OWNER = 35,
|
||||||
|
GST_QUARK_UPDATE = 36,
|
||||||
|
GST_QUARK_APPLIED_RATE = 37,
|
||||||
|
GST_QUARK_START = 38,
|
||||||
|
GST_QUARK_STOP = 39,
|
||||||
|
GST_QUARK_MINSIZE = 40,
|
||||||
|
GST_QUARK_MAXSIZE = 41,
|
||||||
|
GST_QUARK_ASYNC = 42,
|
||||||
|
GST_QUARK_PROPORTION = 43,
|
||||||
|
GST_QUARK_DIFF = 44,
|
||||||
|
GST_QUARK_TIMESTAMP = 45,
|
||||||
|
GST_QUARK_FLAGS = 46,
|
||||||
|
GST_QUARK_CUR_TYPE = 47,
|
||||||
|
GST_QUARK_CUR = 48,
|
||||||
|
GST_QUARK_STOP_TYPE = 49,
|
||||||
|
GST_QUARK_LATENCY = 50,
|
||||||
|
|
||||||
GST_QUARK_MAX = 36
|
GST_QUARK_MAX = 51
|
||||||
} GstQuarkId;
|
} GstQuarkId;
|
||||||
|
|
||||||
extern GQuark _priv_gst_quark_table[GST_QUARK_MAX];
|
extern GQuark _priv_gst_quark_table[GST_QUARK_MAX];
|
||||||
|
|
|
@ -165,6 +165,7 @@ GST_START_TEST (test_watch)
|
||||||
main_loop = g_main_loop_new (NULL, FALSE);
|
main_loop = g_main_loop_new (NULL, FALSE);
|
||||||
|
|
||||||
id = gst_bus_add_watch (test_bus, gst_bus_async_signal_func, NULL);
|
id = gst_bus_add_watch (test_bus, gst_bus_async_signal_func, NULL);
|
||||||
|
fail_if (id == 0);
|
||||||
g_signal_connect (test_bus, "message::eos", (GCallback) message_func_eos,
|
g_signal_connect (test_bus, "message::eos", (GCallback) message_func_eos,
|
||||||
NULL);
|
NULL);
|
||||||
g_signal_connect (test_bus, "message::application",
|
g_signal_connect (test_bus, "message::application",
|
||||||
|
|
Loading…
Reference in a new issue