// -*- c++ -*-
// Generated by gmmproc 2.42.0 -- DO NOT MODIFY!
#ifndef _GSTREAMERMM_SEGMENT_H
#define _GSTREAMERMM_SEGMENT_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 <gstreamermm/clock.h>
#include <gstreamermm/format.h>


#ifndef DOXYGEN_SHOULD_SKIP_THIS
extern "C" { typedef struct _GstSegment GstSegment; }
#endif

namespace Gst
{

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

/** 
 *  @var SeekFlags SEEK_FLAG_NONE
 *  No flag.
 * 
 *  @var SeekFlags SEEK_FLAG_FLUSH
 *  Flush pipeline.
 * 
 *  @var SeekFlags SEEK_FLAG_ACCURATE
 *  Accurate position is requested, this might be considerably slower for some formats.
 * 
 *  @var SeekFlags SEEK_FLAG_KEY_UNIT
 *  Seek to the nearest keyframe. This might be faster but less accurate.
 * 
 *  @var SeekFlags SEEK_FLAG_SEGMENT
 *  Perform a segment seek.
 * 
 *  @var SeekFlags SEEK_FLAG_SKIP
 *  When doing fast foward or fast reverse playback, allow elements to skip frames instead of generating all frames.
 * 
 *  @var SeekFlags SEEK_FLAG_SNAP_BEFORE
 *  Go to a location before the requested position, if KEY_UNIT this means the keyframe at or before the requested position the one at or before the seek target.
 * 
 *  @var SeekFlags SEEK_FLAG_SNAP_AFTER
 *  Go to a location after the requested position, if KEY_UNIT this means the keyframe at of after the requested position.
 * 
 *  @var SeekFlags SEEK_FLAG_SNAP_NEAREST
 *  Go to a position near the requested position, if KEY_UNIT this means the keyframe closest to the requested position, if both keyframes are at an equal distance, behaves like SNAP_BEFORE.
 * 
 *  @enum SeekFlags
 * 
 * Flags to be used with Gst::Element::seek() or gst_event_new_seek(). All flags
 * can be used together.
 * 
 * A non flushing seek might take some time to perform as the currently
 * playing data in the pipeline will not be cleared.
 * 
 * An accurate seek might be slower for formats that don't have any indexes
 * or timestamp markers in the stream. Specifying this flag might require a
 * complete scan of the file in those cases.
 * 
 * When performing a segment seek: after the playback of the segment completes,
 * no EOS will be emmited by the element that performed the seek, but a
 * Gst::MESSAGE_SEGMENT_DONE message will be posted on the bus by the element.
 * When this message is posted, it is possible to send a new seek event to
 * continue playback. With this seek method it is possible to perform seamless
 * looping or simple linear editing.
 * 
 * When doing fast forward (rate > 1.0) or fast reverse (rate < -1.0) trickmode
 * playback, the @a GST_SEEK_FLAG_SKIP flag can be used to instruct decoders
 * and demuxers to adjust the playback rate by skipping frames. This can improve
 * performance and decrease CPU usage because not all frames need to be decoded.
 * 
 * The @a GST_SEEK_FLAG_SNAP_BEFORE flag can be used to snap to the previous
 * relevant location, and the @a GST_SEEK_FLAG_SNAP_AFTER flag can be used to
 * select the next relevant location. If KEY_UNIT is specified, the relevant
 * location is a keyframe. If both flags are specified, the nearest of these
 * locations will be selected. If none are specified, the implementation is
 * free to select whichever it wants.
 * The before and after here are in running time, so when playing backwards,
 * the next location refers to the one that will played in next, and not the
 * one that is located after in the actual source stream.
 * 
 * Also see part-seeking.txt in the GStreamer design documentation for more
 * details on the meaning of these flags and the behaviour expected of
 * elements that handle them.
 * @ingroup gstreamermmEnums
 * @par Bitwise operators:
 * <tt>%SeekFlags operator|(SeekFlags, SeekFlags)</tt><br>
 * <tt>%SeekFlags operator&(SeekFlags, SeekFlags)</tt><br>
 * <tt>%SeekFlags operator^(SeekFlags, SeekFlags)</tt><br>
 * <tt>%SeekFlags operator~(SeekFlags)</tt><br>
 * <tt>%SeekFlags& operator|=(SeekFlags&, SeekFlags)</tt><br>
 * <tt>%SeekFlags& operator&=(SeekFlags&, SeekFlags)</tt><br>
 * <tt>%SeekFlags& operator^=(SeekFlags&, SeekFlags)</tt><br>
 */
enum SeekFlags
{
  SEEK_FLAG_NONE = 0x0,
  SEEK_FLAG_FLUSH = (1 << 0),
  SEEK_FLAG_ACCURATE = (1 << 1),
  SEEK_FLAG_KEY_UNIT = (1 << 2),
  SEEK_FLAG_SEGMENT = (1 << 3),
  SEEK_FLAG_SKIP = (1 << 4),
  SEEK_FLAG_SNAP_BEFORE = (1 << 5),
  SEEK_FLAG_SNAP_AFTER = (1 << 6),
  SEEK_FLAG_SNAP_NEAREST = 0x60
};

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

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

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

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

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

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

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

} // namespace Gst


