/* GStreamer
 *
 * unit test for gstrtpbin
 *
 * Copyright (C) <2009> Wim Taymans <wim.taymans@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include <gst/check/gstcheck.h>

GST_START_TEST (test_pads)
{
  GstElement *element;
  GstPad *pad;

  element = gst_element_factory_make ("rtpsession", NULL);

  pad = gst_element_get_request_pad (element, "recv_rtcp_sink");
  gst_object_unref (pad);
  gst_object_unref (element);
}

GST_END_TEST;

GST_START_TEST (test_cleanup_send)
{
  GstElement *rtpbin;
  GstPad *rtp_sink, *rtp_src, *rtcp_src;
  GObject *session;
  gint count = 2;

  rtpbin = gst_element_factory_make ("rtpbin", "rtpbin");

  while (count--) {
    /* request session 0 */
    rtp_sink = gst_element_get_request_pad (rtpbin, "send_rtp_sink_0");
    fail_unless (rtp_sink != NULL);
    ASSERT_OBJECT_REFCOUNT (rtp_sink, "rtp_sink", 2);

    /* this static pad should be created automatically now */
    rtp_src = gst_element_get_static_pad (rtpbin, "send_rtp_src_0");
    fail_unless (rtp_src != NULL);
    ASSERT_OBJECT_REFCOUNT (rtp_src, "rtp_src", 2);

    /* we should be able to get an internal session 0 now */
    g_signal_emit_by_name (rtpbin, "get-internal-session", 0, &session);
    fail_unless (session != NULL);
    g_object_unref (session);

    /* get the send RTCP pad too */
    rtcp_src = gst_element_get_request_pad (rtpbin, "send_rtcp_src_0");
    fail_unless (rtcp_src != NULL);
    ASSERT_OBJECT_REFCOUNT (rtcp_src, "rtcp_src", 2);

    gst_element_release_request_pad (rtpbin, rtp_sink);
    /* we should only have our refs to the pads now */
    ASSERT_OBJECT_REFCOUNT (rtp_sink, "rtp_sink", 1);
    ASSERT_OBJECT_REFCOUNT (rtp_src, "rtp_src", 1);
    ASSERT_OBJECT_REFCOUNT (rtcp_src, "rtp_src", 2);

    /* the other pad should be gone now */
    fail_unless (gst_element_get_static_pad (rtpbin, "send_rtp_src_0") == NULL);

    /* internal session should still be there */
    g_signal_emit_by_name (rtpbin, "get-internal-session", 0, &session);
    fail_unless (session != NULL);
    g_object_unref (session);

    /* release the RTCP pad */
    gst_element_release_request_pad (rtpbin, rtcp_src);
    /* we should only have our refs to the pads now */
    ASSERT_OBJECT_REFCOUNT (rtp_sink, "rtp_sink", 1);
    ASSERT_OBJECT_REFCOUNT (rtp_src, "rtp_src", 1);
    ASSERT_OBJECT_REFCOUNT (rtcp_src, "rtp_src", 1);

    /* the session should be gone now */
    g_signal_emit_by_name (rtpbin, "get-internal-session", 0, &session);
    fail_unless (session == NULL);

    /* unref the request pad and the static pad */
    gst_object_unref (rtp_sink);
    gst_object_unref (rtp_src);
    gst_object_unref (rtcp_src);
  }

  gst_object_unref (rtpbin);
}

GST_END_TEST;

typedef struct
{
  guint16 seqnum;
  gboolean pad_added;
  GstPad *pad;
  GMutex lock;
  GCond cond;
  GstPad *sinkpad;
  GList *pads;
} CleanupData;

static void
init_data (CleanupData * data)
{
  data->seqnum = 10;
  data->pad_added = FALSE;
  g_mutex_init (&data->lock);
  g_cond_init (&data->cond);
  data->pads = NULL;
}

static void
clean_data (CleanupData * data)
{
  g_list_foreach (data->pads, (GFunc) gst_object_unref, NULL);
  g_list_free (data->pads);
  g_mutex_clear (&data->lock);
  g_cond_clear (&data->cond);
}

static guint8 rtp_packet[] = { 0x80, 0x60, 0x94, 0xbc, 0x8f, 0x37, 0x4e, 0xb8,
  0x44, 0xa8, 0xf3, 0x7c, 0x06, 0x6a, 0x0c, 0xce,
  0x13, 0x25, 0x19, 0x69, 0x1f, 0x93, 0x25, 0x9d,
  0x2b, 0x82, 0x31, 0x3b, 0x36, 0xc1, 0x3c, 0x13
};

