From b46e786ab743f807d627eac3c3321e5e39d3d299 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Thu, 22 Oct 2009 19:21:10 +0200 Subject: [PATCH] fecdec: Fix decoding of the audio file header. The handling of the audio file header in the fecdec code is currently broken: We output all decoded header slices although the last slice might only be partially used. This patch introduces the new fec_group_usability value "FEC_GROUP_USABLE_WITH_HEADER" which gets used when streaming starts in the middle of the file. In this case, after the group has been decoded, we make sure that only h.audio_header_size many bytes are being written to the output buffer. We then proceed to write the output corresponding to the data slices as in the FEC_GROUP_USABLE_SKIP_HEADER case. In paraslash-0.3. only ogg vorbis uses audio file headers, and the ogg code is quite forgiving and successfully resyncs the stream, which is why this bug was never noticed. However, the wma decoder of paraslash-0.4 fails badly due to the garbage that is written after the header. --- fecdec_filter.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/fecdec_filter.c b/fecdec_filter.c index a7290e6a..a393a230 100644 --- a/fecdec_filter.c +++ b/fecdec_filter.c @@ -262,6 +262,7 @@ enum fec_group_usability { FEC_GROUP_UNUSABLE, FEC_GROUP_USABLE, FEC_GROUP_USABLE_SKIP_HEADER, + FEC_GROUP_USABLE_WITH_HEADER }; static enum fec_group_usability group_is_usable(struct fecdec_group *fg, @@ -279,14 +280,14 @@ static enum fec_group_usability group_is_usable(struct fecdec_group *fg, if (fg->h.bos) return FEC_GROUP_USABLE; if (fg->h.audio_header_size) - return FEC_GROUP_USABLE; + return FEC_GROUP_USABLE_WITH_HEADER; 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, need; + size_t written, need; struct private_fecdec_data *pfd = fn->private_data; enum fec_group_usability u = group_is_usable(fg, pfd); @@ -317,6 +318,21 @@ static int decode_group(struct fecdec_group *fg, struct filter_node *fn) PARA_INFO_LOG("increasing fec buf to %zu\n", fn->bufsize); fn->buf = para_realloc(fn->buf, fn->bufsize); } + if (u == FEC_GROUP_USABLE_WITH_HEADER) { + PARA_INFO_LOG("writing audio file header\n"); + written = 0; + for (i = 0; i < fg->h.data_slices_per_group; i++) { + size_t n = sb; + if (written >= fg->h.audio_header_size) + 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); + fn->loaded += n; + written += n; + } + } + written = 0; for (; i < fg->h.data_slices_per_group; i++) { size_t n = sb; if (n + written > fg->h.group_bytes) -- 2.39.5