FEC initialization cleanups.
authorAndre Noll <maan@systemlinux.org>
Sat, 7 Aug 2010 14:50:59 +0000 (16:50 +0200)
committerAndre Noll <maan@systemlinux.org>
Sun, 31 Oct 2010 11:06:56 +0000 (12:06 +0100)
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

diff --git a/vss.c b/vss.c
index 941f22f..7980ccc 100644 (file)
--- 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;