static GstFlowReturn
chain_rtp_packet (GstPad * pad, CleanupData * data)
{
  GstFlowReturn res;
  static GstCaps *caps = NULL;
  GstSegment segment;
  GstBuffer *buffer;
  GstMapInfo map;

  if (caps == NULL) {
    caps = gst_caps_from_string ("application/x-rtp,"
        "media=(string)audio, clock-rate=(int)44100, "
        "encoding-name=(string)L16, encoding-params=(string)1, channels=(int)1");
    data->seqnum = 0;
  }

  gst_pad_send_event (pad, gst_event_new_stream_start (GST_OBJECT_NAME (pad)));
  gst_pad_send_event (pad, gst_event_new_caps (caps));
  gst_segment_init (&segment, GST_FORMAT_TIME);
  gst_pad_send_event (pad, gst_event_new_segment (&segment));

  buffer = gst_buffer_new_and_alloc (sizeof (rtp_packet));
  gst_buffer_map (buffer, &map, GST_MAP_WRITE);
  memcpy (map.data, rtp_packet, sizeof (rtp_packet));

  map.data[2] = (data->seqnum >> 8) & 0xff;
  map.data[3] = data->seqnum & 0xff;

  data->seqnum++;
  gst_buffer_unmap (buffer, &map);

  res = gst_pad_chain (pad, buffer);

  return res;
}

static GstFlowReturn
dummy_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
{
  gst_buffer_unref (buffer);

  return GST_FLOW_OK;
}

static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("application/x-rtp"));


static GstPad *
make_sinkpad (CleanupData * data)
{
  GstPad *pad;

  pad = gst_pad_new_from_static_template (&sink_factory, "sink");

  gst_pad_set_chain_function (pad, dummy_chain);
  gst_pad_set_active (pad, TRUE);

  data->pads = g_list_prepend (data->pads, pad);

  return pad;
}

static void
pad_added_cb (GstElement * rtpbin, GstPad * pad, CleanupData * data)
{
  GstPad *sinkpad;

  GST_DEBUG ("pad added %s:%s\n", GST_DEBUG_PAD_NAME (pad));

  if (GST_PAD_IS_SINK (pad))
    return;

  fail_unless (data->pad_added == FALSE);

  sinkpad = make_sinkpad (data);
  fail_unless (gst_pad_link (pad, sinkpad) == GST_PAD_LINK_OK);

  g_mutex_lock (&data->lock);
  data->pad_added = TRUE;
  data->pad = pad;
  g_cond_signal (&data->cond);
  g_mutex_unlock (&data->lock);
}

static void
pad_removed_cb (GstElement * rtpbin, GstPad * pad, CleanupData * data)
{
  GST_DEBUG ("pad removed %s:%s\n", GST_DEBUG_PAD_NAME (pad));

  if (data->pad != pad)
    return;

  fail_unless (data->pad_added == TRUE);

  g_mutex_lock (&data->lock);
  data->pad_added = FALSE;
  g_cond_signal (&data->cond);
  g_mutex_unlock (&data->lock);
}

