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); }
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; }