[asterisk-commits] jrose: branch group/media_formats-reviewed-trunk r418635 - in /team/group/med...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Jul 15 12:03:05 CDT 2014
Author: jrose
Date: Tue Jul 15 12:03:01 2014
New Revision: 418635
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=418635
Log:
media formats: Get chan_iax2 to be runnable/usable in media formats branch
This patch fixes a missing symbol in chan_iax2, gets codec preferences to
be read and interpreted properly, and restores the ability to make basic
chan_iax2 calls. While codec preferences are read and interpreted properly
with this patch, they still aren't being applied (that's in progress)
(issue ASTERISK-23958)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/3747/
Modified:
team/group/media_formats-reviewed-trunk/channels/chan_iax2.c
team/group/media_formats-reviewed-trunk/channels/iax2/parser.c
team/group/media_formats-reviewed-trunk/include/asterisk/format_compatibility.h
team/group/media_formats-reviewed-trunk/main/format_compatibility.c
Modified: team/group/media_formats-reviewed-trunk/channels/chan_iax2.c
URL: http://svnview.digium.com/svn/asterisk/team/group/media_formats-reviewed-trunk/channels/chan_iax2.c?view=diff&rev=418635&r1=418634&r2=418635
==============================================================================
--- team/group/media_formats-reviewed-trunk/channels/chan_iax2.c (original)
+++ team/group/media_formats-reviewed-trunk/channels/chan_iax2.c Tue Jul 15 12:03:01 2014
@@ -1883,8 +1883,24 @@
return 1;
}
- ast_format_compatibility_bitfield2cap(*formats, cap);
+ /* We want to add the formats to the cap in the preferred order */
+ for (i = 0; i < AST_CODEC_PREF_SIZE; i++) {
+ uint64_t pref_as_bitfield = ast_codec_pref_order_value_to_format_bitfield(pref->order[i]);
+
+ if (!pref_as_bitfield) {
+ break;
+ }
+
+ if (ast_format_compatibility_bitfield2cap(pref_as_bitfield, cap)) {
+ ao2_ref(cap, -1);
+ return 1;
+ }
+ }
+
res = ast_format_cap_update_by_allow_disallow(cap, list, allowing);
+ *formats = ast_format_compatibility_cap2bitfield(cap);
+
+ ast_codec_pref_remove_missing(pref, *formats);
for (i = 0; i < ast_format_cap_count(cap); i++) {
struct ast_format *fmt = ast_format_cap_get_format(cap, i);
@@ -3756,7 +3772,7 @@
struct iax2_peer *peer;
struct ast_str *codec_buf = ast_str_alloca(64);
struct ast_str *encmethods = ast_str_alloca(256);
- int x = 0, load_realtime = 0;
+ int load_realtime = 0;
switch (cmd) {
case CLI_INIT:
@@ -3808,19 +3824,10 @@
ast_cli(a->fd, " Codecs : ");
ast_cli(a->fd, "%s\n", iax2_getformatname_multiple(peer->capability, &codec_buf));
- ast_cli(a->fd, " Codec Order : (");
- for(x = 0; x < AST_CODEC_PREF_SIZE; x++) {
- struct ast_format *tmpfmt;
- if(!(ast_codec_pref_index(&peer->prefs, x, &tmpfmt)))
- break;
- ast_cli(a->fd, "%s", ast_format_get_name(tmpfmt));
- if(x < 31 && ast_codec_pref_index(&peer->prefs, x+1, &tmpfmt))
- ast_cli(a->fd, "|");
- }
-
- if (!x)
- ast_cli(a->fd, "none");
- ast_cli(a->fd, ")\n");
+ ast_cli(a->fd, " Codec Order : ");
+ if (ast_codec_pref_string(&peer->prefs, cbuf, sizeof(cbuf)) != -1) {
+ ast_cli(a->fd, "%s\n", cbuf);
+ }
ast_cli(a->fd, " Status : ");
peer_status(peer, status, sizeof(status));
@@ -6005,7 +6012,7 @@
int voice = 0;
int genuine = 0;
int adjust;
- int rate = ast_format_get_sample_rate(f->subclass.format) / 1000;
+ int rate = 0;
struct timeval *delivery = NULL;
@@ -6017,6 +6024,7 @@
*/
if (f->frametype == AST_FRAME_VOICE) {
voice = 1;
+ rate = ast_format_get_sample_rate(f->subclass.format) / 1000;
delivery = &f->delivery;
} else if (f->frametype == AST_FRAME_IAX) {
genuine = 1;
@@ -6126,8 +6134,9 @@
}
}
p->lastsent = ms;
- if (voice)
+ if (voice) {
p->nextpred = p->nextpred + f->samples / rate;
+ }
return ms;
}
Modified: team/group/media_formats-reviewed-trunk/channels/iax2/parser.c
URL: http://svnview.digium.com/svn/asterisk/team/group/media_formats-reviewed-trunk/channels/iax2/parser.c?view=diff&rev=418635&r1=418634&r2=418635
==============================================================================
--- team/group/media_formats-reviewed-trunk/channels/iax2/parser.c (original)
+++ team/group/media_formats-reviewed-trunk/channels/iax2/parser.c Tue Jul 15 12:03:01 2014
@@ -1183,6 +1183,7 @@
{
fr->af.frametype = f->frametype;
fr->af.subclass.format = f->subclass.format;
+ fr->af.subclass.integer = f->subclass.integer;
fr->af.mallocd = 0; /* Our frame is static relative to the container */
fr->af.datalen = f->datalen;
fr->af.samples = f->samples;
Modified: team/group/media_formats-reviewed-trunk/include/asterisk/format_compatibility.h
URL: http://svnview.digium.com/svn/asterisk/team/group/media_formats-reviewed-trunk/include/asterisk/format_compatibility.h?view=diff&rev=418635&r1=418634&r2=418635
==============================================================================
--- team/group/media_formats-reviewed-trunk/include/asterisk/format_compatibility.h (original)
+++ team/group/media_formats-reviewed-trunk/include/asterisk/format_compatibility.h Tue Jul 15 12:03:01 2014
@@ -37,6 +37,29 @@
/*! Framing size of the codec */
unsigned int framing[AST_CODEC_PREF_SIZE];
};
+
+/*!
+ * \brief Convert an ast_codec_pref order value into a format bitfield
+ *
+ * \param order_value value being converted
+ *
+ * \return the bitfield value of the order_value format
+ */
+uint64_t ast_codec_pref_order_value_to_format_bitfield(uint64_t order_value);
+
+/*!
+ * \brief Convert a format bitfield into an ast_codec_pref order value
+ *
+ * \param bitfield value being converted
+ *
+ * \return the ast_codec_pref order value of the most significant format
+ * in the bitfield.
+ *
+ * \note This is really meant to be used on single format bitfields.
+ * It will work with multiformat bitfields, but it can only return the
+ * index of the most significant one if that is the case.
+ */
+uint64_t ast_codec_pref_format_bitfield_to_order_value(uint64_t bitfield);
/*!
* \brief Convert a format structure to its respective bitfield
@@ -105,10 +128,23 @@
/*! \brief Convert a preference structure to a capabilities structure */
void ast_codec_pref_to_cap(struct ast_codec_pref *pref, struct ast_format_cap *cap);
-/*! \brief Remove audio a codec from a preference list */
-void ast_codec_pref_remove(struct ast_codec_pref *pref, struct ast_format *format);
+/*! \brief Removes format from the pref list that aren't in the bitfield */
+void ast_codec_pref_remove_missing(struct ast_codec_pref *pref, uint64_t bitfield);
-/*! \brief Dump audio codec preference list into a string */
+/*!
+ * \brief Dump audio codec preference list into a string
+ *
+ * \param pref preference structure to dump string representation of order for
+ * \param buf character buffer to put string into
+ * \param size size of the character buffer
+ *
+ * \return -1 on error. Otherwise returns the remaining spaaaaaace in the buffer.
+ *
+ * \note Format is (codec1|codec2|codec3|...) -- if the list is too long for the
+ * size of the buffer, codecs will be written until they exceed the length
+ * remaining in which case the list will be closed with '...)' after the last
+ * writable codec.
+ */
int ast_codec_pref_string(struct ast_codec_pref *pref, char *buf, size_t size);
/*! \brief Append a audio codec to a preference list, removing it first if it was already there
Modified: team/group/media_formats-reviewed-trunk/main/format_compatibility.c
URL: http://svnview.digium.com/svn/asterisk/team/group/media_formats-reviewed-trunk/main/format_compatibility.c?view=diff&rev=418635&r1=418634&r2=418635
==============================================================================
--- team/group/media_formats-reviewed-trunk/main/format_compatibility.c (original)
+++ team/group/media_formats-reviewed-trunk/main/format_compatibility.c Tue Jul 15 12:03:01 2014
@@ -336,41 +336,35 @@
return 0;
}
-#if 0
-#error BUGBUG: these procedures need to be converted
void ast_codec_pref_convert(struct ast_codec_pref *pref, char *buf, size_t size, int right)
{
- size_t f_len;
- const struct ast_format_list *f_list = ast_format_list_get(&f_len);
- int x, differential = (int) 'A', mem;
- char *from, *to;
-
- /* TODO re-evaluate this function. It is using the order of the formats specified
- * in the global format list in a way that may not be safe. */
+ static int differential = (int) 'A';
+ int x;
+
if (right) {
- from = pref->order;
- to = buf;
- mem = size;
+ for (x = 0; x < AST_CODEC_PREF_SIZE && x < size; x++) {
+ if (!pref->order[x]) {
+ break;
+ }
+
+ buf[x] = pref->order[x] + differential;
+ }
+
+ buf[x] = '\0';
} else {
- to = pref->order;
- from = buf;
- mem = AST_CODEC_PREF_SIZE;
- }
-
- memset(to, 0, mem);
- for (x = 0; x < AST_CODEC_PREF_SIZE; x++) {
- if (!from[x]) {
- break;
- }
- to[x] = right ? (from[x] + differential) : (from[x] - differential);
- if (!right && to[x] && (to[x] < f_len)) {
- ast_format_copy(&pref->formats[x], &f_list[to[x]-1].format);
- }
- }
- ast_format_list_destroy(f_list);
-}
-
-#endif
+ for (x = 0; x < AST_CODEC_PREF_SIZE && x < size; x++) {
+ if (buf[x] == '\0') {
+ break;
+ }
+
+ pref->order[x] = buf[x] - differential;
+ }
+
+ if (x < size) {
+ pref->order[x] = 0;
+ }
+ }
+}
struct ast_format *ast_codec_pref_index(struct ast_codec_pref *pref, int idx, struct ast_format **result)
{
@@ -398,71 +392,171 @@
int ast_codec_pref_string(struct ast_codec_pref *pref, char *buf, size_t size)
{
int x;
- struct ast_format *format;
- size_t total_len, slen;
+ struct ast_format_cap *cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+ size_t total_len;
+ char *cur;
+
+ if (!cap) {
+ return -1;
+ }
+
+ /* This function is useless if you have less than a 6 character buffer.
+ * '(...)' is six characters. */
+ if (size < 6) {
+ return -1;
+ }
+
+ /* Convert the preferences into a format cap so that we can read the formst names */
+ for (x = 0; x < AST_CODEC_PREF_SIZE; x++) {
+ uint64_t bitfield = ast_codec_pref_order_value_to_format_bitfield(pref->order[x]);
+ if (!bitfield) {
+ break;
+ }
+
+ ast_format_compatibility_bitfield2cap(bitfield, cap);
+ }
+
+ /* We know that at a minimum, 3 characters are used - (, ), and \0 */
+ total_len = size - 3;
memset(buf, 0, size);
- total_len = size;
+
+ /* This character has already been accounted for total_len purposes */
buf[0] = '(';
- total_len--;
- for (x = 0; x < AST_CODEC_PREF_SIZE; x++) {
- if (total_len <= 0)
- break;
- if (!(ast_codec_pref_index(pref, x, &format)))
- break;
- slen = strlen(ast_format_get_name(format));
- if (slen > total_len)
- break;
- strncat(buf, ast_format_get_name(format), total_len - 1); /* safe */
- total_len -= slen;
- if (total_len && x < AST_CODEC_PREF_SIZE - 1 && ast_codec_pref_index(pref, x + 1, &format)) {
- strncat(buf, "|", total_len - 1); /* safe */
- total_len--;
- }
- }
- if (total_len) {
- strncat(buf, ")", total_len - 1); /* safe */
- total_len--;
- }
+ cur = buf + 1;
+
+ /* Loop through the formats and write as many into the buffer as we can */
+ for (x = 0; x < ast_format_cap_count(cap); x++) {
+ size_t name_len;
+ struct ast_format *fmt = ast_format_cap_get_format(cap, x);
+ const char *name = ast_format_get_name(fmt);
+
+ name_len = strlen(name);
+
+ /* all entries after the first need a delimiter character */
+ if (x) {
+ name_len++;
+ }
+
+ /* Terminate the list early if we don't have room for the entry.
+ * If it's not the last entry in the list, save enough room to write '...'.
+ */
+ if (((x == ast_format_cap_count(cap) - 1) && (total_len < name_len)) ||
+ ((x < ast_format_cap_count(cap) - 1) && (total_len < name_len + 3))) {
+ strcpy(cur, "...");
+ cur += 3;
+ total_len -= 3;
+ ao2_ref(fmt, -1);
+ break;
+ }
+
+ sprintf(cur, "%s%s", x ? "|" : "", name);
+ cur += name_len;
+ total_len -= name_len;
+
+ ao2_ref(fmt, -1);
+ }
+ ao2_ref(cap, -1);
+
+ /* These two characters have already been accounted for total_len purposes */
+ cur[0] = ')';
+ cur[1] = '\0';
return size - total_len;
}
+static void codec_pref_remove_index(struct ast_codec_pref *pref, int codec_pref_index)
+{
+ int x;
+
+ for (x = codec_pref_index; x < AST_CODEC_PREF_SIZE; x++) {
+ pref->order[x] = pref->order[x + 1];
+ pref->framing[x] = pref->framing[x + 1];
+ if (!pref->order[x]) {
+ return;
+ }
+ }
+}
+
/*! \brief Remove codec from pref list */
-void ast_codec_pref_remove(struct ast_codec_pref *pref, struct ast_format *format)
-{
- uint64_t bitfield = ast_format_compatibility_format2bitfield(format);
- struct ast_codec_pref oldorder;
- int x, y = 0;
+static void codec_pref_remove(struct ast_codec_pref *pref, int format_index)
+{
+ int x;
if (!pref->order[0]) {
return;
}
- memcpy(&oldorder, pref, sizeof(oldorder));
- memset(pref, 0, sizeof(*pref));
-
for (x = 0; x < AST_CODEC_PREF_SIZE; x++) {
- if (!oldorder.order[x]) {
- break;
- }
- if (oldorder.order[x] != bitfield) {
- pref->order[y++] = bitfield;
- }
- }
+ if (!pref->order[x]) {
+ break;
+ }
+
+ if (pref->order[x] == format_index) {
+ codec_pref_remove_index(pref, x);
+ break;
+ }
+ }
+}
+
+void ast_codec_pref_remove_missing(struct ast_codec_pref *pref, uint64_t bitfield)
+{
+ int x;
+
+ if (!pref->order[0]) {
+ return;
+ }
+
+ for (x = 0; x < AST_CODEC_PREF_SIZE; x++) {
+ uint64_t format_as_bitfield = ast_codec_pref_order_value_to_format_bitfield(pref->order[x]);
+ if (!pref->order[x]) {
+ break;
+ }
+
+ /* If this format isn't in the bitfield, remove it from the prefs. */
+ if (!(format_as_bitfield & bitfield)) {
+ codec_pref_remove_index(pref, x);
+ }
+ }
+}
+
+uint64_t ast_codec_pref_order_value_to_format_bitfield(uint64_t order_value)
+{
+ if (!order_value) {
+ return 0;
+ }
+
+ return 1 << (order_value - 1);
+}
+
+uint64_t ast_codec_pref_format_bitfield_to_order_value(uint64_t bitfield)
+{
+ int format_index = 1;
+
+ if (!bitfield) {
+ return 0;
+ }
+
+ while (bitfield > 1) {
+ bitfield = bitfield >> 1;
+ format_index++;
+ }
+
+ return format_index;
}
/*! \brief Append codec to list */
int ast_codec_pref_append(struct ast_codec_pref *pref, struct ast_format *format, unsigned int framing)
{
uint64_t bitfield = ast_format_compatibility_format2bitfield(format);
- int x;
-
- ast_codec_pref_remove(pref, format);
+ int format_index = ast_codec_pref_format_bitfield_to_order_value(bitfield);
+ int x;
+
+ codec_pref_remove(pref, format_index);
for (x = 0; x < AST_CODEC_PREF_SIZE; x++) {
if (!pref->order[x]) {
- pref->order[x] = bitfield;
+ pref->order[x] = format_index;
pref->framing[x] = framing;
break;
}
More information about the asterisk-commits
mailing list