GST_START_TEST (test_cleanup_recv)
{
  GstElement *rtpbin;
  GstPad *rtp_sink;
  CleanupData data;
  GstStateChangeReturn ret;
  GstFlowReturn res;
  gint count = 2;

  init_data (&data);

  rtpbin = gst_element_factory_make ("rtpbin", "rtpbin");

  g_signal_connect (rtpbin, "pad-added", (GCallback) pad_added_cb, &data);
  g_signal_connect (rtpbin, "pad-removed", (GCallback) pad_removed_cb, &data);

  ret = gst_element_set_state (rtpbin, GST_STATE_PLAYING);
  fail_unless (ret == GST_STATE_CHANGE_SUCCESS);

  while (count--) {
    /* request session 0 */
    rtp_sink = gst_element_get_request_pad (rtpbin, "recv_rtp_sink_0");
    fail_unless (rtp_sink != NULL);
    ASSERT_OBJECT_REFCOUNT (rtp_sink, "rtp_sink", 2);

    /* no sourcepads are created yet */
    fail_unless (rtpbin->numsinkpads == 1);
    fail_unless (rtpbin->numsrcpads == 0);

    res = chain_rtp_packet (rtp_sink, &data);
    GST_DEBUG ("res %d, %s\n", res, gst_flow_get_name (res));
    fail_unless (res == GST_FLOW_OK);

    res = chain_rtp_packet (rtp_sink, &data);
    GST_DEBUG ("res %d, %s\n", res, gst_flow_get_name (res));
    fail_unless (res == GST_FLOW_OK);

    /* we wait for the new pad to appear now */
    g_mutex_lock (&data.lock);
    while (!data.pad_added)
      g_cond_wait (&data.cond, &data.lock);
    g_mutex_unlock (&data.lock);

    /* sourcepad created now */
    fail_unless (rtpbin->numsinkpads == 1);
    fail_unless (rtpbin->numsrcpads == 1);

    /* remove the session */
    gst_element_release_request_pad (rtpbin, rtp_sink);
    gst_object_unref (rtp_sink);

    /* pad should be gone now */
    g_mutex_lock (&data.lock);
    while (data.pad_added)
      g_cond_wait (&data.cond, &data.lock);
    g_mutex_unlock (&data.lock);

    /* nothing left anymore now */
    fail_unless (rtpbin->numsinkpads == 0);
    fail_unless (rtpbin->numsrcpads == 0);
  }

  ret = gst_element_set_state (rtpbin, GST_STATE_NULL);
  fail_unless (ret == GST_STATE_CHANGE_SUCCESS);

  gst_object_unref (rtpbin);

  clean_data (&data);
}

GST_END_TEST;

GST_START_TEST (test_cleanup_recv2)
{
  GstElement *rtpbin;
  GstPad *rtp_sink;
  CleanupData data;
  GstStateChangeReturn ret;
  GstFlowReturn res;
  gint count = 2;

  init_data (&data);

  rtpbin = gst_element_factory_make ("rtpbin", "rtpbin");

  g_signal_connect (rtpbin, "pad-added", (GCallback) pad_added_cb, &data);
  g_signal_connect (rtpbin, "pad-removed", (GCallback) pad_removed_cb, &data);

  ret = gst_element_set_state (rtpbin, GST_STATE_PLAYING);
  fail_unless (ret == GST_STATE_CHANGE_SUCCESS);

  /* request session 0 */
  rtp_sink = gst_element_get_request_pad (rtpbin, "recv_rtp_sink_0");
  fail_unless (rtp_sink != NULL);
  ASSERT_OBJECT_REFCOUNT (rtp_sink, "rtp_sink", 2);

  while (count--) {
    /* no sourcepads are created yet */
    fail_unless (rtpbin->numsinkpads == 1);
    fail_unless (rtpbin->numsrcpads == 0);

    res = chain_rtp_packet (rtp_sink, &data);
    GST_DEBUG ("res %d, %s\n", res, gst_flow_get_name (res));
    fail_unless (res == GST_FLOW_OK);

    res = chain_rtp_packet (rtp_sink, &data);
    GST_DEBUG ("res %d, %s\n", res, gst_flow_get_name (res));
    fail_unless (res == GST_FLOW_OK);

    /* we wait for the new pad to appear now */
    g_mutex_lock (&data.lock);
    while (!data.pad_added)
      g_cond_wait (&data.cond, &data.lock);
    g_mutex_unlock (&data.lock);

    /* sourcepad created now */
    fail_unless (rtpbin->numsinkpads == 1);
    fail_unless (rtpbin->numsrcpads == 1);

    /* change state */
    ret = gst_element_set_state (rtpbin, GST_STATE_NULL);
    fail_unless (ret == GST_STATE_CHANGE_SUCCESS);

    /* pad should be gone now */
    g_mutex_lock (&data.lock);
    while (data.pad_added)
      g_cond_wait (&data.cond, &data.lock);
    g_mutex_unlock (&data.lock);

    /* back to playing for the next round */
    ret = gst_element_set_state (rtpbin, GST_STATE_PLAYING);
    fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
  }

  /* remove the session */
  gst_element_release_request_pad (rtpbin, rtp_sink);
  gst_object_unref (rtp_sink);

  /* nothing left anymore now */
  fail_unless (rtpbin->numsinkpads == 0);
  fail_unless (rtpbin->numsrcpads == 0);

  ret = gst_element_set_state (rtpbin, GST_STATE_NULL);
  fail_unless (ret == GST_STATE_CHANGE_SUCCESS);

  gst_object_unref (rtpbin);

  clean_data (&data);
}

