static void
fs_rtp_special_source_dispose (GObject *object)
{
  FsRtpSpecialSource *self = FS_RTP_SPECIAL_SOURCE (object);

  if (self->priv->disposed)
    return;


  FS_RTP_SPECIAL_SOURCE_LOCK (self);

  if (self->priv->disposed)
  {
    FS_RTP_SPECIAL_SOURCE_UNLOCK (self);
    return;
  }

  if (self->priv->src)
  {
    GError *error = NULL;

    if (self->priv->stop_thread)
    {
      GST_DEBUG ("stopping thread for special source already running");
      return;
    }

    g_object_ref (self);
    self->priv->stop_thread = g_thread_create (stop_source_thread, self, FALSE,
        &error);

    if (!self->priv->stop_thread)
    {
      GST_WARNING ("Could not start stopping thread for FsRtpSpecialSource:"
          " %s", error->message);
    }
    g_clear_error (&error);

    FS_RTP_SPECIAL_SOURCE_UNLOCK (self);
    return;
  }

  if (self->priv->rtpmuxer)
  {
    gst_object_unref (self->priv->rtpmuxer);
    self->priv->rtpmuxer = NULL;
  }

  if (self->priv->outer_bin)
  {
    gst_object_unref (self->priv->outer_bin);
    self->priv->outer_bin = NULL;
  }

  self->priv->disposed = TRUE;

  FS_RTP_SPECIAL_SOURCE_UNLOCK (self);

  G_OBJECT_CLASS (fs_rtp_special_source_parent_class)->dispose (object);
}
static void
fs_rtp_special_source_finalize (GObject *object)
{
  FsRtpSpecialSource *self = FS_RTP_SPECIAL_SOURCE (object);

  if (self->priv->rtpmuxer)
  {
    gst_object_unref (self->priv->rtpmuxer);
    self->priv->rtpmuxer = NULL;
  }

  if (self->priv->outer_bin)
  {
    gst_object_unref (self->priv->outer_bin);
    self->priv->outer_bin = NULL;
  }

  if (self->codec)
    fs_codec_destroy (self->codec);
  self->codec = NULL;

  if (self->priv->mutex)
    g_mutex_free (self->priv->mutex);
  self->priv->mutex = NULL;

  G_OBJECT_CLASS (fs_rtp_special_source_parent_class)->finalize (object);
}
static gpointer
stop_source_thread (gpointer data)
{
  FsRtpSpecialSource *self = FS_RTP_SPECIAL_SOURCE (data);

  gst_element_set_locked_state (self->priv->src, TRUE);
  gst_element_set_state (self->priv->src, GST_STATE_NULL);

  FS_RTP_SPECIAL_SOURCE_LOCK (self);
  if (self->priv->muxer_request_pad)
  {
    gst_element_release_request_pad (self->priv->rtpmuxer,
        self->priv->muxer_request_pad);
    gst_object_unref (self->priv->muxer_request_pad);
  }
  self->priv->muxer_request_pad = NULL;

  gst_bin_remove (GST_BIN (self->priv->outer_bin), self->priv->src);
  self->priv->src = NULL;
  FS_RTP_SPECIAL_SOURCE_UNLOCK (self);

  g_object_unref (self);

  return NULL;
}
static void
fs_rtp_dtmf_sound_source_init (FsRtpDtmfSoundSource *self)
{
    FsRtpSpecialSource *source = FS_RTP_SPECIAL_SOURCE (self);

    self->priv = FS_RTP_DTMF_SOUND_SOURCE_GET_PRIVATE (self);

    source->order = 2;
}