aboutsummaryrefslogtreecommitdiffstats
path: root/main/frame.c
diff options
context:
space:
mode:
authorkpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b>2009-06-16 18:54:30 +0000
committerkpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b>2009-06-16 18:54:30 +0000
commitea5a74f18bf3fc8f013718409de934279f1f2560 (patch)
tree1dd57b8b026f8601093e89d231d739594d6b7288 /main/frame.c
parentd2292f0eca49f9ec9297bab8aa9c551557213662 (diff)
Merged revisions 200991 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r200991 | kpfleming | 2009-06-16 12:05:38 -0500 (Tue, 16 Jun 2009) | 11 lines Improve support for media paths that can generate multiple frames at once. There are various media paths in Asterisk (codec translators and UDPTL, primarily) that can generate more than one frame to be generated when the application calling them expects only a single frame. This patch addresses a number of those cases, at least the primary ones to solve the known problems. In addition it removes the broken TRACE_FRAMES support, fixes a number of bugs in various frame-related API functions, and cleans up various code paths affected by these changes. https://reviewboard.asterisk.org/r/175/ ........ git-svn-id: http://svn.digium.com/svn/asterisk/trunk@201056 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'main/frame.c')
-rw-r--r--main/frame.c121
1 files changed, 52 insertions, 69 deletions
diff --git a/main/frame.c b/main/frame.c
index bc1c60b8a..e305580ac 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)