From ee66911aeab325627c349edcb5f7e1fa40aeabf7 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Sat, 7 Aug 2010 16:50:59 +0200 Subject: [PATCH] FEC initialization cleanups. Initialization was performed in two steps: During vss_send and during compute_next_fec_slice(). This patch moves the init code for fec clients to the single location. --- vss.c | 151 +++++++++++++++++++++++++++++----------------------------- 1 file changed, 76 insertions(+), 75 deletions(-) diff --git a/vss.c b/vss.c index 941f22fd..7980ccc8 100644 --- a/vss.c +++ b/vss.c @@ -229,9 +229,9 @@ static int need_audio_header(struct fec_client *fc, struct vss_task *vsst) return 1; } -static int num_slices(long unsigned bytes, struct fec_client *fc, int rs) +static int num_slices(long unsigned bytes, int mps, int rs) { - int m = fc->fcp->max_slice_bytes - FEC_HEADER_SIZE; + int m = mps - FEC_HEADER_SIZE; int ret; assert(m > 0); @@ -254,48 +254,84 @@ static void set_group_timing(struct fec_client *fc, struct fec_group *g) tv2ms(&g->duration), tv2ms(chunk_tv), tv2ms(&g->slice_duration)); } -static int setup_next_fec_group(struct fec_client *fc, struct vss_task *vsst) +static int initialize_fec_client(struct fec_client *fc, struct vss_task *vsst) { - int ret, i, k, data_slices; + int k, n, ret, mps; int hs, ds, rs; /* header/data/redundant slices */ + struct fec_client_parms *fcp = fc->fcp; + + /* set mps */ + if (fcp->init_fec) { + /* + * Set the maximum slice size to the Maximum Packet Size if the + * transport protocol allows to determine this value. The user + * can specify a slice size up to this value. + */ + ret = fcp->init_fec(fc->sc); + if (ret < 0) + return ret; + mps = ret; + } else + mps = generic_max_transport_msg_size(fc->sc->fd); + if (mps <= FEC_HEADER_SIZE) + return -ERRNO_TO_PARA_ERROR(EINVAL); + + rs = fc->fcp->slices_per_group - fc->fcp->data_slices_per_group; + ret = num_slices(vsst->header_len, mps, rs); + if (ret < 0) + goto err; + hs = ret; + ret = num_slices(afh_get_largest_chunk_size(&mmd->afd.afhi), + mps, rs); + if (ret < 0) + goto err; + ds = ret; + k = ret + ds; + if (k < fc->fcp->data_slices_per_group) + k = fc->fcp->data_slices_per_group; + n = k + rs; + PARA_CRIT_LOG("hs: %d, ds: %d, rs: %d, k: %d, n: %d\n", hs, ds, rs, k, n); + fec_free(fc->parms); + ret = fec_new(k, n, &fc->parms); + if (ret < 0) + return ret; + fc->num_extra_slices = k - fc->fcp->data_slices_per_group; + PARA_NOTICE_LOG("fec parms %d:%d:%d (%d extra slices)\n", + mps, k, n, fc->num_extra_slices); + fc->src_data = para_realloc(fc->src_data, k * sizeof(char *)); + fc->enc_buf = para_realloc(fc->enc_buf, mps); + memset(fc->enc_buf, 0, mps); + fc->extra_src_buf = para_realloc(fc->extra_src_buf, mps); + memset(fc->extra_src_buf, 0, mps); + + fc->fcp->max_slice_bytes = mps; + fc->state = FEC_STATE_READY_TO_RUN; + fc->next_header_time.tv_sec = 0; + fc->stream_start = *now; + fc->first_stream_chunk = mmd->current_chunk; + return 1; +err: + fec_free(fc->parms); + return ret; +} + +static int setup_next_fec_group(struct fec_client *fc, struct vss_task *vsst) +{ + int ret, i, k, n, data_slices; size_t len; const char *buf, *start_buf; struct fec_group *g = &fc->group; - unsigned slice_bytes = fc->fcp->max_slice_bytes - FEC_HEADER_SIZE; + unsigned slice_bytes; uint32_t max_data_size; - rs = fc->fcp->slices_per_group - fc->fcp->data_slices_per_group; if (fc->first_stream_chunk < 0) { - int n; - - ret = num_slices(vsst->header_len, fc, rs); - if (ret < 0) - return ret; - hs = ret; - ret = num_slices(afh_get_largest_chunk_size(&mmd->afd.afhi), - fc, rs); - if (ret < 0) - return ret; - ds = ret; - k = hs + ds; - if (k > 255) - return -E_BAD_CT; - if (k < fc->fcp->data_slices_per_group) - k = fc->fcp->data_slices_per_group; - n = k + rs; - fc->num_extra_slices = k - fc->fcp->data_slices_per_group; - PARA_NOTICE_LOG("fec parms %d:%d:%d (%d extra slices)\n", - slice_bytes, k, n, fc->num_extra_slices); - fec_free(fc->parms); - fc->src_data = para_realloc(fc->src_data, k * sizeof(char *)); - ret = fec_new(k, n, &fc->parms); + ret = initialize_fec_client(fc, vsst); if (ret < 0) return ret; - fc->stream_start = *now; - fc->first_stream_chunk = mmd->current_chunk; g->first_chunk = mmd->current_chunk; g->num = 0; g->start = *now; + } else { struct timeval tmp; if (g->first_chunk + g->num_chunks >= mmd->afd.afhi.chunks_total) @@ -306,13 +342,18 @@ static int setup_next_fec_group(struct fec_client *fc, struct vss_task *vsst) */ tmp = g->start; tv_add(&tmp, &g->duration, &g->start); - k = fc->fcp->data_slices_per_group + fc->num_extra_slices; set_group_timing(fc, g); g->first_chunk += g->num_chunks; g->num++; } + slice_bytes = fc->fcp->max_slice_bytes - FEC_HEADER_SIZE; + PARA_CRIT_LOG("slice_bytes: %d\n", slice_bytes); + k = fc->fcp->data_slices_per_group + fc->num_extra_slices; + n = fc->fcp->slices_per_group + fc->num_extra_slices; + PARA_CRIT_LOG("k: %d, n: %d\n", k, n); if (need_audio_header(fc, vsst)) { - ret = num_slices(vsst->header_len, fc, rs); + ret = num_slices(vsst->header_len, fc->fcp->max_slice_bytes, + n - k); if (ret < 0) return ret; g->num_header_slices = ret; @@ -813,42 +854,6 @@ err: mmd->new_vss_status_flags = VSS_NEXT; } -static int initialize_fec_client(struct fec_client *fc) -{ - int ret; - struct fec_client_parms *fcp = fc->fcp; - - if (fcp->init_fec) { - /* - * Set the maximum slice size to the Maximum Packet Size if the - * transport protocol allows to determine this value. The user - * can specify a slice size up to this value. - */ - ret = fcp->init_fec(fc->sc); - if (ret < 0) - return ret; - if (!fcp->max_slice_bytes || fcp->max_slice_bytes > ret) - fcp->max_slice_bytes = ret; - } - if (fcp->max_slice_bytes < FEC_HEADER_SIZE + fcp->data_slices_per_group) - return -ERRNO_TO_PARA_ERROR(EINVAL); - ret = fec_new(fcp->data_slices_per_group, fcp->slices_per_group, - &fc->parms); - if (ret < 0) - goto err; - fc->first_stream_chunk = -1; /* stream not yet started */ - fc->src_data = para_malloc(fc->fcp->slices_per_group * sizeof(char *)); - fc->enc_buf = para_calloc(fc->fcp->max_slice_bytes); - fc->num_extra_slices = 0; - fc->extra_src_buf = para_calloc(fc->fcp->max_slice_bytes); - fc->next_header_time.tv_sec = 0; - fc->state = FEC_STATE_READY_TO_RUN; - return 1; -err: - fec_free(fc->parms); - return ret; -} - /** * Main sending function. * @@ -860,7 +865,7 @@ err: */ static void vss_send(struct vss_task *vsst) { - int ret, i, fec_active = 0; + int i, fec_active = 0; struct timeval due; struct fec_client *fc, *tmp_fc; @@ -876,11 +881,7 @@ static void vss_send(struct vss_task *vsst) case FEC_STATE_DISABLED: continue; case FEC_STATE_NONE: - ret = initialize_fec_client(fc); - if (ret < 0) { - PARA_ERROR_LOG("%s\n", para_strerror(-ret)); - continue; - } + fc->first_stream_chunk = -1; /* need setup */ /* fall through */ case FEC_STATE_READY_TO_RUN: break; -- 2.39.5