diff options
Diffstat (limited to 'main/frame.c')
-rw-r--r-- | main/frame.c | 121 |
1 files changed, 52 insertions, 69 deletions
diff --git a/main/frame.c b/main/frame.c index a0feb6558..88f1e20f7 100644 --- a/main/frame.c +++ b/main/frame.c @@ -40,11 +40,6 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/dsp.h" #include "asterisk/file.h" -#ifdef TRACE_FRAMES -static int headers; -static AST_LIST_HEAD_STATIC(headerlist, ast_frame); -#endif - #if !defined(LOW_MEMORY) static void frame_cache_cleanup(void *data); @@ -318,12 +313,6 @@ static struct ast_frame *ast_frame_header_new(void) #endif f->mallocd_hdr_len = sizeof(*f); -#ifdef TRACE_FRAMES - AST_LIST_LOCK(&headerlist); - headers++; - AST_LIST_INSERT_HEAD(&headerlist, f, frame_list); - AST_LIST_UNLOCK(&headerlist); -#endif return f; } @@ -341,7 +330,7 @@ static void frame_cache_cleanup(void *data) } #endif -void ast_frame_free(struct ast_frame *fr, int cache) +static void __frame_free(struct ast_frame *fr, int cache) { if (ast_test_flag(fr, AST_FRFLAG_FROM_TRANSLATOR)) { ast_translate_frame_freed(fr); @@ -360,8 +349,8 @@ void ast_frame_free(struct ast_frame *fr, int cache) * to keep things simple... */ struct ast_frame_cache *frames; - if ((frames = ast_threadstorage_get(&frame_cache, sizeof(*frames))) - && frames->size < FRAME_CACHE_MAX_SIZE) { + if ((frames = ast_threadstorage_get(&frame_cache, sizeof(*frames))) && + (frames->size < FRAME_CACHE_MAX_SIZE)) { AST_LIST_INSERT_HEAD(&frames->list, fr, frame_list); frames->size++; return; @@ -375,19 +364,25 @@ void ast_frame_free(struct ast_frame *fr, int cache) } if (fr->mallocd & AST_MALLOCD_SRC) { if (fr->src) - ast_free((char *)fr->src); + ast_free((void *) fr->src); } if (fr->mallocd & AST_MALLOCD_HDR) { -#ifdef TRACE_FRAMES - AST_LIST_LOCK(&headerlist); - headers--; - AST_LIST_REMOVE(&headerlist, fr, frame_list); - AST_LIST_UNLOCK(&headerlist); -#endif ast_free(fr); } } + +void ast_frame_free(struct ast_frame *frame, int cache) +{ + struct ast_frame *next; + + for (next = AST_LIST_NEXT(frame, frame_list); + frame; + frame = next, next = frame ? AST_LIST_NEXT(frame, frame_list) : NULL) { + __frame_free(frame, cache); + } +} + /*! * \brief 'isolates' a frame by duplicating non-malloc'ed components * (header, src, data). @@ -398,19 +393,29 @@ struct ast_frame *ast_frisolate(struct ast_frame *fr) struct ast_frame *out; void *newdata; - ast_clear_flag(fr, AST_FRFLAG_FROM_TRANSLATOR); - ast_clear_flag(fr, AST_FRFLAG_FROM_DSP); + /* if none of the existing frame is malloc'd, let ast_frdup() do it + since it is more efficient + */ + if (fr->mallocd == 0) { + return ast_frdup(fr); + } + + /* if everything is already malloc'd, we are done */ + if ((fr->mallocd & (AST_MALLOCD_HDR | AST_MALLOCD_SRC | AST_MALLOCD_DATA)) == + (AST_MALLOCD_HDR | AST_MALLOCD_SRC | AST_MALLOCD_DATA)) { + return fr; + } if (!(fr->mallocd & AST_MALLOCD_HDR)) { /* Allocate a new header if needed */ - if (!(out = ast_frame_header_new())) + if (!(out = ast_frame_header_new())) { return NULL; + } out->frametype = fr->frametype; out->subclass = fr->subclass; out->datalen = fr->datalen; out->samples = fr->samples; out->offset = fr->offset; - out->data = fr->data; /* Copy the timing data */ ast_copy_flags(out, fr, AST_FRFLAG_HAS_TIMING_INFO); if (ast_test_flag(fr, AST_FRFLAG_HAS_TIMING_INFO)) { @@ -418,26 +423,34 @@ struct ast_frame *ast_frisolate(struct ast_frame *fr) out->len = fr->len; out->seqno = fr->seqno; } - } else + } else { + ast_clear_flag(fr, AST_FRFLAG_FROM_TRANSLATOR); + ast_clear_flag(fr, AST_FRFLAG_FROM_DSP); + ast_clear_flag(fr, AST_FRFLAG_FROM_FILESTREAM); out = fr; + } - if (!(fr->mallocd & AST_MALLOCD_SRC)) { - if (fr->src) { - if (!(out->src = ast_strdup(fr->src))) { - if (out != fr) - ast_free(out); - return NULL; + if (!(fr->mallocd & AST_MALLOCD_SRC) && fr->src) { + if (!(out->src = ast_strdup(fr->src))) { + if (out != fr) { + ast_free(out); } + return NULL; } - } else + } else { out->src = fr->src; + fr->src = NULL; + fr->mallocd &= ~AST_MALLOCD_SRC; + } if (!(fr->mallocd & AST_MALLOCD_DATA)) { if (!(newdata = ast_malloc(fr->datalen + AST_FRIENDLY_OFFSET))) { - if (out->src != fr->src) + if (out->src != fr->src) { ast_free((void *) out->src); - if (out != fr) + } + if (out != fr) { ast_free(out); + } return NULL; } newdata += AST_FRIENDLY_OFFSET; @@ -445,6 +458,10 @@ struct ast_frame *ast_frisolate(struct ast_frame *fr) out->datalen = fr->datalen; memcpy(newdata, fr->data.ptr, fr->datalen); out->data.ptr = newdata; + } else { + out->data = fr->data; + memset(&fr->data, 0, sizeof(fr->data)); + fr->mallocd &= ~AST_MALLOCD_DATA; } out->mallocd = AST_MALLOCD_HDR | AST_MALLOCD_SRC | AST_MALLOCD_DATA; @@ -939,44 +956,10 @@ void ast_frame_dump(const char *name, struct ast_frame *f, char *prefix) } -#ifdef TRACE_FRAMES -static char *show_frame_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) -{ - struct ast_frame *f; - int x=1; - - switch (cmd) { - case CLI_INIT: - e->command = "core show frame stats"; - e->usage = - "Usage: core show frame stats\n" - " Displays debugging statistics from framer\n"; - return NULL; - case CLI_GENERATE: - return NULL; - } - - if (a->argc != 4) - return CLI_SHOWUSAGE; - AST_LIST_LOCK(&headerlist); - ast_cli(a->fd, " Framer Statistics \n"); - ast_cli(a->fd, "---------------------------\n"); - ast_cli(a->fd, "Total allocated headers: %d\n", headers); - ast_cli(a->fd, "Queue Dump:\n"); - AST_LIST_TRAVERSE(&headerlist, f, frame_list) - ast_cli(a->fd, "%d. Type %d, subclass %d from %s\n", x++, f->frametype, f->subclass, f->src ? f->src : "<Unknown>"); - AST_LIST_UNLOCK(&headerlist); - return CLI_SUCCESS; -} -#endif - /* Builtin Asterisk CLI-commands for debugging */ static struct ast_cli_entry my_clis[] = { AST_CLI_DEFINE(show_codecs, "Displays a list of codecs"), AST_CLI_DEFINE(show_codec_n, "Shows a specific codec"), -#ifdef TRACE_FRAMES - AST_CLI_DEFINE(show_frame_stats, "Shows frame statistics"), -#endif }; int init_framer(void) |