std::string SdpEndpointImpl::processOffer (const std::string &offer) { GstSDPMessage *offerSdp = NULL, *result = NULL; std::string offerSdpStr; bool expected = false; if (!offerInProcess.compare_exchange_strong (expected, true) ) { //the endpoint is already negotiated throw KurentoException (SDP_END_POINT_ALREADY_NEGOTIATED, "Endpoint already negotiated"); } offerSdp = str_to_sdp (offer); g_signal_emit_by_name (element, "process-offer", offerSdp, &result); gst_sdp_message_free (offerSdp); if (result == NULL) { offerInProcess = false; throw KurentoException (SDP_END_POINT_PROCESS_OFFER_ERROR, "Error processing offer"); } sdp_to_str (offerSdpStr, result); gst_sdp_message_free (result); MediaSessionStarted event (shared_from_this(), MediaSessionStarted::getName() ); signalMediaSessionStarted (event); return offerSdpStr; }
GST_END_TEST GST_START_TEST (copy) { GstSDPMessage *message, *copy; glong length = -1; gchar *message_str, *copy_str; const gchar *repeat1[] = { "789", "012", NULL }; const gchar *repeat2[] = { "987", "210", NULL }; gst_sdp_message_new (&message); gst_sdp_message_parse_buffer ((guint8 *) sdp, length, message); gst_sdp_message_add_time (message, "123", "456", repeat1); gst_sdp_message_add_time (message, "321", "654", repeat2); gst_sdp_message_copy (message, ©); message_str = gst_sdp_message_as_text (message); GST_DEBUG ("Original:\n%s", message_str); gst_sdp_message_free (message); copy_str = gst_sdp_message_as_text (copy); gst_sdp_message_free (copy); GST_DEBUG ("Copy:\n%s", copy_str); fail_if (g_strcmp0 (copy_str, message_str) != 0); g_free (copy_str); g_free (message_str); }
GstSDPMessage * kms_sdp_message_context_pack (SdpMessageContext * ctx, GError ** error) { GstSDPMessage *msg; gchar *sdp_str; GSList *l; gst_sdp_message_new (&msg); /* Context's message only stores media session attributes */ sdp_str = gst_sdp_message_as_text (ctx->msg); if (gst_sdp_message_parse_buffer ((const guint8 *) sdp_str, -1, msg) != GST_SDP_OK) { g_set_error_literal (error, KMS_SDP_AGENT_ERROR, SDP_AGENT_UNEXPECTED_ERROR, "Can not create SDP message"); g_free (sdp_str); return NULL; } g_free (sdp_str); /* Add group attributes */ g_slist_foreach (ctx->groups, (GFunc) add_group_to_sdp_message, msg); /* Append medias to the message */ for (l = ctx->medias; l != NULL; l = g_slist_next (l)) { if (!add_media_to_sdp_message (l->data, msg, error)) { gst_sdp_message_free (msg); return NULL; } } return msg; }
GST_END_TEST GST_START_TEST (media_from_caps_rtcp_fb_pt_101) { GstSDPResult ret = GST_SDP_OK; GstSDPMessage *message; glong length = -1; GstSDPMedia *media_caps; const GstSDPMedia *media_sdp; GstCaps *caps; const gchar *attr_val_caps1, *attr_val_sdp1; caps = gst_caps_from_string (caps_video_rtcp_fb_pt_101); gst_sdp_media_new (&media_caps); fail_unless (media_caps != NULL); ret = gst_sdp_media_set_media_from_caps (caps, media_caps); fail_unless (ret == GST_SDP_OK); gst_caps_unref (caps); gst_sdp_message_new (&message); gst_sdp_message_parse_buffer ((guint8 *) sdp_rtcp_fb, length, message); media_sdp = gst_sdp_message_get_media (message, 0); fail_unless (media_sdp != NULL); attr_val_caps1 = gst_sdp_media_get_attribute_val (media_caps, "rtcp-fb"); attr_val_sdp1 = gst_sdp_media_get_attribute_val_n (media_sdp, "rtcp-fb", 3); fail_if (g_strcmp0 (attr_val_caps1, attr_val_sdp1) != 0); gst_sdp_media_free (media_caps); gst_sdp_message_free (message); }
std::string SdpEndpointImpl::generateOffer () { GstSDPMessage *offer = NULL; std::string offerStr; bool expected = false; if (!offerInProcess.compare_exchange_strong (expected, true) ) { //the endpoint is already negotiated throw KurentoException (SDP_END_POINT_ALREADY_NEGOTIATED, "Endpoint already negotiated"); } if (element == NULL) { } g_signal_emit_by_name (element, "generate-offer", &offer); if (offer == NULL) { offerInProcess = false; throw KurentoException (SDP_END_POINT_GENERATE_OFFER_ERROR, "Error generating offer"); } sdp_to_str (offerStr, offer); gst_sdp_message_free (offer); waitingAnswer = true; return offerStr; }
std::string SdpEndpointImpl::processAnswer (const std::string &answer) { GstSDPMessage *answerSdp; std::string resultStr; bool expected = true; bool expected_false = false; if (!waitingAnswer.compare_exchange_strong (expected, true) ) { //offer not generated throw KurentoException (SDP_END_POINT_NOT_OFFER_GENERATED, "Offer not generated. It is not possible to process an answer."); } if (!answerProcessed.compare_exchange_strong (expected_false, true) ) { //the endpoint is already negotiated throw KurentoException (SDP_END_POINT_ANSWER_ALREADY_PROCCESED, "Sdp Answer already processed"); } answerSdp = str_to_sdp (answer); g_signal_emit_by_name (element, "process-answer", answerSdp, NULL); gst_sdp_message_free (answerSdp); MediaSessionStarted event (shared_from_this(), MediaSessionStarted::getName() ); signalMediaSessionStarted (event); return getLocalSessionDescriptor (); }
GST_END_TEST GST_START_TEST (modify) { GstSDPMessage *message; glong length = -1; const GstSDPMedia *media; const gchar *old_val; const gchar *result; GstSDPAttribute attr; gst_sdp_message_new (&message); gst_sdp_message_parse_buffer ((guint8 *) sdp, length, message); /* modify session attribute */ fail_unless (gst_sdp_message_add_attribute (message, "test_attr_session", "param1=val1") == GST_SDP_OK); old_val = gst_sdp_message_get_attribute_val (message, "test_attr_session"); fail_unless (old_val != NULL); attr.key = g_strdup ("test_attr_session"); attr.value = g_strdup_printf ("%s;param2=val2", old_val); fail_unless (gst_sdp_message_replace_attribute (message, 0, &attr) == GST_SDP_OK); result = gst_sdp_message_get_attribute_val (message, "test_attr_session"); fail_unless (result != NULL); fail_unless (g_strcmp0 (result, "param1=val1;param2=val2") == 0); /* modify media attribute */ media = gst_sdp_message_get_media (message, 0); fail_unless (media != NULL); fail_unless (gst_sdp_media_add_attribute ((GstSDPMedia *) media, "test_attr_media", "param3=val3") == GST_SDP_OK); old_val = gst_sdp_media_get_attribute_val ((GstSDPMedia *) media, "test_attr_media"); fail_unless (old_val != NULL); attr.key = g_strdup ("test_attr_media"); attr.value = g_strdup ("myparam=myval"); fail_unless (gst_sdp_media_replace_attribute ((GstSDPMedia *) media, 0, &attr) == GST_SDP_OK); result = gst_sdp_media_get_attribute_val ((GstSDPMedia *) media, "test_attr_media"); fail_unless (result != NULL); fail_unless (g_strcmp0 (result, "myparam=myval") == 0); gst_sdp_message_free (message); }
static void kms_sdp_agent_release_sdp (GstSDPMessage ** sdp) { if (*sdp == NULL) { return; } gst_sdp_message_free (*sdp); *sdp = NULL; }
static gboolean test_response_sdp (GstRTSPClient * client, GstRTSPMessage * response, gboolean close, gpointer user_data) { guint8 *data; guint size; GstSDPMessage *sdp_msg; const GstSDPMedia *sdp_media; const GstSDPBandwidth *bw; gint bandwidth_val = GPOINTER_TO_INT (user_data); fail_unless (gst_rtsp_message_get_body (response, &data, &size) == GST_RTSP_OK); gst_sdp_message_new (&sdp_msg); fail_unless (gst_sdp_message_parse_buffer (data, size, sdp_msg) == GST_SDP_OK); /* session description */ /* v= */ fail_unless (gst_sdp_message_get_version (sdp_msg) != NULL); /* o= */ fail_unless (gst_sdp_message_get_origin (sdp_msg) != NULL); /* s= */ fail_unless (gst_sdp_message_get_session_name (sdp_msg) != NULL); /* t=0 0 */ fail_unless (gst_sdp_message_times_len (sdp_msg) == 0); /* verify number of medias */ fail_unless (gst_sdp_message_medias_len (sdp_msg) == 1); /* media description */ sdp_media = gst_sdp_message_get_media (sdp_msg, 0); fail_unless (sdp_media != NULL); /* m= */ fail_unless (gst_sdp_media_get_media (sdp_media) != NULL); /* media bandwidth */ if (bandwidth_val) { fail_unless (gst_sdp_media_bandwidths_len (sdp_media) == 1); bw = gst_sdp_media_get_bandwidth (sdp_media, 0); fail_unless (bw != NULL); fail_unless (g_strcmp0 (bw->bwtype, "AS") == 0); fail_unless (bw->bandwidth == bandwidth_val); } else { fail_unless (gst_sdp_media_bandwidths_len (sdp_media) == 0); } gst_sdp_message_free (sdp_msg); return TRUE; }
std::string SdpEndpointImpl::processOffer (const std::string &offer) { GstSDPMessage *offerSdp = NULL, *result = NULL; std::string offerSdpStr; offerSdp = str_to_sdp (offer); g_signal_emit_by_name (element, "process-offer", offerSdp, &result); gst_sdp_message_free (offerSdp); if (result == NULL) { throw KurentoException (SDP_END_POINT_PROCESS_OFFER_ERROR, "Error processing offer"); } sdp_to_str (offerSdpStr, result); gst_sdp_message_free (result); MediaSessionStarted event (shared_from_this(), MediaSessionStarted::getName() ); signalMediaSessionStarted (event); return offerSdpStr; }
std::string SdpEndpointImpl::processAnswer (const std::string &answer) { GstSDPMessage *answerSdp; std::string resultStr; answerSdp = str_to_sdp (answer); g_signal_emit_by_name (element, "process-answer", answerSdp, NULL); gst_sdp_message_free (answerSdp); MediaSessionStarted event (shared_from_this(), MediaSessionStarted::getName() ); signalMediaSessionStarted (event); return getLocalSessionDescriptor (); }
std::string SdpEndpointImpl::getRemoteSessionDescriptor () { GstSDPMessage *remoteSdp = NULL; std::string remoteSdpStr; g_object_get (element, "remote-sdp", &remoteSdp, NULL); if (remoteSdp == NULL) { throw KurentoException (SDP_END_POINT_NO_REMOTE_SDP_ERROR, "No remote SDP"); } sdp_to_str (remoteSdpStr, remoteSdp);; gst_sdp_message_free (remoteSdp); return remoteSdpStr; }
std::string SdpEndpointImpl::getRemoteSessionDescriptor () { GstSDPMessage *remoteSdp = NULL; std::string remoteSdpStr; g_signal_emit_by_name (element, "get-remote-sdp", sessId.c_str (), &remoteSdp); if (remoteSdp == NULL) { throw KurentoException (SDP_END_POINT_NO_REMOTE_SDP_ERROR, "No remote SDP"); } sdp_to_str (remoteSdpStr, remoteSdp);; gst_sdp_message_free (remoteSdp); return remoteSdpStr; }
std::string SdpEndpointImpl::getLocalSessionDescriptor () { GstSDPMessage *localSdp = NULL; std::string localSdpStr; g_signal_emit_by_name (element, "get-local-sdp", sessId.c_str (), &localSdp); if (localSdp == NULL) { throw KurentoException (SDP_END_POINT_NO_LOCAL_SDP_ERROR, "No local SDP"); } sdp_to_str (localSdpStr, localSdp); gst_sdp_message_free (localSdp); return localSdpStr; }
std::string SdpEndpointImpl::getLocalSessionDescriptor () { GstSDPMessage *localSdp = NULL; std::string localSdpStr; g_object_get (element, "local-sdp", &localSdp, NULL); if (localSdp == NULL) { throw KurentoException (SDP_END_POINT_NO_LOCAL_SDP_ERROR, "No local SDP"); } sdp_to_str (localSdpStr, localSdp); gst_sdp_message_free (localSdp); return localSdpStr; }
GST_END_TEST GST_START_TEST (media_from_caps) { GstSDPResult ret = GST_SDP_OK; GstSDPMessage *message; glong length = -1; GstSDPMedia *media_video, *media_audio; const GstSDPMedia *result_video, *result_audio; GstCaps *caps_video, *caps_audio; const gchar *media1_text, *media2_text, *media3_text, *media4_text; caps_video = gst_caps_from_string (caps_video_string1); caps_audio = gst_caps_from_string (caps_audio_string); gst_sdp_media_new (&media_video); fail_unless (media_video != NULL); gst_sdp_media_new (&media_audio); fail_unless (media_audio != NULL); ret = gst_sdp_media_set_media_from_caps (caps_video, media_video); fail_unless (ret == GST_SDP_OK); gst_caps_unref (caps_video); ret = gst_sdp_media_set_media_from_caps (caps_audio, media_audio); fail_unless (ret == GST_SDP_OK); gst_caps_unref (caps_audio); gst_sdp_message_new (&message); gst_sdp_message_parse_buffer ((guint8 *) sdp, length, message); result_video = gst_sdp_message_get_media (message, 0); fail_unless (result_video != NULL); result_audio = gst_sdp_message_get_media (message, 2); fail_unless (result_audio != NULL); media1_text = gst_sdp_media_get_attribute_val (media_video, "rtpmap"); media2_text = gst_sdp_media_get_attribute_val (result_video, "rtpmap"); media3_text = gst_sdp_media_get_format (media_audio, 0); media4_text = gst_sdp_media_get_format (result_audio, 0); fail_if (g_strcmp0 (media1_text, media2_text) != 0); fail_if (g_strcmp0 (media3_text, media4_text) != 0); gst_sdp_media_free (media_video); gst_sdp_media_free (media_audio); gst_sdp_message_free (message); }
void kms_sdp_message_context_destroy (SdpMessageContext * ctx) { if (ctx->msg != NULL) { gst_sdp_message_free (ctx->msg); } g_hash_table_unref (ctx->mids); g_slist_free_full (ctx->medias, (GDestroyNotify) kms_sdp_context_destroy_media_config); g_slist_free_full (ctx->groups, (GDestroyNotify) kms_sdp_context_destroy_media_group); g_slice_free (SdpMessageContext, ctx); }
GST_END_TEST GST_START_TEST (caps_from_media) { GstSDPMessage *message; glong length = -1; const GstSDPMedia *media1, *media2, *media3; GstCaps *caps_video1, *caps_video2, *caps_audio; GstCaps *result_video1, *result_video2, *result_audio; gst_sdp_message_new (&message); gst_sdp_message_parse_buffer ((guint8 *) sdp, length, message); media1 = gst_sdp_message_get_media (message, 0); fail_unless (media1 != NULL); media2 = gst_sdp_message_get_media (message, 1); fail_unless (media2 != NULL); media3 = gst_sdp_message_get_media (message, 2); fail_unless (media2 != NULL); caps_video1 = gst_sdp_media_get_caps_from_media (media1, 96); caps_video2 = gst_sdp_media_get_caps_from_media (media1, 97); caps_audio = gst_sdp_media_get_caps_from_media (media3, 14); result_video1 = gst_caps_from_string (caps_video_string1); fail_unless (gst_caps_is_strictly_equal (caps_video1, result_video1)); gst_caps_unref (result_video1); gst_caps_unref (caps_video1); result_video2 = gst_caps_from_string (caps_video_string2); fail_unless (gst_caps_is_strictly_equal (caps_video2, result_video2)); gst_caps_unref (result_video2); gst_caps_unref (caps_video2); result_audio = gst_caps_from_string (caps_audio_string); fail_unless (gst_caps_is_strictly_equal (caps_audio, result_audio)); gst_caps_unref (result_audio); gst_caps_unref (caps_audio); gst_sdp_message_free (message); }
std::string SdpEndpointImpl::generateOffer () { GstSDPMessage *offer = NULL; std::string offerStr; if (element == NULL) { } g_signal_emit_by_name (element, "generate-offer", &offer); if (offer == NULL) { throw KurentoException (SDP_END_POINT_GENERATE_OFFER_ERROR, "Error generating offer"); } sdp_to_str (offerStr, offer); gst_sdp_message_free (offer); return offerStr; }
void rtsp_media_free(RTSP_media *medium) { g_assert(medium != NULL); if (medium->sdp) { gst_sdp_message_free(medium->sdp); } if (medium->rtp_sessions) { rtsp_media_del_rtp_sessions(medium->rtp_sessions); } if (medium->content_base) { g_free(medium->content_base); } g_free(medium); }
GST_END_TEST GST_START_TEST (caps_from_media_rtcp_fb_all) { GstSDPMessage *message; glong length = -1; const GstSDPMedia *media1; GstCaps *caps1, *caps2, *caps3; GstCaps *result1, *result2, *result3; gst_sdp_message_new (&message); gst_sdp_message_parse_buffer ((guint8 *) sdp_rtcp_fb_all, length, message); media1 = gst_sdp_message_get_media (message, 0); fail_unless (media1 != NULL); caps1 = gst_sdp_media_get_caps_from_media (media1, 100); result1 = gst_caps_from_string (caps_video_rtcp_fb_all_pt_100); fail_unless (gst_caps_is_strictly_equal (caps1, result1)); gst_caps_unref (result1); gst_caps_unref (caps1); caps2 = gst_sdp_media_get_caps_from_media (media1, 101); result2 = gst_caps_from_string (caps_video_rtcp_fb_all_pt_101); fail_unless (gst_caps_is_strictly_equal (caps2, result2)); gst_caps_unref (result2); gst_caps_unref (caps2); caps3 = gst_sdp_media_get_caps_from_media (media1, 102); result3 = gst_caps_from_string (caps_video_rtcp_fb_all_pt_102); fail_unless (gst_caps_is_strictly_equal (caps3, result3)); gst_caps_unref (result3); gst_caps_unref (caps3); gst_sdp_message_free (message); }
static GstSDPMessage * str_to_sdp (const std::string &sdpStr) { GstSDPResult result; GstSDPMessage *sdp = NULL; result = gst_sdp_message_new (&sdp); if (result != GST_SDP_OK) { throw KurentoException (SDP_CREATE_ERROR, "Error creating SDP message"); } result = gst_sdp_message_parse_buffer ( (const guint8 *) sdpStr.c_str (), -1, sdp); if (result != GST_SDP_OK) { gst_sdp_message_free (sdp); throw KurentoException (SDP_PARSE_ERROR, "Error parsing SDP"); } return sdp; }
SDPDescription::~SDPDescription() { gst_sdp_message_free(sdp_description_); }
GST_END_TEST GST_START_TEST (negotiation_offerer) { GArray *audio_codecs_array, *video_codecs_array; gchar *audio_codecs[] = { "OPUS/48000/1", "AMR/8000/1", NULL }; gchar *video_codecs[] = { "H263-1998/90000", "VP8/90000", NULL }; GstElement *offerer = gst_element_factory_make ("rtpendpoint", NULL); GstElement *answerer = gst_element_factory_make ("rtpendpoint", NULL); GstSDPMessage *offer = NULL, *answer = NULL; GstSDPMessage *offerer_local_sdp = NULL, *offerer_remote_sdp = NULL; gchar *offerer_local_sdp_str, *offerer_remote_sdp_str; GstSDPMessage *answerer_local_sdp = NULL, *answerer_remote_sdp = NULL; gchar *answerer_local_sdp_str, *answerer_remote_sdp_str; gchar *sdp_str = NULL; audio_codecs_array = create_codecs_array (audio_codecs); video_codecs_array = create_codecs_array (video_codecs); g_object_set (offerer, "num-audio-medias", 1, "audio-codecs", g_array_ref (audio_codecs_array), "num-video-medias", 1, "video-codecs", g_array_ref (video_codecs_array), NULL); g_object_set (answerer, "num-audio-medias", 1, "audio-codecs", g_array_ref (audio_codecs_array), "num-video-medias", 1, "video-codecs", g_array_ref (video_codecs_array), NULL); g_array_unref (audio_codecs_array); g_array_unref (video_codecs_array); g_signal_emit_by_name (offerer, "generate-offer", &offer); fail_unless (offer != NULL); GST_DEBUG ("Offer:\n%s", (sdp_str = gst_sdp_message_as_text (offer))); g_free (sdp_str); sdp_str = NULL; g_signal_emit_by_name (answerer, "process-offer", offer, &answer); fail_unless (answer != NULL); GST_DEBUG ("Answer:\n%s", (sdp_str = gst_sdp_message_as_text (answer))); g_free (sdp_str); sdp_str = NULL; g_signal_emit_by_name (offerer, "process-answer", answer); gst_sdp_message_free (offer); gst_sdp_message_free (answer); g_object_get (offerer, "local-sdp", &offerer_local_sdp, NULL); fail_unless (offerer_local_sdp != NULL); g_object_get (offerer, "remote-sdp", &offerer_remote_sdp, NULL); fail_unless (offerer_remote_sdp != NULL); g_object_get (answerer, "local-sdp", &answerer_local_sdp, NULL); fail_unless (answerer_local_sdp != NULL); g_object_get (answerer, "remote-sdp", &answerer_remote_sdp, NULL); fail_unless (answerer_remote_sdp != NULL); offerer_local_sdp_str = gst_sdp_message_as_text (offerer_local_sdp); offerer_remote_sdp_str = gst_sdp_message_as_text (offerer_remote_sdp); answerer_local_sdp_str = gst_sdp_message_as_text (answerer_local_sdp); answerer_remote_sdp_str = gst_sdp_message_as_text (answerer_remote_sdp); GST_DEBUG ("Offerer local SDP\n%s", offerer_local_sdp_str); GST_DEBUG ("Offerer remote SDPr\n%s", offerer_remote_sdp_str); GST_DEBUG ("Answerer local SDP\n%s", answerer_local_sdp_str); GST_DEBUG ("Answerer remote SDP\n%s", answerer_remote_sdp_str); fail_unless (g_strcmp0 (offerer_local_sdp_str, answerer_remote_sdp_str) == 0); fail_unless (g_strcmp0 (offerer_remote_sdp_str, answerer_local_sdp_str) == 0); g_free (offerer_local_sdp_str); g_free (offerer_remote_sdp_str); g_free (answerer_local_sdp_str); g_free (answerer_remote_sdp_str); gst_sdp_message_free (offerer_local_sdp); gst_sdp_message_free (offerer_remote_sdp); gst_sdp_message_free (answerer_local_sdp); gst_sdp_message_free (answerer_remote_sdp); g_object_unref (offerer); g_object_unref (answerer); }
static void test_audio_sendrecv (const gchar * audio_enc_name, GstStaticCaps expected_caps, gchar * codec) { GArray *codecs_array; gchar *codecs[] = { codec, NULL }; HandOffData *hod; GMainLoop *loop = g_main_loop_new (NULL, TRUE); GstSDPMessage *offer, *answer; GstElement *pipeline = gst_pipeline_new (NULL); GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); GstElement *audiotestsrc_offerer = gst_element_factory_make ("audiotestsrc", NULL); GstElement *audiotestsrc_answerer = gst_element_factory_make ("audiotestsrc", NULL); GstElement *audio_enc_offerer = gst_element_factory_make (audio_enc_name, NULL); GstElement *audio_enc_answerer = gst_element_factory_make (audio_enc_name, NULL); GstElement *rtpendpoint_offerer = gst_element_factory_make ("rtpendpoint", NULL); GstElement *rtpendpoint_answerer = gst_element_factory_make ("rtpendpoint", NULL); GstElement *fakesink_offerer = gst_element_factory_make ("fakesink", NULL); GstElement *fakesink_answerer = gst_element_factory_make ("fakesink", NULL); gst_bus_add_signal_watch (bus); g_signal_connect (bus, "message", G_CALLBACK (bus_msg), pipeline); codecs_array = create_codecs_array (codecs); g_object_set (rtpendpoint_offerer, "num-audio-medias", 1, "audio-codecs", g_array_ref (codecs_array), NULL); g_object_set (rtpendpoint_answerer, "num-audio-medias", 1, "audio-codecs", g_array_ref (codecs_array), NULL); g_array_unref (codecs_array); hod = g_slice_new (HandOffData); hod->expected_caps = expected_caps; hod->loop = loop; g_object_set (G_OBJECT (fakesink_offerer), "signal-handoffs", TRUE, NULL); g_signal_connect (G_OBJECT (fakesink_offerer), "handoff", G_CALLBACK (sendrecv_offerer_fakesink_hand_off), hod); g_object_set (G_OBJECT (fakesink_answerer), "signal-handoffs", TRUE, NULL); g_signal_connect (G_OBJECT (fakesink_answerer), "handoff", G_CALLBACK (sendrecv_answerer_fakesink_hand_off), hod); /* Add elements */ gst_bin_add (GST_BIN (pipeline), rtpendpoint_offerer); connect_sink_async (rtpendpoint_offerer, audiotestsrc_offerer, audio_enc_offerer, NULL, pipeline, "sink_audio"); gst_bin_add (GST_BIN (pipeline), rtpendpoint_answerer); connect_sink_async (rtpendpoint_answerer, audiotestsrc_answerer, audio_enc_answerer, NULL, pipeline, "sink_audio"); gst_element_set_state (pipeline, GST_STATE_PLAYING); /* SDP negotiation */ mark_point (); g_signal_emit_by_name (rtpendpoint_offerer, "generate-offer", &offer); fail_unless (offer != NULL); mark_point (); g_signal_emit_by_name (rtpendpoint_answerer, "process-offer", offer, &answer); fail_unless (answer != NULL); mark_point (); g_signal_emit_by_name (rtpendpoint_offerer, "process-answer", answer); gst_sdp_message_free (offer); gst_sdp_message_free (answer); gst_bin_add (GST_BIN (pipeline), fakesink_offerer); g_object_set_data (G_OBJECT (rtpendpoint_offerer), AUDIO_SINK, fakesink_offerer); g_signal_connect (rtpendpoint_offerer, "pad-added", G_CALLBACK (connect_sink_on_srcpad_added), NULL); fail_unless (kms_element_request_srcpad (rtpendpoint_offerer, KMS_ELEMENT_PAD_TYPE_AUDIO)); gst_bin_add (GST_BIN (pipeline), fakesink_answerer); g_object_set_data (G_OBJECT (rtpendpoint_answerer), AUDIO_SINK, fakesink_answerer); g_signal_connect (rtpendpoint_answerer, "pad-added", G_CALLBACK (connect_sink_on_srcpad_added), NULL); fail_unless (kms_element_request_srcpad (rtpendpoint_answerer, KMS_ELEMENT_PAD_TYPE_AUDIO)); GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "test_audio_sendrecv_before_entering_loop"); mark_point (); g_main_loop_run (loop); mark_point (); GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "test_audio_sendrecv_end"); gst_element_set_state (pipeline, GST_STATE_NULL); gst_bus_remove_signal_watch (bus); g_object_unref (bus); g_main_loop_unref (loop); g_object_unref (pipeline); g_slice_free (HandOffData, hod); }
GST_END_TEST GST_START_TEST (process_webrtc_offer) { GstSDPMessage *pattern_sdp; GstElement *rtpendpoint = gst_element_factory_make ("rtpendpoint", NULL); GstSDPMessage *offer = NULL, *answer = NULL; gchar *aux = NULL; static const gchar *offer_str = "v=0\r\n" "o=- 1783800438437245920 2 IN IP4 127.0.0.1\r\n" "s=-\r\n" "t=0 0\r\n" "a=group:BUNDLE audio video\r\n" "a=msid-semantic: WMS MediaStream0\r\n" "m=audio 37426 RTP/SAVPF 111 103 9 102 0 8 106 105 13 127 126\r\n" "c=IN IP4 5.5.5.5\r\n" "a=rtcp:37426 IN IP4 5.5.5.5\r\n" "a=candidate:1840965416 1 udp 2113937151 192.168.0.100 37426 typ host generation 0\r\n" "a=candidate:1840965416 2 udp 2113937151 192.168.0.100 37426 typ host generation 0\r\n" "a=candidate:590945240 1 tcp 1509957375 192.168.0.100 46029 typ host generation 0\r\n" "a=candidate:590945240 2 tcp 1509957375 192.168.0.100 46029 typ host generation 0\r\n" "a=candidate:3975340444 1 udp 1677729535 5.5.5.5 37426 typ srflx raddr 192.168.0.100 rport 37426 generation 0\r\n" "a=candidate:3975340444 2 udp 1677729535 5.5.5.5 37426 typ srflx raddr 192.168.0.100 rport 37426 generation 0\r\n" "a=ice-ufrag:RkI7xTFiQgGZu1ww\r\n" "a=ice-pwd:6ZTKNoP2vXWYLweywju9Bydv\r\n" "a=ice-options:google-ice\r\n" "a=mid:audio\r\n" "a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\n" "a=sendrecv\r\n" "a=rtcp-mux\r\n" "a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:vpy+PnhF0bWmwYlAngWT1cc9qppYCvRlwT4aKrYh\r\n" "a=rtpmap:111 opus/48000/1\r\n" "a=fmtp:111 minptime=10\r\n" "a=rtpmap:103 ISAC/16000\r\n" "a=rtpmap:9 G722/16000\r\n" "a=rtpmap:102 ILBC/8000\r\n" "a=rtpmap:0 PCMU/8000\r\n" "a=rtpmap:8 PCMA/8000\r\n" "a=rtpmap:106 CN/32000\r\n" "a=rtpmap:105 CN/16000\r\n" "a=rtpmap:13 CN/8000\r\n" "a=rtpmap:127 red/8000\r\n" "a=rtpmap:126 telephone-event/8000\r\n" "a=maxptime:60\r\n" "a=ssrc:4210654932 cname:/9kskFtadoxn1x70\r\n" "a=ssrc:4210654932 msid:MediaStream0 AudioTrack0\r\n" "a=ssrc:4210654932 mslabel:MediaStream0\r\n" "a=ssrc:4210654932 label:AudioTrack0\r\n" "m=video 37426 RTP/SAVPF 100 116 117\r\n" "c=IN IP4 5.5.5.5\r\n" "a=rtcp:37426 IN IP4 5.5.5.5\r\n" "a=candidate:1840965416 1 udp 2113937151 192.168.0.100 37426 typ host generation 0\r\n" "a=candidate:1840965416 2 udp 2113937151 192.168.0.100 37426 typ host generation 0\r\n" "a=candidate:590945240 1 tcp 1509957375 192.168.0.100 46029 typ host generation 0\r\n" "a=candidate:590945240 2 tcp 1509957375 192.168.0.100 46029 typ host generation 0\r\n" "a=candidate:3975340444 1 udp 1677729535 5.5.5.5 37426 typ srflx raddr 192.168.0.100 rport 37426 generation 0\r\n" "a=candidate:3975340444 2 udp 1677729535 5.5.5.5 37426 typ srflx raddr 192.168.0.100 rport 37426 generation 0\r\n" "a=ice-ufrag:RkI7xTFiQgGZu1ww\r\n" "a=ice-pwd:6ZTKNoP2vXWYLweywju9Bydv\r\n" "a=ice-options:google-ice\r\n" "a=mid:video\r\n" "a=extmap:2 urn:ietf:params:rtp-hdrext:toffset\r\n" "a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\n" "a=sendrecv\r\n" "a=rtcp-mux\r\n" "a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:vpy+PnhF0bWmwYlAngWT1cc9qppYCvRlwT4aKrYh\r\n" "a=rtpmap:100 VP8/90000\r\n" "a=rtcp-fb:100 ccm fir\r\n" "a=rtcp-fb:100 nack\r\n" "a=rtcp-fb:100 nack pli\r\n" "a=rtcp-fb:100 goog-remb\r\n" "a=rtpmap:116 red/90000\r\n" "a=rtpmap:117 ulpfec/90000\r\n" "a=ssrc:1686396354 cname:/9kskFtadoxn1x70\r\n" "a=ssrc:1686396354 msid:MediaStream0 VideoTrack0\r\n" "a=ssrc:1686396354 mslabel:MediaStream0\r\n" "a=ssrc:1686396354 label:VideoTrack0\r\n"; fail_unless (gst_sdp_message_new (&pattern_sdp) == GST_SDP_OK); fail_unless (gst_sdp_message_parse_buffer ((const guint8 *) pattern_offer_sdp_str, -1, pattern_sdp) == GST_SDP_OK); g_object_set (rtpendpoint, "pattern-sdp", pattern_sdp, NULL); fail_unless (gst_sdp_message_free (pattern_sdp) == GST_SDP_OK); g_object_get (rtpendpoint, "pattern-sdp", &pattern_sdp, NULL); fail_unless (pattern_sdp != NULL); fail_unless (gst_sdp_message_free (pattern_sdp) == GST_SDP_OK); fail_unless (gst_sdp_message_new (&offer) == GST_SDP_OK); fail_unless (gst_sdp_message_parse_buffer ((const guint8 *) offer_str, -1, offer) == GST_SDP_OK); GST_DEBUG ("Offer:\n%s", (aux = gst_sdp_message_as_text (offer))); g_free (aux); aux = NULL; g_signal_emit_by_name (rtpendpoint, "process-offer", offer, &answer); fail_unless (answer != NULL); GST_DEBUG ("Answer:\n%s", (aux = gst_sdp_message_as_text (answer))); g_free (aux); aux = NULL; gst_sdp_message_free (offer); gst_sdp_message_free (answer); g_object_unref (rtpendpoint); }
GST_END_TEST GST_START_TEST (negotiation_offerer) { GstSDPMessage *pattern_sdp; GstElement *offerer = gst_element_factory_make ("rtpendpoint", NULL); GstElement *answerer = gst_element_factory_make ("rtpendpoint", NULL); GstSDPMessage *offer = NULL, *answer = NULL; GstSDPMessage *local_offer = NULL, *local_answer = NULL, *remote_offer = NULL, *remote_answer = NULL; gchar *local_offer_str, *local_answer_str, *remote_offer_str, *remote_answer_str; gchar *aux = NULL; fail_unless (gst_sdp_message_new (&pattern_sdp) == GST_SDP_OK); fail_unless (gst_sdp_message_parse_buffer ((const guint8 *) pattern_offer_sdp_str, -1, pattern_sdp) == GST_SDP_OK); g_object_set (offerer, "pattern-sdp", pattern_sdp, NULL); fail_unless (gst_sdp_message_free (pattern_sdp) == GST_SDP_OK); g_object_get (offerer, "pattern-sdp", &pattern_sdp, NULL); fail_unless (pattern_sdp != NULL); fail_unless (gst_sdp_message_free (pattern_sdp) == GST_SDP_OK); fail_unless (gst_sdp_message_new (&pattern_sdp) == GST_SDP_OK); fail_unless (gst_sdp_message_parse_buffer ((const guint8 *) pattern_answer_sdp_str, -1, pattern_sdp) == GST_SDP_OK); g_object_set (answerer, "pattern-sdp", pattern_sdp, NULL); fail_unless (gst_sdp_message_free (pattern_sdp) == GST_SDP_OK); g_signal_emit_by_name (offerer, "generate-offer", &offer); fail_unless (offer != NULL); GST_DEBUG ("Offer:\n%s", (aux = gst_sdp_message_as_text (offer))); g_free (aux); aux = NULL; g_signal_emit_by_name (answerer, "process-offer", offer, &answer); fail_unless (answer != NULL); GST_DEBUG ("Answer:\n%s", (aux = gst_sdp_message_as_text (answer))); g_free (aux); aux = NULL; g_signal_emit_by_name (offerer, "process-answer", answer); gst_sdp_message_free (offer); gst_sdp_message_free (answer); g_object_get (offerer, "local-offer-sdp", &local_offer, NULL); g_object_get (offerer, "remote-answer-sdp", &remote_answer, NULL); g_object_get (answerer, "remote-offer-sdp", &remote_offer, NULL); g_object_get (answerer, "local-answer-sdp", &local_answer, NULL); fail_unless (local_offer != NULL); fail_unless (remote_answer != NULL); fail_unless (remote_offer != NULL); fail_unless (local_answer != NULL); local_offer_str = gst_sdp_message_as_text (local_offer); remote_answer_str = gst_sdp_message_as_text (remote_answer); remote_offer_str = gst_sdp_message_as_text (remote_offer); local_answer_str = gst_sdp_message_as_text (local_answer); GST_DEBUG ("Local offer\n%s", local_offer_str); GST_DEBUG ("Remote answer\n%s", remote_answer_str); GST_DEBUG ("Remote offer\n%s", remote_offer_str); GST_DEBUG ("Local answer\n%s", local_answer_str); fail_unless (g_strcmp0 (local_offer_str, remote_offer_str) == 0); fail_unless (g_strcmp0 (remote_answer_str, local_answer_str) == 0); g_free (local_offer_str); g_free (remote_answer_str); g_free (local_answer_str); g_free (remote_offer_str); gst_sdp_message_free (local_offer); gst_sdp_message_free (remote_answer); gst_sdp_message_free (remote_offer); gst_sdp_message_free (local_answer); g_object_unref (offerer); g_object_unref (answerer); }
static GstRTSPStatusCode nmp_rtsp_handle_response(NmpMediaDevice *device, GstRTSPMessage *response) { GstRTSPStatusCode res_code; GstRTSPVersion version; const gchar *reason = NULL; gchar *sessid = NULL, *cseq = NULL, *content_base = NULL; GstRTSPResult ret; NmpRtspMedia *media = NULL; NmpSessionState s_state; GstSDPMessage *sdp = NULL; guint8 *sdp_body = NULL; guint sdp_size, seq; gst_rtsp_message_parse_response(response, &res_code, &reason, &version); if (version != GST_RTSP_VERSION_1_0) { nmp_warning("Device RTSP response version mismatch"); return GST_RTSP_STS_RTSP_VERSION_NOT_SUPPORTED; } ret = gst_rtsp_message_get_header(response, GST_RTSP_HDR_CSEQ, &cseq, 0); if (ret != GST_RTSP_OK) { nmp_warning("Device RTSP response, No 'CSeq:' field"); return GST_RTSP_STS_INVALID; } seq = atoi(cseq); if (!seq) return GST_RTSP_OK; media = nmp_rtsp_device_get_media(device, seq); if (!media) { //TEARDOWN或者SET_PARAMETER响应 nmp_print( "Drop device response(TEARDOWN|SET_PARAMETER), seq:'%s'.", cseq ); return GST_RTSP_OK; } s_state = nmp_rtsp_media_get_session_state(media); if (s_state == NMP_SESSION_TEARDOWN) { nmp_print( "Response _After_ TEARDOWN ?? seq:'%s'", cseq ); goto handle_teardown_ok; } if (res_code != GST_RTSP_STS_OK) { nmp_warning("Device RTSP res-code: %d", res_code); goto handle_response_failed; } ret = gst_rtsp_message_get_header(response, GST_RTSP_HDR_SESSION, &sessid, 0); if (ret != GST_RTSP_OK) { //只有DESCRIBE消息没有SESSION域 if (s_state != NMP_SESSION_DESCRIBE) { nmp_warning("Device RTSP response, No 'Session:' field"); goto handle_response_failed; } ret = gst_rtsp_message_get_header(response, GST_RTSP_HDR_CONTENT_BASE, &content_base, 0); if (ret != GST_RTSP_OK) { nmp_warning("Device RTSP response, No 'Content-Base:' field"); goto handle_response_failed; } //处理DESCRIBE消息 if (gst_sdp_message_new(&sdp) != GST_SDP_OK) { nmp_warning("Create SDP message failed"); goto handle_response_failed; } gst_rtsp_message_get_body(response, &sdp_body, &sdp_size); if (gst_sdp_message_parse_buffer(sdp_body, sdp_size, sdp) != GST_SDP_OK) { nmp_warning("Device DESCRIBE response, invalid SDP info"); gst_sdp_message_free(sdp); goto handle_response_failed; } nmp_rtsp_media_set_sdp_info(media, sdp); } else { if (s_state == NMP_SESSION_SETUP) nmp_rtsp_media_set_session_id(media, sessid); } if (nmp_rtsp_media_session_state_next(media) == NMP_SESSION_PLAY) nmp_rtsp_media_deal_pending_request(media); if (nmp_rtsp_device_request(device, media)) { nmp_warning("Device RTSP Request failed"); goto handle_response_failed; } handle_teardown_ok: nmp_rtsp_media_unref(media); return GST_RTSP_OK; handle_response_failed: nmp_rtsp_media_die_announce(media, device); // nmp_rtsp_media_deal_pending_request(media); /* nmp_rtsp_media_kill_unref() can do this */ nmp_rtsp_device_remove_media(device, media); nmp_rtsp_media_kill_unref(media); return GST_RTSP_OK; }
static void test_video_sendonly (const gchar * video_enc_name, GstStaticCaps expected_caps, const gchar * pattern_sdp_sendonly_str, const gchar * pattern_sdp_recvonly_str, gboolean play_after_negotiation) { HandOffData *hod; GMainLoop *loop = g_main_loop_new (NULL, TRUE); GstSDPMessage *pattern_sdp, *offer, *answer; GstElement *pipeline = gst_pipeline_new (NULL); GstElement *videotestsrc = gst_element_factory_make ("videotestsrc", NULL); GstElement *video_enc = gst_element_factory_make (video_enc_name, NULL); GstElement *rtpendpointsender = gst_element_factory_make ("rtpendpoint", NULL); GstElement *rtpendpointreceiver = gst_element_factory_make ("rtpendpoint", NULL); GstElement *outputfakesink = gst_element_factory_make ("fakesink", NULL); GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); gst_bus_add_watch (bus, gst_bus_async_signal_func, NULL); g_signal_connect (bus, "message", G_CALLBACK (bus_msg), pipeline); g_object_unref (bus); fail_unless (gst_sdp_message_new (&pattern_sdp) == GST_SDP_OK); fail_unless (gst_sdp_message_parse_buffer ((const guint8 *) pattern_sdp_sendonly_str, -1, pattern_sdp) == GST_SDP_OK); g_object_set (rtpendpointsender, "pattern-sdp", pattern_sdp, NULL); fail_unless (gst_sdp_message_free (pattern_sdp) == GST_SDP_OK); fail_unless (gst_sdp_message_new (&pattern_sdp) == GST_SDP_OK); fail_unless (gst_sdp_message_parse_buffer ((const guint8 *) pattern_sdp_recvonly_str, -1, pattern_sdp) == GST_SDP_OK); g_object_set (rtpendpointreceiver, "pattern-sdp", pattern_sdp, NULL); fail_unless (gst_sdp_message_free (pattern_sdp) == GST_SDP_OK); hod = g_slice_new (HandOffData); hod->expected_caps = expected_caps; hod->loop = loop; g_object_set (G_OBJECT (outputfakesink), "signal-handoffs", TRUE, NULL); g_signal_connect (G_OBJECT (outputfakesink), "handoff", G_CALLBACK (fakesink_hand_off), hod); /* Add elements */ gst_bin_add_many (GST_BIN (pipeline), videotestsrc, video_enc, rtpendpointsender, NULL); gst_element_link (videotestsrc, video_enc); gst_element_link_pads (video_enc, NULL, rtpendpointsender, "video_sink"); gst_bin_add_many (GST_BIN (pipeline), rtpendpointreceiver, outputfakesink, NULL); kms_element_link_pads (rtpendpointreceiver, "video_src_%u", outputfakesink, "sink"); if (!play_after_negotiation) gst_element_set_state (pipeline, GST_STATE_PLAYING); /* SDP negotiation */ mark_point (); g_signal_emit_by_name (rtpendpointsender, "generate-offer", &offer); fail_unless (offer != NULL); mark_point (); g_signal_emit_by_name (rtpendpointreceiver, "process-offer", offer, &answer); fail_unless (answer != NULL); mark_point (); g_signal_emit_by_name (rtpendpointsender, "process-answer", answer); gst_sdp_message_free (offer); gst_sdp_message_free (answer); if (play_after_negotiation) gst_element_set_state (pipeline, GST_STATE_PLAYING); GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "test_sendonly_before_entering_loop"); mark_point (); g_main_loop_run (loop); mark_point (); GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "test_sendonly_end"); gst_element_set_state (pipeline, GST_STATE_NULL); g_object_unref (pipeline); g_slice_free (HandOffData, hod); g_main_loop_unref (loop); }
GST_END_TEST GST_START_TEST (negotiation_offerer) { GArray *audio_codecs_array, *video_codecs_array; gchar *audio_codecs[] = { "OPUS/48000/1", "AMR/8000/1", NULL }; gchar *video_codecs[] = { "H263-1998/90000", "VP8/90000", NULL }; gchar *offerer_sess_id, *answerer_sess_id; GstElement *offerer = gst_element_factory_make ("rtpendpoint", NULL); GstElement *answerer = gst_element_factory_make ("rtpendpoint", NULL); GstSDPMessage *offer = NULL, *answer = NULL; GstSDPMessage *offerer_local_sdp = NULL, *offerer_remote_sdp = NULL; gchar *offerer_local_sdp_str, *offerer_remote_sdp_str; GstSDPMessage *answerer_local_sdp = NULL, *answerer_remote_sdp = NULL; gchar *answerer_local_sdp_str, *answerer_remote_sdp_str; gchar *sdp_str = NULL; const GstSDPConnection *connection; gboolean answer_ok; audio_codecs_array = create_codecs_array (audio_codecs); video_codecs_array = create_codecs_array (video_codecs); g_object_set (offerer, "num-audio-medias", 1, "audio-codecs", g_array_ref (audio_codecs_array), "num-video-medias", 1, "video-codecs", g_array_ref (video_codecs_array), NULL); g_object_set (answerer, "num-audio-medias", 1, "audio-codecs", g_array_ref (audio_codecs_array), "num-video-medias", 1, "video-codecs", g_array_ref (video_codecs_array), NULL); g_array_unref (audio_codecs_array); g_array_unref (video_codecs_array); /* Session creation */ g_signal_emit_by_name (offerer, "create-session", &offerer_sess_id); GST_DEBUG_OBJECT (offerer, "Created session with id '%s'", offerer_sess_id); g_signal_emit_by_name (answerer, "create-session", &answerer_sess_id); GST_DEBUG_OBJECT (answerer, "Created session with id '%s'", answerer_sess_id); /* SDP negotiation */ g_signal_emit_by_name (offerer, "generate-offer", offerer_sess_id, &offer); fail_unless (offer != NULL); GST_DEBUG ("Offer:\n%s", (sdp_str = gst_sdp_message_as_text (offer))); g_free (sdp_str); sdp_str = NULL; connection = gst_sdp_message_get_connection (offer); fail_unless (g_strcmp0 (connection->address, "0.0.0.0")); fail_unless (g_strcmp0 (connection->address, "::")); g_signal_emit_by_name (answerer, "process-offer", answerer_sess_id, offer, &answer); fail_unless (answer != NULL); GST_DEBUG ("Answer:\n%s", (sdp_str = gst_sdp_message_as_text (answer))); g_free (sdp_str); sdp_str = NULL; g_signal_emit_by_name (offerer, "process-answer", offerer_sess_id, answer, &answer_ok); fail_unless (answer_ok); gst_sdp_message_free (offer); gst_sdp_message_free (answer); g_signal_emit_by_name (offerer, "get-local-sdp", offerer_sess_id, &offerer_local_sdp); fail_unless (offerer_local_sdp != NULL); g_signal_emit_by_name (offerer, "get-remote-sdp", offerer_sess_id, &offerer_remote_sdp); fail_unless (offerer_remote_sdp != NULL); g_signal_emit_by_name (answerer, "get-local-sdp", answerer_sess_id, &answerer_local_sdp); fail_unless (answerer_local_sdp != NULL); g_signal_emit_by_name (answerer, "get-remote-sdp", answerer_sess_id, &answerer_remote_sdp); fail_unless (answerer_remote_sdp != NULL); offerer_local_sdp_str = gst_sdp_message_as_text (offerer_local_sdp); offerer_remote_sdp_str = gst_sdp_message_as_text (offerer_remote_sdp); answerer_local_sdp_str = gst_sdp_message_as_text (answerer_local_sdp); answerer_remote_sdp_str = gst_sdp_message_as_text (answerer_remote_sdp); GST_DEBUG ("Offerer local SDP\n%s", offerer_local_sdp_str); GST_DEBUG ("Offerer remote SDPr\n%s", offerer_remote_sdp_str); GST_DEBUG ("Answerer local SDP\n%s", answerer_local_sdp_str); GST_DEBUG ("Answerer remote SDP\n%s", answerer_remote_sdp_str); fail_unless (g_strcmp0 (offerer_local_sdp_str, answerer_remote_sdp_str) == 0); fail_unless (g_strcmp0 (offerer_remote_sdp_str, answerer_local_sdp_str) == 0); g_free (offerer_local_sdp_str); g_free (offerer_remote_sdp_str); g_free (answerer_local_sdp_str); g_free (answerer_remote_sdp_str); gst_sdp_message_free (offerer_local_sdp); gst_sdp_message_free (offerer_remote_sdp); gst_sdp_message_free (answerer_local_sdp); gst_sdp_message_free (answerer_remote_sdp); g_object_unref (offerer); g_object_unref (answerer); g_free (offerer_sess_id); g_free (answerer_sess_id); }