// -*- c++ -*-
// Generated by gtkmmproc -- DO NOT MODIFY!
#ifndef _GSTREAMERMM_BUFFER_H
#define _GSTREAMERMM_BUFFER_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/gstbuffer.h>
#include <gstreamermm/miniobject.h>
#include <gstreamermm/wrap.h>
#include <gstreamermm/caps.h>


#ifndef DOXYGEN_SHOULD_SKIP_THIS
typedef struct _GstBuffer GstBuffer;
typedef struct _GstBufferClass GstBufferClass;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


namespace Gst
{ class Buffer_Class; } // namespace Gst
namespace Gst
{

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

/**
 * @ingroup gstreamermmEnums
 * @par Bitwise operators:
 * <tt>%BufferFlag operator|(BufferFlag, BufferFlag)</tt><br>
 * <tt>%BufferFlag operator&(BufferFlag, BufferFlag)</tt><br>
 * <tt>%BufferFlag operator^(BufferFlag, BufferFlag)</tt><br>
 * <tt>%BufferFlag operator~(BufferFlag)</tt><br>
 * <tt>%BufferFlag& operator|=(BufferFlag&, BufferFlag)</tt><br>
 * <tt>%BufferFlag& operator&=(BufferFlag&, BufferFlag)</tt><br>
 * <tt>%BufferFlag& operator^=(BufferFlag&, BufferFlag)</tt><br>
 */
enum BufferFlag
{
  BUFFER_FLAG_READONLY = GST_MINI_OBJECT_FLAG_READONLY,
  BUFFER_FLAG_MEDIA4 = GST_MINI_OBJECT_FLAG_RESERVED1,
  BUFFER_FLAG_PREROLL = (GST_MINI_OBJECT_FLAG_LAST << 0),
  BUFFER_FLAG_DISCONT = (GST_MINI_OBJECT_FLAG_LAST << 1),
  BUFFER_FLAG_IN_CAPS = (GST_MINI_OBJECT_FLAG_LAST << 2),
  BUFFER_FLAG_GAP = (GST_MINI_OBJECT_FLAG_LAST << 3),
  BUFFER_FLAG_DELTA_UNIT = (GST_MINI_OBJECT_FLAG_LAST << 4),
  BUFFER_FLAG_MEDIA1 = (GST_MINI_OBJECT_FLAG_LAST << 5),
  BUFFER_FLAG_MEDIA2 = (GST_MINI_OBJECT_FLAG_LAST << 6),
  BUFFER_FLAG_MEDIA3 = (GST_MINI_OBJECT_FLAG_LAST << 7),
  BUFFER_FLAG_LAST = (GST_MINI_OBJECT_FLAG_LAST << 8)
};

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

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

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

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

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

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

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

} // namespace Gst


#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

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

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


namespace Gst
{

/**
 * @ingroup gstreamermmEnums
 * @par Bitwise operators:
 * <tt>%BufferCopyFlags operator|(BufferCopyFlags, BufferCopyFlags)</tt><br>
 * <tt>%BufferCopyFlags operator&(BufferCopyFlags, BufferCopyFlags)</tt><br>
 * <tt>%BufferCopyFlags operator^(BufferCopyFlags, BufferCopyFlags)</tt><br>
 * <tt>%BufferCopyFlags operator~(BufferCopyFlags)</tt><br>
 * <tt>%BufferCopyFlags& operator|=(BufferCopyFlags&, BufferCopyFlags)</tt><br>
 * <tt>%BufferCopyFlags& operator&=(BufferCopyFlags&, BufferCopyFlags)</tt><br>
 * <tt>%BufferCopyFlags& operator^=(BufferCopyFlags&, BufferCopyFlags)</tt><br>
 */
enum BufferCopyFlags
{
  BUFFER_COPY_FLAGS = (1 << 0),
  BUFFER_COPY_TIMESTAMPS = (1 << 1),
  BUFFER_COPY_CAPS = (1 << 2)
};

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

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

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

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

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

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

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

} // namespace Gst


#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

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

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


namespace Gst
{


/** A data-passing buffer type, supporting sub-buffers.
 * Buffers are the basic unit of data transfer in GStreamer. The Gst::Buffer
 * type provides all the state necessary to define a region of memory as part
 * of a stream. Sub-buffers are also supported, allowing a smaller region of a
 * buffer to become its own buffer, with mechanisms in place to ensure that
 * neither memory space goes away prematurely.
 *
 * Buffers are usually created with create(). After a buffer has been created
 * one will typically allocate memory for it and set the size of the buffer
 * data. The following example creates a buffer that can hold a given video
 * frame with a given width, height and bits per plane.
 */

class Buffer : public MiniObject
{
  
#ifndef DOXYGEN_SHOULD_SKIP_THIS

public:
  typedef Buffer CppObjectType;
  typedef Buffer_Class CppClassType;
  typedef GstBuffer BaseObjectType;
  typedef GstBufferClass BaseClassType;

private:
  friend class Buffer_Class;
  static CppClassType buffer_class_;

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

protected:
  explicit Buffer(GstBuffer* castitem);

#endif /* DOXYGEN_SHOULD_SKIP_THIS */

public:
  virtual ~Buffer();

#ifndef DOXYGEN_SHOULD_SKIP_THIS
  static GType get_type()      G_GNUC_CONST;
  static GType get_base_type() G_GNUC_CONST;
#endif

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

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

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

private:


public:
  
