// -*- c++ -*-
// Generated by gmmproc 2.42.0 -- DO NOT MODIFY!
#ifndef _GSTREAMERMM_CLOCK_H
#define _GSTREAMERMM_CLOCK_H


#include <glibmm/ustring.h>
#include <sigc++/sigc++.h>

/* gstreamermm - a C++ wrapper for gstreamer
 *
 * Copyright 2008 The gstreamermm Development Team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <gst/gst.h>
#include <gstreamermm/object.h>
#include <gstreamermmconfig.h>


#ifndef DOXYGEN_SHOULD_SKIP_THIS
typedef struct _GstClock GstClock;
typedef struct _GstClockClass GstClockClass;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


namespace Gst
{ class Clock_Class; } // namespace Gst
namespace Gst
{

class Clock;

/** A data type to hold a time, measured in nanoseconds.
 */
typedef GstClockTime ClockTime;

/** A data type to hold a timedifference, measured in nanoseconds.
 */
typedef GstClockTimeDiff ClockTimeDiff;

/** A constant to define an undefined clock time.
 */
extern GSTREAMERMM_API const ClockTime CLOCK_TIME_NONE;

/** A constant that defines one GStreamer second.
 */
extern GSTREAMERMM_API const ClockTime SECOND;

/** A constant that defines one GStreamer millisecond.
 */
extern GSTREAMERMM_API const ClockTime MILLI_SECOND;

/** A constant that defines one GStreamer microsecond.
 */
extern GSTREAMERMM_API const ClockTime MICRO_SECOND;

/** A constant that defines one GStreamer nanosecond.
 */
extern GSTREAMERMM_API const ClockTime NANO_SECOND;

/** @addtogroup gstreamermmEnums gstreamermm Enums and Flags */

/** 
 *  @var ClockEntryType CLOCK_ENTRY_SINGLE
 *  A single shot timeout.
 * 
 *  @var ClockEntryType CLOCK_ENTRY_PERIODIC
 *  A periodic timeout request.
 * 
 *  @enum ClockEntryType
 * 
 * The type of the clock entry
 * @ingroup gstreamermmEnums
 */
enum ClockEntryType
{
  CLOCK_ENTRY_SINGLE,
  CLOCK_ENTRY_PERIODIC
};

} // namespace Gst


#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

template <>
class Value<Gst::ClockEntryType> : public Glib::Value_Enum<Gst::ClockEntryType>
{
public:
  static GType value_type() G_GNUC_CONST;
};

} // namespace Glib
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


namespace Gst
{

/** 
 *  @var ClockReturn CLOCK_OK
 *  The operation succeeded.
 * 
 *  @var ClockReturn CLOCK_EARLY
 *  The operation was scheduled too late.
 * 
 *  @var ClockReturn CLOCK_UNSCHEDULED
 *  The clockID was unscheduled.
 * 
 *  @var ClockReturn CLOCK_BUSY
 *  The ClockID is busy.
 * 
 *  @var ClockReturn CLOCK_BADTIME
 *  A bad time was provided to a function.
 * 
 *  @var ClockReturn CLOCK_ERROR
 *  An error occurred.
 * 
 *  @var ClockReturn CLOCK_UNSUPPORTED
 *  Operation is not supported.
 * 
 *  @var ClockReturn CLOCK_DONE
 *  The ClockID is done waiting.
 * 
 *  @enum ClockReturn
 * 
 * The return value of a clock operation.
 * @ingroup gstreamermmEnums
 */
enum ClockReturn
{
  CLOCK_OK,
  CLOCK_EARLY,
  CLOCK_UNSCHEDULED,
  CLOCK_BUSY,
  CLOCK_BADTIME,
  CLOCK_ERROR,
  CLOCK_UNSUPPORTED,
  CLOCK_DONE
};

} // namespace Gst


#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

template <>
class Value<Gst::ClockReturn> : public Glib::Value_Enum<Gst::ClockReturn>
{
public:
  static GType value_type() G_GNUC_CONST;
};

} // namespace Glib
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


