codec_negotiation: Implement outgoing_call_offer_pref

Based on this new endpoint setting, a joint list of preferred codecs
between those received from the Asterisk core (remote), and those
specified in the endpoint's "allow" parameter (local) is created and
is used to create the outgoing SDP offer.

* Add outgoing_call_offer_pref to pjsip_configuration (endpoint)

* Add "call_direction" to res_pjsip_session.

* Update pjsip_session_caps.c to make the functions more generic
  so they could be used for both incoming and outgoing.

* Update ast_sip_session_create_outgoing to create the
  pending_media_state->topology with the results of
  ast_sip_session_create_joint_call_stream().

* The endpoint "preferred_codec_only" option now automatically sets
  AST_SIP_CALL_CODEC_PREF_FIRST in incoming_call_offer_pref.

* A helper function ast_stream_get_format_count() was added to
  streams to return the current count of formats.

ASTERISK-28777

Change-Id: Id4ec0b4a906c2ae5885bf947f101c59059935437
This commit is contained in:
George Joseph
2020-03-13 13:40:46 -06:00
committed by Friendly Automation
parent 57a457c26c
commit 2ee455958e
13 changed files with 408 additions and 297 deletions

View File

@@ -399,13 +399,13 @@ static void get_codecs(struct ast_sip_session *session, const struct pjmedia_sdp
static int apply_cap_to_bundled(struct ast_sip_session_media *session_media,
struct ast_sip_session_media *session_media_transport,
struct ast_stream *asterisk_stream, const struct ast_format_cap *joint)
struct ast_stream *asterisk_stream, struct ast_format_cap *joint)
{
if (!joint) {
return -1;
}
ast_stream_set_formats(asterisk_stream, (struct ast_format_cap *)joint);
ast_stream_set_formats(asterisk_stream, joint);
/* If this is a bundled stream then apply the payloads to RTP instance acting as transport to prevent conflicts */
if (session_media_transport != session_media && session_media->bundled) {
@@ -428,11 +428,11 @@ static int apply_cap_to_bundled(struct ast_sip_session_media *session_media,
return 0;
}
static const struct ast_format_cap *set_incoming_call_offer_cap(
static struct ast_format_cap *set_incoming_call_offer_cap(
struct ast_sip_session *session, struct ast_sip_session_media *session_media,
const struct pjmedia_sdp_media *stream)
{
const struct ast_format_cap *incoming_call_offer_cap;
struct ast_format_cap *incoming_call_offer_cap;
struct ast_format_cap *remote;
struct ast_rtp_codecs codecs = AST_RTP_CODECS_NULL_INIT;
int fmts = 0;
@@ -448,12 +448,13 @@ static const struct ast_format_cap *set_incoming_call_offer_cap(
get_codecs(session, stream, &codecs, session_media);
ast_rtp_codecs_payload_formats(&codecs, remote, &fmts);
incoming_call_offer_cap = ast_sip_session_join_incoming_call_offer_cap(
session, session_media, remote);
incoming_call_offer_cap = ast_sip_session_create_joint_call_cap(
session, session_media->type, remote);
ao2_ref(remote, -1);
if (!incoming_call_offer_cap) {
if (!incoming_call_offer_cap || ast_format_cap_empty(incoming_call_offer_cap)) {
ao2_cleanup(incoming_call_offer_cap);
ast_rtp_codecs_payloads_destroy(&codecs);
return NULL;
}
@@ -1413,6 +1414,7 @@ static int negotiate_incoming_sdp_stream(struct ast_sip_session *session,
struct ast_sip_session_media *session_media_transport;
enum ast_media_type media_type = session_media->type;
enum ast_sip_session_media_encryption encryption = AST_SIP_MEDIA_ENCRYPT_NONE;
struct ast_format_cap *joint;
int res;
/* If no type formats have been configured reject this stream */
@@ -1504,8 +1506,10 @@ static int negotiate_incoming_sdp_stream(struct ast_sip_session *session,
}
}
if (apply_cap_to_bundled(session_media, session_media_transport, asterisk_stream,
set_incoming_call_offer_cap(session, session_media, stream))) {
joint = set_incoming_call_offer_cap(session, session_media, stream);
res = apply_cap_to_bundled(session_media, session_media_transport, asterisk_stream, joint);
ao2_cleanup(joint);
if (res != 0) {
return 0;
}