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); }
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); }
/** * \brief creates SAP message: header + payload returned in a buffer * \param channelTable_entry * entry the entry in the channelTable associated to the socket * \param sap_msg_length a location to save the lenght of the SAP message * \param gboolean deletion specify if we should build the SAP deletion message * \return char* buffer that contains the SAP message (the UDP payload) */ static char* build_SAP_msg(struct channelTable_entry * entry, int *sap_msg_length, gboolean deletion){ GstSDPMessage *msg; /* create a new SDP message */ if (gst_sdp_message_new(&msg)){ g_critical("Failed to create SDP message\n"); return FALSE; } /* * build the SDP message */ create_SDP(msg, entry); /* extract the randomly generated session_version integer */ const GstSDPOrigin *origin = gst_sdp_message_get_origin (msg); int session_version = htonl(atoi(origin->sess_version)); /* Build the header */ char header[SAP_header_size]; build_SAP_header(header, session_version, deletion); /* Build the *payload */ char *payload = g_strdup (gst_sdp_message_as_text(msg)); /* concat header and payload */ int sap_msg_size = SAP_header_size+strlen(payload); char *sap_msg = (char*) malloc(sap_msg_size*sizeof(char)); memcpy(sap_msg, header, SAP_header_size); memcpy(sap_msg+SAP_header_size, payload, strlen(payload)); *sap_msg_length = sap_msg_size; // save the length if the message into sap_msg_length free(payload); return sap_msg; }
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 (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 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; }
GstSDPMessage * SdpEndpointImpl::getSdpPattern () { GstSDPMessage *sdp; GstSDPResult result; boost::filesystem::path sdp_pattern_file; std::unique_lock<std::mutex> lock (sdpMutex); if (pattern) { return pattern.get(); } try { sdp_pattern_file = boost::filesystem::path ( getConfigValue<std::string, SdpEndpoint> ("sdpPattern") ); } catch (boost::property_tree::ptree_error &e) { throw kurento::KurentoException (SDP_CONFIGURATION_ERROR, "Error reading SDP pattern from configuration, please contact the administrator: " + std::string (e.what() ) ); } if (!sdp_pattern_file.is_absolute() ) { try { sdp_pattern_file = boost::filesystem::path ( getConfigValue<std::string, SdpEndpoint> ("configPath") ) / sdp_pattern_file; } catch (boost::property_tree::ptree_error &e) { } } result = gst_sdp_message_new (&sdp); if (result != GST_SDP_OK) { GST_ERROR ("Error creating sdp message"); throw kurento::KurentoException (SDP_CREATE_ERROR, "Error creating SDP pattern"); } pattern = std::shared_ptr<GstSDPMessage> (sdp, gst_sdp_message_free); result = gst_sdp_message_parse_buffer ( (const guint8 *) readEntireFile ( sdp_pattern_file.string() ).c_str(), -1, sdp); if (result != GST_SDP_OK) { GST_ERROR ("Error parsing SDP config pattern"); pattern.reset(); throw kurento::KurentoException (SDP_CONFIGURATION_ERROR, "Error reading SDP pattern from configuration, please contact the administrator"); } return pattern.get(); }
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); }
SdpMessageContext * kms_sdp_message_context_new (SdpIPv ipv, const gchar * addr, GError ** error) { SdpMessageContext *ctx; ctx = g_slice_new0 (SdpMessageContext); gst_sdp_message_new (&ctx->msg); ctx->mids = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) kms_utils_destroy_guint); if (!kms_sdp_message_context_set_default_session_attributes (ctx->msg, ipv, addr, error)) { kms_sdp_message_context_destroy (ctx); return NULL; } return 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); }
SDPDescription::SDPDescription(const std::string& ip_addr) : ip_addr_(ip_addr) { gst_sdp_message_new(&sdp_description_); /* some standard things first */ gst_sdp_message_set_version(sdp_description_, "0"); // FIXME check and chose between IP4 and IP6, IP4 hardcoded // FIXME generate proper session id &version gst_sdp_message_set_origin(sdp_description_, "-", // the user name "1188340656180883", // a session id "1", // a session version "IN", // a network type "IP4", // an address type ip_addr.c_str()); // an address gst_sdp_message_set_session_name(sdp_description_, "switcher"); gst_sdp_message_set_information(sdp_description_, "telepresence"); gst_sdp_message_add_time(sdp_description_, "0", "0", nullptr); gst_sdp_message_add_attribute(sdp_description_, "tool", "switcher"); gst_sdp_message_add_attribute(sdp_description_, "type", "broadcast"); gst_sdp_message_add_attribute(sdp_description_, "control", "*"); }
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; }
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); }
static gint create_and_send_ANNOUNCE_message2(GstRTSPsink* sink, GTimeVal *timeout, char **szSessionNumber) { const gchar *url_client_ip_str = "0.0.0.0";//"192.168.2.104"; const gchar *url_server_str_full = g_strdup_printf("rtsp://%s:%d/%s", sink->host, sink->port, sink->stream_name); //"rtsp://192.168.2.108:1935/live/1"; //conn = sink->conn; GstRTSPMessage msg = { 0 }; GstSDPMessage *sdp; GstRTSPMethod method; GstRTSPResult res; guint num_ports = 1; guint rtp_port = 5006; char *szPayloadType = g_strdup_printf("%d", sink->payload); method = GST_RTSP_ANNOUNCE ; res = gst_rtsp_message_init_request(&msg, method, url_server_str_full); if (res < 0) return res; /* set user-agent */ if (sink->user_agent) gst_rtsp_message_add_header(&msg, GST_RTSP_HDR_USER_AGENT, sink->user_agent); gst_rtsp_message_add_header(&msg, GST_RTSP_HDR_CONTENT_TYPE, "application/sdp"); // allocate sdp messege buffer... res = gst_sdp_message_new(&sdp); //v=.. res = gst_sdp_message_set_version(sdp, "0"); //o=... res = gst_sdp_message_set_origin(sdp, "-", "0", "0", "IN", "IP4", "0.0.0.0"); //s=.. if (sink->session_name) res = gst_sdp_message_set_session_name(sdp, "Unnamed"); //i=.. if (sink->information) res = gst_sdp_message_set_information(sdp, "N/A"); //c=... res = gst_sdp_message_set_connection(sdp, "IN", "IP4", url_client_ip_str, 0, 0); //a=... res = gst_sdp_message_add_attribute(sdp, "recvonly", NULL); // create media GstSDPMedia *media; res = gst_sdp_media_new(&media); res = gst_sdp_media_init(media); //m=... res = gst_sdp_media_set_media(media, "video"); res = gst_sdp_media_set_port_info(media, rtp_port, num_ports); res = gst_sdp_media_set_proto(media, "RTP/AVP"); res = gst_sdp_media_add_format(media, szPayloadType); //a=... char *rtpmap = g_strdup_printf("%s %s/%d", szPayloadType, sink->encoding_name, sink->clock_rate); res = gst_sdp_media_add_attribute(media, "rtpmap", rtpmap); res = gst_sdp_media_add_attribute(media, "fmtp", szPayloadType); res = gst_sdp_media_add_attribute(media, "control", "streamid=0"); // insert media into sdp res = gst_sdp_message_add_media(sdp, media); gchar * sdp_str = gst_sdp_message_as_text(sdp); int size = g_utf8_strlen(sdp_str, 500); gst_sdp_message_free(sdp); gst_sdp_media_free(media); res = gst_rtsp_message_set_body(&msg, sdp_str, size); sink->responce = &msg; // Send our packet receive server answer and check some basic checks. if ((res = sendReceiveAndCheck(sink->conn, timeout, &msg, sink->debug)) != GST_RTSP_OK) { return res; } // get session number *szSessionNumber = extractSessionNumberFromMessage(&msg); return GST_RTSP_OK; }