Clock updates, remove deprecated methods, simplify operations.

Original commit message from CVS:
* gst/gstbin.c: (gst_bin_set_index), (gst_bin_set_clock),
(gst_bin_set_bus), (gst_bin_set_scheduler), (gst_bin_add_func),
(gst_bin_iterate_elements), (gst_bin_change_state),
(gst_bin_get_by_name_recurse_up):
* gst/gstbuffer.c: (gst_buffer_default_copy):
* gst/gstbuffer.h:
* gst/gstclock.c: (gst_clock_init), (gst_clock_get_time),
(gst_clock_set_time_adjust):
* gst/gstclock.h:
* gst/gstelement.h:
* gst/gstevent.h:
* gst/gstinfo.h:
* gst/gstpipeline.c: (is_eos), (pipeline_bus_handler),
(gst_pipeline_change_state):
* gst/gstpipeline.h:
* gst/gstsystemclock.c: (gst_system_clock_wait):
* gst/gstutils.c: (gst_element_finish_preroll),
(gst_element_get_compatible_pad_filtered),
(gst_element_link_pads_filtered), (gst_element_unlink):
* gst/registries/gstxmlregistry.c:
(gst_xml_registry_parse_element_factory),
(gst_xml_registry_end_element):
* libs/gst/dataprotocol/dataprotocol.c:
(gst_dp_header_from_buffer):
Clock updates, remove deprecated methods, simplify operations.
Fix clocking and time management in GstPipeline.
Preroll also occurs when going from playing to paused.
This commit is contained in:
Wim Taymans 2004-12-31 10:44:46 +00:00
parent 6bd0304727
commit af728740a3
15 changed files with 131 additions and 156 deletions

View file

@ -1,3 +1,33 @@
2004-12-31 Wim Taymans <wim@fluendo.com>
* gst/gstbin.c: (gst_bin_set_index), (gst_bin_set_clock),
(gst_bin_set_bus), (gst_bin_set_scheduler), (gst_bin_add_func),
(gst_bin_iterate_elements), (gst_bin_change_state),
(gst_bin_get_by_name_recurse_up):
* gst/gstbuffer.c: (gst_buffer_default_copy):
* gst/gstbuffer.h:
* gst/gstclock.c: (gst_clock_init), (gst_clock_get_time),
(gst_clock_set_time_adjust):
* gst/gstclock.h:
* gst/gstelement.h:
* gst/gstevent.h:
* gst/gstinfo.h:
* gst/gstpipeline.c: (is_eos), (pipeline_bus_handler),
(gst_pipeline_change_state):
* gst/gstpipeline.h:
* gst/gstsystemclock.c: (gst_system_clock_wait):
* gst/gstutils.c: (gst_element_finish_preroll),
(gst_element_get_compatible_pad_filtered),
(gst_element_link_pads_filtered), (gst_element_unlink):
* gst/registries/gstxmlregistry.c:
(gst_xml_registry_parse_element_factory),
(gst_xml_registry_end_element):
* libs/gst/dataprotocol/dataprotocol.c:
(gst_dp_header_from_buffer):
Clock updates, remove deprecated methods, simplify operations.
Fix clocking and time management in GstPipeline.
Preroll also occurs when going from playing to paused.
2004-12-29 Wim Taymans <wim@fluendo.com>
* gst/elements/gstfakesrc.c: (gst_fakesrc_loop),

View file

