From d67fcd1fc34ec2de6bed616e8e96c91a67cbaca7 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Tue, 5 Jan 2010 23:08:36 +0100 Subject: [PATCH 1/1] btr support for the fecdec filter. --- fecdec_filter.c | 77 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 66 insertions(+), 11 deletions(-) diff --git a/fecdec_filter.c b/fecdec_filter.c index 901a9169..39e78163 100644 --- a/fecdec_filter.c +++ b/fecdec_filter.c @@ -290,6 +290,7 @@ static int decode_group(struct fecdec_group *fg, struct filter_node *fn) size_t written, need; struct private_fecdec_data *pfd = fn->private_data; enum fec_group_usability u = group_is_usable(fg, pfd); + char *buf = NULL, *p; if (u == FEC_GROUP_UNUSABLE) { PARA_INFO_LOG("dropping unusable group %d\n", fg->h.group_num); @@ -310,13 +311,19 @@ 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); + need = fn->loaded + (fg->h.data_slices_per_group - i) * sb; + if (fn->btrn) { + buf = para_malloc(need); + p = buf; + } else { + 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); + } + p = fn->buf + fn->loaded; } if (u == FEC_GROUP_USABLE_WITH_HEADER) { PARA_INFO_LOG("writing audio file header\n"); @@ -327,20 +334,24 @@ static int decode_group(struct fecdec_group *fg, struct filter_node *fn) break; if (sb + written > fg->h.audio_header_size) n = fg->h.audio_header_size - written; - memcpy(fn->buf + fn->loaded, fg->data[i], n); + memcpy(p + written, fg->data[i], n); fn->loaded += n; written += n; } + p += written; } written = 0; 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; - memcpy(fn->buf + fn->loaded, fg->data[i], n); + memcpy(p + written, fg->data[i], n); fn->loaded += n; written += n; } + p += written; + if (fn->btrn) + btr_add_output(buf, p - buf, fn->btrn); return 0; } @@ -385,8 +396,11 @@ static int dispatch_slice(char *buf, size_t len, struct fec_header *h, int ret, k, n; struct private_fecdec_data *pfd = fn->private_data; - if (h->slice_bytes > len) /* can not use the thing, try to read more */ + PARA_CRIT_LOG("sb: %d, len: %d\n", h->slice_bytes, len); + if (h->slice_bytes > len) { /* can not use the thing, try to read more */ + fn->min_iqs = h->slice_bytes + FEC_HEADER_SIZE; return 0; + } ret = get_group(h, pfd, &fg); if (ret < 0) return ret; @@ -458,6 +472,44 @@ static void fecdec_close(struct filter_node *fn) fec_free(pfd->fec); free(fn->private_data); fn->private_data = NULL; + fn->conf = NULL; +} + +static void fecdec_post_select(__a_unused struct sched *s, struct task *t) +{ + struct filter_node *fn = container_of(t, struct filter_node, task); + struct btr_node *btrn = fn->btrn; + int ret; + struct fec_header h; + char *buf; + size_t len; + +next_buffer: + ret = btr_node_status(btrn, fn->min_iqs, BTR_NT_INTERNAL); + if (ret <= 0) + goto out; + btr_merge(btrn, fn->min_iqs); + len = btr_next_buffer(btrn, &buf); + ret = read_fec_header(buf, len, &h); + if (ret <= 0) + goto out; + ret = -E_BAD_SLICE_SIZE; + if (!h.slice_bytes) + goto out; + ret = -E_BAD_SLICE_NUM; + if (h.slice_num > h.slices_per_group) + goto out; + ret = dispatch_slice(buf + FEC_HEADER_SIZE, len - FEC_HEADER_SIZE, + &h, fn); + //PARA_INFO_LOG("ret: %d, len: %d, slice_bytes: %d\n", ret, len, h.slice_bytes); + if (ret <= 0) + goto out; + btr_consume(btrn, FEC_HEADER_SIZE + h.slice_bytes); + goto next_buffer; +out: + t->error = ret; + if (ret < 0) + btr_remove_node(btrn); } static void fecdec_open(struct filter_node *fn) @@ -468,16 +520,19 @@ static void fecdec_open(struct filter_node *fn) pfd = para_calloc(sizeof(*pfd)); fn->private_data = pfd; fn->loaded = 0; + fn->min_iqs = FEC_HEADER_SIZE; } /** * The init function of the fecdec filter. * - * \param f struct to initialize. + * \param f Struct to initialize. */ void fecdec_filter_init(struct filter *f) { f->convert = fecdec; f->close = fecdec_close; f->open = fecdec_open; + f->pre_select = generic_filter_pre_select; + f->post_select = fecdec_post_select; } -- 2.30.2