Пример #1
0
static SalStreamDescription * sdp_to_stream_description(SalMediaDescription *md, belle_sdp_media_description_t *media_desc) {
	SalStreamDescription *stream;
	belle_sdp_connection_t* cnx;
	belle_sdp_media_t* media;
	belle_sdp_attribute_t* attribute;
	const char* value;
	const char *mtype,*proto;

	stream=&md->streams[md->n_total_streams];
	media=belle_sdp_media_description_get_media ( media_desc );

	memset ( stream,0,sizeof ( *stream ) );

	proto = belle_sdp_media_get_protocol ( media );
	stream->proto=SalProtoOther;
	if ( proto ) {
		if ( strcasecmp ( proto,"RTP/AVP" ) ==0 )
			stream->proto=SalProtoRtpAvp;
		else if ( strcasecmp ( proto,"RTP/SAVP" ) ==0 ) {
			stream->proto=SalProtoRtpSavp;
		}else{
			strncpy(stream->proto_other,proto,sizeof(stream->proto_other)-1);
		}
	}
	if ( ( cnx=belle_sdp_media_description_get_connection ( media_desc ) ) && belle_sdp_connection_get_address ( cnx ) ) {
		strncpy ( stream->rtp_addr,belle_sdp_connection_get_address ( cnx ), sizeof ( stream->rtp_addr ) -1 );
	}

	stream->rtp_port=belle_sdp_media_get_media_port ( media );

	if ( stream->rtp_port > 0 )
		md->n_active_streams++;

	mtype = belle_sdp_media_get_media_type ( media );
	if ( strcasecmp ( "audio", mtype ) == 0 ) {
		stream->type=SalAudio;
	} else if ( strcasecmp ( "video", mtype ) == 0 ) {
		stream->type=SalVideo;
	} else {
		stream->type=SalOther;
		strncpy ( stream->typeother,mtype,sizeof ( stream->typeother )-1 );
	}

	if ( belle_sdp_media_description_get_bandwidth ( media_desc,"AS" ) >0 ) {
		stream->bandwidth=belle_sdp_media_description_get_bandwidth ( media_desc,"AS" );
	}

	if ( belle_sdp_media_description_get_attribute ( media_desc,"sendrecv" ) ) {
		stream->dir=SalStreamSendRecv;
	} else if ( belle_sdp_media_description_get_attribute ( media_desc,"sendonly" ) ) {
		stream->dir=SalStreamSendOnly;
	} else if ( belle_sdp_media_description_get_attribute ( media_desc,"recvonly" ) ) {
		stream->dir=SalStreamRecvOnly;
	} else if ( belle_sdp_media_description_get_attribute ( media_desc,"inactive" ) ) {
		stream->dir=SalStreamInactive;
	} else {
		stream->dir=md->dir; /*takes default value if not present*/
	}

	/* Get media payload types */
	sdp_parse_payload_types(media_desc, stream);

	/* Get media specific RTCP attribute */
	stream->rtcp_port = stream->rtp_port + 1;
	snprintf(stream->rtcp_addr, sizeof(stream->rtcp_addr), "%s", stream->rtp_addr);
	attribute=belle_sdp_media_description_get_attribute(media_desc,"rtcp");
	if (attribute && (value=belle_sdp_attribute_get_value(attribute))!=NULL){
		char tmp[256];
		int nb = sscanf(value, "%d IN IP4 %s", &stream->rtcp_port, tmp);
		if (nb == 1) {
			/* SDP rtcp attribute only contains the port */
		} else if (nb == 2) {
			strncpy(stream->rtcp_addr, tmp, sizeof(stream->rtcp_addr)-1);
		} else {
			ms_warning("sdp has a strange a=rtcp line (%s) nb=%i", value, nb);
		}
	}

	/* Read crypto lines if any */
	if ( stream->proto == SalProtoRtpSavp ) {
		sdp_parse_media_crypto_parameters(media_desc, stream);
	}

	/* Get ICE candidate attributes if any */
	sdp_parse_media_ice_parameters(media_desc, stream);

	/* Get RTCP-XR attributes if any */
	stream->rtcp_xr = md->rtcp_xr;	// Use session parameters if no stream parameters are defined
	sdp_parse_media_rtcp_xr_parameters(media_desc, &stream->rtcp_xr);

	md->n_total_streams++;
	return stream;
}
Пример #2
0
static SalStreamDescription * sdp_to_stream_description(SalMediaDescription *md, belle_sdp_media_description_t *media_desc) {
	SalStreamDescription *stream;
	belle_sdp_connection_t* cnx;
	belle_sdp_media_t* media;
	belle_sdp_attribute_t* attribute;
	const char* value;
	const char *mtype,*proto;

	stream=&md->streams[md->nb_streams];
	media=belle_sdp_media_description_get_media ( media_desc );

	proto = belle_sdp_media_get_protocol ( media );
	stream->proto=SalProtoOther;
	if ( proto ) {
		if (strcasecmp(proto, "RTP/AVP") == 0) {
			stream->proto = SalProtoRtpAvp;
		} else if (strcasecmp(proto, "RTP/SAVP") == 0) {
			stream->proto = SalProtoRtpSavp;
		} else if (strcasecmp(proto, "RTP/AVPF") == 0) {
			stream->proto = SalProtoRtpAvpf;
		} else if (strcasecmp(proto, "RTP/SAVPF") == 0) {
			stream->proto = SalProtoRtpSavpf;
		} else if (strcasecmp(proto, "UDP/TLS/RTP/SAVP") == 0) {
			stream->proto = SalProtoUdpTlsRtpSavp;
		} else if (strcasecmp(proto, "UDP/TLS/RTP/SAVPF") == 0) {
			stream->proto = SalProtoUdpTlsRtpSavpf;
		} else {
			strncpy(stream->proto_other,proto,sizeof(stream->proto_other)-1);
		}
	}
	if ( ( cnx=belle_sdp_media_description_get_connection ( media_desc ) ) && belle_sdp_connection_get_address ( cnx ) ) {
		strncpy ( stream->rtp_addr,belle_sdp_connection_get_address ( cnx ), sizeof ( stream->rtp_addr ) -1 );
		stream->ttl=belle_sdp_connection_get_ttl(cnx);
	}

	stream->rtp_port=belle_sdp_media_get_media_port ( media );

	mtype = belle_sdp_media_get_media_type ( media );
	if ( strcasecmp ( "audio", mtype ) == 0 ) {
		stream->type=SalAudio;
	} else if ( strcasecmp ( "video", mtype ) == 0 ) {
		stream->type=SalVideo;
	} else {
		stream->type=SalOther;
		strncpy ( stream->typeother,mtype,sizeof ( stream->typeother )-1 );
	}

	if ( belle_sdp_media_description_get_bandwidth ( media_desc,"AS" ) >0 ) {
		stream->bandwidth=belle_sdp_media_description_get_bandwidth ( media_desc,"AS" );
	}

	if ( belle_sdp_media_description_get_attribute ( media_desc,"sendrecv" ) ) {
		stream->dir=SalStreamSendRecv;
	} else if ( belle_sdp_media_description_get_attribute ( media_desc,"sendonly" ) ) {
		stream->dir=SalStreamSendOnly;
	} else if ( belle_sdp_media_description_get_attribute ( media_desc,"recvonly" ) ) {
		stream->dir=SalStreamRecvOnly;
	} else if ( belle_sdp_media_description_get_attribute ( media_desc,"inactive" ) ) {
		stream->dir=SalStreamInactive;
	} else {
		stream->dir=md->dir; /*takes default value if not present*/
	}

	/* Get media payload types */
	sdp_parse_payload_types(media_desc, stream);

	/* Get media specific RTCP attribute */
	stream->rtcp_port = stream->rtp_port + 1;
	snprintf(stream->rtcp_addr, sizeof(stream->rtcp_addr), "%s", stream->rtp_addr);
	attribute=belle_sdp_media_description_get_attribute(media_desc,"rtcp");
	if (attribute && (value=belle_sdp_attribute_get_value(attribute))!=NULL){
		char tmp[256];
		int nb = sscanf(value, "%d IN IP4 %s", &stream->rtcp_port, tmp);
		if (nb == 1) {
			/* SDP rtcp attribute only contains the port */
		} else if (nb == 2) {
			strncpy(stream->rtcp_addr, tmp, sizeof(stream->rtcp_addr)-1);
		} else {
			ms_warning("sdp has a strange a=rtcp line (%s) nb=%i", value, nb);
		}
	}

	/* Read DTLS specific attributes : check is some are found in the stream description otherwise copy the session description one(which are at least set to Invalid) */
	if (((stream->proto == SalProtoUdpTlsRtpSavpf) || (stream->proto == SalProtoUdpTlsRtpSavp))) {
		attribute=belle_sdp_media_description_get_attribute(media_desc,"setup");
		if (attribute && (value=belle_sdp_attribute_get_value(attribute))!=NULL){
			if (strncmp(value, "actpass", 7) == 0) {
				stream->dtls_role = SalDtlsRoleUnset;
			} else if (strncmp(value, "active", 6) == 0) {
				stream->dtls_role = SalDtlsRoleIsClient;
			} else if (strncmp(value, "passive", 7) == 0) {
				stream->dtls_role = SalDtlsRoleIsServer;
			}
		}
		if (stream->dtls_role != SalDtlsRoleInvalid && (attribute=belle_sdp_media_description_get_attribute(media_desc,"fingerprint"))) {
			strncpy(stream->dtls_fingerprint, belle_sdp_attribute_get_value(attribute),sizeof(stream->dtls_fingerprint));
		}
	}

	/* Read crypto lines if any */
	if ((stream->proto == SalProtoRtpSavpf) || (stream->proto == SalProtoRtpSavp)) {
		sdp_parse_media_crypto_parameters(media_desc, stream);
	}

	/* Get ICE candidate attributes if any */
	sdp_parse_media_ice_parameters(media_desc, stream);

	/* Get RTCP-FB attributes if any */
	if ((stream->proto == SalProtoRtpAvpf) || (stream->proto == SalProtoRtpSavpf)) {
		enable_avpf_for_stream(stream);
		sdp_parse_rtcp_fb_parameters(media_desc, stream);
	}

	/* Get RTCP-XR attributes if any */
	stream->rtcp_xr = md->rtcp_xr;	// Use session parameters if no stream parameters are defined
	sdp_parse_media_rtcp_xr_parameters(media_desc, &stream->rtcp_xr);

	md->nb_streams++;
	return stream;
}