GST_END_TEST;

GST_START_TEST (test_request_pad_by_template_name)
{
  GstElement *rtpbin;
  GstPad *rtp_sink1, *rtp_sink2, *rtp_sink3;

  rtpbin = gst_element_factory_make ("rtpbin", "rtpbin");
  rtp_sink1 = gst_element_get_request_pad (rtpbin, "recv_rtp_sink_%u");
  fail_unless (rtp_sink1 != NULL);
  fail_unless_equals_string (GST_PAD_NAME (rtp_sink1), "recv_rtp_sink_0");
  ASSERT_OBJECT_REFCOUNT (rtp_sink1, "rtp_sink1", 2);

  rtp_sink2 = gst_element_get_request_pad (rtpbin, "recv_rtp_sink_%u");
  fail_unless (rtp_sink2 != NULL);
  fail_unless_equals_string (GST_PAD_NAME (rtp_sink2), "recv_rtp_sink_1");
  ASSERT_OBJECT_REFCOUNT (rtp_sink2, "rtp_sink2", 2);

  rtp_sink3 = gst_element_get_request_pad (rtpbin, "recv_rtp_sink_%u");
  fail_unless (rtp_sink3 != NULL);
  fail_unless_equals_string (GST_PAD_NAME (rtp_sink3), "recv_rtp_sink_2");
  ASSERT_OBJECT_REFCOUNT (rtp_sink3, "rtp_sink3", 2);


  gst_element_release_request_pad (rtpbin, rtp_sink2);
  gst_element_release_request_pad (rtpbin, rtp_sink1);
  gst_element_release_request_pad (rtpbin, rtp_sink3);
  ASSERT_OBJECT_REFCOUNT (rtp_sink3, "rtp_sink3", 1);
  ASSERT_OBJECT_REFCOUNT (rtp_sink2, "rtp_sink2", 1);
  ASSERT_OBJECT_REFCOUNT (rtp_sink1, "rtp_sink", 1);
  gst_object_unref (rtp_sink1);
  gst_object_unref (rtp_sink2);
  gst_object_unref (rtp_sink3);

  gst_object_unref (rtpbin);
}

GST_END_TEST;

static GstElement *
encoder_cb (GstElement * rtpbin, guint sessid, GstElement * bin)
{
  GstPad *srcpad, *sinkpad;

  fail_unless (sessid == 2);

  GST_DEBUG ("making encoder");
  sinkpad = gst_ghost_pad_new_no_target ("rtp_sink_2", GST_PAD_SINK);
  srcpad = gst_ghost_pad_new_no_target ("rtp_src_2", GST_PAD_SRC);

  gst_element_add_pad (bin, sinkpad);
  gst_element_add_pad (bin, srcpad);

  return gst_object_ref (bin);
}

static GstElement *
encoder_cb2 (GstElement * rtpbin, guint sessid, GstElement * bin)
{
  GstPad *srcpad, *sinkpad;

  fail_unless (sessid == 3);

  GST_DEBUG ("making encoder");
  sinkpad = gst_ghost_pad_new_no_target ("rtp_sink_3", GST_PAD_SINK);
  srcpad = gst_ghost_pad_new_no_target ("rtp_src_3", GST_PAD_SRC);

  gst_element_add_pad (bin, sinkpad);
  gst_element_add_pad (bin, srcpad);

  return gst_object_ref (bin);
}

