/* 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/gstpad.h>
#include <gstreamermm/object.h>
#include <gstreamermm/miniobject.h>
#include <gstreamermm/format.h>
#include <gstreamermm/query.h>

_DEFS(gstreamermm,gst)

namespace Gst
{

class Buffer;
class Caps;
class Element;
class Event;
class PadTemplate;
class Query;

//Gst::Iterator<> forward declaration.
template <class CppType>
class Iterator;

_WRAP_ENUM(ActivateMode, GstActivateMode)
_WRAP_ENUM(FlowReturn, GstFlowReturn)
_WRAP_ENUM(PadDirection, GstPadDirection)
_WRAP_ENUM(PadFlags, GstPadFlags)
_WRAP_ENUM(PadLinkReturn, GstPadLinkReturn)
_WRAP_ENUM(PadLinkCheck, GstPadLinkCheck)

/** A class that represents objects contained by elements that allows links to
 * other elements.
 * A Gst::Element is linked to other elements via "pads", which are extremely
 * light-weight generic link points. After two pads are retrieved from an
 * element with Element::get_pad(), the pads can be link with link(). (For
 * quick links, you can also use Element::link(), which will make the obvious
 * link for you if it's straightforward.)
 *
 * Pads are typically created from a Gst::PadTemplate with the create() method
 * that takes a Gst::PadTemplate.
 *
 * Pads have Gst::Caps attached to it to describe the media type they are
 * capable of dealing with. get_caps() and set_caps() are used to manipulate
 * the caps of the pads. Pads created from a pad template cannot set
 * capabilities that are incompatible with the pad template capabilities.
 *
 * Pads without pad templates can be created with create(), which takes a
 * direction and a name as an argument.
 *
 * get_parent_element() will retrieve the Gst::Element that owns the pad.
 *
 * A Gst::Element creating a pad will typically use the underlying C API to
 * register callbacks for various events on the pads.
 *
 * Elements will use push() and pull_range() to push out or pull in a buffer.
 *
 * To send a Gst::Event on a pad, use send_event() and push_event().
 *
 * Last reviewed on 2006-07-06 (0.10.9)
 */
class Pad : public Object 
{
  _CLASS_GOBJECT(Pad, GstPad, GST_PAD, Object, GstObject)

protected:
  /** Constructs a Pad given a name and a direction.
   * @param name The desired name of the pad.
   * @param direction The desired direction of the pad.
   */
  _WRAP_CTOR(Pad(const Glib::ustring& name, PadDirection direction), gst_pad_new)

  /** Constructs a Pad given a direction without specifying a name.  A unique
   * name will be assigned to the pad.
   * @param direction the direction of the pad.
   */
  explicit Pad(PadDirection direction);

  /** Constructs a Pad from a PadTemplate with the specified name.
   * @param templ The PadTemplate.
   * @param name The desired name of the pad.
   * @throw std::runtime_error if construction fails.
   */
  Pad(const Glib::RefPtr<const Gst::PadTemplate>& templ,
    const Glib::ustring& name);

  /** Constructs a Pad from a PadTemplate without specifying a name.  A unique
   * name will ge assigned to the pad.
   * @param templ The PadTemplate.
   * @throw std::runtime_error if construction fails.
   */
  explicit Pad(const Glib::RefPtr<const Gst::PadTemplate>& templ);

public:
  /** For example,
   * void on_block(const Glib::RefPtr<Gst::Pad>& pad, bool blocked);.
   */
  typedef sigc::slot<void, const Glib::RefPtr<Gst::Pad>&, bool> SlotBlock;

  /** For example,
   * bool on_have_data(const Glib::RefPtr<Gst::Pad>& pad, const
   * Glib::RefPtr<Gst::MiniObjec>& data);.
   * The data method should return true to keep the data in the pipeline, false
   * to drop it (throw it away).
   */
  typedef sigc::slot< bool, const Glib::RefPtr<Gst::Pad>&, const Glib::RefPtr<Gst::MiniObject>& > SlotData;

  /** Creates a new pad with the given name in the given direction.
   *
   * @param name The name of the new pad.
   * @param direction The GstPadDirection of the pad.
   * @return A new Gst::Pad, or a null RefPtr<> in case of an error. MT safe.
   */
  _WRAP_CREATE(const Glib::ustring& name, PadDirection dir)

  /** Creates a new pad with a guaranteed unique name (across all pads) in the
   * given direction.
   *
   * @param direction The GstPadDirection of the pad.
   * @return A new Gst::Pad, or a null RefPtr<> in case of an error. MT safe.
   */
  _WRAP_CREATE(PadDirection dir)

