+ tv2ms(&g->duration), tv2ms(chunk_tv), tv2ms(&g->slice_duration));
+}
+
+static int initialize_fec_client(struct fec_client *fc, struct vss_task *vsst)
+{
+ 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->mps = 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;