Kill afhi->header_offset.
[paraslash.git] / vss.c
diff --git a/vss.c b/vss.c
index 3405d5a0600d27f359558be50f2cb1f853a0ab9e..21ac37470e4748ea407fd7bacb96dfb42f3ee55a 100644 (file)
--- a/vss.c
+++ b/vss.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1997-2010 Andre Noll <maan@systemlinux.org>
+ * Copyright (C) 1997-2011 Andre Noll <maan@systemlinux.org>
  *
  * Licensed under the GPL v2. For licencing details see COPYING.
  */
@@ -211,10 +211,11 @@ static void write_fec_header(struct fec_client *fc, struct vss_task *vsst)
        write_u32(buf + 14, g->bytes);
 
        write_u8(buf + 18, fc->current_slice_num);
+       write_u8(buf + 19, 0); /* unused */
        write_u16(buf + 20, g->slice_bytes);
        write_u8(buf + 22, g->first_chunk? 0 : 1);
        write_u8(buf + 23, vsst->header_len? 1 : 0);
-       memset(buf + 24, 0, 7);
+       memset(buf + 24, 0, 8);
 }
 
 static bool need_audio_header(struct fec_client *fc, struct vss_task *vsst)
@@ -227,12 +228,29 @@ static bool need_audio_header(struct fec_client *fc, struct vss_task *vsst)
                return false;
        if (vsst->header_len == 0)
                return false;
-       if (fc->group.num && tv_diff(&fc->next_header_time, now, NULL) > 0)
-               return false;
+       if (fc->group.num > 0) {
+               if (!fc->fcp->need_periodic_header)
+                       return false;
+               if (tv_diff(&fc->next_header_time, now, NULL) > 0)
+                       return false;
+       }
        tv_add(now, &vsst->header_interval, &fc->next_header_time);
        return true;
 }
 
+static bool need_data_slices(struct fec_client *fc, struct vss_task *vsst)
+{
+       if (fc->group.num > 0)
+               return true;
+       if (!vsst->header_buf)
+               return true;
+       if (vsst->header_len == 0)
+               return true;
+       if (fc->fcp->need_periodic_header)
+               return true;
+       return false;
+}
+
 static int num_slices(long unsigned bytes, int max_payload, int rs)
 {
        int ret;
@@ -246,11 +264,15 @@ static int num_slices(long unsigned bytes, int max_payload, int rs)
 }
 
 /* set group start and group duration */
-static void set_group_timing(struct fec_client *fc, struct fec_group *g)
+static void set_group_timing(struct fec_client *fc, struct vss_task *vsst)
 {
+       struct fec_group *g = &fc->group;
        struct timeval *chunk_tv = vss_chunk_time();
 
-       tv_scale(g->num_chunks, chunk_tv, &g->duration);
+       if (!need_data_slices(fc, vsst))
+               ms2tv(200, &g->duration);
+       else
+               tv_scale(g->num_chunks, chunk_tv, &g->duration);
        tv_divide(fc->fcp->slices_per_group + fc->num_extra_slices,
                &g->duration, &g->slice_duration);
        PARA_DEBUG_LOG("durations (group/chunk/slice): %lu/%lu/%lu\n",
@@ -282,13 +304,16 @@ static int initialize_fec_client(struct fec_client *fc, struct vss_task *vsst)
        rs = fc->fcp->slices_per_group - fc->fcp->data_slices_per_group;
        ret = num_slices(vsst->header_len, fc->mps - FEC_HEADER_SIZE, rs);
        if (ret < 0)
-               goto err;
+               return ret;
        hs = ret;
        ret = num_slices(mmd->afd.max_chunk_size, fc->mps - FEC_HEADER_SIZE, rs);
        if (ret < 0)
-               goto err;
+               return ret;
        ds = ret;
-       k = hs + ds;
+       if (fc->fcp->need_periodic_header)
+               k = hs + ds;
+       else
+               k = PARA_MAX(hs, ds);
        if (k < fc->fcp->data_slices_per_group)
                k = fc->fcp->data_slices_per_group;
        fc->num_extra_slices = k - fc->fcp->data_slices_per_group;
@@ -308,9 +333,6 @@ static int initialize_fec_client(struct fec_client *fc, struct vss_task *vsst)
        fc->stream_start = *now;
        fc->first_stream_chunk = mmd->current_chunk;
        return 1;
-err:
-       fec_free(fc->parms);
-       return ret;
 }
 
 static void compute_group_size(struct vss_task *vsst, struct fec_group *g,
@@ -410,6 +432,13 @@ static int compute_slice_size(struct fec_client *fc, struct vss_task *vsst)
                        g->slice_bytes = 1;
                return 1;
        }
+       if (!need_data_slices(fc, vsst)) {
+               g->bytes = 0;
+               g->num_chunks = 0;
+               g->slice_bytes = DIV_ROUND_UP(vsst->header_len, k);
+               g->num_header_slices = k;
+               return 1;
+       }
        h = vsst->header_len;
        max_group_bytes = (k - num_slices(h, max_slice_bytes, n - k))
                * max_slice_bytes;
@@ -470,7 +499,7 @@ static int setup_next_fec_group(struct fec_client *fc, struct vss_task *vsst)
                 */
                tmp = g->start;
                tv_add(&tmp, &g->duration, &g->start);
-               set_group_timing(fc, g);
+               set_group_timing(fc, vsst);
                g->first_chunk += g->num_chunks;
                g->num++;
        }
@@ -486,7 +515,7 @@ static int setup_next_fec_group(struct fec_client *fc, struct vss_task *vsst)
        assert(g->num_header_slices + data_slices <= k);
        fc->current_slice_num = 0;
        if (g->num == 0)
-               set_group_timing(fc, g);
+               set_group_timing(fc, vsst);
 
        /* setup header slices */
        buf = vsst->header_buf;