  /** Creates a newly allocated buffer without any data.
   * 
   * MT safe.
   * @return The new Gst::Buffer.
   */
  static Glib::RefPtr<Gst::Buffer> create();
  
  /** Tries to create a newly allocated buffer with data of the given size. If
   * the requested amount of memory can't be allocated, <tt>0</tt> will be returned.
   * The buffer memory is not cleared.
   * 
   * Note that when @a size == 0, the buffer data pointer will be <tt>0</tt>.
   * 
   * MT safe.
   * @param size The size in bytes of the new buffer's data.
   * @return A new Gst::Buffer, or <tt>0</tt> if the memory couldn't
   * be allocated.
   */
  static Glib::RefPtr<Gst::Buffer> create(guint size);

  /** Create a copy of the given buffer. This will also make a newly allocated
   * copy of the data the source buffer contains.
   * @return The Gst::Buffer copy.
   */
  Glib::RefPtr<Gst::Buffer> copy() const;

  
  /** Copies the metadata from @a src into @a dest. The data, size and mallocdata
   * fields are not copied.
   * 
   *  @a flags indicate which fields will be copied. Use Gst::BUFFER_COPY_ALL to copy
   * all the metadata fields.
   * 
   * This function is typically called from a custom buffer copy function after
   * creating @a dest and setting the data, size, mallocdata.
   * @param src A source Gst::Buffer.
   * @param flags Flags indicating what metadata fields should be copied.
   */
  void copy_metadata(const Glib::RefPtr<Gst::Buffer>& source_buffer, BufferCopyFlags flags);
  
  /** Similar to gst_buffer_is_writable, but this only ensures that the
   * refcount of the buffer is 1, indicating that the caller is the sole
   * owner and can change the buffer metadata, such as caps and timestamps.
   * @return <tt>true</tt> if the metadata is writable.
   */
  bool is_metadata_writable() const;

  /** Makes a writable buffer from the given buffer. If the source buffer is
   * already writable, this will simply return the same buffer. A copy will
   * otherwise be made.
   * @return A buffer (possibly the same pointer) that is writable.
   */
  Glib::RefPtr<Gst::Buffer> create_writable();

  //This is const because it always returns a new buffer:
  
  /** Similar to gst_buffer_make_writable, but does not ensure that the buffer
   * data array is writable. Instead, this just ensures that the returned buffer
   * is solely owned by the caller, by creating a subbuffer of the original
   * buffer if necessary.
   * 
   * After calling this function, @a buf should not be referenced anymore. The
   * result of this function has guaranteed writable metadata.
   * @return A new Gst::Buffer with writable metadata, which
   * may or may not be the same as @a buf.
   */
  Glib::RefPtr<Gst::Buffer> make_metadata_writable() const;

  
  /** Gets the media type of the buffer. This can be <tt>0</tt> if there
   * is no media type attached to this buffer.
   * @return A reference to the Gst::Caps. unref after usage.
   * Returns <tt>0</tt> if there were no caps on this buffer.
   */
  Glib::RefPtr<Gst::Caps> get_caps();
  
  /** Gets the media type of the buffer. This can be <tt>0</tt> if there
   * is no media type attached to this buffer.
   * @return A reference to the Gst::Caps. unref after usage.
   * Returns <tt>0</tt> if there were no caps on this buffer.
   */
  Glib::RefPtr<const Gst::Caps> get_caps() const;
  
  /** Sets the media type on the buffer. The refcount of the caps will
   * be increased and any previous caps on the buffer will be
   * unreffed.
   * @param caps A Gst::Caps.
   */
  void set_caps(const Glib::RefPtr<Gst::Caps>& caps);
  
  /** Creates a sub-buffer from @a parent at @a offset and @a size.
   * This sub-buffer uses the actual memory space of the parent buffer.
   * This function will copy the offset and timestamp fields when the
   * offset is 0. If not, they will be set to Gst::CLOCK_TIME_NONE and 
   * Gst::BUFFER_OFFSET_NONE.
   * If @a offset equals 0 and @a size equals the total size of @a buffer, the
   * duration and offset end fields are also copied. If not they will be set
   * to Gst::CLOCK_TIME_NONE and Gst::BUFFER_OFFSET_NONE.
   * 
   * MT safe.
   * @param offset The offset into parent Gst::Buffer at which the new sub-buffer 
   * begins.
   * @param size The size of the new Gst::Buffer sub-buffer, in bytes.
   * @return The new Gst::Buffer or <tt>0</tt> if the arguments were
   * invalid.
   */
  Glib::RefPtr<Gst::Buffer> create_sub(const guint& offset, const guint& size);
  
