From 0c9c3239eb328c8b802447b4f9d2c922085e74ee Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Mon, 1 Nov 2010 16:30:22 +0100 Subject: [PATCH] vss: Avoid large FEC parameters for the DCCP transport. Now that for DCCP streams the audio file header is sent only once at client connect time, we can go one step further and send the header as its own FEC group. Then all subsequent FEC groups contain data slices only, hence the maximal required size for a FEC group reduces from header_size + largest_chunk_size to max(header_size, largest_chunk_size) This patch introduces a new helper function need_data_slices() which returns false only at the beginning of a DCCP stream. In this case FEC group 0 consists of the header only and an arbitrary time interval of 200ms is used for this group. --- vss.c | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/vss.c b/vss.c index 8c16c958..121373dc 100644 --- a/vss.c +++ b/vss.c @@ -237,6 +237,19 @@ static bool need_audio_header(struct fec_client *fc, struct vss_task *vsst) 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; @@ -250,11 +263,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", @@ -292,7 +309,10 @@ static int initialize_fec_client(struct fec_client *fc, struct vss_task *vsst) if (ret < 0) 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; @@ -411,6 +431,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; @@ -471,7 +498,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++; } @@ -487,7 +514,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; -- 2.39.5