  /** Creates a new pad with the given name from the given template.
   *
   * @param templ The pad template to use.
   * @param name The name of the element.
   * @return A new Gst::Pad, or a null RefPtr<> in case of an error.
   * @throw std::runtime_error if construction fails.
   */
  _WRAP_CREATE(const Glib::RefPtr<const Gst::PadTemplate>& pad_template)

  /** Creates a new pad with a guaranteed unique name (across all pads) from
   * the given template.
   *
   * @param templ The pad template to use.
   * @return A new Gst::Pad, or a null RefPtr<> in case of an error.
   * @throw std::runtime_error if construction fails.
   */
  _WRAP_CREATE(const Glib::RefPtr<const Gst::PadTemplate>& pad_template, const Glib::ustring& name)

  _WRAP_METHOD(PadDirection get_direction() const, gst_pad_get_direction)
  _WRAP_METHOD(Glib::RefPtr<Gst::Element> get_parent_element(), gst_pad_get_parent_element)
  _WRAP_METHOD(Glib::RefPtr<const Gst::Element> get_parent_element() const, gst_pad_get_parent_element, constversion)
  _WRAP_METHOD(Glib::RefPtr<Gst::PadTemplate> get_pad_template(), gst_pad_get_pad_template)
  _WRAP_METHOD(Glib::RefPtr<const Gst::PadTemplate> get_pad_template() const, gst_pad_get_pad_template, constversion)
  _WRAP_METHOD(PadLinkReturn link(const Glib::RefPtr<Gst::Pad>& sink_pad), gst_pad_link)
  _WRAP_METHOD(bool unlink(const Glib::RefPtr<Gst::Pad>& sink_pad), gst_pad_unlink)
  _WRAP_METHOD(bool is_linked() const, gst_pad_is_linked)
  _WRAP_METHOD(bool can_link(const Glib::RefPtr<const Gst::Pad>& other_pad) const, gst_pad_can_link)

  _WRAP_METHOD(Glib::RefPtr<Gst::Caps> get_caps(), gst_pad_get_caps)
  _WRAP_METHOD(Glib::RefPtr<const Gst::Caps> get_caps() const, gst_pad_get_caps, constversion)
  _IGNORE(gst_pad_get_caps_reffed)

  _WRAP_METHOD(Glib::RefPtr<Gst::Caps> get_allowed_caps(), gst_pad_get_allowed_caps)
  _WRAP_METHOD(Glib::RefPtr<const Gst::Caps> get_allowed_caps() const, gst_pad_get_allowed_caps, constversion)
  _WRAP_METHOD(Glib::RefPtr<Gst::Caps> get_negotiated_caps(), gst_pad_get_negotiated_caps)
  _WRAP_METHOD(Glib::RefPtr<const Gst::Caps> get_negotiated_caps() const, gst_pad_get_negotiated_caps, constversion)

  //The documentation gst_pad_get_pad_template_caps() suggests that there shouldn't be a non-const return:
  /** Gets the capabilities for pad's template.
   *
   * @return The Gst::Caps of this pad template.
   */
  Glib::RefPtr<const Gst::Caps> get_pad_template_caps() const;
  _IGNORE(gst_pad_get_pad_template_caps)

  _WRAP_METHOD(bool set_caps(const Glib::RefPtr<Gst::Caps>& caps), gst_pad_set_caps)
  _WRAP_METHOD(Glib::RefPtr<Gst::Pad> get_peer(), gst_pad_get_peer)
  _WRAP_METHOD(Glib::RefPtr<const Gst::Pad> get_peer() const, gst_pad_get_peer, constversion)

  _WRAP_METHOD(Glib::RefPtr<Gst::Caps> peer_get_caps(), gst_pad_peer_get_caps)
  _WRAP_METHOD(Glib::RefPtr<const Gst::Caps> peer_get_caps() const, gst_pad_peer_get_caps, constversion)
  _IGNORE(gst_pad_peer_get_caps_reffed)

  _WRAP_METHOD(void use_fixed_caps(), gst_pad_use_fixed_caps)
  _WRAP_METHOD(bool is_active() const, gst_pad_is_active)
  _WRAP_METHOD(bool set_blocked(bool blocked = true), gst_pad_set_blocked)