namespace Gst
{

/** 
 *  @var ClockFlags CLOCK_FLAG_CAN_DO_SINGLE_SYNC
 *  Clock can do a single sync timeout request.
 * 
 *  @var ClockFlags CLOCK_FLAG_CAN_DO_SINGLE_ASYNC
 *  Clock can do a single async timeout request.
 * 
 *  @var ClockFlags CLOCK_FLAG_CAN_DO_PERIODIC_SYNC
 *  Clock can do sync periodic timeout requests.
 * 
 *  @var ClockFlags CLOCK_FLAG_CAN_DO_PERIODIC_ASYNC
 *  Clock can do async periodic timeout callbacks.
 * 
 *  @var ClockFlags CLOCK_FLAG_CAN_SET_RESOLUTION
 *  Clock's resolution can be changed.
 * 
 *  @var ClockFlags CLOCK_FLAG_CAN_SET_MASTER
 *  Clock can be slaved to a master clock.
 * 
 *  @var ClockFlags CLOCK_FLAG_LAST
 *  Subclasses can add additional flags starting from this flag.
 * 
 *  @enum ClockFlags
 * 
 * The capabilities of this clock
 * @ingroup gstreamermmEnums
 * @par Bitwise operators:
 * <tt>%ClockFlags operator|(ClockFlags, ClockFlags)</tt><br>
 * <tt>%ClockFlags operator&(ClockFlags, ClockFlags)</tt><br>
 * <tt>%ClockFlags operator^(ClockFlags, ClockFlags)</tt><br>
 * <tt>%ClockFlags operator~(ClockFlags)</tt><br>
 * <tt>%ClockFlags& operator|=(ClockFlags&, ClockFlags)</tt><br>
 * <tt>%ClockFlags& operator&=(ClockFlags&, ClockFlags)</tt><br>
 * <tt>%ClockFlags& operator^=(ClockFlags&, ClockFlags)</tt><br>
 */
enum ClockFlags
{
  CLOCK_FLAG_CAN_DO_SINGLE_SYNC = (GST_OBJECT_FLAG_LAST << 0),
  CLOCK_FLAG_CAN_DO_SINGLE_ASYNC = (GST_OBJECT_FLAG_LAST << 1),
  CLOCK_FLAG_CAN_DO_PERIODIC_SYNC = (GST_OBJECT_FLAG_LAST << 2),
  CLOCK_FLAG_CAN_DO_PERIODIC_ASYNC = (GST_OBJECT_FLAG_LAST << 3),
  CLOCK_FLAG_CAN_SET_RESOLUTION = (GST_OBJECT_FLAG_LAST << 4),
  CLOCK_FLAG_CAN_SET_MASTER = (GST_OBJECT_FLAG_LAST << 5),
  CLOCK_FLAG_LAST = (GST_OBJECT_FLAG_LAST << 8)
};

/** @ingroup gstreamermmEnums */
inline ClockFlags operator|(ClockFlags lhs, ClockFlags rhs)
  { return static_cast<ClockFlags>(static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs)); }

/** @ingroup gstreamermmEnums */
inline ClockFlags operator&(ClockFlags lhs, ClockFlags rhs)
  { return static_cast<ClockFlags>(static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs)); }

/** @ingroup gstreamermmEnums */
inline ClockFlags operator^(ClockFlags lhs, ClockFlags rhs)
  { return static_cast<ClockFlags>(static_cast<unsigned>(lhs) ^ static_cast<unsigned>(rhs)); }

/** @ingroup gstreamermmEnums */
inline ClockFlags operator~(ClockFlags flags)
  { return static_cast<ClockFlags>(~static_cast<unsigned>(flags)); }

/** @ingroup gstreamermmEnums */
inline ClockFlags& operator|=(ClockFlags& lhs, ClockFlags rhs)
  { return (lhs = static_cast<ClockFlags>(static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs))); }