#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

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

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


namespace Gst
{

/** 
 *  @var SeekType SEEK_TYPE_NONE
 *  No change in position is required.
 * 
 *  @var SeekType SEEK_TYPE_SET
 *  Absolute position is requested.
 * 
 *  @var SeekType SEEK_TYPE_END
 *  Relative position to duration is requested.
 * 
 *  @enum SeekType
 * 
 * The different types of seek events. When constructing a seek event with
 * gst_event_new_seek() or when doing Gst::Segment::do_seek().
 * @ingroup gstreamermmEnums
 */
enum SeekType
{
  SEEK_TYPE_NONE,
  SEEK_TYPE_SET,
  SEEK_TYPE_END
};

} // namespace Gst


#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

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

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


namespace Gst
{


/** A class that describes the configured region of interest in a media file.
 * This helper structure holds the relevant values for tracking the region of
 * interest in a media file, called a segment.
 *
 * The structure can be used for two purposes:
 * 
 *  - performing seeks (handling seek events)
 *  - tracking playback regions (handling newsegment events)
 *
 * The segment is usually configured by the application with a seek event which
 * is propagated upstream and eventually handled by an element that performs
 * the seek.
 *
 * The configured segment is then propagated back downstream with a newsegment
 * event. This information is then used to clip media to the segment
 * boundaries.
 *
 * A segment structure is initialized with init(), which takes a Format that
 * will be used as the format of the segment values. The segment will be
 * configured with a start value of 0 and a stop/duration of -1, which is
 * undefined. The default rate and applied_rate is 1.0.
 *
 * The current position in the segment should be set with the set_last_stop().
 * The public last_stop field contains the last set stop position in the
 * segment.
 *
 * For elements that perform seeks, the current segment should be updated with
 * the set_seek() and the values from the seek event. This method will update
 * all the segment fields. The last_stop field will contain the new playback
 * position. If the cur_type was different from Gst::SEEK_TYPE_NONE, playback
 * continues from the last_stop position, possibly with updated flags or rate.
 *
 * For elements that want to synchronize to the pipeline clock,
 * to_running_time() can be used to convert a timestamp to a value that can be
 * used to synchronize to the clock. This function takes into account all
 * accumulated segments as well as any rate or applied_rate conversions.
 *
 * For elements that need to perform operations on media data in stream_time,
 * to_stream_time() can be used to convert a timestamp and the segment info to
 * stream time (which is always between 0 and the duration of the stream).
 *
 * Last reviewed on 2007-05-17 (0.10.13)
 */
class Segment
{
  public:
#ifndef DOXYGEN_SHOULD_SKIP_THIS
  typedef Segment CppObjectType;
  typedef GstSegment BaseObjectType;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */

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

  Segment();

  explicit Segment(GstSegment* gobject, bool make_a_copy = true);

  Segment(const Segment& other);
  Segment& operator=(const Segment& other);

  ~Segment();

  void swap(Segment& other);

  ///Provides access to the underlying C instance.
  GstSegment*       gobj()       { return gobject_; }

  ///Provides access to the underlying C instance.
  const GstSegment* gobj() const { return gobject_; }

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

protected:
  GstSegment* gobject_;

private:

  
public:
  
  /** Clip the given @a start and @a stop values to the segment boundaries given
   * in @a segment. @a start and @a stop are compared and clipped to @a segment
   * start and stop values.
   * 
   * If the function returns <tt>false</tt>, @a start and @a stop are known to fall
   * outside of @a segment and @a clip_start and @a clip_stop are not updated.
   * 
   * When the function returns <tt>true</tt>, @a clip_start and @a clip_stop will be
   * updated. If @a clip_start or @a clip_stop are different from @a start or @a stop
   * respectively, the region fell partially in the segment.
   * 
   * Note that when @a stop is -1, @a clip_stop will be set to the end of the
   * segment. Depending on the use case, this may or may not be what you want.
   * 
   * @param format The format of the segment.
   * @param start The start position in the segment.
   * @param stop The stop position in the segment.
   * @param clip_start The clipped start position in the segment.
   * @param clip_stop The clipped stop position in the segment.
   * @return <tt>true</tt> if the given @a start and @a stop times fall partially or
   * completely in @a segment, <tt>false</tt> if the values are completely outside
   * of the segment.
   */
  bool clip(Format format, guint64 start, guint64 stop, guint64& clip_start, guint64& clip_stop) const;
  