  /** Blocks or unblocks the dataflow on a pad asynchronously. The provided
   * slot is called when the operation succeeds; this happens right before the
   * next attempt at pushing a buffer on the pad.
   *
   * This can take a while as the pad can only become blocked when real
   * dataflow is happening. When the pipeline is stalled, for example in
   * PAUSED, this can take an indeterminate amount of time. Be careful with
   * this blocking call as it might not return for reasons stated above.
   *
   * @param slot SlotBlock that will be called when the operation succeeds.
   * @param blocked boolean indicating whether the pad should be blocked or
   * unblocked.
   * @return true if the pad could be blocked. This function can fail if the
   * pad was already in the requested state. MT safe.
   */
  bool set_blocked_async(const SlotBlock& slot, bool blocked = true);
  _IGNORE( gst_pad_set_blocked_async, gst_pad_set_blocked_async_full)

  _WRAP_METHOD(bool is_blocked() const, gst_pad_is_blocked)
  _WRAP_METHOD(bool is_blocking() const, gst_pad_is_blocking)

  /** Adds a "data probe" to a pad. The slot will be called whenever data
   * passes through a pad. In this case data means both events and buffers. The
   * probe will be called with the data as an argument. Note that the data will
   * have a reference count greater than 1, so it will be immutable -- you must
   * not change it.
   *
   * For source pads, the probe will be called after the blocking function, if
   * any (see set_blocked_async()), but before looking up the peer to chain to.
   * For sink pads, the probe function will be called before configuring the
   * sink with new caps, if any, and before calling the pad's chain function.
   *
   * Your data probe should return true to let the data continue to flow, or
   * false to drop it. Dropping data is rarely useful, but occasionally comes
   * in handy with events.
   *
   * To remove a probe, use the appropriate function, such as
   * remove_data_probe().
   *
   * @param slot The slot to call when data is passed over pad (note: slot is
   * not copied because it is connected to a signal).
   * @return The handler id which may be used to remove the connection later.
   */
  gulong add_data_probe(const SlotData& slot);
  _IGNORE(gst_pad_add_data_probe, gst_pad_add_data_probe_full)

  /** Adds a probe that will be called for all buffers passing through a pad.
   * See add_data_probe() for more information.
   *
   * @param slot The slot to call when buffers are passed over pad.
   * @return The handler id.
   */
  gulong add_buffer_probe(const SlotData& slot);
  _IGNORE(gst_pad_add_buffer_probe, gst_pad_add_buffer_probe_full)

  /** Adds a probe that will be called for all events passing through a pad.
   * See add_data_probe() for more information.
   *
   * @param slot The slot to call when events are passed over pad.
   * @return The handler id.
   */
  gulong add_event_probe(const SlotData& slot);
  _IGNORE(gst_pad_add_event_probe, gst_pad_add_event_probe_full)

  _WRAP_METHOD(void remove_data_probe(guint handler_id), gst_pad_remove_data_probe)
  _WRAP_METHOD(void remove_buffer_probe(guint handler_id), gst_pad_remove_buffer_probe)
  _WRAP_METHOD(void remove_event_probe(guint handler_id), gst_pad_remove_event_probe)

  //This is handwritten because conversion from Glib::RefPtr<Gst::Buffer>& to
  //GstBuffer** is difficult.
  /** Allocates a new, empty buffer optimized to push to pad pad. This function
   * only works if pad is a source pad and has a peer.
   *
   * A new, empty Gst::Buffer will be put in the buf argument. You need to
   * check the caps of the buffer after performing this function and
   * renegotiate to the format if needed.
   *
   * @param offset The offset of the new buffer in the stream.
   * @param size The size of the new buffer.
   * @param caps The caps of the new buffer.
   * @param buf An uninitialized Glib::RefPtr<> in which to store the new
   * Gst::Buffer.
   * @return A result code indicating success of the operation. Any result code
   * other than Gst::FLOW_OK is an error and buf should not be used. An error
   * can occur if the pad is not connected or when the downstream peer elements
   * cannot provide an acceptable buffer. MT safe.
   */
  FlowReturn alloc_buffer(guint64 offset, int size, const Glib::RefPtr<Gst::Caps>& caps, Glib::RefPtr<Gst::Buffer>& buf);
  _IGNORE(gst_pad_alloc_buffer)