GST_START_TEST (test_encoder)
{
  GstElement *rtpbin, *bin;
  GstPad *rtp_sink1, *rtp_sink2;
  gulong id;

  bin = gst_bin_new ("rtpenc");

  rtpbin = gst_element_factory_make ("rtpbin", "rtpbin");

  id = g_signal_connect (rtpbin, "request-rtp-encoder", (GCallback) encoder_cb,
      bin);

  rtp_sink1 = gst_element_get_request_pad (rtpbin, "send_rtp_sink_2");
  fail_unless (rtp_sink1 != NULL);
  fail_unless_equals_string (GST_PAD_NAME (rtp_sink1), "send_rtp_sink_2");
  ASSERT_OBJECT_REFCOUNT (rtp_sink1, "rtp_sink1", 2);

  g_signal_handler_disconnect (rtpbin, id);

  id = g_signal_connect (rtpbin, "request-rtp-encoder", (GCallback) encoder_cb2,
      bin);

  rtp_sink2 = gst_element_get_request_pad (rtpbin, "send_rtp_sink_3");
  fail_unless (rtp_sink2 != NULL);

  /* remove the session */
  gst_element_release_request_pad (rtpbin, rtp_sink1);
  gst_object_unref (rtp_sink1);

  gst_element_release_request_pad (rtpbin, rtp_sink2);
  gst_object_unref (rtp_sink2);

  /* nothing left anymore now */
  fail_unless (rtpbin->numsinkpads == 0);
  fail_unless (rtpbin->numsrcpads == 0);

  gst_object_unref (rtpbin);
  gst_object_unref (bin);
}

GST_END_TEST;

static GstElement *
decoder_cb (GstElement * rtpbin, guint sessid, gpointer user_data)
{
  GstElement *bin;
  GstPad *srcpad, *sinkpad;

  bin = gst_bin_new (NULL);

  GST_DEBUG ("making decoder");
  sinkpad = gst_ghost_pad_new_no_target ("rtp_sink", GST_PAD_SINK);
  srcpad = gst_ghost_pad_new_no_target ("rtp_src", GST_PAD_SRC);

  gst_element_add_pad (bin, sinkpad);
  gst_element_add_pad (bin, srcpad);

  return bin;
}

GST_START_TEST (test_decoder)
{
  GstElement *rtpbin;
  GstPad *rtp_sink1, *rtp_sink2;
  gulong id;


  rtpbin = gst_element_factory_make ("rtpbin", "rtpbin");

  id = g_signal_connect (rtpbin, "request-rtp-decoder", (GCallback) decoder_cb,
      NULL);

  rtp_sink1 = gst_element_get_request_pad (rtpbin, "recv_rtp_sink_2");
  fail_unless (rtp_sink1 != NULL);
  fail_unless_equals_string (GST_PAD_NAME (rtp_sink1), "recv_rtp_sink_2");
  ASSERT_OBJECT_REFCOUNT (rtp_sink1, "rtp_sink1", 2);

  rtp_sink2 = gst_element_get_request_pad (rtpbin, "recv_rtp_sink_3");
  fail_unless (rtp_sink2 != NULL);

  g_signal_handler_disconnect (rtpbin, id);

  /* remove the session */
  gst_element_release_request_pad (rtpbin, rtp_sink1);
  gst_object_unref (rtp_sink1);

  gst_element_release_request_pad (rtpbin, rtp_sink2);
  gst_object_unref (rtp_sink2);

  /* nothing left anymore now */
  fail_unless (rtpbin->numsinkpads == 0);
  fail_unless (rtpbin->numsrcpads == 0);

  gst_object_unref (rtpbin);
}

GST_END_TEST;

static GstElement *
aux_sender_cb (GstElement * rtpbin, guint sessid, gpointer user_data)
{
  GstElement *bin;
  GstPad *srcpad, *sinkpad;

  bin = gst_bin_new (NULL);

  GST_DEBUG ("making AUX sender");
  sinkpad = gst_ghost_pad_new_no_target ("sink_2", GST_PAD_SINK);
  gst_element_add_pad (bin, sinkpad);

  srcpad = gst_ghost_pad_new_no_target ("src_2", GST_PAD_SRC);
  gst_element_add_pad (bin, srcpad);
  srcpad = gst_ghost_pad_new_no_target ("src_1", GST_PAD_SRC);
  gst_element_add_pad (bin, srcpad);
  srcpad = gst_ghost_pad_new_no_target ("src_3", GST_PAD_SRC);
  gst_element_add_pad (bin, srcpad);

  return bin;
}