/** @ingroup gstreamermmEnums */
inline ClockFlags& operator&=(ClockFlags& lhs, ClockFlags rhs)
  { return (lhs = static_cast<ClockFlags>(static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs))); }

/** @ingroup gstreamermmEnums */
inline ClockFlags& operator^=(ClockFlags& lhs, ClockFlags rhs)
  { return (lhs = static_cast<ClockFlags>(static_cast<unsigned>(lhs) ^ static_cast<unsigned>(rhs))); }

} // namespace Gst


#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

template <>
class Value<Gst::ClockFlags> : public Glib::Value_Flags<Gst::ClockFlags>
{
public:
  static GType value_type() G_GNUC_CONST;
};

} // namespace Glib
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


namespace Gst
{


/** A data type to hold the handle to an outstanding sync or async clock
 * callback.
 */
class ClockID
{
  public:
#ifndef DOXYGEN_SHOULD_SKIP_THIS
  typedef ClockID CppObjectType;
  typedef GstClockEntry BaseObjectType;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


  /** Increment the reference count for this object.
   * You should never need to do this manually - use the object via a RefPtr instead.
   */
  void reference()   const;

  /** Decrement the reference count for this object.
   * You should never need to do this manually - use the object via a RefPtr instead.
   */
  void unreference() const;

  ///Provides access to the underlying C instance.
  GstClockEntry*       gobj();

  ///Provides access to the underlying C instance.
  const GstClockEntry* gobj() const;

  ///Provides access to the underlying C instance. The caller is responsible for unrefing it. Use when directly setting fields in structs.
  GstClockEntry* gobj_copy() const;

protected:
  // Do not derive this.  Gst::ClockID can neither be constructed nor deleted.
  ClockID();
  void operator delete(void*, std::size_t);

private:
  // noncopyable
  ClockID(const ClockID&);
  ClockID& operator=(const ClockID&);


public:
  /** For example,
   * bool on_clock(const Glib::RefPtr<Gst::Clock>& clock, ClockTime time, const
   * Glib::RefPtr<Gst::ClockID>& id);.
   * The clock function return value is currently unused (see GstClockCallback).
   */
  typedef sigc::slot< bool, const Glib::RefPtr<Gst::Clock>&, ClockTime, const Glib::RefPtr<Gst::ClockID>& > SlotClock;

  
  /** Get the time of the clock ID
   * 
   * @return The time of the given clock id.
   * 
   * MT safe.
   */
  ClockTime get_time() const;
  
  /** Perform a blocking wait on the Gst::ClockID. 
   * The Gst::ClockID should have been created with
   * Gst::Clock::create_single_shot_id() or Gst::Clock::create_periodic_id()
   * and should not have been unscheduled with a call to unschedule(). 
   * 
   * If this function returns Gst::CLOCK_OK or Gst::CLOCK_EARLY,
   * the @a jitter argument will contain the difference
   * against the clock and the time of the Gst::ClockID when this method was
   * called.
   * Positive values indicate how late the Gst::ClockID was relative to the clock
   * (in which case this function will return Gst::CLOCK_EARLY). 
   * Negative values indicate how much time was spent waiting on the clock 
   * before this function returned.
   * 
   * @param jitter A pointer that will contain the jitter.
   * @return The result of the blocking wait. Gst::CLOCK_EARLY will be returned
   * if the current clock time is past the time of the Gst::ClockID, Gst::CLOCK_OK
   * if Gst::ClockID was scheduled in time. Gst::CLOCK_UNSCHEDULED if Gst::ClockID
   * was unscheduled with unschedule().
   * 
   * MT safe.
   */
  ClockReturn wait(ClockTimeDiff& jitter);

