Merge branch 'maint'
authorAndre Noll <maan@systemlinux.org>
Mon, 30 Nov 2009 22:51:01 +0000 (23:51 +0100)
committerAndre Noll <maan@systemlinux.org>
Mon, 30 Nov 2009 22:51:01 +0000 (23:51 +0100)
1  2 
fecdec_filter.c

diff --combined fecdec_filter.c
index 2c63fc6b00ac6d671f74142ac74060bacece8bed,a6218e436506d8000192a3cbb8f7a44da1133d32..08a0ad0b19befe22befbff26112358b9c6685093
@@@ -6,8 -6,6 +6,8 @@@
  
  /** \file fecdec_filter.c A filter that fec-decodes an audio stream. */
  
 +#include <regex.h>
 +
  #include <dirent.h>
  #include "para.h"
  #include "error.h"
@@@ -72,20 -70,6 +72,6 @@@ struct fecdec_group 
        unsigned char **data;
  };
  
- /**
-  * The fecdec filter defers decoding of the first group until the first slice
-  * of the next group was received. This avoids buffer underruns in subsequent
-  * filters of the filter chain.
-  */
- enum group_completion_status {
-       /** No complete group received so far. */
-       GCS_NO_COMPLETE_GROUP,
-       /** First group received, but not yet decoded. */
-       GCS_FIRST_GROUP_COMPLETE,
-       /** At least one complete group decoded. */
-       GCS_FIRST_GROUP_DECODED,
- };
  /**
   * Data private to the fecdec filter.
   */
@@@ -96,8 -80,6 +82,6 @@@ struct private_fecdec_data 
        struct fecdec_group groups[NUM_FEC_GROUPS];
        /** Whether an audio file header was already received. */
        int have_header;
-       /** See \ref group_completion_status. */
-       unsigned completion_status;
        /** Points to the first received group. */
        struct fecdec_group *first_complete_group;
  };
@@@ -177,8 -159,7 +161,7 @@@ static struct fecdec_group *try_to_free
                 * Don't clear the first complete group if it has not yet been
                 * decoded.
                 */
-               if (pfd->completion_status == GCS_FIRST_GROUP_COMPLETE
-                               && pfd->first_complete_group == fg)
+               if (fg == pfd->first_complete_group)
                        continue;
                clear_group(fg);
                return fg;
@@@ -198,8 -179,8 +181,8 @@@ static struct fecdec_group *free_oldest
                PARA_WARNING_LOG("Clearing incomplete group %d "
                        "(contains %d slices)\n", oldest->h.group_num,
                        oldest->num_received_slices);
-       assert(pfd->completion_status != GCS_FIRST_GROUP_COMPLETE
-               || oldest != pfd->first_complete_group);
+       if (oldest == pfd->first_complete_group)
+               pfd->first_complete_group = NULL;
        clear_group(oldest);
        return oldest;
  }
@@@ -392,41 -373,39 +375,39 @@@ static int dispatch_slice(char *buf, si
        ret = get_group(h, pfd, &fg);
        if (ret < 0)
                return ret;
-       if (!add_slice(buf, fg))
+       if (!add_slice(buf, fg)) /* group already complete */
                return 1;
-       if (group_complete(fg)) {
-               if (pfd->completion_status == GCS_NO_COMPLETE_GROUP) {
-                       enum fec_group_usability u = group_is_usable(fg, pfd);
-                       assert(u != FEC_GROUP_USABLE_SKIP_HEADER);
-                       if (u == FEC_GROUP_UNUSABLE)
-                               return 1;
-                       pfd->completion_status = GCS_FIRST_GROUP_COMPLETE;
-                       pfd->first_complete_group = fg;
+       if (!group_complete(fg))
+               return 1;
+       /* this slice completed the group */
+       if (pfd->fec)
+               goto decode;
+       /* it's either the first or the second complete group */
+       if (!pfd->first_complete_group) { /* it's the first group */
+               enum fec_group_usability u = group_is_usable(fg, pfd);
+               assert(u != FEC_GROUP_USABLE_SKIP_HEADER);
+               if (u == FEC_GROUP_UNUSABLE) /* forget it */
                        return 1;
-               }
-               assert(pfd->fec);
-               ret = decode_group(fg, fn);
-               if (ret < 0)
-                       return ret;
+               pfd->first_complete_group = fg; /* remember it */
                return 1;
        }
-       if (pfd->completion_status == GCS_NO_COMPLETE_GROUP)
-               return 1;
-       if (pfd->completion_status == GCS_FIRST_GROUP_DECODED)
-               return 1;
-       if (fg == pfd->first_complete_group)
-               return 1;
-       assert(!pfd->fec);
+       /* we have two complete groups, let's go */
        k = h->data_slices_per_group;
        n = h->slices_per_group;
        PARA_NOTICE_LOG("init fec (%d, %d)\n", k, n);
        ret = fec_new(k, n, &pfd->fec);
        if (ret < 0)
                return ret;
+       /* decode and clear the first group */
        ret = decode_group(pfd->first_complete_group, fn);
        if (ret < 0)
                return ret;
-       pfd->completion_status = GCS_FIRST_GROUP_DECODED;
+       clear_group(pfd->first_complete_group);
+       pfd->first_complete_group = NULL;
+ decode:
+       ret = decode_group(fg, fn);
+       if (ret < 0)
+               return ret;
        return 1;
  }
  
@@@ -470,7 -449,6 +451,6 @@@ static void fecdec_open(struct filter_n
        fn->bufsize = FECDEC_DEFAULT_OUTBUF_SIZE;
        fn->buf = para_malloc(fn->bufsize);
        pfd = para_calloc(sizeof(*pfd));
-       pfd->completion_status = GCS_NO_COMPLETE_GROUP;
        fn->private_data = pfd;
        fn->loaded = 0;
  }