  /** The start/position fields are set to 0 and the stop/duration
   * fields are set to -1 (unknown). The default rate of 1.0 and no
   * flags are set.
   * 
   * Initialize @a segment to its default values.
   * 
   * @param format The format of the segment.
   */
  void init(Format format);
  
  /** Update the segment structure with the field values of a seek event (see
   * gst_event_new_seek()).
   * 
   * After calling this method, the segment field position and time will
   * contain the requested new position in the segment. The new requested
   * position in the segment depends on @a rate and @a start_type and @a stop_type.
   * 
   * For positive @a rate, the new position in the segment is the new @a segment
   * start field when it was updated with a @a start_type different from
   * Gst::SEEK_TYPE_NONE. If no update was performed on @a segment start position
   * (Gst::SEEK_TYPE_NONE), @a start is ignored and @a segment position is
   * unmodified.
   * 
   * For negative @a rate, the new position in the segment is the new @a segment
   * stop field when it was updated with a @a stop_type different from
   * Gst::SEEK_TYPE_NONE. If no stop was previously configured in the segment, the
   * duration of the segment will be used to update the stop position.
   * If no update was performed on @a segment stop position (Gst::SEEK_TYPE_NONE),
   *  @a stop is ignored and @a segment position is unmodified.
   * 
   * The applied rate of the segment will be set to 1.0 by default.
   * If the caller can apply a rate change, it should update @a segment
   * rate and applied_rate after calling this function.
   * 
   *  @a update will be set to <tt>true</tt> if a seek should be performed to the segment
   * position field. This field can be <tt>false</tt> if, for example, only the @a rate
   * has been changed but not the playback position.
   * 
   * @param rate The rate of the segment.
   * @param format The format of the segment.
   * @param flags The segment flags for the segment.
   * @param start_type The seek method.
   * @param start The seek start value.
   * @param stop_type The seek method.
   * @param stop The seek stop value.
   * @param update Boolean holding whether position was updated.
   * @return <tt>true</tt> if the seek could be performed.
   */

  void set_seek(double rate, Format format, SeekFlags flags, SeekType start_type, gint64 start, SeekType stop_type, gint64 stop, bool& update);
  
  /** Translate @a position to the total running time using the currently configured
   * segment. Position is a value between @a segment start and stop time.
   * 
   * This function is typically used by elements that need to synchronize to the
   * global clock in a pipeline. The runnning time is a constantly increasing value
   * starting from 0. When init() is called, this value will reset to
   * 0.
   * 
   * This function returns -1 if the position is outside of @a segment start and stop.
   * 
   * @param format The format of the segment.
   * @param position The position in the segment.
   * @return The position as the total running time or -1 when an invalid position
   * was given.
   */
  guint64 to_running_time(Format format, guint64 position) const;
  
  /** Translate @a position to stream time using the currently configured
   * segment. The @a position value must be between @a segment start and
   * stop value.
   * 
   * This function is typically used by elements that need to operate on
   * the stream time of the buffers it receives, such as effect plugins.
   * In those use cases, @a position is typically the buffer timestamp or
   * clock time that one wants to convert to the stream time.
   * The stream time is always between 0 and the total duration of the
   * media stream.
   * 
   * @param format The format of the segment.
   * @param position The position in the segment.
   * @return The position in stream_time or -1 when an invalid position
   * was given.
   */
  guint64 to_stream_time(Format format, guint64 position) const;
  
  /** Convert @a running_time into a position in the segment so that
   * to_running_time() with that position returns @a running_time.
   * 
   * @param format The format of the segment.
   * @param running_time The running_time in the segment.
   * @return The position in the segment for @a running_time. This function returns
   * -1 when @a running_time is -1 or when it is not inside @a segment.
   */
  guint64 to_position(Format format, guint64 running_time) const;
  
  /** Adjust the start/stop and base values of @a segment such that the next valid
   * buffer will be one with @a running_time.
   * 
   * @param format The format of the segment.
   * @param running_time The running_time in the segment.
   * @return <tt>true</tt> if the segment could be updated successfully. If <tt>false</tt> is
   * returned, @a running_time is -1 or not in @a segment.
   */
  bool set_running_time(Format format, guint64 running_time);


};

} //namespace Gst


namespace Gst
{

/** @relates Gst::Segment
 * @param lhs The left-hand side
 * @param rhs The right-hand side
 */
inline void swap(Segment& lhs, Segment& rhs)
  { lhs.swap(rhs); }

} // 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::Segment
 */
Gst::Segment wrap(GstSegment* object, bool take_copy = false);

#ifndef DOXYGEN_SHOULD_SKIP_THIS
template <>
class Value<Gst::Segment> : public Glib::Value_Boxed<Gst::Segment>
{};
#endif /* DOXYGEN_SHOULD_SKIP_THIS */

} // namespace Glib


#endif /* _GSTREAMERMM_SEGMENT_H */

