/*
- * 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.
*/
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;
}
/* 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",
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;
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,
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;
*/
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++;
}
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;