static GstPad *
gst_gl_mixer_bin_request_new_pad (GstElement * element, GstPadTemplate * templ,
    const gchar * req_name, const GstCaps * caps)
{
  GstGLMixerBin *self = GST_GL_MIXER_BIN (element);
  GstPadTemplate *mixer_templ;
  struct input_chain *chain;
  GstPad *mixer_pad;

  chain = g_new0 (struct input_chain, 1);

  mixer_templ = _find_element_pad_template (self->mixer,
      GST_PAD_TEMPLATE_DIRECTION (templ), GST_PAD_TEMPLATE_PRESENCE (templ));
  g_return_val_if_fail (mixer_templ, NULL);

  mixer_pad =
      gst_element_request_pad (self->mixer, mixer_templ, req_name, NULL);
  g_return_val_if_fail (mixer_pad, NULL);

  if (!_create_input_chain (self, chain, mixer_pad)) {
    gst_element_release_request_pad (self->mixer, mixer_pad);
    _free_input_chain (chain);
    return NULL;
  }

  GST_OBJECT_LOCK (element);
  self->priv->input_chains = g_list_prepend (self->priv->input_chains, chain);
  GST_OBJECT_UNLOCK (element);

  gst_child_proxy_child_added (GST_CHILD_PROXY (self),
      G_OBJECT (chain->ghost_pad), GST_OBJECT_NAME (chain->ghost_pad));

  return GST_PAD (chain->ghost_pad);
}
static void
gst_gl_mixer_bin_release_pad (GstElement * element, GstPad * pad)
{
  GstGLMixerBin *self = GST_GL_MIXER_BIN (element);
  GList *l = self->priv->input_chains;
  gboolean released = FALSE;

  GST_OBJECT_LOCK (element);
  while (l) {
    struct input_chain *chain = l->data;
    if (GST_PAD (chain->ghost_pad) == pad) {
      self->priv->input_chains =
          g_list_delete_link (self->priv->input_chains, l);
      GST_OBJECT_UNLOCK (element);

      _free_input_chain (chain);
      gst_element_remove_pad (element, pad);
      released = TRUE;
      break;
    }
    l = l->next;
  }
  if (!released)
    GST_OBJECT_UNLOCK (element);
}
static void
gst_gl_mixer_bin_release_pad (GstElement * element, GstPad * pad)
{
  GstGLMixerBin *self = GST_GL_MIXER_BIN (element);
  GList *l = self->priv->input_chains;

  GST_OBJECT_LOCK (element);
  while (l) {
    struct input_chain *chain = l->data;
    if (chain->mixer_pad == pad) {
      _free_input_chain (chain);
      self->priv->input_chains =
          g_list_remove_link (self->priv->input_chains, l);
      break;
    }
    l = l->next;
  }
  GST_OBJECT_UNLOCK (element);

  gst_element_remove_pad (element, pad);
}