  /** Perform a blocking wait without requiring a jitter argument.
   * Gst::ClockID should have been created with
   * Gst::Clock::create_single_shot_id() or Gst::Clock::create_periodic_id()
   * and should not have been unscheduled with a call to unschedule().
   * @return The result of the blocking wait. Gst::CLOCK_EARLY will be returned
   * if the current clock time is past the time of Gst::ClockID, Gst::CLOCK_OK
   * if Gst::ClockID was scheduled in time. Gst::CLOCK_UNSCHEDULED if
   * Gst::ClockID was unscheduled with unschedule().
   */
  ClockReturn wait();

  /** Register a slot on the given Gst::ClockID id with the given slot. When
   * passing a Gst::ClockID with an invalid time to this function, the slot
   * will be called immediatly with a time set to Gst::CLOCK_TIME_NONE. The
   * slot will be called when the time of id has been reached.
   *
   * @param slot The slot to callback.
   * @return The result of the non blocking wait. MT safe. 
   */
  ClockReturn wait_async(const SlotClock& slot);
  

  /** Cancel an outstanding request with @a id. This can either
   * be an outstanding async notification or a pending sync notification.
   * After this call, @a id cannot be used anymore to receive sync or
   * async notifications, you need to create a new Gst::ClockID.
   * 
   * MT safe.
   * 
   */
  void unschedule();


};

/** Gets the hour component of Gst::ClockTime.
 * @param time The Gst::ClockTime to parse.
 * @return The hour component of the Gst::ClockTime.
 */
guint get_hours(ClockTime time);

/** Gets the minute component of Gst::ClockTime.
 * @param time The Gst::ClockTime to parse.
 * @return The minute component of the Gst::ClockTime.
 */
guint get_minutes(ClockTime time);

/** Gets the seconds component of Gst::ClockTime.
 * @param time The Gst::ClockTime to parse.
 * @return The seconds component of the Gst::ClockTime.
 */
guint get_seconds(ClockTime time);

/** Gets the milliseconds component of Gst::ClockTime.
 * @param time The Gst::ClockTime to parse.
 * @return The milliseconds component of the Gst::ClockTime.
 */
guint get_milliseconds(ClockTime time);

/** Gets the microseconds component of Gst::ClockTime.
 * @param time The Gst::ClockTime to parse.
 * @return The microseconds component of the Gst::ClockTime.
 */
guint get_microseconds(ClockTime time);

/** Gets the nanoseconds component of Gst::ClockTime.
 * @param time The Gst::ClockTime to parse.
 * @return The nanoseconds component of the Gst::ClockTime.
 */
guint get_nanoseconds(ClockTime time);

/** Gets the fractional component (milli, micro and nano seconds) of
 * Gst::ClockTime.
 * @param time The Gst::ClockTime to parse.
 * @return The fractional component of the Gst::ClockTime.
 */
guint get_fractional_seconds(ClockTime time);

/** An abstract class for global clocks.
 * GStreamer uses a global clock to synchronize the plugins in a pipeline.
 * Different clock implementations are possible by implementing this abstract
 * base class.
 *
 * The Gst::Clock returns a monotonically increasing time with the method
 * get_time(). Its accuracy and base time depend on the specific clock
 * implementation but time is always expressed in nanoseconds. Since the
 * baseline of the clock is undefined, the clock time returned is not
 * meaningful in itself, what matters are the deltas between two clock times.
 * The time returned by a clock is called the absolute time.
 *
 * The pipeline uses the clock to calculate the stream time. Usually all
 * renderers synchronize to the global clock using the buffer timestamps, the
 * newsegment events and the element's base time, see Gst::Pipeline.
 *
 * A clock implementation can support periodic and single shot clock
 * notifications both synchronous and asynchronous.
 *
 * One first needs to create a Gst::ClockID for the periodic or single shot
 * notification using create_single_shot_id() or create_periodic_id().
 *
 * To perform a blocking wait for the specific time of the Gst::ClockID use the
 * Gst::ClockID::wait() method. To receive a callback when the specific time is
 * reached in the clock use Gst::ClockID::wait_async(). Both these calls can be
 * interrupted with the Gst::ClockID::unschedule() call. If the blocking wait
 * is unscheduled a return value of Gst::CLOCK_UNSCHEDULED is returned.
 *
 * Periodic callbacks scheduled async will be repeadedly called automatically
 * until it is unscheduled. To schedule a sync periodic callback,
 * Gst::ClockID::wait() should be called repeadedly.
 *
 * The async callbacks can happen from any thread, either provided by the core
 * or from a streaming thread. The application should be prepared for this.
 *
 * A Gst::ClockID that has been unscheduled cannot be used again for any wait
 * operation, a new Gst::ClockID should be created.
 *
 * It is possible to perform a blocking wait on the same ClockID from multiple
 * threads. However, registering the same ClockID for multiple async
 * notifications is not possible, the slot will only be called for the thread
 * registering the entry last.
 *
 * None of the wait operations unref the Gst::ClockID, the owner is responsible
 * for unreffing the ids itself. This holds for both periodic and single shot
 * notifications. The reason being that the owner of the Gst::ClockID has to
 * keep a handle to the Gst::ClockID to unblock the wait on FLUSHING events or
 * state changes and if the entry would be unreffed automatically, the handle
 * might become invalid without any notification. (The RefPtr takes care of
 * unreffing in this case)
 *
 * These clock operations do not operate on the stream time, so the callbacks
 * will also occur when not in PLAYING state as if the clock just keeps on
 * running. Some clocks however do not progress when the element that provided
 * the clock is not PLAYING.
 *
 * When a clock has the Gst::CLOCK_FLAG_CAN_SET_MASTER flag set, it can be
 * slaved to another Gst::Clock with the set_master() method. The clock will
 * then automatically be synchronized to this master clock by repeadedly
 * sampling the master clock and the slave clock and recalibrating the slave
 * clock with set_calibration(). This feature is mostly useful for plugins that
 * have an internal clock but must operate with another clock selected by the
 * Gst::Pipeline.  They can track the offset and rate difference of their
 * internal clock relative to the master clock by using the get_calibration()
 * method.
 *
 * The master/slave synchronisation can be tuned with the "timeout",
 * "window-size" and "window-threshold" properties. The "timeout" property
 * defines the interval to sample the master clock and run the calibration
 * functions. "window-size" defines the number of samples to use when
 * calibrating and "window-threshold" defines the minimum number of samples
 * before the calibration is performed.
 *
 * Last reviewed on 2006-08-11 (0.10.10)
 */

class Clock : public Object
{
  
#ifndef DOXYGEN_SHOULD_SKIP_THIS

public:
  typedef Clock CppObjectType;
  typedef Clock_Class CppClassType;
  typedef GstClock BaseObjectType;
  typedef GstClockClass BaseClassType;

private:  friend class Clock_Class;
  static CppClassType clock_class_;

private:
  // noncopyable
  Clock(const Clock&);
  Clock& operator=(const Clock&);

protected:
  explicit Clock(const Glib::ConstructParams& construct_params);
  explicit Clock(GstClock* castitem);

#endif /* DOXYGEN_SHOULD_SKIP_THIS */

public:
  virtual ~Clock();