  //This is handwritten because conversion from Glib::RefPtr<Gst::Buffer>& to
  //GstBuffer** is difficult.
  /** In addition to the function alloc_buffer(), this function automatically
   * calls set_caps() when the caps of the newly allocated buffer are different
   * from the pad caps.  Again, the pad must be a source pad.
   *
   * @param offset The offset of the new buffer in the stream.
   * @param size The size of the new buffer.
   * @param caps The caps of the new buffer.
   * @param buf An uninitialized Glib::RefPtr<> in which to store the new
   * Gst::Buffer.
   * @return A result code indicating success of the operation. Any result code
   * other than Gst::FLOW_OK is an error and buf should not be used. An error
   * can occur if the pad is not connected or when the downstream peer elements
   * cannot provide an acceptable buffer. MT safe.
   */
  FlowReturn alloc_buffer_and_set_caps(guint64 offset, int size, const Glib::RefPtr<Gst::Caps>& caps, Glib::RefPtr<Gst::Buffer>& buf);
  _IGNORE(gst_pad_alloc_buffer_and_set_caps)

  //This is handwritten because conversion from Glib::RefPtr<Gst::Buffer>& to
  //GstBuffer** is difficult.
  /** When pad is flushing this function returns Gst::FLOW_WRONG_STATE
   * immediatly.  Calls the getrange function of pad.  If pad has no getrange
   * function installed this function returns Gst::FLOW_NOT_SUPPORTED.
   *
   * This is a lowlevel function. Usually pull_range() is used.  This function
   * is designed to be used with a source pad only.
   *
   * @param offset The start offset of the buffer.
   * @param size The length of the buffer.
   * @param buffer An unitialized Glib::RefPtr<> in which to store the
   * Gst::Buffer.
   * @return A Gst::FlowReturn from the pad (Gst::FLOW_NOT_SUPPORTED if pad is
   * not a source pad). MT safe.
   */
  FlowReturn get_range(guint64 offset, guint size, Glib::RefPtr<Gst::Buffer>& buffer);
  _IGNORE(gst_pad_get_range)

  _WRAP_METHOD(bool accept_caps(const Glib::RefPtr<const Gst::Caps>& caps) const, gst_pad_accept_caps)
  _WRAP_METHOD(Glib::RefPtr<Gst::Caps> proxy_getcaps(), gst_pad_proxy_getcaps)
  _WRAP_METHOD(Glib::RefPtr<const Gst::Caps> proxy_getcaps() const, gst_pad_proxy_getcaps, constversion)
  _WRAP_METHOD(bool proxy_setcaps(const Glib::RefPtr<Gst::Caps>& caps), gst_pad_proxy_setcaps)
  _WRAP_METHOD(void fixate_caps(const Glib::RefPtr<Gst::Caps>& caps), gst_pad_fixate_caps)
  _WRAP_METHOD(bool peer_accept_caps(const Glib::RefPtr<const Gst::Caps>& caps) const, gst_pad_peer_accept_caps)

  // This method is written manually because an extra ref is necessary
  /** Pushes a buffer to the peer of the pad. The pad must be a source pad,
   * otherwise this method returns Gst::FLOW_ERROR.
   *
   * This function will call an installed pad block before triggering any
   * installed pad probes.
   *
   * If the caps on buffer are different from the currently configured caps on
   * pad, this function will call any installed setcaps function on pad (see
   * the C API gst_pad_set_setcaps_function()). In case of failure to
   * renegotiate the new format, this function returns
   * Gst::FLOW_NOT_NEGOTIATED.
   *
   * The function proceeds calling chain() on the peer pad and returns the
   * value from that function. If pad has no peer, Gst::FLOW_NOT_LINKED will
   * be returned.
   *
   * @param buffer The Gst::Buffer to push.
   * @return A Gst::FlowReturn from the peer pad. MT safe.
   */
  FlowReturn push(const Glib::RefPtr<Gst::Buffer>& buffer);
  _IGNORE(gst_pad_push)

  // This method is written manually because an extra ref is necessary
  /** Sends the event to the peer of the pad. This function is mainly used by
   * elements to send events to their peer elements.
   *
   * @param event The GstEvent to send to the pad.
   * @return true if the event was handled. MT safe.
   */
  bool push_event(const Glib::RefPtr<Gst::Event>& event);
  _IGNORE(gst_pad_push_event)

  _WRAP_METHOD(bool check_pull_range() const, gst_pad_check_pull_range)

