// -*- c++ -*-
// Generated by gtkmmproc -- DO NOT MODIFY!
#ifndef _GSTREAMERMM_BASESRC_H
#define _GSTREAMERMM_BASESRC_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/base/gstbasesrc.h>
#include <gstreamermm/element.h>
#include <gstreamermm/pad.h>
#include <gstreamermm/format.h>
#include <gstreamermm/clock.h>
#include <gstreamermm/segment.h>


#ifndef DOXYGEN_SHOULD_SKIP_THIS
typedef struct _GstBaseSrc GstBaseSrc;
typedef struct _GstBaseSrcClass GstBaseSrcClass;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


namespace Gst
{ class BaseSrc_Class; } // namespace Gst
namespace Gst
{

/** A base class for getrange based source elements.
 * This is a generice base class for source elements. The following types of
 * sources are supported:
 *
 *- random access sources like files
 *- seekable sources
 *- live sources
 *
 * The source can be configured to operate in any Gst::Format with the
 * set_format() method. The currently set format determines the format of the
 * internal Gst::Segment and any Gst::EVENT_NEWSEGMENT events. The default
 * format for Gst::BaseSrc is Gst::FORMAT_BYTES.
 *
 * Gst::BaseSrc always supports push mode scheduling. If the following
 * conditions are met, it also supports pull mode scheduling:
 *
 *     - The format is set to Gst::FORMAT_BYTES (default).
 *     - Gst::BaseSrc::is_seekable_vfunc() returns TRUE.
 *
 * Since GStreamer 0.10.9, any Gst::BaseSrc can enable pull based scheduling at
 * any time by overriding Gst::BaseSrc::check_get_range_vfunc() so that it
 * returns TRUE.
 *
 * If all the conditions are met for operating in pull mode, Gst::BaseSrc is
 * automatically seekable in push mode as well. The following conditions must
 * be met to make the element seekable in push mode when the format is not
 * Gst::FORMAT_BYTES:
 *
 *     - Gst::BaseSrc::is_seekable_vfunc() returns TRUE.
 *     - Gst::BaseSrc::query_vfunc() can convert all supported seek formats to
 *     the internal format as set with set_format().
 *     - Gst::BaseSrc::do_seek_vfunc() is implemented, performs the seek and
 *     returns TRUE.
 *
 * When the element does not meet the requirements to operate in pull mode, the
 * offset and length in the Gst::BaseSrc::create_vfunc() method should be
 * ignored. It is recommended to subclass Gst::PushSrc instead, in this
 * situation. If the element can operate in pull mode but only with specific
 * offsets and lengths, it is allowed to generate an error when the wrong
 * values are passed to the Gst::BaseSrc::create_vfunc() function.
 *
 * Gst::BaseSrc has support for live sources. Live sources are sources that
 * when paused discard data, such as audio or video capture devices. A typical
 * live source also produces data at a fixed rate and thus provides a clock to
 * publish this rate. Use set_live() to activate the live source mode.
 *
 * A live source does not produce data in the PAUSED state. This means that the
 * Gst::BaseSrc::create_vfunc() method will not be called in PAUSED but only in
 * PLAYING. To signal the pipeline that the element will not produce data, the
 * return value from the READY to PAUSED state will be
 * Gst::STATE_CHANGE_NO_PREROLL.
 *
 * A typical live source will timestamp the buffers it creates with the current
 * running time of the pipeline. This is one reason why a live source can only
 * produce data in the PLAYING state, when the clock is actually distributed
 * and running.
 *
 * Live sources that synchronize and block on the clock (an audio source, for
 * example) can since GStreamer 0.10.12 use wait_playing() when the
 * create_vfunc() function was interrupted by a state change to PAUSED.
 *
 * The Gst::BaseSrc::get_times_vfunc() method can be used to implement
 * pseudo-live sources. It only makes sense to implement the get_times_vfunc()
 * function if the source is a live source. The get_times_vfunc() function
 * should return timestamps starting from 0, as if it were a non-live source.
 * The base class will make sure that the timestamps are transformed into the
 * current running_time. The base source will then wait for the calculated
 * running_time before pushing out the buffer.
 *
 * For live sources, the base class will by default report a latency of 0. For
 * pseudo live sources, the base class will by default measure the difference
 * between the first buffer timestamp and the start time of get_times_vfunc()
 * and will report this value as the latency. Subclasses should override the
 * query_vfunc() function when this behaviour is not acceptable.
 *
 * TODO: Edit below paragraph for C++ and include C++ example from C API (if
 * necessary):
 *
 * There is only support in Gst::BaseSrc for exactly one source pad, which
 * should be named "src". A source implementation (subclass of Gst::BaseSrc)
 * should install a pad template in its class_init function, like so:
 *
 * <H2>Controlled shutdown of live sources in applications</H2>
 *
 * Applications that record from a live source may want to stop recording in a
 * controlled way, so that the recording is stopped, but the data already in
 * the pipeline is processed to the end (remember that many live sources would
 * go on recording forever otherwise). For that to happen the application needs
 * to make the source stop recording and send an EOS event down the pipeline.
 * The application would then wait for an EOS message posted on the pipeline's
 * bus to know when all data has been processed and the pipeline can safely be
 * stopped.
 *
 * Since GStreamer 0.10.16 an application may send an EOS event to a source
 * element to make it perform the EOS logic (send EOS event downstream or post
 * a Gst::MESSAGE_SEGMENT_DONE on the bus). This can typically be done with the
 * Gst::Element::send_event() function on the element or its parent bin.
 *
 * After the EOS has been sent to the element, the application should wait for
 * an EOS message to be posted on the pipeline's bus. Once this EOS message is
 * received, it may safely shut down the entire pipeline.
 *
 * The old behaviour for controlled shutdown introduced since GStreamer 0.10.3
 * is still available but deprecated as it is dangerous and less flexible.
 *
 * Last reviewed on 2007-12-19 (0.10.16).
 *
 * @ingroup GstBaseClasses
 */

class BaseSrc
: public Element
{
  
#ifndef DOXYGEN_SHOULD_SKIP_THIS

public:
  typedef BaseSrc CppObjectType;
  typedef BaseSrc_Class CppClassType;
  typedef GstBaseSrc BaseObjectType;
  typedef GstBaseSrcClass BaseClassType;

private:  friend class BaseSrc_Class;
  static CppClassType basesrc_class_;

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

protected:
  explicit BaseSrc(const Glib::ConstructParams& construct_params);
  explicit BaseSrc(GstBaseSrc* castitem);

#endif /* DOXYGEN_SHOULD_SKIP_THIS */

public:
  virtual ~BaseSrc();

  /** 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.
  GstBaseSrc*       gobj()       { return reinterpret_cast<GstBaseSrc*>(gobject_); }

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

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

private:


public:
  
  /** If the Gst::BaseSrcClass.create() method performs its own synchronisation
   * against the clock it must unblock when going from PLAYING to the PAUSED state
   * and call this method before continuing to produce the remaining data.
   * 
   * This function will block until a state change to PLAYING happens (in which
   * case this function returns Gst::FLOW_OK) or the processing must be stopped due
   * to a state change to READY or a FLUSH event (in which case this function
   * returns Gst::FLOW_WRONG_STATE).
   * @return Gst::FLOW_OK if @a src is PLAYING and processing can
   * continue. Any other return value should be returned from the create vmethod.
   */
  FlowReturn wait_playing();
  
  /** Check if an element is in live mode.
   * @return <tt>true</tt> if element is in live mode.
   */
  bool is_live() const;
  
  /** If the element listens to a live source, @a live should
   * be set to <tt>true</tt>.
   * 
   * A live source will not produce data in the PAUSED state and
   * will therefore not be able to participate in the PREROLL phase
   * of a pipeline. To signal this fact to the application and the
   * pipeline, the state change return value of the live source will
   * be GST_STATE_CHANGE_NO_PREROLL.
   * @param live New live-mode.
   */
  void set_live(bool live);
  
  /** Sets the default format of the source. This will be the format used
   * for sending NEW_SEGMENT events and for performing seeks.
   * 
   * If a format of GST_FORMAT_BYTES is set, the element will be able to
   * operate in pull mode if the Gst::BaseSrcClass.is_seekable() returns <tt>true</tt>.
   * 
   * This function must only be called in states < Gst::STATE_PAUSED.
   * @param format The format to use.
   */
  void set_format(Format format);

  
  /** Query the source for the latency parameters. @a live will be <tt>true</tt> when @a src is
   * configured as a live source. @a min_latency will be set to the difference
   * between the running time and the timestamp of the first buffer.
   *  @a max_latency is always the undefined value of -1.
   * 
   * This function is mostly used by subclasses.
   * @param live If the source is live.
   * @param min_latency The min latency of the source.
   * @param max_latency The max latency of the source.
   * @return <tt>true</tt> if the query succeeded.
   */

  bool query_latency(bool& live, ClockTime& min_latency,
    ClockTime& max_latency) const;

  
  /** Get the number of bytes that @a src will push out with each buffer.
   * @return The number of bytes pushed with each buffer.
   */
  gulong get_blocksize() const;
  
  /** Set the number of bytes that @a src will push out with each buffer. When
   *  @a blocksize is set to -1, a default length will be used.
   * @param blocksize The new blocksize in bytes.
   */
  void set_blocksize(gulong blocksize);
  
  /** Query if @a src timestamps outgoing buffers based on the current running_time.
   * @return <tt>true</tt> if the base class will automatically timestamp outgoing buffers.
   */
  bool get_do_timestamp() const;
  
  /** Configure @a src to automatically timestamp outgoing buffers based on the
   * current running_time of the pipeline. This property is mostly useful for live
   * sources.
   * @param timestamp Enable or disable timestamping.
   */
  void set_do_timestamp(bool timestamp);
  
  /** Prepare a new seamless segment for emission downstream. This function must
   * only be called by derived sub-classes, and only from the create() function,
   * as the stream-lock needs to be held.
   * 
   * The format for the new segment will be the current format of the source, as
   * configured with set_format()
   * @param start The new start value for the segment.
   * @param stop Stop value for the new segment.
   * @param position The position value for the new segent.
   * @return <tt>true</tt> if preparation of the seamless segment succeeded.
   */
  bool new_seamless_segment(gint64 start, gint64 stop, gint64 position);

  /** Gets the source Gst::Pad object of the element.
   */
   Glib::RefPtr<Gst::Pad> get_src_pad();
  Glib::RefPtr<const Gst::Pad> get_src_pad() const;
 
  #ifdef GLIBMM_PROPERTIES_ENABLED
/** Size in bytes to read per buffer (-1 = default).
   *
   * 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 property of the value, or receive notification when
   * the value of the property changes.
   */
  Glib::PropertyProxy< gulong > property_blocksize() ;
#endif //#GLIBMM_PROPERTIES_ENABLED

#ifdef GLIBMM_PROPERTIES_ENABLED
/** Size in bytes to read per buffer (-1 = default).
   *
   * 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 property of the value, or receive notification when
   * the value of the property changes.
   */
  Glib::PropertyProxy_ReadOnly< gulong > property_blocksize() const;
#endif //#GLIBMM_PROPERTIES_ENABLED

  #ifdef GLIBMM_PROPERTIES_ENABLED
/** Apply current stream time to buffers.
   *
   * 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 property of the value, or receive notification when
   * the value of the property changes.
   */
  Glib::PropertyProxy< bool > property_do_timestamp() ;
#endif //#GLIBMM_PROPERTIES_ENABLED

#ifdef GLIBMM_PROPERTIES_ENABLED
/** Apply current stream time to buffers.
   *
   * 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 property of the value, or receive notification when
   * the value of the property changes.
   */
  Glib::PropertyProxy_ReadOnly< bool > property_do_timestamp() const;
#endif //#GLIBMM_PROPERTIES_ENABLED

  #ifdef GLIBMM_PROPERTIES_ENABLED
/** Number of buffers to output before sending EOS (-1 = unlimited).
   *
   * 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 property of the value, or receive notification when
   * the value of the property changes.
   */
  Glib::PropertyProxy< int > property_num_buffers() ;
#endif //#GLIBMM_PROPERTIES_ENABLED

#ifdef GLIBMM_PROPERTIES_ENABLED
/** Number of buffers to output before sending EOS (-1 = unlimited).
   *
   * 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 property of the value, or receive notification when
   * the value of the property changes.
   */
  Glib::PropertyProxy_ReadOnly< int > property_num_buffers() const;
#endif //#GLIBMM_PROPERTIES_ENABLED

  #ifdef GLIBMM_PROPERTIES_ENABLED
/** Run typefind before negotiating.
   *
   * 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 property of the value, or receive notification when
   * the value of the property changes.
   */
  Glib::PropertyProxy< bool > property_typefind() ;
#endif //#GLIBMM_PROPERTIES_ENABLED

#ifdef GLIBMM_PROPERTIES_ENABLED
/** Run typefind before negotiating.
   *
   * 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 property of the value, or receive notification when
   * the value of the property changes.
   */
  Glib::PropertyProxy_ReadOnly< bool > property_typefind() const;
#endif //#GLIBMM_PROPERTIES_ENABLED


  /** Called to get the caps to report.
   */
    virtual Glib::RefPtr<Gst::Caps> get_caps_vfunc() const;


  /** Notify subclass of changed output caps.
   */
    virtual bool set_caps_vfunc(const Glib::RefPtr<Gst::Caps>& caps);


  /** Negotiated the caps with the peer.
   */
    virtual bool negotiate_vfunc();


  /** Generate and send a new_segment event (UNUSED).
   */
    virtual bool new_segment_vfunc();


  /** Start processing. Subclasses should open resources and prepare to produce
   * data.
   */
    virtual bool start_vfunc();


  /** Stop processing. Subclasses should use this to close resources.
   */
    virtual bool stop_vfunc();


  /** Given a buffer, return the start and stop time when it should be pushed
   * out. The base class will sync on the clock using these times.
   */
    virtual void get_times_vfunc(const Glib::RefPtr<Gst::Buffer>& buffer, ClockTime& start, ClockTime& end) const;


  /** Return the total size of the resource, in the configured format.
   */
    virtual bool get_size_vfunc(guint64& size) const;


  /** Check if the source can seek.
   */
    virtual bool is_seekable_vfunc() const;


  /** Unlock any pending access to the resource. Subclasses should unblock any
   * blocked function ASAP.
   */
    virtual bool unlock_vfunc();


  /** Override this to implement custom event handling.
   */
    virtual bool event_vfunc(const Glib::RefPtr<Gst::Event>& event);


  virtual FlowReturn create_vfunc(guint64 offset, guint size, Glib::RefPtr<Gst::Buffer>& buffer);

  /** Perform seeking on the resource to the indicated segment.
   */
  virtual bool do_seek_vfunc(Gst::Segment& segment); 

 
  /** Handle a requested query.
   */
  //_WRAP_VFUNC(bool query(const Glib::RefPtr<Gst::Query>& query) const, "query")

  /** Check whether the source would support pull-based operation if it were to
   * be opened now. This vfunc is optional, but should be implemented if
   * possible to avoid unnecessary start/stop cycles. The default
   * implementation will open and close the resource to find out whether
   * get_range() is supported, and that is usually undesirable.
   */
    virtual bool check_get_range_vfunc();


  /** Called during negotiation if caps need fixating. Implement instead of
   * setting a fixate function on the source pad.
   */
    virtual void fixate_vfunc(const Glib::RefPtr<Gst::Caps>& caps);


  /** Clear the previous unlock request. Subclasses should clear any state they
   * set during unlock_vfunc(), such as clearing command queues.
   */
    virtual bool unlock_stop_vfunc();


  /** Prepare the Gst::Segment that will be passed to the do_seek_vfunc()
   * vmethod for executing a seek request. Sub-classes should override this if
   * they support seeking in formats other than the configured native format.
   * By default, it tries to convert the seek arguments to the configured
   * native format and prepare a segment in that format.
   */
   virtual bool prepare_seek_segment_vfunc(const Glib::RefPtr<Gst::Event>& seek, Gst::Segment& segment);

protected:

  
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::BaseSrc
   */
  Glib::RefPtr<Gst::BaseSrc> wrap(GstBaseSrc* object, bool take_copy = false);
}


#endif /* _GSTREAMERMM_BASESRC_H */