  /** Get the GType for this class, for use with the underlying GObject type system.
   */
  static GType get_type()      G_GNUC_CONST;

#ifndef DOXYGEN_SHOULD_SKIP_THIS


  static GType get_base_type() G_GNUC_CONST;
#endif

  ///Provides access to the underlying C GObject.
  GstClock*       gobj()       { return reinterpret_cast<GstClock*>(gobject_); }

  ///Provides access to the underlying C GObject.
  const GstClock* gobj() const { return reinterpret_cast<GstClock*>(gobject_); }

  ///Provides access to the underlying C instance. The caller is responsible for unrefing it. Use when directly setting fields in structs.
  GstClock* gobj_copy();

private:


public:
  
  /** The time @a master of the master clock and the time @a slave of the slave
   * clock are added to the list of observations. If enough observations
   * are available, a linear regression algorithm is run on the
   * observations and @a clock is recalibrated.
   * 
   * If this functions returns <tt>true</tt>, @a r_squared will contain the 
   * correlation coefficient of the interpolation. A value of 1.0
   * means a perfect regression was performed. This value can
   * be used to control the sampling frequency of the master and slave
   * clocks.
   * 
   * @param slave A time on the slave.
   * @param master A time on the master.
   * @param r_squared A pointer to hold the result.
   * @return <tt>true</tt> if enough observations were added to run the 
   * regression algorithm.
   * 
   * MT safe.
   */
  bool add_observation(ClockTime slave_time, ClockTime master_time, gdouble* result);
  
