static void run_shm_transmitter_test (gint flags) { GError *error = NULL; FsTransmitter *trans; FsStreamTransmitter *st; GstBus *bus = NULL; GParameter params[1]; GList *local_cands = NULL; GstStateChangeReturn ret; FsCandidate *cand; GList *remote_cands = NULL; int param_count = 0; gint bus_source; done = FALSE; connected_count = 0; g_cond_init (&cond); g_mutex_init (&test_mutex); buffer_count[0] = 0; buffer_count[1] = 0; received_known[0] = 0; received_known[1] = 0; got_candidates[0] = FALSE; got_candidates[1] = FALSE; got_prepared[0] = FALSE; got_prepared[1] = FALSE; if (unlink ("/tmp/src1") < 0 && errno != ENOENT) fail ("Could not unlink /tmp/src1: %s", strerror (errno)); if (unlink ("/tmp/src2") < 0 && errno != ENOENT) fail ("Could not unlink /tmp/src2: %s", strerror (errno)); local_cands = g_list_append (local_cands, fs_candidate_new (NULL, 1, FS_CANDIDATE_TYPE_HOST, FS_NETWORK_PROTOCOL_UDP, "/tmp/src1", 0)); local_cands = g_list_append (local_cands, fs_candidate_new (NULL, 2, FS_CANDIDATE_TYPE_HOST, FS_NETWORK_PROTOCOL_UDP, "/tmp/src2", 0)); if (flags & FLAG_LOCAL_CANDIDATES) { memset (params, 0, sizeof (GParameter)); params[0].name = "preferred-local-candidates"; g_value_init (¶ms[0].value, FS_TYPE_CANDIDATE_LIST); g_value_take_boxed (¶ms[0].value, local_cands); param_count = 1; } associate_on_source = !(flags & FLAG_NO_SOURCE); if ((flags & FLAG_NOT_SENDING) && (flags & FLAG_RECVONLY_FILTER)) { buffer_count[0] = 20; received_known[0] = 20; } trans = fs_transmitter_new ("shm", 2, 0, &error); if (error) ts_fail ("Error creating transmitter: (%s:%d) %s", g_quark_to_string (error->domain), error->code, error->message); ts_fail_if (trans == NULL, "No transmitter create, yet error is still NULL"); g_clear_error (&error); if (flags & FLAG_RECVONLY_FILTER) ts_fail_unless (g_signal_connect (trans, "get-recvonly-filter", G_CALLBACK (get_recvonly_filter), NULL)); pipeline = setup_pipeline (trans, G_CALLBACK (_handoff_handler)); bus = gst_element_get_bus (pipeline); bus_source = gst_bus_add_watch (bus, bus_error_callback, NULL); gst_bus_enable_sync_message_emission (bus); g_signal_connect (bus, "sync-message::error", G_CALLBACK (sync_error_handler), NULL); gst_object_unref (bus); st = fs_transmitter_new_stream_transmitter (trans, NULL, param_count, params, &error); if (param_count) g_value_unset (¶ms[0].value); if (error) ts_fail ("Error creating stream transmitter: (%s:%d) %s", g_quark_to_string (error->domain), error->code, error->message); ts_fail_if (st == NULL, "No stream transmitter created, yet error is NULL"); g_clear_error (&error); g_object_set (st, "sending", !(flags & FLAG_NOT_SENDING), NULL); ts_fail_unless (g_signal_connect (st, "new-local-candidate", G_CALLBACK (_new_local_candidate), trans), "Could not connect new-local-candidate signal"); ts_fail_unless (g_signal_connect (st, "local-candidates-prepared", G_CALLBACK (_candidate_prepared), NULL), "Could not connect local-candidates-prepared signal"); ts_fail_unless (g_signal_connect (st, "error", G_CALLBACK (stream_transmitter_error), NULL), "Could not connect error signal"); ts_fail_unless (g_signal_connect (st, "known-source-packet-received", G_CALLBACK (_known_source_packet_received), NULL), "Could not connect known-source-packet-received signal"); ts_fail_unless (g_signal_connect (st, "state-changed", G_CALLBACK (_state_changed), NULL), "Could not connect state-changed signal"); if (!fs_stream_transmitter_gather_local_candidates (st, &error)) { if (error) ts_fail ("Could not start gathering local candidates (%s:%d) %s", g_quark_to_string (error->domain), error->code, error->message); else ts_fail ("Could not start gathering candidates" " (without a specified error)"); } else { ts_fail_unless (error == NULL); } g_clear_error (&error); ret = gst_element_set_state (pipeline, GST_STATE_PLAYING); ts_fail_if (ret == GST_STATE_CHANGE_FAILURE, "Could not set the pipeline to playing"); if (!(flags & FLAG_LOCAL_CANDIDATES)) { ret = fs_stream_transmitter_force_remote_candidates (st, local_cands, &error); fs_candidate_list_destroy (local_cands); if (error) ts_fail ("Error while adding candidate: (%s:%d) %s", g_quark_to_string (error->domain), error->code, error->message); ts_fail_unless (ret == TRUE, "No detailed error from add_remote_candidate"); } else { ts_fail_unless (error == NULL); } g_clear_error (&error); cand = fs_candidate_new (NULL, 1, FS_CANDIDATE_TYPE_HOST, FS_NETWORK_PROTOCOL_UDP, NULL, 0); cand->username = g_strdup ("/tmp/src1"); remote_cands = g_list_prepend (remote_cands, cand); cand = fs_candidate_new (NULL, 2, FS_CANDIDATE_TYPE_HOST, FS_NETWORK_PROTOCOL_UDP, NULL, 0); cand->username = g_strdup ("/tmp/src2"); remote_cands = g_list_prepend (remote_cands, cand); ret = fs_stream_transmitter_force_remote_candidates (st, remote_cands, &error); fs_candidate_list_destroy (remote_cands); if (error) ts_fail ("Error while adding candidate: (%s:%d) %s", g_quark_to_string (error->domain), error->code, error->message); ts_fail_unless (ret == TRUE, "No detailed error from add_remote_candidate"); g_clear_error (&error); g_mutex_lock (&test_mutex); while (connected_count < 2) g_cond_wait (&cond, &test_mutex); g_mutex_unlock (&test_mutex); setup_fakesrc (trans, pipeline, 1); setup_fakesrc (trans, pipeline, 2); g_mutex_lock (&test_mutex); while (!done) g_cond_wait (&cond, &test_mutex); g_mutex_unlock (&test_mutex); fail_unless (got_prepared[0] == TRUE); fail_unless (got_prepared[1] == TRUE); fail_unless (got_candidates[0] == TRUE); fail_unless (got_candidates[1] == TRUE); gst_element_set_state (pipeline, GST_STATE_NULL); if (st) { fs_stream_transmitter_stop (st); g_object_unref (st); } g_object_unref (trans); g_source_remove (bus_source); gst_object_unref (pipeline); g_cond_clear (&cond); g_mutex_clear (&test_mutex); }
static gboolean bus_watch (GstBus *bus, GstMessage *message, gpointer user_data) { struct SimpleMsnConference *dat = user_data; switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_ELEMENT: { const GstStructure *s = gst_message_get_structure (message); ts_fail_if (s==NULL, "NULL structure in element message"); if (gst_structure_has_name (s, "farstream-error")) { const GValue *value; FsError errorno; const gchar *error; ts_fail_unless ( gst_implements_interface_check (GST_MESSAGE_SRC (message), FS_TYPE_CONFERENCE), "Received farstream-error from non-farstream element"); ts_fail_unless ( gst_structure_has_field_typed (s, "src-object", G_TYPE_OBJECT), "farstream-error structure has no src-object field"); ts_fail_unless ( gst_structure_has_field_typed (s, "error-no", FS_TYPE_ERROR), "farstream-error structure has no src-object field"); ts_fail_unless ( gst_structure_has_field_typed (s, "error-msg", G_TYPE_STRING), "farstream-error structure has no src-object field"); value = gst_structure_get_value (s, "error-no"); errorno = g_value_get_enum (value); error = gst_structure_get_string (s, "error-msg"); ts_fail ("Error on BUS (%d) %s", errorno, error); } else if (gst_structure_has_name (s, "farstream-new-local-candidate")) { FsStream *stream; FsCandidate *candidate; const GValue *value; ts_fail_unless ( gst_implements_interface_check (GST_MESSAGE_SRC (message), FS_TYPE_CONFERENCE), "Received farstream-error from non-farstream element"); ts_fail_unless ( gst_structure_has_field_typed (s, "stream", FS_TYPE_STREAM), "farstream-new-local-candidate structure has no stream field"); ts_fail_unless ( gst_structure_has_field_typed (s, "candidate", FS_TYPE_CANDIDATE), "farstream-new-local-candidate structure has no candidate field"); value = gst_structure_get_value (s, "stream"); stream = g_value_get_object (value); value = gst_structure_get_value (s, "candidate"); candidate = g_value_get_boxed (value); ts_fail_unless (stream && candidate, "new-local-candidate with NULL" " stream(%p) or candidate(%p)", stream, candidate); if (dat->target) { GError *error = NULL; GList *list = g_list_append (NULL, candidate); gboolean add_remote_candidates_res; GST_DEBUG ("Setting candidate: %s %d", candidate->ip, candidate->port); add_remote_candidates_res = fs_stream_add_remote_candidates ( dat->target->stream, list, &error); ts_fail_unless (add_remote_candidates_res, "Could not set remote candidate: %s", error ? error->message : "No GError"); ts_fail_unless (error == NULL); g_list_free (list); } } } break; case GST_MESSAGE_ERROR: { GError *error = NULL; gchar *debug = NULL; gst_message_parse_error (message, &error, &debug); ts_fail ("Got an error on the BUS (%d): %s (%s)", error->code, error->message, debug); g_error_free (error); g_free (debug); } break; case GST_MESSAGE_WARNING: { GError *error = NULL; gchar *debug = NULL; gst_message_parse_warning (message, &error, &debug); GST_DEBUG ("%d: Got a warning on the BUS: %s (%s)", error->code, error->message, debug); g_error_free (error); g_free (debug); } break; default: break; } return TRUE; }
static void run_multicast_transmitter_test (gint n_parameters, GParameter *params) { GError *error = NULL; FsTransmitter *trans; FsStreamTransmitter *st; FsCandidate *tmpcand = NULL; GList *candidates = NULL; GstBus *bus = NULL; loop = g_main_loop_new (NULL, FALSE); trans = fs_transmitter_new ("multicast", 2, &error); if (error) { ts_fail ("Error creating transmitter: (%s:%d) %s", g_quark_to_string (error->domain), error->code, error->message); } ts_fail_if (trans == NULL, "No transmitter create, yet error is still NULL"); pipeline = setup_pipeline (trans, G_CALLBACK (_handoff_handler)); st = fs_transmitter_new_stream_transmitter (trans, NULL, n_parameters, params, &error); if (error) { ts_fail ("Error creating stream transmitter: (%s:%d) %s", g_quark_to_string (error->domain), error->code, error->message); } ts_fail_if (st == NULL, "No stream transmitter created, yet error is NULL"); bus = gst_element_get_bus (pipeline); gst_bus_add_watch (bus, bus_error_callback, NULL); gst_object_unref (bus); ts_fail_unless (g_signal_connect (st, "new-active-candidate-pair", G_CALLBACK (_new_active_candidate_pair), trans), "Coult not connect new-active-candidate-pair signal"); ts_fail_unless (g_signal_connect (st, "error", G_CALLBACK (stream_transmitter_error), NULL), "Could not connect error signal"); g_idle_add (_start_pipeline, pipeline); tmpcand = fs_candidate_new ("L1", FS_COMPONENT_RTP, FS_CANDIDATE_TYPE_MULTICAST, FS_NETWORK_PROTOCOL_UDP, "224.0.0.110", 2322); tmpcand->ttl = 1; candidates = g_list_prepend (candidates, tmpcand); tmpcand = fs_candidate_new ("L2", FS_COMPONENT_RTCP, FS_CANDIDATE_TYPE_MULTICAST, FS_NETWORK_PROTOCOL_UDP, "224.0.0.110", 2323); tmpcand->ttl = 1; candidates = g_list_prepend (candidates, tmpcand); if (!fs_stream_transmitter_set_remote_candidates (st, candidates, &error)) ts_fail ("Error setting the remote candidates: %p %s", error, error ? error->message : "NO ERROR SET"); ts_fail_unless (error == NULL, "Error is not null after successful candidate" " addition"); fs_candidate_list_destroy (candidates); g_main_run (loop); g_object_unref (st); g_object_unref (trans); gst_element_set_state (pipeline, GST_STATE_NULL); gst_object_unref (pipeline); g_main_loop_unref (loop); }
struct SimpleMsnConference * setup_conference (FsStreamDirection dir, struct SimpleMsnConference *target) { struct SimpleMsnConference *dat = g_new0 (struct SimpleMsnConference, 1); GError *error = NULL; GstBus *bus; GParameter param = {NULL, {0}}; gint n_params = 0; guint tos; dat->target = target; dat->direction = dir; dat->pipeline = gst_pipeline_new (NULL); bus = gst_element_get_bus (dat->pipeline); gst_bus_add_watch (bus, bus_watch, dat); gst_object_unref (bus); if (dir == FS_DIRECTION_SEND) dat->conf = FS_CONFERENCE ( gst_element_factory_make ("fsmsncamsendconference", NULL)); else dat->conf = FS_CONFERENCE ( gst_element_factory_make ("fsmsncamrecvconference", NULL)); ts_fail_unless (dat->conf != NULL); ts_fail_unless (gst_bin_add (GST_BIN (dat->pipeline), GST_ELEMENT (dat->conf))); dat->part = fs_conference_new_participant (dat->conf, &error); ts_fail_unless (error == NULL, "Error: %s", error ? error->message: ""); ts_fail_unless (dat->part != NULL); dat->session = fs_conference_new_session (dat->conf, FS_MEDIA_TYPE_VIDEO, &error); ts_fail_unless (dat->session != NULL, "Session create error: %s:", error ? error->message : "No GError"); ts_fail_unless (error == NULL); g_object_set (dat->session, "tos", 2, NULL); g_object_get (dat->session, "tos", &tos, NULL); ts_fail_unless (tos == 2); if (dir == FS_DIRECTION_SEND) { GstPad *sinkpad, *srcpad; GstElement *src; src = gst_element_factory_make ("videotestsrc", NULL); ts_fail_unless (src != NULL); g_object_set (src, "is-live", TRUE, NULL); ts_fail_unless (gst_bin_add (GST_BIN (dat->pipeline), GST_ELEMENT (src))); g_object_get (dat->session, "sink-pad", &sinkpad, NULL); ts_fail_if (sinkpad == NULL); srcpad = gst_element_get_static_pad (src, "src"); ts_fail_if (srcpad == NULL); ts_fail_if (GST_PAD_LINK_FAILED (gst_pad_link ( srcpad, sinkpad))); gst_object_unref (srcpad); gst_object_unref (sinkpad); } if (target) { guint session_id = 0; n_params = 1; g_object_get (target->stream, "session-id", &session_id, NULL); ts_fail_unless (session_id >= 9000 && session_id < 10000); param.name = "session-id"; g_value_init (¶m.value, G_TYPE_UINT); g_value_set_uint (¶m.value, session_id); } dat->stream = fs_session_new_stream (dat->session, dat->part, dir, &error); ts_fail_unless (dat->stream != NULL); ts_fail_unless (error == NULL); fail_unless (fs_stream_set_transmitter (dat->stream, NULL, ¶m, n_params, &error)); fail_unless (error == NULL); g_signal_connect (dat->stream, "src-pad-added", G_CALLBACK (stream_src_pad_added), dat); ts_fail_if (gst_element_set_state (dat->pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE); return dat; }