X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=fecdec_filter.c;h=794add49ec42d07c04ea826e36f8f77b80a9dad6;hp=d5593f25d02c5cde248e0c775a1d3235a279ef8f;hb=1beeb3913ee5d0e03805e55300720d267a6a51e0;hpb=42d5f658d742dad5b8caa2c2ab7ca62768b0b105 diff --git a/fecdec_filter.c b/fecdec_filter.c index d5593f25..794add49 100644 --- a/fecdec_filter.c +++ b/fecdec_filter.c @@ -28,7 +28,7 @@ #define NUM_FEC_GROUPS 3 /** Size of the output buffer of the fecdec filter. */ -#define FECDEC_OUTBUF_SIZE (128 * 1024) +#define FECDEC_OUTBUF_SIZE (1024 * 1024) /* FIXME: This has to depend on the fec params */ /** Data read from the header of a slice. */ struct fec_header { @@ -46,6 +46,10 @@ struct fec_header { uint8_t slice_num; /** Used data bytes of this slice. */ uint16_t slice_bytes; + /** Non-zero if this group is the beginning of the stream. */ + uint8_t bos; + /** Non-zero if this stream embedds audio headers into fec groups. */ + uint8_t header_stream; }; /** @@ -72,6 +76,7 @@ struct private_fecdec_data { struct fec_parms *fec; /** Keeps track of what was received so far. */ struct fecdec_group groups[NUM_FEC_GROUPS]; + int have_header; }; /** Iterate over all fecdec groups. */ @@ -218,19 +223,58 @@ static int add_slice(char *buf, struct fecdec_group *fg) return 1; } +enum fec_group_usability { + FEC_GROUP_UNUSABLE, + FEC_GROUP_USABLE, + FEC_GROUP_USABLE_SKIP_HEADER, +}; + +static enum fec_group_usability group_is_usable(struct fecdec_group *fg, + struct private_fecdec_data *pfd) +{ + struct fec_header *h = &fg->h; + + if (!h->header_stream) + return FEC_GROUP_USABLE; + if (pfd->have_header) { + if (h->audio_header_size) + return FEC_GROUP_USABLE_SKIP_HEADER; + return FEC_GROUP_USABLE; + } + if (fg->h.bos) + return FEC_GROUP_USABLE; + if (fg->h.audio_header_size) + return FEC_GROUP_USABLE; + return FEC_GROUP_UNUSABLE; +} + static int decode_group(struct fecdec_group *fg, struct filter_node *fn) { int i, ret, sb = fg->h.slice_bytes; size_t written = 0; struct private_fecdec_data *pfd = fn->private_data; + enum fec_group_usability u = group_is_usable(fg, pfd); + if (u == FEC_GROUP_UNUSABLE) { + PARA_INFO_LOG("dropping unusable group %d\n", fg->h.group_num); + return 0; + } + PARA_DEBUG_LOG("decoding group %d %d slices\n", fg->h.group_num, + fg->h.data_slices_per_group); ret = fec_decode(pfd->fec, fg->data, fg->idx, sb); if (ret < 0) return ret; + 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; + PARA_DEBUG_LOG("skipping %d header slices\n", i); + } 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); - for (i = 0; i < fg->h.data_slices_per_group; i++) { + 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; @@ -267,6 +311,8 @@ static int read_fec_header(char *buf, size_t len, struct fec_header *h) h->slice_num = read_u8(buf + 18); h->slice_bytes = read_u16(buf + 20); + h->bos = read_u8(buf + 22); + h->header_stream = read_u8(buf + 23); if (!memcmp(buf, FEC_EOF_PACKET, FEC_EOF_PACKET_LEN)) return -E_FECDEC_EOF; // PARA_DEBUG_LOG("group %u, slize %u, slices per group: %u\n",