  /** Set @a master as the master clock for @a clock. @a clock will be automatically
   * calibrated so that get_time() reports the same time as the
   * master clock.  
   * 
   * A clock provider that slaves its clock to a master can get the current
   * calibration values with get_calibration().
   * 
   *  @a master can be <tt>0</tt> in which case @a clock will not be slaved anymore. It will
   * however keep reporting its time adjusted with the last configured rate 
   * and time offsets.
   * 
   * @param master A master Gst::Clock.
   * @return <tt>true</tt> if the clock is capable of being slaved to a master clock. 
   * Trying to set a master on a clock without the 
   * Gst::CLOCK_FLAG_CAN_SET_MASTER flag will make this function return <tt>false</tt>.
   * 
   * MT safe.
   */
  bool set_master(const Clock& master_clock);
  
  /** Get the master clock that @a clock is slaved to or <tt>0</tt> when the clock is
   * not slaved to any master clock.
   * 
   * @return A master Gst::Clock or <tt>0</tt> when this clock is
   * not slaved to a master clock. Unref after usage.
   * 
   * MT safe.
   */
  Glib::RefPtr<Gst::Clock> get_master();
  
  /** Get the master clock that @a clock is slaved to or <tt>0</tt> when the clock is
   * not slaved to any master clock.
   * 
   * @return A master Gst::Clock or <tt>0</tt> when this clock is
   * not slaved to a master clock. Unref after usage.
   * 
   * MT safe.
   */
  Glib::RefPtr<const Gst::Clock> get_master() const;
  
  /** Set the accuracy of the clock. Some clocks have the possibility to operate
   * with different accuracy at the expense of more resource usage. There is
   * normally no need to change the default resolution of a clock. The resolution
   * of a clock can only be changed if the clock has the
   * Gst::CLOCK_FLAG_CAN_SET_RESOLUTION flag set.
   * 
   * @param resolution The resolution to set.
   * @return The new resolution of the clock.
   */
  ClockTime set_resolution(ClockTime resolution);
  
  /** Get the accuracy of the clock. The accuracy of the clock is the granularity
   * of the values returned by get_time().
   * 
   * @return The resolution of the clock in units of Gst::ClockTime.
   * 
   * MT safe.
   */
  ClockTime get_resolution() const;
  
  /** Gets the current time of the given clock. The time is always
   * monotonically increasing and adjusted according to the current
   * offset and rate.
   * 
   * @return The time of the clock. Or GST_CLOCK_TIME_NONE when
   * given invalid input.
   * 
   * MT safe.
   */
  ClockTime get_time() const;
  
  /** Get a Gst::ClockID from @a clock to trigger a single shot
   * notification at the requested time. The single shot id should be
   * unreffed after usage.
   * 
   * Free-function: gst_clock_id_unref
   * 
   * @param time The requested time.
   * @return A Gst::ClockID that can be used to request the
   * time notification.
   * 
   * MT safe.
   */
  Glib::RefPtr<Gst::ClockID> create_single_shot_id(ClockTime time);
  
