// -*- c++ -*-
// Generated by gtkmmproc -- DO NOT MODIFY!
#ifndef _GSTREAMERMM_BASETRANSFORM_H
#define _GSTREAMERMM_BASETRANSFORM_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/gstbasetransform.h>
#include <gstreamermm/element.h>
#include <gstreamermm/pad.h>


#ifndef DOXYGEN_SHOULD_SKIP_THIS
typedef struct _GstBaseTransform GstBaseTransform;
typedef struct _GstBaseTransformClass GstBaseTransformClass;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


namespace Gst
{ class BaseTransform_Class; } // namespace Gst
namespace Gst
{

/** A base class for simple transform filters.
 * This base class is for filter elements that process data.
 *
 * It provides for:
 *     - one sinkpad and one srcpad
 *     - Possible formats on sink and source pad implemented with custom
 *     transform_caps_vfunc() function. By default uses same format on sink and
 *     source.
 *     - Handles state changes.
 *     - Does flushing.
 *     - Push mode.
 *     - Pull mode if the sub-class transform_vfunc() can operate on arbitrary
 *     data.
 * 
 * <H3>Use Cases:</H3>
 *    -   <B>1. Passthrough mode</B>
 *           - Element has no interest in modifying the buffer. It may want to
 *           inspect it, in which case the element should have a
 *           transform_ip_vfunc() function. If there is no transform_ip_vfunc()
 *           function in passthrough mode, the buffer is pushed intact.
 *           - On the GstBaseTransformClass is the passthrough_on_same_caps
 *           variable which will automatically set/unset passthrough based on
 *           whether the element negotiates the same caps on both pads.
 *           - passthrough_on_same_caps on an element that doesn't implement a
 *           transform_caps_vfunc() function is useful for elements that only
 *           inspect data (such as level).
 *           .
 *       <B>Example elements</B>
 *           - Level
 *           - VideoScale, AudioConvert, FfmpegColorSpace, AudioResample in
 *           certain modes.
 *       .
 *    -   <B>2. Modifications in-place - input buffer and output buffer are the
 *    same thing.</B>
 *           - The element must implement a transform_ip_vfunc() function.
 *           - Output buffer size must <= input buffer size.
 *           - If the always_in_place flag is set, non-writable buffers will be
 *           copied and passed to the transform_ip_vfunc() function, otherwise
 *           a new buffer will be created and the transform_vfunc() function
 *           called.
 *           - Incoming writable buffers will be passed to the
 *           transform_ip_vfunc() function immediately.
 *           - only implementing transform_ip_vfunc() and not transform_vfunc()
 *           implies always_in_place = TRUE.
 *           .
 *       <B>Example elements</B>
 *           - Volume.
 *           - AudioConvert in certain modes (signed/unsigned conversion).
 *           - FfmpegColorSpace in certain modes (endianness swapping).
 *
 *    -  <B>3. Modifications only to the caps/metadata of a buffer</B>
 *           - The element does not require writable data, but non-writable
 *           buffers should be subbuffered so that the meta-information can be
 *           replaced.
 *           - Elements wishing to operate in this mode should replace the
 *           prepare_output_buffer_vfunc() method to create subbuffers of the
 *           input buffer and set always_in_place to TRUE.
 *           .
 *       <B>Example elements</B>
 *           - CapsFilter when setting caps on outgoing buffers that have none.
 *           - Identity when it is going to re-timestamp buffers by datarate.
 *
 *    -  <B>4. Normal mode</B>
 *           - always_in_place flag is not set, or there is no
 *           transform_ip_vfunc() function.
 *           - Element will receive an input buffer and output buffer to
 *           operate on.
 *           - Output buffer is allocated by calling the
 *           prepare_output_buffer_vfunc() function.
 *           .
 *       <B>Example elements</B>
 *           - VideoScale, FfmpegColorSpace, AudioConvert when doing
 *           scaling/conversions.
 *
 *    -  <B>5. Special output buffer allocations</B>
 *           - Elements which need to do special allocation of their output
 *           buffers other than what Gst::Pad::alloc_buffer() allows should
 *           implement a prepare_output_buffer_vfunc() method, which calls the
 *           parent implementation and passes the newly allocated buffer. 
 *           .
 *       <B>Example elements</B>
 *           - Efence.
 * 
 * <B>Sub-class settable flags on Gst::BaseTransform</B>
 * 
 *     - <B>passthrough</B>
 *           - Implies that in the current configuration, the sub-class is not
 *           interested in modifying the buffers.
 *           - Elements which are always in passthrough mode whenever the same
 *           caps has been negotiated on both pads can set the class variable
 *           passthrough_on_same_caps to have this behaviour automatically.
 *           .
 *     - <B>always_in_place</B>
 *           - Determines whether a non-writable buffer will be copied before
 *           passing to the transform_ip function.
 *           - Implied TRUE if no transform function is implemented.
 *           - Implied FALSE if ONLY transform function is implemented.
 *
 * @ingroup GstBaseClasses
**/

class BaseTransform
: public Element
{
  
#ifndef DOXYGEN_SHOULD_SKIP_THIS

public:
  typedef BaseTransform CppObjectType;
  typedef BaseTransform_Class CppClassType;
  typedef GstBaseTransform BaseObjectType;
  typedef GstBaseTransformClass BaseClassType;

private:  friend class BaseTransform_Class;
  static CppClassType basetransform_class_;

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

protected:
  explicit BaseTransform(const Glib::ConstructParams& construct_params);
  explicit BaseTransform(GstBaseTransform* castitem);

#endif /* DOXYGEN_SHOULD_SKIP_THIS */

public:
  virtual ~BaseTransform();

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

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

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

private:


public:
  /** The name of the templates for the sink pad ("sink").
   */
  static const Glib::ustring SINK_NAME;

  /** The name of the templates for the source pad ("src").
   */
  static const Glib::ustring SRC_NAME;

  
  /** See if @a trans is configured as a passthrough transform.
   * @return <tt>true</tt> is the transform is configured in passthrough mode.
   * 
   * MT safe.
   */
  bool is_passthrough() const;
  
  /** Set passthrough mode for this filter by default. This is mostly
   * useful for filters that do not care about negotiation.
   * 
   * Always <tt>true</tt> for filters which don't implement either a transform
   * or transform_ip method.
   * 
   * MT safe.
   * @param passthrough Boolean indicating passthrough mode.
   */
  void set_passthrough(bool passthrough);
  
  /** See if @a trans is configured as a in_place transform.
   * @return <tt>true</tt> is the transform is configured in in_place mode.
   * 
   * MT safe.
   */
  bool is_in_place() const;
  
  /** Determines whether a non-writable buffer will be copied before passing
   * to the transform_ip function.
   * - Always <tt>true</tt> if no transform function is implemented.
   * - Always <tt>false</tt> if ONLY transform function is implemented.
   * 
   * MT safe.
   * @param in_place Boolean value indicating that we would like to operate
   * on in_place buffers.
   */
  void set_in_place(bool in_place);
  
  /** Queries if the transform will handle QoS.
   * @return <tt>true</tt> if QoS is enabled.
   * 
   * MT safe.
   */
  bool is_qos_enabled() const;
  
  /** Enable or disable QoS handling in the transform.
   * 
   * MT safe.
   * @param enabled New state.
   */
  void set_qos_enabled(bool enabled);
  
  /** Set the QoS parameters in the transform. This function is called internally
   * when a QOS event is received but subclasses can provide custom information
   * when needed.
   * 
   * MT safe.
   * @param proportion The proportion.
   * @param diff The diff against the clock.
   * @param timestamp The timestamp of the buffer generating the QoS expressed in
   * running_time.
   */
  void update_qos(double proportion, ClockTimeDiff diff, ClockTime timestamp);
  
  /** If @a gap_aware is <tt>false</tt> (the default), output buffers will have the
   * Gst::BUFFER_FLAG_GAP flag unset.
   * 
   * If set to <tt>true</tt>, the element must handle output buffers with this flag set
   * correctly, i.e. it can assume that the buffer contains neutral data but must
   * unset the flag if the output is no neutral data.
   * 
   * MT safe.
   * @param gap_aware New state.
   */
  void set_gap_aware(bool gap_aware);
  
  /** Instructs @a trans to suggest new @a caps upstream. A copy of @a caps will be
   * taken.
   * @param caps Caps to suggest.
   * @param size Buffer size to suggest.
   */
  void suggest(const Glib::RefPtr<Gst::Caps>& caps, guint size);
  
  /** Instructs @a trans to renegotiate a new downstream transform on the next
   * buffer. This function is typically called after properties on the transform
   * were set that influence the output format.
   */
  void reconfigure();

  /** Obtain a lock to protect the transform function from concurrent access.
   */
  void lock();

  /** Release the lock that protects the transform function from concurrent
   * access.
   */
  void unlock();

  /** Gives the refptr to the sink Gst::Pad object of the element.
   */
   Glib::RefPtr<Gst::Pad> get_sink_pad();
  Glib::RefPtr<const Gst::Pad> get_sink_pad() const;
 
  /** Gives the refptr to 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
/** Handle Quality-of-Service events.
   *
   * 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_qos() ;
#endif //#GLIBMM_PROPERTIES_ENABLED

#ifdef GLIBMM_PROPERTIES_ENABLED
/** Handle Quality-of-Service events.
   *
   * 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_qos() const;
#endif //#GLIBMM_PROPERTIES_ENABLED


  /** Optional. Given the pad in this direction and the given caps, what caps
   * are allowed on the other pad in this element ?
   */
    virtual Glib::RefPtr<Gst::Caps> transform_caps_vfunc(PadDirection direction, const Glib::RefPtr<Gst::Caps>& caps);


  /** Optional. Given the pad in this direction and the given caps, fixate the
   * caps on the other pad.
   */
    virtual void fixate_caps_vfunc(PadDirection direction, const Glib::RefPtr<Gst::Caps>& caps, const Glib::RefPtr<Gst::Caps>& othercaps);


  //TODO: This virtual function can't be wrapped without causing execution
  //errors with the ogg_player_gtkmm example.
  ///** Optional. Given the size of a buffer in the given direction with the
   //* given caps, calculate the size in bytes of a buffer on the other pad with
   //* the given other caps. The default implementation uses
   //* get_unit_size_vfunc() and keeps the number of units the same.
   //*/
  //_WRAP_VFUNC(bool transform_size(PadDirection direction, const Glib::RefPtr<Gst::Caps>& caps, guint size, const Glib::RefPtr<Gst::Caps>& othercaps, guint& othersize), "transform_size")

  /** Required if the transform is not in-place. Get the size in bytes of one
   * unit for the given caps.
   */
    virtual bool get_unit_size_vfunc(const Glib::RefPtr<Gst::Caps>& caps, guint& size) const;


  /** Allows the subclass to be notified of the actual caps set.
   */
    virtual bool set_caps_vfunc(const Glib::RefPtr<Gst::Caps>& incaps, const Glib::RefPtr<Gst::Caps>& outcaps);


  //TODO: Handwrapped because default return should be true otherwise the
  //ogg_player_gtkmm example fails to run successfully.
  /** Optional. Called when the element starts processing. Allows opening
   * external resources.
   */
  virtual bool start_vfunc();

  //TODO: Handwrapped because default return should be true otherwise the
  //ogg_player_gtkmm example fails to run successfully.
  /** Optional. Called when the element stops processing. Allows closing
   * external resources.
   */
  virtual bool stop_vfunc();

 
  /* Optional. Event handler on the sink pad. This function should return
   * <tt>true</tt> if the base class should forward the event.
   */
    virtual bool event_vfunc(const Glib::RefPtr<Gst::Event>& event);


  /** Required if the element does not operate in-place. Transforms one
   * incoming buffer to one outgoing buffer. The function is allowed to change
   * size/timestamp/duration of the outgoing buffer.
   */
    virtual FlowReturn transform_vfunc(const Glib::RefPtr<Gst::Buffer>& inbuf, const Glib::RefPtr<Gst::Buffer>& outbuf);


  /** Required if the element operates in-place. Transform the incoming buffer
   * in-place.
   */
    virtual FlowReturn transform_ip_vfunc(const Glib::RefPtr<Gst::Buffer>& buf);


  /** Optional. Subclasses can override this to do their own allocation of
   * output buffers. Elements that only do analysis can return a subbuffer or
   * even just increment the reference to the input buffer (if in passthrough
   * mode).
   */
  virtual FlowReturn prepare_output_buffer_vfunc(const Glib::RefPtr<Gst::Buffer>& input, int size, const Glib::RefPtr<Gst::Caps>& caps, Glib::RefPtr<Gst::Buffer>& buffer);

  /** Optional. Event handler on the source pad.
   */
    virtual bool src_event_vfunc(const Glib::RefPtr<Gst::Event>& event);


  /** Optional. Since 0.10.22 This method is called right before the base class
   * will start processing. Dynamic properties or other delayed configuration
   * could be performed in this method.
   */
    virtual void before_transform_vfunc(const Glib::RefPtr<Gst::Buffer>& buffer);


  /** Optional. Since 0.10.30 Subclasses can override this method to check if
   * the caps can be handled by the element. The default implementation might
   * not be the most optimal way to check this in all cases.
   */
    virtual bool accept_caps_vfunc(PadDirection direction, const Glib::RefPtr<const Gst::Caps>& caps);


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


#endif /* _GSTREAMERMM_BASETRANSFORM_H */

