X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=fecdec_filter.c;h=4f3ba950d985b3548dfc926402bbaae5e1ad2434;hp=10f1c642034c9457af12e6c23a1450bbf5eb3245;hb=87c857765884b6d05a2b090fa9509e90d220a2f8;hpb=ffb2eaa90429f6d5c3d369509efcdf91c5463dad diff --git a/fecdec_filter.c b/fecdec_filter.c index 10f1c642..4f3ba950 100644 --- a/fecdec_filter.c +++ b/fecdec_filter.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2010 Andre Noll + * Copyright (C) 2009-2011 Andre Noll * * Licensed under the GPL v2. For licencing details see COPYING. */ @@ -61,6 +61,8 @@ struct fecdec_group { struct fec_header h; /** How many slices received so far. */ int num_received_slices; + /** Bitmap of received slices. */ + uint8_t received_slices[32]; /** The size of the \a idx and the \a data arrays below. */ int num_slices; /** Array of indices of the received slices. */ @@ -102,18 +104,11 @@ static void clear_group(struct fecdec_group *fg) { int i; - for (i = 0; i < fg->num_slices; i++) { + for (i = 0; i < fg->num_slices; i++) free(fg->data[i]); - fg->data[i] = NULL; - fg->idx[i] = -1; - } free(fg->data); - fg->data = NULL; free(fg->idx); - fg->idx = NULL; - fg->num_slices = 0; - memset(&fg->h, 0, sizeof(struct fec_header)); - fg->num_received_slices = 0; + memset(fg, 0, sizeof(*fg)); } static int find_group(struct fec_header *h, @@ -213,29 +208,40 @@ success: return ret; } +static bool test_and_set_slice_bit(struct fecdec_group *fg, uint8_t slice_num) +{ + uint8_t *p = fg->received_slices + slice_num / 8, old = *p; + + *p |= 1 << (slice_num % 8); + return old == *p; +} + /* * returns 1 if slice was added, zero otherwise (because the group was already - * complete). In any case the number of received slices is being increased by - * one. + * complete or a slice has been received twice). */ static int add_slice(char *buf, struct fecdec_group *fg) { - int r, slice_num; + int r; + uint8_t slice_num = fg->h.slice_num; if (group_complete(fg)) { PARA_DEBUG_LOG("group %d complete, ignoring slice %d\n", - fg->h.group_num, fg->h.slice_num); - fg->num_received_slices++; + fg->h.group_num, slice_num); return 0; } - slice_num = fg->h.slice_num; if (fg->num_slices == 0) { fg->num_slices = fg->h.slices_per_group; fg->idx = para_malloc(fg->num_slices * sizeof(int)); - fg->data = para_malloc(fg->num_slices * sizeof(unsigned char *)); - memset(fg->data, 0, fg->num_slices * sizeof(unsigned char *)); + fg->data = para_calloc(fg->num_slices * sizeof(unsigned char *)); } r = fg->num_received_slices; + /* Check if we already have this slice. */ + if (test_and_set_slice_bit(fg, slice_num)) { + PARA_INFO_LOG("ignoring duplicate slice %d:%d\n", fg->h.group_num, + slice_num); + return 0; + } fg->idx[r] = slice_num; fg->data[r] = para_malloc(fg->h.slice_bytes); memcpy(fg->data[r], buf, fg->h.slice_bytes); @@ -300,8 +306,7 @@ static int decode_group(struct fecdec_group *fg, struct filter_node *fn) pfd->have_header = 1; i = 0; if (u == FEC_GROUP_USABLE_SKIP_HEADER) { - i = ROUND_UP(fg->h.audio_header_size, fg->h.slice_bytes) - / fg->h.slice_bytes; + i = DIV_ROUND_UP(fg->h.audio_header_size, fg->h.slice_bytes); PARA_DEBUG_LOG("skipping %d header slices\n", i); } PARA_DEBUG_LOG("writing group %d (%d/%d decoded data bytes)\n", @@ -409,7 +414,7 @@ static int dispatch_slice(char *buf, size_t len, struct fec_header *h, ret = fec_new(k, n, &pfd->fec); if (ret < 0) return ret; - pfd->btrp = btr_pool_new("fecdec", 20 * k * h->slice_bytes); + pfd->btrp = btr_pool_new("fecdec", 64 * 1024); /* decode and clear the first group */ ret = decode_group(pfd->first_complete_group, fn); if (ret < 0)