@ -745,8 +745,8 @@ gst_bin_change_state (GstElement * element)
if (GST_FLAG_IS_SET (qelement, GST_ELEMENT_LOCKED_STATE))
goto next_element;
/* FIXME handle delayed elements like src and loop based
* elements */
qelement->base_time = element->base_time;
ret = gst_element_set_state (qelement, pending);
switch (ret) {
case GST_STATE_SUCCESS:

View file

@ -136,7 +136,7 @@ gst_buffer_default_copy (GstBuffer * buffer)
GST_CAT_LOG (GST_CAT_BUFFER, "copy %p to %p", buffer, copy);
/* copy relevant flags */
flags = GST_DATA_FLAG_SHIFT (GST_BUFFER_KEY_UNIT) |
flags = GST_DATA_FLAG_SHIFT (GST_BUFFER_PREROLL) |
GST_DATA_FLAG_SHIFT (GST_BUFFER_IN_CAPS) |
GST_DATA_FLAG_SHIFT (GST_BUFFER_DELTA_UNIT);
flags = GST_BUFFER_FLAGS (buffer) & flags;

View file

@ -97,7 +97,7 @@ typedef enum {
GST_BUFFER_SUBBUFFER = GST_DATA_FLAG_LAST,
GST_BUFFER_ORIGINAL, /* original data, not copied, not currently used */
GST_BUFFER_DONTFREE, /* buffer data is managed by somebody else and cannot be freeed */
GST_BUFFER_KEY_UNIT, /* sync point in the stream, DEPRECATED, use DELTA_UNIT for non-KEY_UNIT buffers */
GST_BUFFER_PREROLL, /* sample should not be displayed */
GST_BUFFER_DISCONT, /* buffer is first after discontinuity in the stream */
GST_BUFFER_IN_CAPS, /* buffer is also part of caps */
GST_BUFFER_GAP, /* buffer has been created to fill a gap in the stream */

View file

@ -251,6 +251,7 @@ gst_clock_id_wait_async (GstClockID id,
return res;
}
#if 0
static void
gst_clock_reschedule_func (GstClockEntry * entry)
{
@ -258,6 +259,7 @@ gst_clock_reschedule_func (GstClockEntry * entry)
gst_clock_id_unlock ((GstClockID) entry);
}
#endif
/**
* gst_clock_id_unschedule:
@ -396,7 +398,7 @@ gst_clock_class_init (GstClockClass * klass)
static void
gst_clock_init (GstClock * clock)
{
clock->start_time = 0;
clock->adjust = 0;
clock->last_time = 0;
clock->entries = NULL;
clock->flags = 0;
@ -417,42 +419,6 @@ gst_clock_dispose (GObject * object)
G_OBJECT_CLASS (parent_class)->dispose (object);
}
/**
* gst_clock_set_speed
* @clock: a #GstClock to modify
* @speed: the speed to set on the clock
*
* Sets the speed on the given clock. 1.0 is the default
* speed.
*
* Returns: the new speed of the clock.
*/
gdouble
gst_clock_set_speed (GstClock * clock, gdouble speed)
{
g_return_val_if_fail (GST_IS_CLOCK (clock), 0.0);
GST_WARNING_OBJECT (clock, "called deprecated function");
return 1.0;
}
/**
* gst_clock_get_speed
* @clock: a #GstClock to query
*
* Gets the speed of the given clock.
*
* Returns: the speed of the clock.
*/
gdouble
gst_clock_get_speed (GstClock * clock)
{
g_return_val_if_fail (GST_IS_CLOCK (clock), 0.0);
GST_WARNING_OBJECT (clock, "called deprecated function");
return 1.0;
}
/**
* gst_clock_set_resolution
* @clock: The clock set the resolution on
@ -502,72 +468,6 @@ gst_clock_get_resolution (GstClock * clock)
return G_GINT64_CONSTANT (1);
}
/**
* gst_clock_set_active
* @clock: a #GstClock to set state of
* @active: flag indicating if the clock should be activated (TRUE) or deactivated
*
* Activates or deactivates the clock based on the active parameter.
* As soon as the clock is activated, the time will start ticking.
*/
void
gst_clock_set_active (GstClock * clock, gboolean active)
{
g_return_if_fail (GST_IS_CLOCK (clock));
GST_ERROR_OBJECT (clock, "called deprecated function that does nothing now.");
return;
}
/**
* gst_clock_is_active
* @clock: a #GstClock to query
*
* Checks if the given clock is active.
*
* Returns: TRUE if the clock is active.
*/
gboolean
gst_clock_is_active (GstClock * clock)
{
g_return_val_if_fail (GST_IS_CLOCK (clock), FALSE);
GST_WARNING_OBJECT (clock, "called deprecated function.");
return TRUE;
}
/**
* gst_clock_reset
* @clock: a #GstClock to reset
*
* Reset the clock to time 0.
*/
void
gst_clock_reset (GstClock * clock)
{
GstClockTime time = G_GINT64_CONSTANT (0);
GstClockClass *cclass;
g_return_if_fail (GST_IS_CLOCK (clock));
GST_ERROR_OBJECT (clock, "called deprecated function.");
cclass = GST_CLOCK_GET_CLASS (clock);
if (cclass->get_internal_time) {
time = cclass->get_internal_time (clock);
}
GST_LOCK (clock);
//clock->active = FALSE;
clock->start_time = time;
clock->last_time = G_GINT64_CONSTANT (0);
g_list_foreach (clock->entries, (GFunc) gst_clock_reschedule_func, NULL);
GST_UNLOCK (clock);
}
/**
* gst_clock_get_time
* @clock: a #GstClock to query
@ -588,7 +488,7 @@ gst_clock_get_time (GstClock * clock)
cclass = GST_CLOCK_GET_CLASS (clock);
if (cclass->get_internal_time) {
ret = cclass->get_internal_time (clock) - clock->start_time;
ret = cclass->get_internal_time (clock) + clock->adjust;
}
/* make sure the time is increasing, else return last_time */
if ((gint64) ret < (gint64) clock->last_time) {
@ -600,6 +500,25 @@ gst_clock_get_time (GstClock * clock)
return ret;
}
/**
* gst_clock_set_time_adjust
* @clock: a #GstClock to adjust
* @adjust: the adjust value
*
* Adjusts the current time of the clock with the adjust value.
* A positive value moves the clock forwards and a backwards value
* moves it backwards. Note that _get_time() always returns
* increasing values so when you move the clock backwards, _get_time()
* will report the previous value until the clock catches up.
*/
void
gst_clock_set_time_adjust (GstClock * clock, GstClockTime adjust)
{
g_return_if_fail (GST_IS_CLOCK (clock));
clock->adjust = adjust;
}
/**
* gst_clock_get_next_id
* @clock: The clock to query

View file

@ -63,6 +63,14 @@ G_STMT_START { \
(ts).tv_usec = ((t) - (ts).tv_sec * GST_SECOND) / GST_NSECOND; \
} G_STMT_END
/* timestamp debugging macros */
#define GST_TIME_FORMAT "u:%02u:%02u.%09u"
#define GST_TIME_ARGS(t) \
(guint) ((t) / (GST_SECOND * 60 * 60)), \
(guint) (((t) / (GST_SECOND * 60)) % 60), \
(guint) (((t) / GST_SECOND) % 60), \
(guint) ((t) % GST_SECOND)
#define GST_CLOCK_ENTRY_TRACE_NAME "GstClockEntry"
typedef struct _GstClockEntry GstClockEntry;
@ -132,15 +140,15 @@ struct _GstClock {
/*< public >*/
GstClockFlags flags;
/*< protected >*/
GstClockTime start_time;
/*< protected >*/ /* with LOCK */
GstClockTime adjust;
GstClockTime last_time;
/*< private >*/
guint64 resolution;
GList *entries;
GMutex *active_mutex;
GCond *active_cond;
/*< private >*/
guint64 resolution;
gboolean stats;
gpointer _gst_reserved[GST_PADDING];
@ -151,9 +159,6 @@ struct _GstClockClass {
/*< protected >*/
/* vtable */
gdouble (*change_speed) (GstClock *clock,
gdouble oldspeed, gdouble newspeed);
gdouble (*get_speed) (GstClock *clock);
guint64 (*change_resolution) (GstClock *clock, guint64 old_resolution,
guint64 new_resolution);
guint64 (*get_resolution) (GstClock *clock);
@ -172,20 +177,12 @@ struct _GstClockClass {
GType gst_clock_get_type (void);
gdouble gst_clock_set_speed (GstClock *clock, gdouble speed);
gdouble gst_clock_get_speed (GstClock *clock);
guint64 gst_clock_set_resolution (GstClock *clock, guint64 resolution);
guint64 gst_clock_get_resolution (GstClock *clock);
void gst_clock_set_active (GstClock *clock, gboolean active);
gboolean gst_clock_is_active (GstClock *clock);
void gst_clock_reset (GstClock *clock);
gboolean gst_clock_handle_discont (GstClock *clock, guint64 time);
GstClockTime gst_clock_get_time (GstClock *clock);
void gst_clock_set_time_adjust (GstClock *clock, GstClockTime adjust);
GstClockID gst_clock_get_next_id (GstClock *clock);
/* creating IDs that can be used to get notifications */
GstClockID gst_clock_new_single_shot_id (GstClock *clock,
@ -193,6 +190,7 @@ GstClockID gst_clock_new_single_shot_id (GstClock *clock,
GstClockID gst_clock_new_periodic_id (GstClock *clock,
GstClockTime start_time,
GstClockTime interval);
GstClockID gst_clock_get_next_id (GstClock *clock);
/* operations on IDs */
GstClockTime gst_clock_id_get_time (GstClockID id);

View file

@ -434,5 +434,10 @@ GstElement *gst_element_factory_create (GstElementFactory * factory,
GstElement *gst_element_factory_make (const gchar * factoryname,
const gchar * name);
void __gst_element_factory_add_pad_template (GstElementFactory *elementfactory,
GstPadTemplate *templ);
void __gst_element_factory_add_interface (GstElementFactory *elementfactory,
const gchar *interfacename);
G_END_DECLS
#endif /* __GST_ELEMENT_H__ */

View file

@ -38,16 +38,15 @@ typedef enum {
GST_EVENT_UNKNOWN = 0,
GST_EVENT_EOS = 1,
GST_EVENT_FLUSH = 2,
GST_EVENT_CAPS = 3,
GST_EVENT_DISCONTINUOUS = 4,
GST_EVENT_QOS = 5,
GST_EVENT_SEEK = 6,
GST_EVENT_SEEK_SEGMENT = 7,
GST_EVENT_SEGMENT_DONE = 8,
GST_EVENT_SIZE = 9,
GST_EVENT_RATE = 10,
GST_EVENT_NAVIGATION = 11,
GST_EVENT_TAG = 12
GST_EVENT_DISCONTINUOUS = 3,
GST_EVENT_QOS = 4,
GST_EVENT_SEEK = 5,
GST_EVENT_SEEK_SEGMENT = 6,
GST_EVENT_SEGMENT_DONE = 7,
GST_EVENT_SIZE = 8,
GST_EVENT_RATE = 9,
GST_EVENT_NAVIGATION = 10,
GST_EVENT_TAG = 11
} GstEventType;
#define GST_EVENT_TRACE_NAME "GstEvent"

View file

@ -825,15 +825,6 @@ GST_LOG (const char *format, ...)
void gst_debug_print_stack_trace (void);
/* timestamp debugging macros */
/* FIXME 0.9: move into the correct header (gstclock.h) */
#define GST_TIME_FORMAT "u:%02u:%02u.%09u"
#define GST_TIME_ARGS(t) \
(guint) ((t) / (GST_SECOND * 60 * 60)), \
(guint) (((t) / (GST_SECOND * 60)) % 60), \
(guint) (((t) / GST_SECOND) % 60), \
(guint) ((t) % GST_SECOND)
G_END_DECLS
#endif /* __GSTINFO_H__ */

View file

@ -269,8 +269,9 @@ gst_pipeline_change_state (GstElement * element)
{
GstElementStateReturn result = GST_STATE_SUCCESS;
GstPipeline *pipeline = GST_PIPELINE (element);
gint transition = GST_STATE_TRANSITION (element);
switch (GST_STATE_TRANSITION (element)) {
switch (transition) {
case GST_STATE_NULL_TO_READY:
gst_scheduler_setup (GST_ELEMENT_SCHEDULER (pipeline));
break;
@ -280,8 +281,13 @@ gst_pipeline_change_state (GstElement * element)
break;
case GST_STATE_PAUSED_TO_PLAYING:
if (element->clock) {
element->base_time = gst_clock_get_time (element->clock);
/* we set time slightly ahead because of context switches */
pipeline->start_time =
gst_clock_get_time (element->clock) + 10 * GST_MSECOND;
element->base_time = pipeline->start_time - pipeline->stream_time;
}
GST_DEBUG ("stream_time=%" G_GUINT64_FORMAT ", start_time=%"
G_GUINT64_FORMAT, pipeline->stream_time, pipeline->start_time);
break;
case GST_STATE_PLAYING_TO_PAUSED:
case GST_STATE_PAUSED_TO_READY:
@ -291,6 +297,26 @@ gst_pipeline_change_state (GstElement * element)
result = GST_ELEMENT_CLASS (parent_class)->change_state (element);
switch (transition) {
case GST_STATE_READY_TO_PAUSED:
pipeline->stream_time = 0;
break;
case GST_STATE_PAUSED_TO_PLAYING:
break;
case GST_STATE_PLAYING_TO_PAUSED:
if (element->clock) {
pipeline->stream_time = gst_clock_get_time (element->clock) -
element->base_time;
}
GST_DEBUG ("stream_time=%" G_GUINT64_FORMAT ", start_time=%"
G_GUINT64_FORMAT, pipeline->stream_time, pipeline->start_time);
break;
case GST_STATE_PAUSED_TO_READY:
break;
case GST_STATE_READY_TO_NULL:
break;
}
/* we wait for async state changes ourselves */
if (result == GST_STATE_ASYNC) {
GST_STATE_UNLOCK (pipeline);

View file

@ -49,6 +49,8 @@ struct _GstPipeline {
GstBin bin;
GstClock *fixed_clock; /* fixed clock if any */
GstClockTime start_time;
GstClockTime stream_time;
GList *eosed; /* list of elements that posted EOS */

View file

@ -191,19 +191,24 @@ gst_system_clock_wait (GstClock * clock, GstClockEntry * entry)
current = gst_clock_get_time (clock);
diff = GST_CLOCK_ENTRY_TIME (entry) - current;
target = gst_system_clock_get_internal_time (clock) + diff;
target = GST_CLOCK_ENTRY_TIME (entry);
GST_CAT_DEBUG (GST_CAT_CLOCK, "real_target %" G_GUINT64_FORMAT
" target %" G_GUINT64_FORMAT
" now %" G_GUINT64_FORMAT, target, GST_CLOCK_ENTRY_TIME (entry), current);
GST_CAT_DEBUG (GST_CAT_CLOCK, "real_target %" GST_TIME_FORMAT
" target %" GST_TIME_FORMAT
" now %" GST_TIME_FORMAT
" diff %" G_GINT64_FORMAT,
GST_TIME_ARGS (target),
GST_TIME_ARGS (GST_CLOCK_ENTRY_TIME (entry)),
GST_TIME_ARGS (current), diff);
if (((gint64) target) > 0) {
if (diff > 0) {
GTimeVal tv;
GST_TIME_TO_TIMEVAL (target, tv);
g_mutex_lock (sysclock->mutex);
g_cond_timed_wait (sysclock->cond, sysclock->mutex, &tv);
g_mutex_unlock (sysclock->mutex);
res = entry->status;
} else {
res = GST_CLOCK_ENTRY_EARLY;

View file

@ -395,7 +395,7 @@ gst_element_finish_preroll (GstElement * element, GMutex * streamlock)
/* grab state change lock */
GST_STATE_LOCK (element);
/* if we are going to PAUSED, we can commit the state change */
if (GST_STATE_TRANSITION (element) == GST_STATE_READY_TO_PAUSED) {
if (GST_STATE_PENDING (element) == GST_STATE_PAUSED) {
gst_element_commit_state (GST_ELEMENT (element));
}
/* if we are paused we need to wait for playing to continue */

View file

@ -814,7 +814,7 @@ gst_xml_registry_parse_element_factory (GMarkupParseContext * context,
} else if (!strcmp (tag, "interface")) {
gchar *tmp = g_strndup (text, text_len);
//__gst_element_factory_add_interface (factory, tmp);
__gst_element_factory_add_interface (factory, tmp);
g_free (tmp);
}
@ -1040,8 +1040,8 @@ gst_xml_registry_end_element (GMarkupParseContext * context,
xmlregistry->name_template = NULL;
xmlregistry->caps = NULL;
//__gst_element_factory_add_pad_template (GST_ELEMENT_FACTORY
// (xmlregistry->current_feature), template);
__gst_element_factory_add_pad_template (GST_ELEMENT_FACTORY
(xmlregistry->current_feature), template);
xmlregistry->state = GST_XML_REGISTRY_FEATURE;
xmlregistry->parser = gst_xml_registry_parse_element_factory;
}

View file

@ -188,7 +188,7 @@ gst_dp_header_from_buffer (const GstBuffer * buffer, GstDPHeaderFlag flags,
/* data flags */
/* we only copy KEY_UNIT,DELTA_UNIT and IN_CAPS flags */
flags_mask = GST_DATA_FLAG_SHIFT (GST_BUFFER_KEY_UNIT) |
flags_mask = GST_DATA_FLAG_SHIFT (GST_BUFFER_PREROLL) |
GST_DATA_FLAG_SHIFT (GST_BUFFER_IN_CAPS) |
GST_DATA_FLAG_SHIFT (GST_BUFFER_DELTA_UNIT);