GST_START_TEST (test_aux_sender)
{
  GstElement *rtpbin;
  GstPad *rtp_sink1, *rtp_src, *rtcp_src;
  gulong id;

  rtpbin = gst_element_factory_make ("rtpbin", "rtpbin");

  id = g_signal_connect (rtpbin, "request-aux-sender",
      (GCallback) aux_sender_cb, NULL);

  rtp_sink1 = gst_element_get_request_pad (rtpbin, "send_rtp_sink_2");
  fail_unless (rtp_sink1 != NULL);
  fail_unless_equals_string (GST_PAD_NAME (rtp_sink1), "send_rtp_sink_2");
  ASSERT_OBJECT_REFCOUNT (rtp_sink1, "rtp_sink1", 2);

  g_signal_handler_disconnect (rtpbin, id);

  rtp_src = gst_element_get_static_pad (rtpbin, "send_rtp_src_2");
  fail_unless (rtp_src != NULL);
  gst_object_unref (rtp_src);

  rtp_src = gst_element_get_static_pad (rtpbin, "send_rtp_src_1");
  fail_unless (rtp_src != NULL);
  gst_object_unref (rtp_src);

  rtcp_src = gst_element_get_request_pad (rtpbin, "send_rtcp_src_1");
  fail_unless (rtcp_src != NULL);
  gst_element_release_request_pad (rtpbin, rtcp_src);
  gst_object_unref (rtcp_src);

  rtp_src = gst_element_get_static_pad (rtpbin, "send_rtp_src_3");
  fail_unless (rtp_src != NULL);
  gst_object_unref (rtp_src);

  /* remove the session */
  gst_element_release_request_pad (rtpbin, rtp_sink1);
  gst_object_unref (rtp_sink1);

  gst_object_unref (rtpbin);
}

GST_END_TEST;

static GstElement *
aux_receiver_cb (GstElement * rtpbin, guint sessid, gpointer user_data)
{
  GstElement *bin;
  GstPad *srcpad, *sinkpad;

  bin = gst_bin_new (NULL);

  GST_DEBUG ("making AUX receiver");
  srcpad = gst_ghost_pad_new_no_target ("src_2", GST_PAD_SRC);
  gst_element_add_pad (bin, srcpad);

  sinkpad = gst_ghost_pad_new_no_target ("sink_2", GST_PAD_SINK);
  gst_element_add_pad (bin, sinkpad);
  sinkpad = gst_ghost_pad_new_no_target ("sink_1", GST_PAD_SINK);
  gst_element_add_pad (bin, sinkpad);
  sinkpad = gst_ghost_pad_new_no_target ("sink_3", GST_PAD_SINK);
  gst_element_add_pad (bin, sinkpad);

  return bin;
}

GST_START_TEST (test_aux_receiver)
{
  GstElement *rtpbin;
  GstPad *rtp_sink1, *rtp_sink2, *rtcp_sink;
  gulong id;

  rtpbin = gst_element_factory_make ("rtpbin", "rtpbin");

  id = g_signal_connect (rtpbin, "request-aux-receiver",
      (GCallback) aux_receiver_cb, NULL);

  rtp_sink1 = gst_element_get_request_pad (rtpbin, "recv_rtp_sink_2");
  fail_unless (rtp_sink1 != NULL);

  rtp_sink2 = gst_element_get_request_pad (rtpbin, "recv_rtp_sink_1");
  fail_unless (rtp_sink2 != NULL);

  g_signal_handler_disconnect (rtpbin, id);

  rtcp_sink = gst_element_get_request_pad (rtpbin, "recv_rtcp_sink_1");
  fail_unless (rtcp_sink != NULL);
  gst_element_release_request_pad (rtpbin, rtcp_sink);
  gst_object_unref (rtcp_sink);

  /* remove the session */
  gst_element_release_request_pad (rtpbin, rtp_sink1);
  gst_object_unref (rtp_sink1);
  gst_element_release_request_pad (rtpbin, rtp_sink2);
  gst_object_unref (rtp_sink2);

  gst_object_unref (rtpbin);
}

GST_END_TEST;

static Suite *
rtpbin_suite (void)
{
  Suite *s = suite_create ("rtpbin");
  TCase *tc_chain = tcase_create ("general");

  suite_add_tcase (s, tc_chain);
  tcase_add_test (tc_chain, test_pads);
  tcase_add_test (tc_chain, test_cleanup_send);
  tcase_add_test (tc_chain, test_cleanup_recv);
  tcase_add_test (tc_chain, test_cleanup_recv2);
  tcase_add_test (tc_chain, test_request_pad_by_template_name);
  tcase_add_test (tc_chain, test_encoder);
  tcase_add_test (tc_chain, test_decoder);
  tcase_add_test (tc_chain, test_aux_sender);
  tcase_add_test (tc_chain, test_aux_receiver);

  return s;
}

GST_CHECK_MAIN (rtpbin);
