Example #1
0
void
fs_rtp_sub_stream_verify_codec_locked (FsRtpSubStream *substream)
{
  GST_LOG ("Starting codec verification process for substream with"
      " SSRC:%x pt:%d", substream->ssrc, substream->pt);


  fs_rtp_sub_stream_add_probe_locked (substream);

  gst_pad_set_blocked_async (substream->priv->rtpbin_pad, TRUE,
      _rtpbin_pad_blocked_callback, substream);
}
Example #2
0
static gboolean
fs_rtp_sub_stream_set_codecbin (FsRtpSubStream *substream,
    FsCodec *codec,
    GstElement *codecbin,
    GError **error)
{
  GstCaps *caps = NULL;
  gchar *tmp;
  gboolean ret = FALSE;
  GstPad *pad;

  if (substream->priv->codecbin)
  {
    gst_element_set_locked_state (substream->priv->codecbin, TRUE);
    if (gst_element_set_state (substream->priv->codecbin, GST_STATE_NULL) !=
        GST_STATE_CHANGE_SUCCESS)
    {
      gst_element_set_locked_state (substream->priv->codecbin, FALSE);
      g_set_error (error, FS_ERROR, FS_ERROR_INTERNAL,
          "Could not set the codec bin for ssrc %u"
          " and payload type %d to the state NULL", substream->ssrc,
          substream->pt);
      gst_object_unref (codecbin);
      fs_codec_destroy (codec);
      return FALSE;
    }

    gst_bin_remove (GST_BIN (substream->priv->conference),
        substream->priv->codecbin);

    FS_RTP_SESSION_LOCK (substream->priv->session);
    substream->priv->codecbin = NULL;
    if (substream->codec)
    {
      fs_codec_destroy (substream->codec);
      substream->codec = NULL;
    }

    if (substream->priv->caps)
      gst_caps_unref (substream->priv->caps);
    substream->priv->caps = NULL;
    FS_RTP_SESSION_UNLOCK (substream->priv->session);
  }


  if (!gst_bin_add (GST_BIN (substream->priv->conference), codecbin))
  {
    gst_object_unref (codecbin);
    fs_codec_destroy (codec);
    g_set_error (error, FS_ERROR, FS_ERROR_CONSTRUCTION,
      "Could not add the codec bin to the conference");
    return FALSE;
  }

  if (gst_element_set_state (codecbin, GST_STATE_PLAYING) ==
      GST_STATE_CHANGE_FAILURE)
  {
    g_set_error (error, FS_ERROR, FS_ERROR_CONSTRUCTION,
      "Could not set the codec bin to the playing state");
    goto error;
  }

  if (!gst_element_link_pads (codecbin, "src",
      substream->priv->output_valve, "sink"))
  {
    g_set_error (error, FS_ERROR, FS_ERROR_CONSTRUCTION,
      "Could not link the codec bin to the output_valve");
    goto error;
  }

  if (!gst_element_link_pads (substream->priv->capsfilter, "src",
          codecbin, "sink"))
  {
     g_set_error (error, FS_ERROR, FS_ERROR_CONSTRUCTION,
         "Could not link the receive capsfilter and the codecbin for pt %d",
         substream->pt);
    goto error;
  }

  caps = fs_codec_to_gst_caps (codec);
  tmp = gst_caps_to_string (caps);
  GST_DEBUG ("Setting caps %s on recv substream", tmp);
  g_free (tmp);
  g_object_set (substream->priv->capsfilter, "caps", caps, NULL);

  pad = gst_element_get_static_pad (codecbin, "sink");
  if (!pad)
  {
    g_set_error (error, FS_ERROR, FS_ERROR_INTERNAL, "Could not get sink pad"
        " from codecbin");
    goto error;
  }

  /* This is a non-error error
   * Some codecs require config data to start.. so we should just ignore them
   */
  if (!gst_pad_set_caps (pad, caps))
  {
    ret = TRUE;
    gst_object_unref (pad);
    gst_caps_unref (caps);

    GST_DEBUG ("Could not set the caps on the codecbin, waiting on config-data"
        " for SSRC:%x pt:%d", substream->ssrc, substream->pt);

    /* We call this to drop all buffers until something comes up */
    fs_rtp_sub_stream_add_probe_locked (substream);
    goto error;
  }

  GST_DEBUG ("New recv codec accepted");

  gst_object_unref (pad);

  FS_RTP_SESSION_LOCK (substream->priv->session);
  substream->priv->caps = caps;
  substream->priv->codecbin = codecbin;
  substream->codec = codec;
  codec = NULL;

  if (substream->priv->stream && !substream->priv->output_ghostpad)
  {
    if (!fs_rtp_sub_stream_add_output_ghostpad_unlock (substream, error))
      goto error;
  }
  else
  {
    FS_RTP_SESSION_UNLOCK (substream->priv->session);
    g_signal_emit (substream, signals[CODEC_CHANGED], 0);
  }


  return TRUE;

 error:

  gst_element_set_locked_state (codecbin, TRUE);
  gst_element_set_state (codecbin, GST_STATE_NULL);
  gst_bin_remove (GST_BIN (substream->priv->conference), codecbin);

  fs_codec_destroy (codec);

  return ret;
}