  /** Creates a sub-buffer from @a parent at @a offset and @a size.
   * This sub-buffer uses the actual memory space of the parent buffer.
   * This function will copy the offset and timestamp fields when the
   * offset is 0. If not, they will be set to Gst::CLOCK_TIME_NONE and 
   * Gst::BUFFER_OFFSET_NONE.
   * If @a offset equals 0 and @a size equals the total size of @a buffer, the
   * duration and offset end fields are also copied. If not they will be set
   * to Gst::CLOCK_TIME_NONE and Gst::BUFFER_OFFSET_NONE.
   * 
   * MT safe.
   * @param offset The offset into parent Gst::Buffer at which the new sub-buffer 
   * begins.
   * @param size The size of the new Gst::Buffer sub-buffer, in bytes.
   * @return The new Gst::Buffer or <tt>0</tt> if the arguments were
   * invalid.
   */
  Glib::RefPtr<const Gst::Buffer> create_sub(const guint& offset, const guint& size) const;
  
  /** Determines whether a span() can be done without copying
   * the contents, that is, whether the data areas are contiguous sub-buffers of 
   * the same buffer.
   * 
   * MT safe.
   * @param buf2 The second Gst::Buffer.
   * @return <tt>true</tt> if the buffers are contiguous,
   * <tt>false</tt> if a copy would be required.
   */
  bool is_span_fast(const Glib::RefPtr<const Gst::Buffer>& other_buffer) const;

  //This is const because it always returns a new buffer:
  
  /** Creates a new buffer that consists of part of buf1 and buf2.
   * Logically, buf1 and buf2 are concatenated into a single larger
   * buffer, and a new buffer is created at the given offset inside
   * this space, with a given length.
   * 
   * If the two source buffers are children of the same larger buffer,
   * and are contiguous, the new buffer will be a child of the shared
   * parent, and thus no copying is necessary. you can use
   * is_span_fast() to determine if a memcpy will be needed.
   * 
   * MT safe.
   * @param offset The offset in the first buffer from where the new
   * buffer should start.
   * @param buf2 The second source Gst::Buffer to merge.
   * @param len The total length of the new buffer.
   * @return The new Gst::Buffer that spans the two source
   * buffers, or <tt>0</tt> if the arguments are invalid.
   */
  Glib::RefPtr<Gst::Buffer> span(const guint32& offset, const Glib::RefPtr<Gst::Buffer>& other_buffer, const guint32& len) const;

  //We ignore gst_buffer_join() because it is just a C convenience function.
  //It is gst_buffer_merge() with unrefs.
  

  //This is const because it always returns a new buffer:
  
  /** Create a new buffer that is the concatenation of the two source
   * buffers.  The original source buffers will not be modified or
   * unref'd.  Make sure you unref the source buffers if they are not used
   * anymore afterwards.
   * 
   * If the buffers point to contiguous areas of memory, the buffer
   * is created without copying the data.
   * 
   * Free-function: gst_buffer_unref
   * @param buf2 The second source Gst::Buffer to merge.
   * @return The new Gst::Buffer which is the concatenation
   * of the source buffers.
   */
  Glib::RefPtr<Gst::Buffer> merge(const Glib::RefPtr<const Gst::Buffer>& other_buffer) const;

  /** Get the data element of this buffer.
   * @returns A pointer to the data element of this buffer.
   */
   guint8* get_data() const;
 
  /** Get the size of this buffer.
   * @return The size in bytes of the data in this buffer.
   */
   guint get_size() const;
 
  /** Get the timestamp of this buffer.
   * @return The timestamp in nanoseconds (as a Gst::ClockTime) of the data in
   * the buffer. Value will be Gst::CLOCK_TIME_NONE if the timestamp is
   * unknown.
   */
   ClockTime get_timestamp() const;
 
  /** Get duration of this buffer.
   * @return he duration in nanoseconds (as a Gst::ClockTime) of the data in
   * the buffer. Value will be Gst::CLOCK_TIME_NONE if the duration is unknown.
   */
   ClockTime get_duration() const;
 
  /** Get the offset of this buffer.
   * @return The offset in the source file of the beginning of this buffer.
   */
   guint64 get_offset() const;
 
  /** Get the offset end of this buffer.
   * @return The offset in the source file of the end of this buffer.
   */
   guint64 get_offset_end() const;
 
  /** Get the malloc data of this buffer.
   * @return A pointer to any data allocated for this buffer using g_malloc().
   * If this is non-null, this memory will be freed at the end of the buffer's
   * lifecycle (i.e. when its refcount becomes zero).
   */
   guint8* get_malloc_data() const;
 
  //gst_buffer_stamp is depricated so ignore it.
  

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 Gst
{
  /** @relates Gst::Buffer
   * @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.
   */
  Glib::RefPtr<Gst::Buffer> wrap(GstBuffer* object, bool take_copy = false);
}


#endif /* _GSTREAMERMM_BUFFER_H */