  /** Pulls a buffer from the peer pad.  This function will first trigger the
   * pad block signal if it was installed.  This method works only on sink
   * pads.
   *
   * When pad is not linked Gst::FLOW_NOT_LINKED is returned else this function
   * returns the result of get_range() on the peer pad.
   *
   * @a buffer's caps must either be unset or the same as what is already
   * configured on pad. Renegotiation within a running pull-mode pipeline is
   * not supported.
   *
   * @param offset The start offset of the buffer.
   * @param size The length of the buffer.
   * @param buffer An uninitialized Glib::RefPtr<> in which to hold the
   * Gst::Buffer.
   * @return A Gst::FlowReturn from the peer pad (Gst::FLOW_ERROR if pad is not
   * a sink pad). When this function returns Gst::FLOW_OK, buffer will contain
   * a valid Gst::Buffer. @a buffer may not be used when any other return value
   * than Gst::FLOW_OK is returned. MT safe.
   */
  FlowReturn pull_range(guint64 offset, guint size, Glib::RefPtr<Gst::Buffer>& buffer);
  _IGNORE(gst_pad_pull_range)

  _WRAP_METHOD(bool activate_pull(bool active = true), gst_pad_activate_pull)
  _WRAP_METHOD(bool activate_push(bool active = true), gst_pad_activate_push)

  // This method is written manually because an extra ref is necessary
  /** Sends the event to the pad. This function can be used by applications to
   * send events in the pipeline.
   *
   * If the pad is a source pad, event should be an upstream event. If the pad
   * is a sink pad, the event should be a downstream event. For example, you
   * would not send a Gst::EVENT_EOS on a src pad; EOS events only propagate
   * downstream.  Furthermore, some downstream events have to be serialized
   * with data flow, like EOS, while some can travel out-of-band, like
   * Gst::EVENT_FLUSH_START.  If the event needs to be serialized with data
   * flow, this function will take the pad's stream lock while calling its
   * event function.
   *
   * To find out whether an event type is upstream, downstream, or downstream
   * and serialized, see Gst::EventTypeFlags, Gst::Enums::get_flags(),
   * is_upstream(), Gst::Event::is_downstream(), and
   * Gst::Event::is_serialized(). Note that in practice that an application or
   * plugin doesn't need to bother itself with this information; the core
   * handles all necessary locks and checks.
   *
   * @param event The Gst::Event to send to the pad.
   * @return true if the event was handled. 
   */
  bool send_event(const Glib::RefPtr<Gst::Event>& event);
  _IGNORE(gst_pad_send_event)

  _WRAP_METHOD(bool event_default(const Glib::RefPtr<Gst::Event>& event), gst_pad_event_default)
  _WRAP_METHOD(bool query(const Glib::RefPtr<Gst::Query>& query) const, gst_pad_query)
  _WRAP_METHOD(bool peer_query(const Glib::RefPtr<Gst::Query>& query) const, gst_pad_peer_query)
  _WRAP_METHOD(bool query_default(const Glib::RefPtr<Gst::Query>& query) const, gst_pad_query_default)
  _WRAP_METHOD(bool query_position(Format& format, gint64& position) const, gst_pad_query_position)

  /** Queries a pad for the stream position parsing only the format.
   * @param format A reference to the Gst::Format asked for. On return contains
   * the Gst::Format used.
   * @return true if the query could be performed.
   */
  bool query_position(Format& format) const;

  _WRAP_METHOD(bool query_duration(Format& format, gint64& duration) const, gst_pad_query_duration)

  /** Queries a pad for the total stream duration parsing only the format.
   * @param format A reference to the Gst::Format asked for. On return contains
   * the GstFormat used.
   * @return true if the query could be performed.
   */
  bool query_duration(Format& format) const;

  _WRAP_METHOD(bool query_convert(Format src_format, gint64 src_value, Format& dst_format, gint64& dst_value) const, gst_pad_query_convert)
  _WRAP_METHOD(bool query_peer_position(Format& format, gint64& position) const, gst_pad_query_peer_position)

  /** Queries the peer of a given sink pad for the stream position parsing only
   * the format.
   * @param format A reference to the Gst::Format asked for. On return contains
   * the Gst::Format used.
   * @return true if the query could be performed.
   */
  bool query_peer_position(Format& format) const;

   _WRAP_METHOD(bool query_peer_duration(Format& format, gint64& duration) const, gst_pad_query_peer_duration)

  /** Queries the peer pad of a given sink pad for the total stream duration.
   * @param format A reference to the Gst::Format asked for. On return contains
   * the Gst::Format used.
   * @return true if the query could be performed.
   */
  bool query_peer_duration(Format& format) const;

