diff options
Diffstat (limited to 'main')
-rw-r--r-- | main/app.c | 26 | ||||
-rw-r--r-- | main/asterisk.c | 1 | ||||
-rw-r--r-- | main/astobj2.c | 14 | ||||
-rw-r--r-- | main/channel.c | 20 | ||||
-rw-r--r-- | main/format_compatibility.c | 4 | ||||
-rw-r--r-- | main/frame.c | 77 | ||||
-rw-r--r-- | main/libasteriskpj.c | 2 | ||||
-rw-r--r-- | main/strings.c | 21 | ||||
-rw-r--r-- | main/translate.c | 11 |
9 files changed, 127 insertions, 49 deletions
diff --git a/main/app.c b/main/app.c index f2e3a0fe0..1eb0741ee 100644 --- a/main/app.c +++ b/main/app.c @@ -1422,22 +1422,20 @@ static struct ast_frame *make_silence(const struct ast_frame *orig) size_t size; size_t datalen; size_t samples = 0; - struct ast_frame *next; if (!orig) { return NULL; } + do { + if (ast_format_cmp(orig->subclass.format, ast_format_slin) == AST_FORMAT_CMP_NOT_EQUAL) { + ast_log(LOG_WARNING, "Attempting to silence non-slin frame\n"); + return NULL; + } - if (ast_format_cmp(orig->subclass.format, ast_format_slin) == AST_FORMAT_CMP_NOT_EQUAL) { - ast_log(LOG_WARNING, "Attempting to silence non-slin frame\n"); - return NULL; - } - - for (next = AST_LIST_NEXT(orig, frame_list); - orig; - orig = next, next = orig ? AST_LIST_NEXT(orig, frame_list) : NULL) { samples += orig->samples; - } + + orig = AST_LIST_NEXT(orig, frame_list); + } while (orig); ast_verb(4, "Silencing %zu samples\n", samples); @@ -1455,7 +1453,7 @@ static struct ast_frame *make_silence(const struct ast_frame *orig) silence->samples = samples; silence->datalen = datalen; - silence->subclass.format = ast_format_slin; + silence->subclass.format = ao2_bump(ast_format_slin); return silence; } @@ -1661,14 +1659,13 @@ static int __ast_play_and_record(struct ast_channel *chan, const char *playfile, /* It's all good */ res = 0; } else { - RAII_VAR(struct ast_frame *, silence, NULL, ast_frame_dtor); + struct ast_frame *silence = NULL; struct ast_frame *orig = f; if (muted) { silence = make_silence(orig); if (!silence) { - ast_log(LOG_WARNING, - "Error creating silence\n"); + ast_log(LOG_WARNING, "Error creating silence\n"); break; } f = silence; @@ -1679,6 +1676,7 @@ static int __ast_play_and_record(struct ast_channel *chan, const char *playfile, } res = ast_writestream(others[x], f); } + ast_frame_dtor(silence); f = orig; } diff --git a/main/asterisk.c b/main/asterisk.c index 338c1f53b..69183c1f3 100644 --- a/main/asterisk.c +++ b/main/asterisk.c @@ -330,6 +330,7 @@ int ast_verb_sys_level; int option_verbose; /*!< Verbosity level */ int option_debug; /*!< Debug level */ +int ast_pjproject_max_log_level = -1;/* Default to -1 to know if we have read the level from pjproject yet. */ int ast_option_pjproject_log_level; double ast_option_maxload; /*!< Max load avg on system */ int ast_option_maxcalls; /*!< Max number of active calls */ diff --git a/main/astobj2.c b/main/astobj2.c index c8e48bbf5..1529e91b0 100644 --- a/main/astobj2.c +++ b/main/astobj2.c @@ -524,6 +524,20 @@ int __ao2_ref(void *user_data, int delta, if (0 < current_value) { /* The object still lives. */ +#define EXCESSIVE_REF_COUNT 100000 + + if (EXCESSIVE_REF_COUNT <= current_value && ret < EXCESSIVE_REF_COUNT) { + char excessive_ref_buf[100]; + + /* We just reached or went over the excessive ref count trigger */ + snprintf(excessive_ref_buf, sizeof(excessive_ref_buf), + "Excessive refcount %d reached on ao2 object %p", + current_value, user_data); + ast_log(__LOG_ERROR, file, line, func, "%s\n", excessive_ref_buf); + + __ast_assert_failed(0, excessive_ref_buf, file, line, func); + } + if (ref_log && tag) { fprintf(ref_log, "%p,%s%d,%d,%s,%d,%s,%d,%s\n", user_data, (delta < 0 ? "" : "+"), delta, ast_get_tid(), diff --git a/main/channel.c b/main/channel.c index 4f8471743..6e88a2906 100644 --- a/main/channel.c +++ b/main/channel.c @@ -1531,6 +1531,7 @@ int ast_is_deferrable_frame(const struct ast_frame *frame) case AST_FRAME_IAX: case AST_FRAME_CNG: case AST_FRAME_MODEM: + case AST_FRAME_RTCP: return 0; } return 0; @@ -2866,6 +2867,7 @@ int __ast_answer(struct ast_channel *chan, unsigned int delay) case AST_FRAME_IMAGE: case AST_FRAME_HTML: case AST_FRAME_MODEM: + case AST_FRAME_RTCP: done = 1; break; case AST_FRAME_CONTROL: @@ -4355,6 +4357,14 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio) */ ast_read_generator_actions(chan, f); break; + case AST_FRAME_RTCP: + /* Incoming RTCP feedback needs to get to the translator for + * outgoing media, which means we treat it as an ast_write */ + if (ast_channel_writetrans(chan)) { + ast_translate(ast_channel_writetrans(chan), f, 0); + } + ast_frfree(f); + f = &ast_null_frame; default: /* Just pass it on! */ break; @@ -4887,16 +4897,18 @@ int ast_sendtext(struct ast_channel *chan, const char *text) if (ast_channel_tech(chan)->write_text && (ast_format_cap_has_type(ast_channel_nativeformats(chan), AST_MEDIA_TYPE_TEXT))) { struct ast_frame f; + memset(&f, 0, sizeof(f)); f.frametype = AST_FRAME_TEXT; f.src = "DIALPLAN"; f.mallocd = AST_MALLOCD_DATA; f.datalen = strlen(text); f.data.ptr = ast_strdup(text); - f.offset = 0; - f.seqno = 0; - f.subclass.format = ast_format_t140; - res = ast_channel_tech(chan)->write_text(chan, &f); + + if (f.data.ptr) { + res = ast_channel_tech(chan)->write_text(chan, &f); + ast_frfree(&f); + } } else if (ast_channel_tech(chan)->send_text) { res = ast_channel_tech(chan)->send_text(chan, text); } diff --git a/main/format_compatibility.c b/main/format_compatibility.c index 84514ac8c..256d3a53c 100644 --- a/main/format_compatibility.c +++ b/main/format_compatibility.c @@ -262,10 +262,10 @@ struct ast_format *ast_format_compatibility_bitfield2format(uint64_t bitfield) /*! T.140 RED Text format RFC 4103 */ case AST_FORMAT_T140_RED: - return ast_format_t140; + return ast_format_t140_red; /*! T.140 Text format - ITU T.140, RFC 4103 */ case AST_FORMAT_T140: - return ast_format_t140_red; + return ast_format_t140; } return NULL; } diff --git a/main/frame.c b/main/frame.c index 0175c7226..c284a8e1c 100644 --- a/main/frame.c +++ b/main/frame.c @@ -82,9 +82,9 @@ static struct ast_frame *ast_frame_header_new(void) if ((frames = ast_threadstorage_get(&frame_cache, sizeof(*frames)))) { if ((f = AST_LIST_REMOVE_HEAD(&frames->list, frame_list))) { size_t mallocd_len = f->mallocd_hdr_len; + memset(f, 0, sizeof(*f)); f->mallocd_hdr_len = mallocd_len; - f->mallocd = AST_MALLOCD_HDR; frames->size--; return f; } @@ -139,12 +139,12 @@ static void __frame_free(struct ast_frame *fr, int cache) #endif if (fr->mallocd & AST_MALLOCD_DATA) { - if (fr->data.ptr) + if (fr->data.ptr) { ast_free(fr->data.ptr - fr->offset); + } } if (fr->mallocd & AST_MALLOCD_SRC) { - if (fr->src) - ast_free((void *) fr->src); + ast_free((void *) fr->src); } if (fr->mallocd & AST_MALLOCD_HDR) { if ((fr->frametype == AST_FRAME_VOICE) || (fr->frametype == AST_FRAME_VIDEO) || @@ -206,14 +206,14 @@ struct ast_frame *ast_frisolate(struct ast_frame *fr) return NULL; } out->frametype = fr->frametype; + out->subclass = fr->subclass; if ((fr->frametype == AST_FRAME_VOICE) || (fr->frametype == AST_FRAME_VIDEO) || (fr->frametype == AST_FRAME_IMAGE)) { - out->subclass.format = ao2_bump(fr->subclass.format); - } else { - memcpy(&out->subclass, &fr->subclass, sizeof(out->subclass)); + ao2_bump(out->subclass.format); } out->datalen = fr->datalen; out->samples = fr->samples; + out->mallocd = AST_MALLOCD_HDR; out->offset = fr->offset; /* Copy the timing data */ ast_copy_flags(out, fr, AST_FLAGS_ALL); @@ -226,47 +226,64 @@ struct ast_frame *ast_frisolate(struct ast_frame *fr) out = fr; } - if (!(fr->mallocd & AST_MALLOCD_SRC) && fr->src) { - if (!(out->src = ast_strdup(fr->src))) { - if (out != fr) { - ast_free(out); + if (fr->src) { + /* The original frame has a source string */ + if (!(fr->mallocd & AST_MALLOCD_SRC)) { + /* + * The original frame has a non-malloced source string. + * + * Duplicate the string and put it into the isolated frame + * which may also be the original frame. + */ + newdata = ast_strdup(fr->src); + if (!newdata) { + if (out != fr) { + ast_frame_free(out, 0); + } + return NULL; } - return NULL; + out->src = newdata; + out->mallocd |= AST_MALLOCD_SRC; + } else if (out != fr) { + /* Steal the source string from the original frame. */ + out->src = fr->src; + fr->src = NULL; + fr->mallocd &= ~AST_MALLOCD_SRC; + out->mallocd |= AST_MALLOCD_SRC; } - } else { - out->src = fr->src; - fr->src = NULL; - fr->mallocd &= ~AST_MALLOCD_SRC; } if (!(fr->mallocd & AST_MALLOCD_DATA)) { + /* The original frame has a non-malloced data buffer. */ if (!fr->datalen) { + /* Actually it's just an int so we can simply copy it. */ out->data.uint32 = fr->data.uint32; - out->mallocd = AST_MALLOCD_HDR | AST_MALLOCD_SRC; return out; } - if (!(newdata = ast_malloc(fr->datalen + AST_FRIENDLY_OFFSET))) { - if (out->src != fr->src) { - ast_free((void *) out->src); - } + /* + * Duplicate the data buffer and put it into the isolated frame + * which may also be the original frame. + */ + newdata = ast_malloc(fr->datalen + AST_FRIENDLY_OFFSET); + if (!newdata) { if (out != fr) { - ast_free(out); + ast_frame_free(out, 0); } return NULL; } newdata += AST_FRIENDLY_OFFSET; out->offset = AST_FRIENDLY_OFFSET; - out->datalen = fr->datalen; memcpy(newdata, fr->data.ptr, fr->datalen); out->data.ptr = newdata; - } else { + out->mallocd |= AST_MALLOCD_DATA; + } else if (out != fr) { + /* Steal the data buffer from the original frame. */ out->data = fr->data; memset(&fr->data, 0, sizeof(fr->data)); fr->mallocd &= ~AST_MALLOCD_DATA; + out->mallocd |= AST_MALLOCD_DATA; } - out->mallocd = AST_MALLOCD_HDR | AST_MALLOCD_SRC | AST_MALLOCD_DATA; - return out; } @@ -533,6 +550,8 @@ void ast_frame_subclass2str(struct ast_frame *f, char *subclass, size_t slen, ch break; } break; + case AST_FRAME_RTCP: + ast_copy_string(subclass, "RTCP", slen); default: ast_copy_string(subclass, "Unknown Subclass", slen); break; @@ -584,6 +603,9 @@ void ast_frame_type2str(enum ast_frame_type frame_type, char *ftype, size_t len) case AST_FRAME_VIDEO: ast_copy_string(ftype, "Video", len); break; + case AST_FRAME_RTCP: + ast_copy_string(ftype, "RTCP", len); + break; default: snprintf(ftype, len, "Unknown Frametype '%u'", frame_type); break; @@ -621,6 +643,9 @@ void ast_frame_dump(const char *name, struct ast_frame *f, char *prefix) if (f->frametype == AST_FRAME_VIDEO) { return; } + if (f->frametype == AST_FRAME_RTCP) { + return; + } ast_frame_type2str(f->frametype, ftype, sizeof(ftype)); ast_frame_subclass2str(f, subclass, sizeof(subclass), moreinfo, sizeof(moreinfo)); diff --git a/main/libasteriskpj.c b/main/libasteriskpj.c index 0f893a2cf..40efa9276 100644 --- a/main/libasteriskpj.c +++ b/main/libasteriskpj.c @@ -45,7 +45,7 @@ int ast_pj_init(void) { #ifdef HAVE_PJPROJECT_BUNDLED - pj_log_set_level(ast_option_pjproject_log_level); + AST_PJPROJECT_INIT_LOG_LEVEL(); pj_init(); #endif return 0; diff --git a/main/strings.c b/main/strings.c index b8f1ccbfd..d29da67bc 100644 --- a/main/strings.c +++ b/main/strings.c @@ -184,15 +184,32 @@ static int str_hash(const void *obj, const int flags) return ast_str_hash(obj); } +static int str_sort(const void *lhs, const void *rhs, int flags) +{ + if ((flags & OBJ_SEARCH_MASK) == OBJ_SEARCH_PARTIAL_KEY) { + return strncmp(lhs, rhs, strlen(rhs)); + } else { + return strcmp(lhs, rhs); + } +} + static int str_cmp(void *lhs, void *rhs, int flags) { - return strcmp(lhs, rhs) ? 0 : CMP_MATCH; + int cmp = 0; + + if ((flags & OBJ_SEARCH_MASK) == OBJ_SEARCH_PARTIAL_KEY) { + cmp = strncmp(lhs, rhs, strlen(rhs)); + } else { + cmp = strcmp(lhs, rhs); + } + + return cmp ? 0 : CMP_MATCH; } //struct ao2_container *ast_str_container_alloc_options(enum ao2_container_opts opts, int buckets) struct ao2_container *ast_str_container_alloc_options(enum ao2_alloc_opts opts, int buckets) { - return ao2_container_alloc_options(opts, buckets, str_hash, str_cmp); + return ao2_container_alloc_hash(opts, 0, buckets, str_hash, str_sort, str_cmp); } int ast_str_container_add(struct ao2_container *str_container, const char *add) diff --git a/main/translate.c b/main/translate.c index fa606e71b..168a72a4b 100644 --- a/main/translate.c +++ b/main/translate.c @@ -530,6 +530,17 @@ struct ast_frame *ast_translate(struct ast_trans_pvt *path, struct ast_frame *f, long len; int seqno; + if (f->frametype == AST_FRAME_RTCP) { + /* Just pass the feedback to the right callback, if it exists. + * This "translation" does nothing so return a null frame. */ + struct ast_trans_pvt *tp; + for (tp = p; tp; tp = tp->next) { + if (tp->t->feedback) + tp->t->feedback(tp, f); + } + return &ast_null_frame; + } + has_timing_info = ast_test_flag(f, AST_FRFLAG_HAS_TIMING_INFO); ts = f->ts; len = f->len; |