mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-27 06:31:54 +00:00 
			
		
		
		
	res_pjsip_sdp_rtp: Preserve order of RTP codecs
The ast_rtp_codecs_payloads functions do not preserve the order in which the payloads were specified on an incoming SDP media line. This leads to a problem with the codec negotiation functionality, as the format capabilities of the stream are extracted from the ast_rtp_codecs. This commit moves the ast_rtp_codec to ast_format conversion to the place where the order is still known. ASTERISK-28863 ASTERISK-29320 Change-Id: I3aabcfed3f379c36654f59c1872c313d0cb57e25
This commit is contained in:
		
				
					committed by
					
						 Joshua Colp
						Joshua Colp
					
				
			
			
				
	
			
			
			
						parent
						
							d83a46869e
						
					
				
				
					commit
					4e204db2bf
				
			| @@ -313,7 +313,7 @@ static int create_rtp(struct ast_sip_session *session, struct ast_sip_session_me | |||||||
| } | } | ||||||
|  |  | ||||||
| static void get_codecs(struct ast_sip_session *session, const struct pjmedia_sdp_media *stream, struct ast_rtp_codecs *codecs, | static void get_codecs(struct ast_sip_session *session, const struct pjmedia_sdp_media *stream, struct ast_rtp_codecs *codecs, | ||||||
| 	struct ast_sip_session_media *session_media) | 	struct ast_sip_session_media *session_media, struct ast_format_cap *astformats) | ||||||
| { | { | ||||||
| 	pjmedia_sdp_attr *attr; | 	pjmedia_sdp_attr *attr; | ||||||
| 	pjmedia_sdp_rtpmap *rtpmap; | 	pjmedia_sdp_rtpmap *rtpmap; | ||||||
| @@ -329,6 +329,8 @@ static void get_codecs(struct ast_sip_session *session, const struct pjmedia_sdp | |||||||
|  |  | ||||||
| 	ast_rtp_codecs_payloads_initialize(codecs); | 	ast_rtp_codecs_payloads_initialize(codecs); | ||||||
|  |  | ||||||
|  | 	ast_format_cap_remove_by_type(astformats, AST_MEDIA_TYPE_UNKNOWN); | ||||||
|  |  | ||||||
| 	/* Iterate through provided formats */ | 	/* Iterate through provided formats */ | ||||||
| 	for (i = 0; i < stream->desc.fmt_count; ++i) { | 	for (i = 0; i < stream->desc.fmt_count; ++i) { | ||||||
| 		/* The payload is kept as a string for things like t38 but for video it is always numerical */ | 		/* The payload is kept as a string for things like t38 but for video it is always numerical */ | ||||||
| @@ -372,11 +374,19 @@ static void get_codecs(struct ast_sip_session *session, const struct pjmedia_sdp | |||||||
| 					ast_rtp_codecs_payload_replace_format(codecs, num, format_parsed); | 					ast_rtp_codecs_payload_replace_format(codecs, num, format_parsed); | ||||||
| 					ao2_ref(format_parsed, -1); | 					ao2_ref(format_parsed, -1); | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				ao2_ref(format, -1); | 				ao2_ref(format, -1); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	/* Parsing done, now fill the ast_format_cap struct in the correct order */ | ||||||
|  | 	for (i = 0; i < stream->desc.fmt_count; ++i) { | ||||||
|  | 		if ((format = ast_rtp_codecs_get_payload_format(codecs, pj_strtoul(&stream->desc.fmt[i])))) { | ||||||
|  | 			ast_format_cap_append(astformats, format, 0); | ||||||
|  | 			ao2_ref(format, -1); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if (!tel_event && (session->dtmf == AST_SIP_DTMF_AUTO)) { | 	if (!tel_event && (session->dtmf == AST_SIP_DTMF_AUTO)) { | ||||||
| 		ast_rtp_instance_dtmf_mode_set(session_media->rtp, AST_RTP_DTMF_MODE_INBAND); | 		ast_rtp_instance_dtmf_mode_set(session_media->rtp, AST_RTP_DTMF_MODE_INBAND); | ||||||
| 		ast_rtp_instance_set_prop(session_media->rtp, AST_RTP_PROPERTY_DTMF, 0); | 		ast_rtp_instance_set_prop(session_media->rtp, AST_RTP_PROPERTY_DTMF, 0); | ||||||
| @@ -398,6 +408,7 @@ static void get_codecs(struct ast_sip_session *session, const struct pjmedia_sdp | |||||||
| 		unsigned long framing = pj_strtoul(pj_strltrim(&attr->value)); | 		unsigned long framing = pj_strtoul(pj_strltrim(&attr->value)); | ||||||
| 		if (framing && session->endpoint->media.rtp.use_ptime) { | 		if (framing && session->endpoint->media.rtp.use_ptime) { | ||||||
| 			ast_rtp_codecs_set_framing(codecs, framing); | 			ast_rtp_codecs_set_framing(codecs, framing); | ||||||
|  | 			ast_format_cap_set_framing(astformats, framing); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -442,7 +453,6 @@ static struct ast_format_cap *set_incoming_call_offer_cap( | |||||||
| 	struct ast_format_cap *incoming_call_offer_cap; | 	struct ast_format_cap *incoming_call_offer_cap; | ||||||
| 	struct ast_format_cap *remote; | 	struct ast_format_cap *remote; | ||||||
| 	struct ast_rtp_codecs codecs = AST_RTP_CODECS_NULL_INIT; | 	struct ast_rtp_codecs codecs = AST_RTP_CODECS_NULL_INIT; | ||||||
| 	int fmts = 0; |  | ||||||
| 	SCOPE_ENTER(1, "%s\n", ast_sip_session_get_name(session)); | 	SCOPE_ENTER(1, "%s\n", ast_sip_session_get_name(session)); | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -454,8 +464,7 @@ static struct ast_format_cap *set_incoming_call_offer_cap( | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	/* Get the peer's capabilities*/ | 	/* Get the peer's capabilities*/ | ||||||
| 	get_codecs(session, stream, &codecs, session_media); | 	get_codecs(session, stream, &codecs, session_media, remote); | ||||||
| 	ast_rtp_codecs_payload_formats(&codecs, remote, &fmts); |  | ||||||
|  |  | ||||||
| 	incoming_call_offer_cap = ast_sip_session_create_joint_call_cap( | 	incoming_call_offer_cap = ast_sip_session_create_joint_call_cap( | ||||||
| 		session, session_media->type, remote); | 		session, session_media->type, remote); | ||||||
| @@ -493,7 +502,6 @@ static int set_caps(struct ast_sip_session *session, | |||||||
| 	RAII_VAR(struct ast_format_cap *, joint, NULL, ao2_cleanup); | 	RAII_VAR(struct ast_format_cap *, joint, NULL, ao2_cleanup); | ||||||
| 	enum ast_media_type media_type = session_media->type; | 	enum ast_media_type media_type = session_media->type; | ||||||
| 	struct ast_rtp_codecs codecs = AST_RTP_CODECS_NULL_INIT; | 	struct ast_rtp_codecs codecs = AST_RTP_CODECS_NULL_INIT; | ||||||
| 	int fmts = 0; |  | ||||||
| 	int direct_media_enabled = !ast_sockaddr_isnull(&session_media->direct_media_addr) && | 	int direct_media_enabled = !ast_sockaddr_isnull(&session_media->direct_media_addr) && | ||||||
| 		ast_format_cap_count(session->direct_media_cap); | 		ast_format_cap_count(session->direct_media_cap); | ||||||
| 	int dsp_features = 0; | 	int dsp_features = 0; | ||||||
| @@ -516,8 +524,7 @@ static int set_caps(struct ast_sip_session *session, | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	/* get the capabilities on the peer */ | 	/* get the capabilities on the peer */ | ||||||
| 	get_codecs(session, stream, &codecs,  session_media); | 	get_codecs(session, stream, &codecs, session_media, peer); | ||||||
| 	ast_rtp_codecs_payload_formats(&codecs, peer, &fmts); |  | ||||||
|  |  | ||||||
| 	/* get the joint capabilities between peer and endpoint */ | 	/* get the joint capabilities between peer and endpoint */ | ||||||
| 	ast_format_cap_get_compatible(caps, peer, joint); | 	ast_format_cap_get_compatible(caps, peer, joint); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user