   _WRAP_METHOD(bool query_peer_convert(Format src_format, gint64 src_value, Format& dst_format, gint64& dst_value) const, gst_pad_query_peer_convert)

#m4 _CONVERSION(`const GstQueryType*',`Glib::ArrayHandle<QueryType>',`Glib::ArrayHandle<QueryType>((QueryType*)($3), Glib::OWNERSHIP_NONE)')
  _WRAP_METHOD(Glib::ArrayHandle<QueryType> get_query_types() const, gst_pad_get_query_types)
  _WRAP_METHOD(Glib::ArrayHandle<QueryType> get_query_types_default() const, gst_pad_get_query_types_default)

  _WRAP_METHOD(Gst::Iterator<Gst::Pad> iterate_internal_links(), gst_pad_iterate_internal_links)
  _WRAP_METHOD(Gst::Iterator<const Gst::Pad> iterate_internal_links() const, gst_pad_iterate_internal_links)
  _WRAP_METHOD(Gst::Iterator<Gst::Pad> iterate_internal_links_default(), gst_pad_iterate_internal_links_default)
  _WRAP_METHOD(Gst::Iterator<const Gst::Pad> iterate_internal_links_default() const, gst_pad_iterate_internal_links_default)

#m4 _CONVERSION(`GList*', `Glib::ListHandle< Glib::RefPtr<Gst::Pad> >', `$2($3, Glib::OWNERSHIP_SHALLOW)')
  _WRAP_METHOD(Glib::ListHandle< Glib::RefPtr<Gst::Pad> > get_internal_links(), gst_pad_get_internal_links)

#m4 _CONVERSION(`GList*', `Glib::ListHandle< Glib::RefPtr<const Gst::Pad> >', `$2($3, Glib::OWNERSHIP_SHALLOW)')
  _WRAP_METHOD(Glib::ListHandle< Glib::RefPtr<const Gst::Pad> > get_internal_links() const, gst_pad_get_internal_links)

  _WRAP_METHOD(Glib::ListHandle< Glib::RefPtr<Gst::Pad> > get_internal_links_default(), gst_pad_get_internal_links_default)
  _WRAP_METHOD(Glib::ListHandle< Glib::RefPtr<const Gst::Pad> > get_internal_links_default() const, gst_pad_get_internal_links_default)

  // This method is written manually because an extra ref is necessary
  FlowReturn chain(const Glib::RefPtr<Gst::Buffer>& buffer);
  _IGNORE(gst_pad_chain)

  _WRAP_METHOD(bool pause_task() , gst_pad_pause_task)
  _WRAP_METHOD(bool stop_task() , gst_pad_stop_task)
  _WRAP_METHOD(bool set_active(bool active = true), gst_pad_set_active)

    //C API specific pad callback setting functions are ignored.
    _IGNORE(
      gst_pad_set_acceptcaps_function,
      gst_pad_set_activate_function,
      gst_pad_set_activatepull_function,
      gst_pad_set_activatepush_function,
      gst_pad_set_bufferalloc_function,
      gst_pad_set_chain_function,
      gst_pad_set_chain_list_function,
      gst_pad_set_checkgetrange_function,
      gst_pad_set_event_function,
      gst_pad_set_fixatecaps_function,
      gst_pad_set_getcaps_function,
      gst_pad_set_getrange_function,
      gst_pad_set_internal_link_function,
      gst_pad_set_iterate_internal_links_function,
      gst_pad_set_link_function,
      gst_pad_set_query_function,
      gst_pad_set_query_type_function,
      gst_pad_set_setcaps_function,
      gst_pad_set_unlink_function,
    )

  //C API helper function gst_pad_get_fixed_caps_func ignored.
  _IGNORE(gst_pad_get_fixed_caps_func)

  //The "have-data" signal never really emits so ignore it.  Adding data, event
  //and buffer probes do emit.
  _IGNORE_SIGNAL(have_data)

#m4 _CONVERSION(`GstPad*',`const Glib::RefPtr<Gst::Pad>&',`Glib::wrap($3, true)')
  /** Signals that a pad has been linked to the peer pad.
   */
  _WRAP_SIGNAL(void linked(const Glib::RefPtr<Gst::Pad>& peer_pad), "linked")

  /** Signals that a pad connection has been requested.
   */
  _WRAP_SIGNAL(void request_link(), "request-link")

  /** Signals that a pad has been unlinked from the peer pad.
   */
  _WRAP_SIGNAL(void unlinked(const Glib::RefPtr<Gst::Pad>& peer_pad), "unlinked")

  _WRAP_PROPERTY("caps", Glib::RefPtr<Gst::Caps>)
  _WRAP_PROPERTY("direction", PadDirection)
  _WRAP_PROPERTY("template", PadTemplate)
};

} // namespace Gst
