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>
|
||||
|
||||
* plugins/elements/Makefile.am:
|
||||
|
|
|
@ -59,12 +59,6 @@ API/ABI
|
|||
|
||||
- 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:
|
||||
* 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/
|
||||
|
|
|
@ -2,46 +2,63 @@ Seeking
|
|||
-------
|
||||
|
||||
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)
|
||||
- seeking without flush, playback will start from the new
|
||||
position after all the queues are emptied with old data.
|
||||
- segment seeking with and without FLUSH, this can be used to
|
||||
implement seamless looping or NLE functionality.
|
||||
When performing a seek, the start and stop values of the segment can be
|
||||
specified as absoulte positions or relative to the currently configured
|
||||
playback segment. Note that it is not possible to seek relative to the current
|
||||
playback position.
|
||||
|
||||
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
|
||||
or samples.
|
||||
|
||||
Seeking can be performed to an absolute position or relative to the
|
||||
currently configured segment.
|
||||
The seeking can be performed to a nearby key unit or to the exact
|
||||
(estimated) unit in the media (GST_SEEK_FLAG_KEY_UNIT).
|
||||
|
||||
For seeking to work reliably, all plugins in the pipeline need to follow
|
||||
the well-defined rules in this document.
|
||||
The seeking can be performed by using an estimated target position or in an
|
||||
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
|
||||
segment has been played.
|
||||
|
||||
Segment seeking will not emit an EOS at the end of the range but will
|
||||
post a SEGMENT_DONE message on the bus. This message is posted by the
|
||||
earliest element in the pipeline, typically a demuxer. After receiving
|
||||
the message, the application can reconnect the pipeline or issue other
|
||||
seek events in the pipeline. Since the message is posted as early as
|
||||
possible in the pipeline, the application has some time to issue a new
|
||||
seek to make the transition seamless. Typically the allowed delay is
|
||||
defined by the buffer sizes of the sinks as well as the size of any
|
||||
queues in the pipeline.
|
||||
Segment seeking (using the GST_SEEK_FLAG_SEGMENT) will not emit an EOS at
|
||||
the end of the playback segment but will post a SEGMENT_DONE message on the
|
||||
bus. This message is posted by the element driving the playback in the
|
||||
pipeline, typically a demuxer. After receiving the message, the application
|
||||
can reconnect the pipeline or issue other seek events in the pipeline.
|
||||
Since the message is posted as early as possible in the pipeline, the
|
||||
application has some time to issue a new seek to make the transition seamless.
|
||||
Typically the allowed delay is defined by the buffer sizes of the sinks as well
|
||||
as the size of any queues in the pipeline.
|
||||
|
||||
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
|
||||
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
|
||||
-------------------------
|
||||
|
||||
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
|
||||
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
|
||||
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.
|
||||
|
@ -57,18 +64,21 @@ Use case: FLUSHING seek
|
|||
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 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
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
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
|
||||
will be rendered immediatly after the seek and the current_position will be
|
||||
the stream_time of the seek that was performed.
|
||||
|
|
179
gst/gstevent.c
179
gst/gstevent.c
|
@ -83,6 +83,7 @@
|
|||
#include "gstevent.h"
|
||||
#include "gstenumtypes.h"
|
||||
#include "gstutils.h"
|
||||
#include "gstquark.h"
|
||||
|
||||
static void gst_event_init (GTypeInstance * instance, gpointer g_class);
|
||||
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,
|
||||
gint64 position)
|
||||
{
|
||||
GstEvent *event;
|
||||
GstStructure *structure;
|
||||
|
||||
g_return_val_if_fail (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)
|
||||
g_return_val_if_fail (start <= stop, NULL);
|
||||
|
||||
return gst_event_new_custom (GST_EVENT_NEWSEGMENT,
|
||||
gst_structure_new ("GstEventNewsegment",
|
||||
"update", G_TYPE_BOOLEAN, update,
|
||||
"rate", G_TYPE_DOUBLE, rate,
|
||||
"applied_rate", G_TYPE_DOUBLE, applied_rate,
|
||||
"format", GST_TYPE_FORMAT, format,
|
||||
"start", G_TYPE_INT64, start,
|
||||
"stop", G_TYPE_INT64, stop,
|
||||
"position", G_TYPE_INT64, position, NULL));
|
||||
structure = gst_structure_empty_new ("GstEventNewsegment");
|
||||
gst_structure_id_set (structure,
|
||||
GST_QUARK (UPDATE), G_TYPE_BOOLEAN, update,
|
||||
GST_QUARK (RATE), G_TYPE_DOUBLE, rate,
|
||||
GST_QUARK (APPLIED_RATE), G_TYPE_DOUBLE, applied_rate,
|
||||
GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
|
||||
GST_QUARK (START), G_TYPE_INT64, start,
|
||||
GST_QUARK (STOP), G_TYPE_INT64, stop,
|
||||
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);
|
||||
if (G_LIKELY (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))
|
||||
*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))
|
||||
*applied_rate =
|
||||
g_value_get_double (gst_structure_get_value (structure,
|
||||
"applied_rate"));
|
||||
g_value_get_double (gst_structure_id_get_value (structure,
|
||||
GST_QUARK (APPLIED_RATE)));
|
||||
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))
|
||||
*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))
|
||||
*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))
|
||||
*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,
|
||||
gint64 maxsize, gboolean async)
|
||||
{
|
||||
GstEvent *event;
|
||||
GstStructure *structure;
|
||||
|
||||
GST_CAT_INFO (GST_CAT_EVENT,
|
||||
"creating buffersize format %s, minsize %" G_GINT64_FORMAT
|
||||
", maxsize %" G_GINT64_FORMAT ", async %d", gst_format_get_name (format),
|
||||
minsize, maxsize, async);
|
||||
|
||||
return gst_event_new_custom (GST_EVENT_BUFFERSIZE,
|
||||
gst_structure_new ("GstEventBufferSize",
|
||||
"format", GST_TYPE_FORMAT, format,
|
||||
"minsize", G_TYPE_INT64, minsize,
|
||||
"maxsize", G_TYPE_INT64, maxsize,
|
||||
"async", G_TYPE_BOOLEAN, async, NULL));
|
||||
structure = gst_structure_empty_new ("GstEventBufferSize");
|
||||
gst_structure_id_set (structure,
|
||||
GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
|
||||
GST_QUARK (MINSIZE), G_TYPE_INT64, minsize,
|
||||
GST_QUARK (MAXSIZE), G_TYPE_INT64, maxsize,
|
||||
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);
|
||||
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)
|
||||
*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)
|
||||
*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)
|
||||
*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,
|
||||
GstClockTime timestamp)
|
||||
{
|
||||
GstEvent *event;
|
||||
GstStructure *structure;
|
||||
|
||||
/* diff must be positive or timestamp + diff must be positive */
|
||||
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,
|
||||
diff, GST_TIME_ARGS (timestamp));
|
||||
|
||||
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));
|
||||
structure = gst_structure_empty_new ("GstEventQOS");
|
||||
gst_structure_id_set (structure,
|
||||
GST_QUARK (PROPORTION), G_TYPE_DOUBLE, proportion,
|
||||
GST_QUARK (DIFF), G_TYPE_INT64, diff,
|
||||
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);
|
||||
if (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)
|
||||
*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)
|
||||
*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.
|
||||
*
|
||||
* @start_type and @stop_type specify how to adjust the currently configured
|
||||
* start and stop fields in @segment. Adjustments can be made relative or
|
||||
* absolute to the last configured values. A type of #GST_SEEK_TYPE_NONE means
|
||||
* that the position should not be updated.
|
||||
* start and stop fields in playback segment. Adjustments can be made relative
|
||||
* or absolute to the last configured values. A type of #GST_SEEK_TYPE_NONE
|
||||
* means that the position should not be updated.
|
||||
*
|
||||
* When the rate is positive and @start has been updated, playback will start
|
||||
* from the newly configured start position.
|
||||
|
@ -863,6 +902,9 @@ GstEvent *
|
|||
gst_event_new_seek (gdouble rate, GstFormat format, GstSeekFlags flags,
|
||||
GstSeekType start_type, gint64 start, GstSeekType stop_type, gint64 stop)
|
||||
{
|
||||
GstEvent *event;
|
||||
GstStructure *structure;
|
||||
|
||||
g_return_val_if_fail (rate != 0.0, NULL);
|
||||
|
||||
if (format == GST_FORMAT_TIME) {
|
||||
|
@ -881,14 +923,18 @@ gst_event_new_seek (gdouble rate, GstFormat format, GstSeekFlags flags,
|
|||
stop);
|
||||
}
|
||||
|
||||
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, start_type,
|
||||
"cur", G_TYPE_INT64, start,
|
||||
"stop_type", GST_TYPE_SEEK_TYPE, stop_type,
|
||||
"stop", G_TYPE_INT64, stop, NULL));
|
||||
structure = gst_structure_empty_new ("GstEventSeek");
|
||||
gst_structure_id_set (structure,
|
||||
GST_QUARK (RATE), G_TYPE_DOUBLE, rate,
|
||||
GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
|
||||
GST_QUARK (FLAGS), GST_TYPE_SEEK_FLAGS, flags,
|
||||
GST_QUARK (CUR_TYPE), GST_TYPE_SEEK_TYPE, start_type,
|
||||
GST_QUARK (CUR), G_TYPE_INT64, start,
|
||||
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);
|
||||
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)
|
||||
*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)
|
||||
*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)
|
||||
*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)
|
||||
*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)
|
||||
*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)
|
||||
*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 *
|
||||
gst_event_new_latency (GstClockTime latency)
|
||||
{
|
||||
GstEvent *event;
|
||||
GstStructure *structure;
|
||||
|
||||
GST_CAT_INFO (GST_CAT_EVENT,
|
||||
"creating latency event %" GST_TIME_FORMAT, GST_TIME_ARGS (latency));
|
||||
|
||||
return gst_event_new_custom (GST_EVENT_LATENCY,
|
||||
gst_structure_new ("GstEventLatency",
|
||||
"latency", G_TYPE_UINT64, latency, NULL));
|
||||
structure = gst_structure_empty_new ("GstEventLatency");
|
||||
gst_structure_id_set (structure,
|
||||
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);
|
||||
if (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",
|
||||
"estimated-total", "old-state", "new-state", "pending-state",
|
||||
"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];
|
||||
|
@ -44,6 +47,10 @@ _priv_gst_quarks_initialize (void)
|
|||
{
|
||||
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++) {
|
||||
_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_TYPE = 34,
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
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,
|
||||
NULL);
|
||||
g_signal_connect (test_bus, "message::application",
|
||||
|
|
Loading…
Reference in a new issue