mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-30 18:40:46 +00:00
Have IAX2 optimize the codec translation path just like chan_sip does it. If
the caller's codec is in our codec list, move it to the top to avoid transcoding. (closes issue #10500) Reported by: stevedavies Patches: iax-prefer-current-codec.patch uploaded by stevedavies (license 184) iax-prefer-current-codec.1.4.patch uploaded by stevedavies (license 184) Tested by: stevedavies, pj, sheldonh git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@99004 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -2896,12 +2896,13 @@ struct create_addr_info {
|
||||
char mohsuggest[MAX_MUSICCLASS];
|
||||
};
|
||||
|
||||
static int create_addr(const char *peername, struct sockaddr_in *sin, struct create_addr_info *cai)
|
||||
static int create_addr(const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai)
|
||||
{
|
||||
struct ast_hostent ahp;
|
||||
struct hostent *hp;
|
||||
struct iax2_peer *peer;
|
||||
int res = -1;
|
||||
struct ast_codec_pref ourprefs;
|
||||
|
||||
ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK);
|
||||
cai->sockfd = defaultsockfd;
|
||||
@@ -2916,7 +2917,11 @@ static int create_addr(const char *peername, struct sockaddr_in *sin, struct cre
|
||||
memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
|
||||
sin->sin_port = htons(IAX_DEFAULT_PORTNO);
|
||||
/* use global iax prefs for unknown peer/user */
|
||||
ast_codec_pref_convert(&prefs, cai->prefs, sizeof(cai->prefs), 1);
|
||||
/* But move the calling channel's native codec to the top of the preference list */
|
||||
memcpy(&ourprefs, &prefs, sizeof(ourprefs));
|
||||
if (c)
|
||||
ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
|
||||
ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
|
||||
return 0;
|
||||
} else {
|
||||
ast_log(LOG_WARNING, "No such host: %s\n", peername);
|
||||
@@ -2940,7 +2945,13 @@ static int create_addr(const char *peername, struct sockaddr_in *sin, struct cre
|
||||
cai->encmethods = peer->encmethods;
|
||||
cai->sockfd = peer->sockfd;
|
||||
cai->adsi = peer->adsi;
|
||||
ast_codec_pref_convert(&peer->prefs, cai->prefs, sizeof(cai->prefs), 1);
|
||||
memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
|
||||
/* Move the calling channel's native codec to the top of the preference list */
|
||||
if (c) {
|
||||
ast_log(LOG_DEBUG, "prepending %x to prefs\n", c->nativeformats);
|
||||
ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
|
||||
}
|
||||
ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
|
||||
ast_copy_string(cai->context, peer->context, sizeof(cai->context));
|
||||
ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
|
||||
ast_copy_string(cai->username, peer->username, sizeof(cai->username));
|
||||
@@ -3115,7 +3126,7 @@ static int iax2_call(struct ast_channel *c, char *dest, int timeout)
|
||||
if (!pds.exten)
|
||||
pds.exten = defaultrdest;
|
||||
|
||||
if (create_addr(pds.peer, &sin, &cai)) {
|
||||
if (create_addr(pds.peer, c, &sin, &cai)) {
|
||||
ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
|
||||
return -1;
|
||||
}
|
||||
@@ -8499,7 +8510,7 @@ static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const
|
||||
if (end) {
|
||||
memcpy(&sin, end, sizeof(sin));
|
||||
cai.sockfd = sockfd;
|
||||
} else if (create_addr(dest, &sin, &cai))
|
||||
} else if (create_addr(dest, NULL, &sin, &cai))
|
||||
return -1;
|
||||
|
||||
/* Build the rest of the message */
|
||||
@@ -8722,7 +8733,7 @@ static struct ast_channel *iax2_request(const char *type, int format, void *data
|
||||
|
||||
|
||||
/* Populate our address from the given */
|
||||
if (create_addr(pds.peer, &sin, &cai)) {
|
||||
if (create_addr(pds.peer, NULL, &sin, &cai)) {
|
||||
*cause = AST_CAUSE_UNREGISTERED;
|
||||
return NULL;
|
||||
}
|
||||
@@ -10037,7 +10048,7 @@ static int cache_get_callno_locked(const char *data)
|
||||
parse_dial_string(tmpstr, &pds);
|
||||
|
||||
/* Populate our address from the given */
|
||||
if (create_addr(pds.peer, &sin, &cai))
|
||||
if (create_addr(pds.peer, NULL, &sin, &cai))
|
||||
return -1;
|
||||
|
||||
if (option_debug)
|
||||
|
@@ -505,6 +505,10 @@ void ast_codec_pref_remove(struct ast_codec_pref *pref, int format);
|
||||
*/
|
||||
int ast_codec_pref_append(struct ast_codec_pref *pref, int format);
|
||||
|
||||
/*! \brief Prepend an audio codec to a preference list, removing it first if it was already there
|
||||
*/
|
||||
void ast_codec_pref_prepend(struct ast_codec_pref *pref, int format, int only_if_existing);
|
||||
|
||||
/*! \brief Select the best audio format according to preference list from supplied options.
|
||||
If "find_best" is non-zero then if nothing is found, the "Best" format of
|
||||
the format list is selected, otherwise 0 is returned. */
|
||||
|
38
main/frame.c
38
main/frame.c
@@ -1149,7 +1149,7 @@ void ast_codec_pref_remove(struct ast_codec_pref *pref, int format)
|
||||
/*! \brief Append codec to list */
|
||||
int ast_codec_pref_append(struct ast_codec_pref *pref, int format)
|
||||
{
|
||||
int x, newindex = -1;
|
||||
int x, newindex = 0;
|
||||
|
||||
ast_codec_pref_remove(pref, format);
|
||||
|
||||
@@ -1172,6 +1172,42 @@ int ast_codec_pref_append(struct ast_codec_pref *pref, int format)
|
||||
return x;
|
||||
}
|
||||
|
||||
/*! \brief Prepend codec to list */
|
||||
void ast_codec_pref_prepend(struct ast_codec_pref *pref, int format, int only_if_existing)
|
||||
{
|
||||
int x, newindex = 0;
|
||||
|
||||
/* First step is to get the codecs "index number" */
|
||||
for (x = 0; x < ARRAY_LEN(AST_FORMAT_LIST); x++) {
|
||||
if (AST_FORMAT_LIST[x].bits == format) {
|
||||
newindex = x + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Done if its unknown */
|
||||
if (!newindex)
|
||||
return;
|
||||
|
||||
/* Now find any existing occurrence, or the end */
|
||||
for (x = 0; x < 32; x++) {
|
||||
if (!pref->order[x] || pref->order[x] == newindex)
|
||||
break;
|
||||
}
|
||||
|
||||
if (only_if_existing && !pref->order[x])
|
||||
return;
|
||||
|
||||
/* Move down to make space to insert - either all the way to the end,
|
||||
or as far as the existing location (which will be overwritten) */
|
||||
for (; x > 0; x--) {
|
||||
pref->order[x] = pref->order[x - 1];
|
||||
pref->framing[x] = pref->framing[x - 1];
|
||||
}
|
||||
|
||||
/* And insert the new entry */
|
||||
pref->order[0] = newindex;
|
||||
pref->framing[0] = 0; /* ? */
|
||||
}
|
||||
|
||||
/*! \brief Set packet size for codec */
|
||||
int ast_codec_pref_setsize(struct ast_codec_pref *pref, int format, int framems)
|
||||
|
Reference in New Issue
Block a user