X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=fecdec_filter.c;h=a3cba9bbd0b3821b545a3aed6a7bb8606ec97b95;hp=5f37f1a81f9199f6080b6669cd455d706a96af06;hb=bc086fe5537bd3078b920454958b61287a75c568;hpb=345e7b4adce741621a412c3845712e8540b572ad diff --git a/fecdec_filter.c b/fecdec_filter.c index 5f37f1a8..a3cba9bb 100644 --- a/fecdec_filter.c +++ b/fecdec_filter.c @@ -27,8 +27,10 @@ */ #define NUM_FEC_GROUPS 3 -/** Size of the output buffer of the fecdec filter. */ -#define FECDEC_OUTBUF_SIZE (1024 * 1024) /* FIXME: This has to depend on the fec params */ +/** Default size of the output buffer of the fecdec filter. */ +#define FECDEC_DEFAULT_OUTBUF_SIZE (3 * 1024) +/** Maximal size of the output buffer of the fecdec filter. */ +#define FECDEC_MAX_OUTBUF_SIZE (1024 * 1024) /** Data read from the header of a slice. */ struct fec_header { @@ -76,6 +78,7 @@ struct private_fecdec_data { struct fec_parms *fec; /** Keeps track of what was received so far. */ struct fecdec_group groups[NUM_FEC_GROUPS]; + /** Whether an audio file header was already received. */ int have_header; }; @@ -256,7 +259,7 @@ static enum fec_group_usability group_is_usable(struct fecdec_group *fg, static int decode_group(struct fecdec_group *fg, struct filter_node *fn) { int i, ret, sb = fg->h.slice_bytes; - size_t written = 0; + size_t written = 0, need; struct private_fecdec_data *pfd = fn->private_data; enum fec_group_usability u = group_is_usable(fg, pfd); @@ -279,12 +282,18 @@ static int decode_group(struct fecdec_group *fg, struct filter_node *fn) PARA_DEBUG_LOG("writing group %d (%d/%d decoded data bytes)\n", fg->h.group_num, fg->h.group_bytes, fg->h.data_slices_per_group * sb); + need = fn->loaded + (fg->h.data_slices_per_group - i)* sb; + if (need > fn->bufsize) { + fn->bufsize = PARA_MAX(fn->bufsize * 2, need); + if (fn->bufsize > FECDEC_MAX_OUTBUF_SIZE) + return -E_FECDEC_OVERRUN; + PARA_INFO_LOG("increasing fec buf to %zu\n", fn->bufsize); + fn->buf = para_realloc(fn->buf, fn->bufsize); + } for (; i < fg->h.data_slices_per_group; i++) { size_t n = sb; if (n + written > fg->h.group_bytes) n = fg->h.group_bytes - written; - if (fn->loaded + n > fn->bufsize) - return -E_FECDEC_OVERRUN; memcpy(fn->buf + fn->loaded, fg->data[i], n); fn->loaded += n; written += n; @@ -363,7 +372,7 @@ static ssize_t fecdec(char *buf, size_t len, struct filter_node *fn) ret = read_fec_header(buf, len, &h); if (ret <= 0) return ret; - if (!h.slice_bytes || h.slice_bytes > fn->bufsize) + if (!h.slice_bytes) return -E_BAD_SLICE_SIZE; if (h.slice_num > h.slices_per_group) return -E_BAD_SLICE_NUM; @@ -391,7 +400,7 @@ static void fecdec_close(struct filter_node *fn) static void fecdec_open(struct filter_node *fn) { - fn->bufsize = FECDEC_OUTBUF_SIZE; + fn->bufsize = FECDEC_DEFAULT_OUTBUF_SIZE; fn->buf = para_malloc(fn->bufsize); fn->private_data = para_calloc(sizeof(struct private_fecdec_data)); fn->loaded = 0;