  /** Get an ID from @a clock to trigger a periodic notification.
   * The periodic notifications will start at time @a start_time and
   * will then be fired with the given @a interval. @a id should be unreffed
   * after usage.
   * 
   * Free-function: gst_clock_id_unref
   * 
   * @param start_time The requested start time.
   * @param interval The requested interval.
   * @return A Gst::ClockID that can be used to request the
   * time notification.
   * 
   * MT safe.
   */
  Glib::RefPtr<Gst::ClockID> create_periodic_id(ClockTime start_time, ClockTime intervals);
  
  /** Gets the current internal time of the given clock. The time is returned
   * unadjusted for the offset and the rate.
   * 
   * @return The internal time of the clock. Or GST_CLOCK_TIME_NONE when
   * given invalid input.
   * 
   * MT safe.
   */
  ClockTime get_internal_time() const;
  
  /** Converts the given @a internal clock time to the external time, adjusting for the
   * rate and reference time set with set_calibration() and making sure
   * that the returned time is increasing. This function should be called with the
   * clock's OBJECT_LOCK held and is mainly used by clock subclasses.
   * 
   * This function is the reverse of unadjust_unlocked().
   * 
   * @param internal A clock time.
   * @return The converted time of the clock.
   */
  ClockTime adjust_unlocked(ClockTime internal_time);
  
  /** Converts the given @a external clock time to the internal time of @a clock,
   * using the rate and reference time set with set_calibration().
   * This function should be called with the clock's OBJECT_LOCK held and
   * is mainly used by clock subclasses.
   * 
   * This function is the reverse of adjust_unlocked().
   * 
   * @param external An external clock time.
   * @return The internal time of the clock corresponding to @a external.
   */
  ClockTime unadjust_unlocked(ClockTime external_time);
  
  /** Gets the internal rate and reference time of @a clock. See
   * set_calibration() for more information.
   * 
   *  @a internal, @a external, @a rate_num, and @a rate_denom can be left <tt>0</tt> if the
   * caller is not interested in the values.
   * 
   * MT safe.
   * 
   * @param internal A location to store the internal time.
   * @param external A location to store the external time.
   * @param rate_num A location to store the rate numerator.
   * @param rate_denom A location to store the rate denominator.
   */
  void get_calibration(ClockTime& internal, ClockTime& external, ClockTime& rate_num, ClockTime& rate_denom) const;
  
  /** Adjusts the rate and time of @a clock. A rate of 1/1 is the normal speed of
   * the clock. Values bigger than 1/1 make the clock go faster.
   * 
   *  @a internal and @a external are calibration parameters that arrange that
   * get_time() should have been @a external at internal time @a internal.
   * This internal time should not be in the future; that is, it should be less
   * than the value of get_internal_time() when this function is called.
   * 
   * Subsequent calls to get_time() will return clock times computed as
   * follows:
   * 
   * 
   * time = (internal_time - internal) * rate_num / rate_denom + external
   * 
   * 
   * This formula is implemented in adjust_unlocked(). Of course, it
   * tries to do the integer arithmetic as precisely as possible.
   * 
   * 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.
   * 
   * MT safe.
   * 
   * @param internal A reference internal time.
   * @param external A reference external time.
   * @param rate_num The numerator of the rate of the clock relative to its
   * internal time.
   * @param rate_denom The denominator of the rate of the clock.
   */
  void set_calibration(ClockTime internal, ClockTime external, ClockTime rate_num, ClockTime rate_denom);
  
  #ifdef GLIBMM_PROPERTIES_ENABLED
/** The amount of time, in nanoseconds, to sample master and slave clocks.
   *
   * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
   * @return A PropertyProxy that allows you to get or set the value of the property,
   * or receive notification when the value of the property changes.
   */
  Glib::PropertyProxy< guint64 > property_timeout() ;
#endif //#GLIBMM_PROPERTIES_ENABLED

#ifdef GLIBMM_PROPERTIES_ENABLED
/** The amount of time, in nanoseconds, to sample master and slave clocks.
   *
   * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
   * @return A PropertyProxy_ReadOnly that allows you to get the value of the property,
   * or receive notification when the value of the property changes.
   */
  Glib::PropertyProxy_ReadOnly< guint64 > property_timeout() const;
#endif //#GLIBMM_PROPERTIES_ENABLED

