Merge branch 'maint'
[paraslash.git] / fecdec_filter.c
index 63510e8fd5cdf72fafee6e74b37fba4e770417e8..2c63fc6b00ac6d671f74142ac74060bacece8bed 100644 (file)
@@ -104,7 +104,7 @@ struct private_fecdec_data {
 
 /** Iterate over all fecdec groups. */
 #define FOR_EACH_FECDEC_GROUP(g, d) for (g = (d)->groups; \
-       (g) - (d)->groups < NUM_FEC_GROUPS; (g)++)
+       (g) < (d)->groups + NUM_FEC_GROUPS; (g)++)
 
 static int group_complete(struct fecdec_group *fg)
 {
@@ -264,6 +264,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,
@@ -281,14 +282,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);
 
@@ -319,6 +320,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)
@@ -380,6 +396,10 @@ static int dispatch_slice(char *buf, size_t len, struct fec_header *h,
                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;
                        return 1;