static void caps_changed (GstPad *pad, GParamSpec *spec, FsStream *stream) { GstCaps *caps; GstStructure *s; FsCodec *codec; GList *codecs; const gchar *config; GError *error = NULL; g_object_get (pad, "caps", &caps, NULL); if (!caps) return; s = gst_caps_get_structure (caps, 0); codec = fs_codec_new (96, "THEORA", FS_MEDIA_TYPE_VIDEO, 90000); config = gst_structure_get_string (s, "configuration"); if (config) fs_codec_add_optional_parameter (codec, "configuration", config); codecs = g_list_prepend (NULL, codec); fail_unless (fs_stream_set_remote_codecs (stream, codecs, &error), "Unable to set remote codec: %s", error ? error->message : "UNKNOWN"); fs_codec_list_destroy (codecs); }
static void skype_audio_stream_update_codecs (SkypeBaseStream *stream, GList **codecs) { SkypeAudioStreamPrivate *priv = SKYPE_AUDIO_STREAM (stream)->priv; FsCodec *codec; gchar *value; guint telephony_pt = priv->last_telephony_pt; if (codecs == NULL || *codecs == NULL || (*codecs)->data == NULL) { g_warning ("update_codecs should not be passed an empty codec list"); return; } codec = (FsCodec *)((*codecs)->data); /* Add ptime value */ value = g_strdup_printf ("%d", priv->ptime); fs_codec_add_optional_parameter (codec, "ptime", value); g_free (value); /* Add telephony codec if needed */ if (priv->pending_telephony_pt != FS_CODEC_ID_DISABLE) telephony_pt = priv->pending_telephony_pt; if (telephony_pt != FS_CODEC_ID_DISABLE) { codec = fs_codec_new (telephony_pt, "telephone-event", FS_MEDIA_TYPE_AUDIO, 8000); fs_codec_add_optional_parameter (codec, "events", "0-11"); *codecs = g_list_append (*codecs, codec); } }
static FsCodec * init_codec_with_three_params (void) { FsCodec *codec = fs_codec_new (1, "aa", FS_MEDIA_TYPE_VIDEO, 650); fs_codec_add_optional_parameter (codec, "aa1", "bb1"); fs_codec_add_optional_parameter (codec, "aa2", "bb2"); fs_codec_add_optional_parameter (codec, "aa3", "bb3"); fs_codec_add_feedback_parameter (codec, "aa1", "bb1", "cc1"); fs_codec_add_feedback_parameter (codec, "aa2", "bb2", "cc2"); fs_codec_add_feedback_parameter (codec, "aa3", "bb3", "cc3"); return codec; }
/** * fs_codec_copy: * @codec: codec to copy * * Copies a #FsCodec structure. * * Returns: a copy of the codec */ FsCodec * fs_codec_copy (const FsCodec * codec) { FsCodec *copy = NULL; GList *lp; GQueue list_copy = G_QUEUE_INIT; if (codec == NULL) return NULL; copy = fs_codec_new (codec->id, codec->encoding_name, codec->media_type, codec->clock_rate); copy->channels = codec->channels; copy->minimum_reporting_interval = codec->minimum_reporting_interval; copy->encoding_name = g_strdup (codec->encoding_name); for (lp = codec->optional_params; lp; lp = g_list_next (lp)) { FsCodecParameter *param_copy; FsCodecParameter *param = lp->data;; param_copy = g_slice_new (FsCodecParameter); param_copy->name = g_strdup (param->name); param_copy->value = g_strdup (param->value); g_queue_push_tail (&list_copy, param_copy); } copy->optional_params = list_copy.head; g_queue_init (&list_copy); for (lp = codec->feedback_params; lp; lp = g_list_next (lp)) { FsFeedbackParameter *param_copy; FsFeedbackParameter *param = lp->data;; param_copy = g_slice_new (FsFeedbackParameter); param_copy->type = g_strdup (param->type); param_copy->subtype = g_strdup (param->subtype); param_copy->extra_params = g_strdup (param->extra_params); g_queue_push_tail (&list_copy, param_copy); } copy->feedback_params = list_copy.head; return copy; }
static void _simple_profile_init (struct SimpleTestStream *st, guint confid, guint streamid) { GList *prefs = NULL; FsCodec *codec = NULL; gboolean ret; codec = fs_codec_new (0, "PCMU", FS_MEDIA_TYPE_AUDIO, 8000); fs_codec_add_optional_parameter (codec, "farstream-send-profile", "audioconvert ! audioresample ! audioconvert ! mulawenc ! rtppcmupay"); prefs = g_list_append (NULL, codec); ret = fs_session_set_codec_preferences (st->dat->session, prefs, NULL); ts_fail_unless (ret, "set codec prefs"); fs_codec_list_destroy (prefs); }
static TestSession* add_audio_session (GstElement *pipeline, FsConference *conf, guint id, FsParticipant *part, gchar *send_socket, gchar *recv_socket) { TestSession *ses = g_slice_new0 (TestSession); GError *error = NULL; GstPad *pad = NULL, *pad2 = NULL; GstElement *src = NULL; GList *cands = NULL; GParameter param = {0}; gboolean res; FsCandidate *cand; GList *codecs = NULL; ses->send_socket = send_socket; ses->recv_socket = recv_socket; ses->session = fs_conference_new_session (conf, FS_MEDIA_TYPE_AUDIO, &error); print_error (error); g_assert (ses->session); g_object_get (ses->session, "sink-pad", &pad, NULL); if (g_getenv ("AUDIOSRC")) src = gst_parse_bin_from_description (g_getenv ("AUDIOSRC"), TRUE, &error); else src = gst_parse_bin_from_description (DEFAULT_AUDIOSRC, TRUE, &error); print_error (error); g_assert (src); g_assert (gst_bin_add (GST_BIN (pipeline), src)); pad2 = gst_element_get_static_pad (src, "src"); g_assert (pad2); g_assert (GST_PAD_LINK_SUCCESSFUL (gst_pad_link (pad2, pad))); gst_object_unref (pad2); gst_object_unref (pad); ses->stream = fs_session_new_stream (ses->session, part, FS_DIRECTION_BOTH, &error); print_error (error); g_assert (ses->stream); cand = fs_candidate_new ("", FS_COMPONENT_RTP, FS_CANDIDATE_TYPE_HOST, FS_NETWORK_PROTOCOL_UDP, send_socket, 0); cands = g_list_prepend (NULL, cand); param.name = "preferred-local-candidates"; g_value_init (¶m.value, FS_TYPE_CANDIDATE_LIST); g_value_take_boxed (¶m.value, cands); res = fs_stream_set_transmitter (ses->stream, "shm", ¶m, 1, &error); print_error (error); g_value_unset (¶m.value); g_signal_connect (ses->stream, "src-pad-added", G_CALLBACK (src_pad_added_cb), pipeline); codecs = g_list_prepend (NULL, fs_codec_new (FS_CODEC_ID_ANY, "PCMA", FS_MEDIA_TYPE_AUDIO, 0)); codecs = g_list_prepend (codecs, fs_codec_new (FS_CODEC_ID_ANY, "PCMU", FS_MEDIA_TYPE_AUDIO, 0)); res = fs_session_set_codec_preferences (ses->session, codecs, &error); print_error (error); fs_codec_list_destroy (codecs); g_object_get (ses->session, "codecs-without-config", &codecs, NULL); res = fs_stream_set_remote_codecs (ses->stream, codecs, &error); print_error (error); g_assert (res); return ses; }
/** * fs_codec_list_from_keyfile * @filename: Name of the #GKeyFile to read the codecs parameters from * @error: location of a #GError, or NULL if no error occured * * Reads the content of a #GKeyFile of the following format into * a #GList of #FsCodec structures. * * * Example: * |[ * [audio/codec1] * clock-rate=8000 * * [audio/codec1:1] * clock-rate=16000 * * [audio/codec2] * one_param=QCIF * another_param=WOW * * [video/codec3] * wierd_param=42 * feedback:nack/pli=1 * feedback:tfrc= * ]| * * Return value: (element-type FsCodec) (transfer full): * The #GList of #FsCodec or %NULL if the keyfile was empty or an error occured. */ GList * fs_codec_list_from_keyfile (const gchar *filename, GError **error) { GKeyFile *keyfile = NULL; GList *codecs = NULL; GError *gerror = NULL; gchar **groups = NULL; gsize groups_count = 0; int i; g_return_val_if_fail (filename, NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); keyfile = g_key_file_new (); if (!g_key_file_load_from_file (keyfile, filename, G_KEY_FILE_NONE, error)) { goto out; } groups = g_key_file_get_groups (keyfile, &groups_count); if (!groups) goto out; for (i=0; i < groups_count && groups[i]; i++) { FsCodec *codec; gchar **keys = NULL; gsize keys_count; int j; gchar *encoding_name = NULL; gchar *next_tok = NULL; FsMediaType media_type; keys = g_key_file_get_keys (keyfile, groups[i], &keys_count, &gerror); if (!keys || gerror) { if (gerror) GST_WARNING ("Unable to read parameters for %s: %s\n", groups[i], gerror->message); else GST_WARNING ("Unknown errors while reading parameters for %s", groups[i]); g_clear_error (&gerror); goto next_codec; } next_tok = strchr (groups[i], '/'); if (!next_tok) { GST_WARNING ("Invalid codec name: %s", groups[i]); goto next_codec; } if ((next_tok - groups[i]) == 5 /* strlen ("audio") */ && !g_ascii_strncasecmp ("audio", groups[i], 5)) { media_type = FS_MEDIA_TYPE_AUDIO; } else if ((next_tok - groups[i]) == 5 /* strlen ("video") */ && !g_ascii_strncasecmp ("video", groups[i], 5)) { media_type = FS_MEDIA_TYPE_VIDEO; } else { GST_WARNING ("Invalid media type in codec name name %s", groups[i]); goto next_codec; } encoding_name = next_tok + 1; next_tok = strchr (encoding_name, ':'); if (encoding_name[0] == 0 || next_tok - encoding_name == 1) goto next_codec; if (next_tok) encoding_name = g_strndup (encoding_name, next_tok - encoding_name); else encoding_name = g_strdup (encoding_name); codec = fs_codec_new (FS_CODEC_ID_ANY, encoding_name, media_type, 0); g_free (encoding_name); for (j = 0; j < keys_count && keys[j]; j++) { if (!g_ascii_strcasecmp ("clock-rate", keys[j])) { codec->clock_rate = g_key_file_get_integer (keyfile, groups[i], keys[j], &gerror); if (gerror) { codec->clock_rate = 0; goto keyerror; } } else if (!g_ascii_strcasecmp ("id", keys[j])) { codec->id = g_key_file_get_integer (keyfile, groups[i], keys[j], &gerror); if (gerror) { codec->id = FS_CODEC_ID_ANY; goto keyerror; } if (codec->id < 0) codec->id = FS_CODEC_ID_DISABLE; } else if (!g_ascii_strcasecmp ("channels", keys[j])) { codec->channels = g_key_file_get_integer (keyfile, groups[i], keys[j], &gerror); if (gerror) { codec->channels = 0; goto keyerror; } } else if (!g_ascii_strcasecmp ("trr-int", keys[j])) { codec->minimum_reporting_interval = g_key_file_get_integer (keyfile, groups[i], keys[j], &gerror); if (gerror) { codec->minimum_reporting_interval = G_MAXUINT; goto keyerror; } } else if (g_str_has_prefix (keys[j], "feedback:")) { gchar *type = keys[j] + strlen ("feedback:"); gchar *subtype = strchr (type, '/'); gchar *extra_params; extra_params = g_key_file_get_string (keyfile, groups[i], keys[j], &gerror); if (gerror) goto keyerror; /* Replace / with \0 and point to name (the next char) */ if (subtype) { *subtype=0; subtype++; } else { subtype = ""; } fs_codec_add_feedback_parameter (codec, type, subtype, extra_params); g_free (extra_params); } else { FsCodecParameter *param = g_slice_new (FsCodecParameter); param->name = g_strdup (keys[j]); param->value = g_key_file_get_string (keyfile, groups[i], keys[j], &gerror); if (gerror) { fs_codec_parameter_free (param); goto keyerror; } if (!param->name || !param->value) fs_codec_parameter_free (param); else codec->optional_params = g_list_append (codec->optional_params, param); } continue; keyerror: GST_WARNING ("Error reading key %s codec %s: %s", keys[j], groups[i], gerror->message); g_clear_error (&gerror); } codecs = g_list_append (codecs, codec); next_codec: g_strfreev (keys); } out: g_strfreev (groups); g_key_file_free (keyfile); return codecs; }
static CodecBlueprint * load_codec_blueprint (FsMediaType media_type, gchar **in, gsize *size) { CodecBlueprint *codec_blueprint = g_slice_new0 (CodecBlueprint); gchar *tmp; gint tmp_size; int i; gint id; gchar *encoding_name = NULL; guint clock_rate; READ_CHECK (read_codec_blueprint_int (in, size, &(id))); READ_CHECK (read_codec_blueprint_string (in, size, &(encoding_name))); READ_CHECK (read_codec_blueprint_uint (in, size, &(clock_rate))); codec_blueprint->codec = fs_codec_new (id, encoding_name, media_type, clock_rate); g_free (encoding_name); READ_CHECK (read_codec_blueprint_uint (in, size, &(codec_blueprint->codec->channels))); READ_CHECK (read_codec_blueprint_int (in, size, &tmp_size)); for (i = 0; i < tmp_size; i++) { gchar *name, *value; READ_CHECK (read_codec_blueprint_string (in, size, &(name))); READ_CHECK (read_codec_blueprint_string (in, size, &(value))); fs_codec_add_optional_parameter (codec_blueprint->codec, name, value); g_free (name); g_free (value); } READ_CHECK (read_codec_blueprint_string (in, size, &tmp)); codec_blueprint->media_caps = gst_caps_from_string (tmp); g_free (tmp); READ_CHECK (read_codec_blueprint_string (in, size, &tmp)); codec_blueprint->rtp_caps = gst_caps_from_string (tmp); g_free (tmp); READ_CHECK (read_codec_blueprint_int (in, size, &tmp_size)); for (i = 0; i < tmp_size; i++) { int j, tmp_size2; GList *tmplist = NULL; READ_CHECK (read_codec_blueprint_int (in, size, &tmp_size2)); for (j = 0; j < tmp_size2; j++) { GstElementFactory *fact = NULL; READ_CHECK (read_codec_blueprint_string (in, size, &(tmp))); fact = gst_element_factory_find (tmp); g_free (tmp); if (!fact) goto error; tmplist = g_list_append (tmplist, fact); } codec_blueprint->send_pipeline_factory = g_list_append (codec_blueprint->send_pipeline_factory, tmplist); } READ_CHECK (read_codec_blueprint_int (in, size, &tmp_size)); for (i = 0; i < tmp_size; i++) { int j, tmp_size2; GList *tmplist = NULL; READ_CHECK (read_codec_blueprint_int (in, size, &tmp_size2)); for (j = 0; j < tmp_size2; j++) { GstElementFactory *fact = NULL; READ_CHECK (read_codec_blueprint_string (in, size, &(tmp))); fact = gst_element_factory_find (tmp); g_free (tmp); if (!fact) goto error; tmplist = g_list_append (tmplist, fact); } codec_blueprint->receive_pipeline_factory = g_list_append (codec_blueprint->receive_pipeline_factory, tmplist); } GST_DEBUG ("adding codec %s with pt %d, send_pipeline %p, receive_pipeline %p", codec_blueprint->codec->encoding_name, codec_blueprint->codec->id, codec_blueprint->send_pipeline_factory, codec_blueprint->receive_pipeline_factory); return codec_blueprint; error: codec_blueprint_destroy (codec_blueprint); return NULL; }
static void _connected ( FsMsnConnection *connection, guint fd, gpointer user_data) { FsMsnStream *self = FS_MSN_STREAM (user_data); GError *error = NULL; GstPad *pad; GstElement *fdelem; int checkfd; FsMsnConference *conference = fs_msn_stream_get_conference (self, NULL); GstElement *codecbin = NULL; GstElement *recv_valve = NULL; GstElement *send_valve = NULL; gboolean drop; if (!conference) goto error; GST_DEBUG ("******** CONNECTED %d**********", fd); gst_element_post_message (GST_ELEMENT (conference), gst_message_new_element (GST_OBJECT (conference), gst_structure_new ("farstream-component-state-changed", "stream", FS_TYPE_STREAM, self, "component", G_TYPE_UINT, 1, "state", FS_TYPE_STREAM_STATE, FS_STREAM_STATE_READY, NULL))); if (self->priv->conference->max_direction == FS_DIRECTION_RECV) codecbin = gst_parse_bin_from_description ( "fdsrc name=fdsrc do-timestamp=true ! mimdec ! valve name=recv_valve", TRUE, &error); else codecbin = gst_parse_bin_from_description ( "videoconvert ! videoscale ! mimenc name=enc !" " fdsink name=fdsink sync=false async=false", TRUE, &error); if (!codecbin) { g_prefix_error (&error, "Error creating codecbin: "); fs_stream_emit_error (FS_STREAM (self), FS_ERROR_CONSTRUCTION, error->message); g_clear_error (&error); goto error; } /* So we don't require an unlreased gst-plugins-bad mimenc */ if (self->priv->conference->max_direction == FS_DIRECTION_SEND) { GstElement *mimenc = gst_bin_get_by_name (GST_BIN (codecbin), "enc"); if (g_object_class_find_property ( G_OBJECT_GET_CLASS (mimenc), "paused-mode")) g_object_set (mimenc, "paused-mode", TRUE, NULL); gst_object_unref (mimenc); } if (self->priv->conference->max_direction == FS_DIRECTION_RECV) { fdelem = gst_bin_get_by_name (GST_BIN (codecbin), "fdsrc"); gst_base_src_set_format (GST_BASE_SRC (fdelem), GST_FORMAT_TIME); } else { fdelem = gst_bin_get_by_name (GST_BIN (codecbin), "fdsink"); } if (!fdelem) { fs_stream_emit_error (FS_STREAM (self), FS_ERROR_CONSTRUCTION, "Could not get fd element"); goto error; } g_object_set (fdelem, "fd", fd, NULL); g_object_get (fdelem, "fd", &checkfd, NULL); gst_object_unref (fdelem); if (fd != checkfd) { fs_stream_emit_error (FS_STREAM (self), FS_ERROR_INTERNAL, "Could not set file descriptor"); goto error; } if (self->priv->conference->max_direction == FS_DIRECTION_RECV) pad = gst_element_get_static_pad (codecbin, "src"); else pad = gst_element_get_static_pad (codecbin, "sink"); if (!pad) { fs_stream_emit_error (FS_STREAM (self), FS_ERROR_CONSTRUCTION, "Could not get codecbin pad"); goto error; } if (!gst_bin_add (GST_BIN (conference), codecbin)) { gst_object_unref (pad); fs_stream_emit_error (FS_STREAM (self), FS_ERROR_CONSTRUCTION, "Could not add codecbin to the conference"); goto error; } GST_OBJECT_LOCK (conference); self->priv->fd = fd; self->priv->codecbin = gst_object_ref (codecbin); GST_OBJECT_UNLOCK (conference); if (self->priv->conference->max_direction == FS_DIRECTION_RECV) { FsCodec *mimic_codec; GstPad *src_pad; src_pad = gst_ghost_pad_new ("src_1_1_1", pad); gst_object_unref (pad); GST_OBJECT_LOCK (conference); self->priv->src_pad = gst_object_ref (src_pad); GST_OBJECT_UNLOCK (conference); gst_pad_set_active (src_pad, TRUE); if (!gst_element_add_pad (GST_ELEMENT (conference), src_pad)) { fs_stream_emit_error (FS_STREAM (self), FS_ERROR_CONSTRUCTION, "Could not add src_1_1_1 pad"); gst_object_unref (src_pad); goto error; } recv_valve = gst_bin_get_by_name (GST_BIN (codecbin), "recv_valve"); if (!recv_valve) { fs_stream_emit_error (FS_STREAM (self), FS_ERROR_CONSTRUCTION, "Could not get recv_valve"); gst_object_unref (src_pad); goto error; } GST_OBJECT_LOCK (conference); self->priv->recv_valve = gst_object_ref (recv_valve); drop = !(self->priv->direction & FS_DIRECTION_RECV); GST_OBJECT_UNLOCK (conference); g_object_set (recv_valve, "drop", drop, NULL); mimic_codec = fs_codec_new (0, "mimic", FS_MEDIA_TYPE_VIDEO, 0); fs_stream_emit_src_pad_added (FS_STREAM (self), src_pad, mimic_codec); fs_codec_destroy (mimic_codec); gst_object_unref (src_pad); } else { GstPad *valvepad; GST_OBJECT_LOCK (conference); if (self->priv->session->valve) send_valve = gst_object_ref (self->priv->session->valve); GST_OBJECT_UNLOCK (conference); if (!send_valve) { fs_stream_emit_error (FS_STREAM (self), FS_ERROR_DISPOSED, "Session was disposed"); goto error; } valvepad = gst_element_get_static_pad (send_valve, "src"); if (!valvepad) { gst_object_unref (pad); fs_stream_emit_error (FS_STREAM (self), FS_ERROR_CONSTRUCTION, "Could not get valve sink pad"); goto error; } if (GST_PAD_LINK_FAILED (gst_pad_link (valvepad, pad))) { gst_object_unref (valvepad); gst_object_unref (pad); fs_stream_emit_error (FS_STREAM (self), FS_ERROR_CONSTRUCTION, "Could not link valve to codec bin"); goto error; } gst_object_unref (valvepad); gst_object_unref (pad); } if (!gst_element_sync_state_with_parent (codecbin)) { fs_stream_emit_error (FS_STREAM (self), FS_ERROR_CONSTRUCTION, "Could not start codec bin"); goto error; } if (self->priv->conference->max_direction == FS_DIRECTION_SEND) { GST_OBJECT_LOCK (conference); fs_msn_stream_set_tos_locked (self, self->priv->tos); drop = !(self->priv->direction & FS_DIRECTION_SEND); GST_OBJECT_UNLOCK (conference); g_object_set (send_valve, "drop", drop, NULL); } error: if (send_valve) gst_object_unref (send_valve); if (recv_valve) gst_object_unref (recv_valve); if (codecbin) gst_object_unref (codecbin); if (conference) gst_object_unref (conference); }
/* insert given codec_cap list into list_codecs and list_codec_blueprints */ static void parse_codec_cap_list (GList *list, FsMediaType media_type) { GList *walk; CodecCap *codec_cap; FsCodec *codec; CodecBlueprint *codec_blueprint; gint i; GstElementFactory *tmpfact; /* go thru all common caps */ for (walk = list; walk; walk = g_list_next (walk)) { codec_cap = (CodecCap *)(walk->data); codec = fs_codec_new (FS_CODEC_ID_ANY, NULL, media_type, 0); for (i = 0; i < gst_caps_get_size (codec_cap->rtp_caps); i++) { GstStructure *structure = gst_caps_get_structure (codec_cap->rtp_caps, i); gst_structure_foreach (structure, extract_field_data, (gpointer) codec); } if (!codec->encoding_name) { GstStructure *caps = gst_caps_get_structure (codec_cap->rtp_caps, 0); const gchar *encoding_name = codec->encoding_name ? codec->encoding_name : gst_structure_get_string (caps, "encoding-name"); GST_DEBUG ("skipping codec %s/%s, no encoding name specified" " (pt: %d clock_rate:%u", media_type == FS_MEDIA_TYPE_AUDIO ? "audio" : "video", encoding_name ? encoding_name : "unknown", codec->id, codec->clock_rate); encoding_name = NULL; fs_codec_destroy (codec); continue; } switch (codec->media_type) { case FS_MEDIA_TYPE_VIDEO: if (!validate_h263_codecs (codec_cap)) { fs_codec_destroy (codec); continue; } break; case FS_MEDIA_TYPE_AUDIO: if (!validate_amr_codecs (codec_cap)) { fs_codec_destroy (codec); continue; } break; default: break; } codec_blueprint = g_slice_new0 (CodecBlueprint); codec_blueprint->codec = codec; codec_blueprint->media_caps = gst_caps_copy (codec_cap->caps); codec_blueprint->rtp_caps = gst_caps_copy (codec_cap->rtp_caps); codec_blueprint->send_pipeline_factory = copy_element_list (codec_cap->element_list2); codec_blueprint->receive_pipeline_factory = copy_element_list (codec_cap->element_list1); /* Lets add the converters at the beginning of the encoding pipelines */ if (media_type == FS_MEDIA_TYPE_VIDEO) { tmpfact = gst_element_factory_find ("fsvideoanyrate"); if (tmpfact) { codec_blueprint->send_pipeline_factory = g_list_append ( codec_blueprint->send_pipeline_factory, g_list_append (NULL, tmpfact)); } tmpfact = gst_element_factory_find ("videoconvert"); if (tmpfact) { codec_blueprint->send_pipeline_factory = g_list_append ( codec_blueprint->send_pipeline_factory, g_list_append (NULL, tmpfact)); } tmpfact = gst_element_factory_find ("videoscale"); if (tmpfact) { codec_blueprint->send_pipeline_factory = g_list_append ( codec_blueprint->send_pipeline_factory, g_list_append (NULL, tmpfact)); } } else if (media_type == FS_MEDIA_TYPE_AUDIO) { tmpfact = gst_element_factory_find ("audioconvert"); if (tmpfact) { codec_blueprint->send_pipeline_factory = g_list_append ( codec_blueprint->send_pipeline_factory, g_list_append (NULL, tmpfact)); } tmpfact = gst_element_factory_find ("audioresample"); if (tmpfact) { codec_blueprint->send_pipeline_factory = g_list_append ( codec_blueprint->send_pipeline_factory, g_list_append (NULL, tmpfact)); } tmpfact = gst_element_factory_find ("audioconvert"); if (tmpfact) { codec_blueprint->send_pipeline_factory = g_list_append ( codec_blueprint->send_pipeline_factory, g_list_append (NULL, tmpfact)); } tmpfact = gst_element_factory_find ("spanplc"); if (tmpfact) { GstElementFactory *tmpfact2; tmpfact2 = gst_element_factory_find ("audioconvert"); if (tmpfact2) { codec_blueprint->receive_pipeline_factory = g_list_append ( codec_blueprint->receive_pipeline_factory, g_list_append (NULL, tmpfact2)); codec_blueprint->receive_pipeline_factory = g_list_append ( codec_blueprint->receive_pipeline_factory, g_list_append (NULL, tmpfact)); } } } /* insert new information into tables */ list_codec_blueprints[media_type] = g_list_append ( list_codec_blueprints[media_type], codec_blueprint); GST_DEBUG ("adding codec %s with pt %d, send_pipeline %p, receive_pipeline %p", codec->encoding_name, codec->id, codec_blueprint->send_pipeline_factory, codec_blueprint->receive_pipeline_factory); GST_DEBUG ("media_caps: %" GST_PTR_FORMAT, codec_blueprint->media_caps); GST_DEBUG ("rtp_caps: %" GST_PTR_FORMAT, codec_blueprint->rtp_caps); debug_pipeline (GST_LEVEL_DEBUG, "send pipeline: ", codec_blueprint->send_pipeline_factory); debug_pipeline (GST_LEVEL_DEBUG, "receive pipeline: ", codec_blueprint->receive_pipeline_factory); } }
static GList* fs_rtp_dtmf_event_source_class_add_blueprint (FsRtpSpecialSourceClass *klass, GList *blueprints) { GList *item; GList *already_done = NULL; GstElementFactory *fact = NULL; GList *new_blueprints = NULL; fact = gst_element_factory_find ("rtpdtmfsrc"); if (fact) { gst_object_unref (fact); } else { GST_CAT_WARNING (fsrtpconference_disco, "Could not find rtpdtmfsrc, will not offer DTMF events"); return blueprints; } fact = gst_element_factory_find ("rtpdtmfdepay"); if (!fact) GST_CAT_WARNING (fsrtpconference_disco, "Could not find rtpdtmfdepay, will not be able to receive DTMF events"); for (item = g_list_first (blueprints); item; item = g_list_next (item)) { CodecBlueprint *bp = item->data; GList *done_item = NULL; gboolean skip = FALSE; CodecBlueprint *new_bp = NULL; if (bp->codec->media_type != FS_MEDIA_TYPE_AUDIO) continue; if (!g_ascii_strcasecmp (bp->codec->encoding_name, "telephone-event")) continue; if (bp->codec->clock_rate == 0) continue; for (done_item = g_list_first (already_done); done_item; done_item = g_list_next (done_item)) { if (GPOINTER_TO_UINT (done_item->data) == bp->codec->clock_rate) { skip = TRUE; break; } } if (skip) continue; new_bp = g_slice_new0 (CodecBlueprint); new_bp->codec = fs_codec_new (FS_CODEC_ID_ANY, "telephone-event", FS_MEDIA_TYPE_AUDIO, bp->codec->clock_rate); fs_codec_add_optional_parameter (new_bp->codec, "events", "0-15"); new_bp->rtp_caps = fs_codec_to_gst_caps (new_bp->codec); new_bp->media_caps = gst_caps_new_any (); if (fact) new_bp->receive_pipeline_factory = g_list_prepend (NULL, g_list_prepend (NULL, gst_object_ref (fact))); new_blueprints = g_list_append (new_blueprints, new_bp); already_done = g_list_prepend (already_done, GUINT_TO_POINTER (bp->codec->clock_rate)); } if (fact) gst_object_unref (fact); g_list_free (already_done); blueprints = g_list_concat (blueprints, new_blueprints); return blueprints; }