  #ifdef GLIBMM_PROPERTIES_ENABLED
/** The size of the window used to calculate rate and offset.
   *
   * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
   * @return A PropertyProxy that allows you to get or set the value of the property,
   * or receive notification when the value of the property changes.
   */
  Glib::PropertyProxy< int > property_window_size() ;
#endif //#GLIBMM_PROPERTIES_ENABLED

#ifdef GLIBMM_PROPERTIES_ENABLED
/** The size of the window used to calculate rate and offset.
   *
   * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
   * @return A PropertyProxy_ReadOnly that allows you to get the value of the property,
   * or receive notification when the value of the property changes.
   */
  Glib::PropertyProxy_ReadOnly< int > property_window_size() const;
#endif //#GLIBMM_PROPERTIES_ENABLED

  #ifdef GLIBMM_PROPERTIES_ENABLED
/** The threshold to start calculating rate and offset.
   *
   * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
   * @return A PropertyProxy that allows you to get or set the value of the property,
   * or receive notification when the value of the property changes.
   */
  Glib::PropertyProxy< int > property_window_threshold() ;
#endif //#GLIBMM_PROPERTIES_ENABLED

#ifdef GLIBMM_PROPERTIES_ENABLED
/** The threshold to start calculating rate and offset.
   *
   * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
   * @return A PropertyProxy_ReadOnly that allows you to get the value of the property,
   * or receive notification when the value of the property changes.
   */
  Glib::PropertyProxy_ReadOnly< int > property_window_threshold() const;
#endif //#GLIBMM_PROPERTIES_ENABLED


  /** Change the resolution of the clock. Not all values might be acceptable.
   * The new resolution should be returned.
   */
    virtual ClockTime change_resolution_vfunc(ClockTime old_resolution, ClockTime new_resolution);


  /** Get the resolution of the clock.
   */
    virtual ClockTime get_resolution_vfunc() const;


  /** Get the internal unadjusted time of the clock.
   */
    virtual ClockTime get_internal_time_vfunc() const;


  /** Perform a blocking wait for the given Gst::ClockID. Deprecated,
   * implement wait_jitter_vfunc() instead.
   */
    virtual ClockReturn wait_vfunc(const Glib::RefPtr<Gst::ClockID>& id, ClockTimeDiff& jitter);


  /** Perform an asynchronous wait for the given Gst::ClockID.
   */
    virtual ClockReturn wait_async_vfunc(const Glib::RefPtr<Gst::ClockID>& id);


  /** Unblock a blocking or async wait operation.
   */
    virtual void unschedule_vfunc(const Glib::RefPtr<Gst::ClockID>& id);


public:

public:
  //C++ methods used to invoke GTK+ virtual functions:

protected:
  //GTK+ Virtual Functions (override these to change behaviour):

  //Default Signal Handlers::


};

} //namespace Gst


namespace Glib
{

  /** A Glib::wrap() method for this object.
   * 
   * @param object The C instance.
   * @param take_copy False if the result should take ownership of the C instance. True if it should take a new copy or ref.
   * @result A C++ instance that wraps this C instance.
   *
   * @relates Gst::ClockID
   */
  Glib::RefPtr<Gst::ClockID> wrap(GstClockEntry* object, bool take_copy = false);

} // namespace Glib


namespace Glib
{
  /** A Glib::wrap() method for this object.
   * 
   * @param object The C instance.
   * @param take_copy False if the result should take ownership of the C instance. True if it should take a new copy or ref.
   * @result A C++ instance that wraps this C instance.
   *
   * @relates Gst::Clock
   */
  Glib::RefPtr<Gst::Clock> wrap(GstClock* object, bool take_copy = false);
}


#endif /* _GSTREAMERMM_CLOCK_H */

