+ int ret, i, max_chunks = PARA_MAX(1LU, 150 / tv2ms(vss_chunk_time()));
+
+ if (g->first_chunk == 0) {
+ g->num_chunks = 1;
+ ret = vss_get_chunk(0, vsst, &buf, &len);
+ if (ret < 0)
+ return ret;
+ g->bytes = len;
+ return 0;
+ }
+
+ g->num_chunks = 0;
+ g->bytes = 0;
+ /*
+ * Include chunks into the group until the group duration is at least
+ * 150ms. For ogg and wma, a single chunk's duration (ogg page/wma
+ * super frame) is already larger than 150ms, so a FEC group consists
+ * of exactly one chunk for these audio formats.
+ */
+ for (i = 0;; i++) {
+ int chunk_num = g->first_chunk + i;
+
+ if (g->bytes > 0 && i >= max_chunks) /* duration limit */
+ break;
+ if (chunk_num >= mmd->afd.afhi.chunks_total) /* eof */
+ break;
+ ret = vss_get_chunk(chunk_num, vsst, &buf, &len);
+ if (ret < 0)
+ return ret;
+ if (g->bytes + len > max_bytes)
+ break;
+ /* Include this chunk */
+ g->bytes += len;
+ g->num_chunks++;
+ }
+ assert(g->num_chunks);
+ return 1;
+}
+
+/*
+ * Compute the slice size of the next group.
+ *
+ * The FEC parameters n and k are fixed but the slice size varies per
+ * FEC group. We'd like to choose slices as small as possible to avoid
+ * unnecessary FEC calculations but large enough to guarantee that the
+ * k data slices suffice to encode the header (if needed) and the data
+ * chunk(s).
+ *
+ * Once we know the payload of the next group, we define the number s
+ * of bytes per slice for this group by
+ *
+ * s = ceil(payload / k)
+ *
+ * However, for header streams, computing s is more complicated since no
+ * overlapping of header and data slices is possible. Hence we have k >=
+ * 2 and s must satisfy
+ *
+ * (*) ceil(h / s) + ceil(d / s) <= k
+ *
+ * where h and d are payload of the header and the data chunk(s)
+ * respectively. In general there is no value for s such that (*)
+ * becomes an equality, for example if h = 4000, d = 5000 and k = 10.
+ *
+ * We use the following approach for computing a suitable value for s:
+ *
+ * Let
+ * k1 := ceil(k * min(h, d) / (h + d)),
+ * k2 := k - k1.
+ *
+ * Note that k >= 2 implies k1 > 0 and k2 > 0, so
+ *
+ * s := max(ceil(min(h, d) / k1), ceil(max(h, d) / k2))
+ *
+ * is well-defined. Inequality (*) holds for this value of s since k1
+ * slices suffice to store min(h, d) while k2 slices suffice to store
+ * max(h, d), i.e. the first addent of (*) is bounded by k1 and the
+ * second by k2.
+ *
+ * For the above example we obtain
+ *
+ * k1 = ceil(10 * 4000 / 9000) = 5, k2 = 5,
+ * s = max(4000 / 5, 5000 / 5) = 1000,
+ *
+ * which is optimal since a slice size of 999 bytes would already require
+ * 11 slices.
+ */
+static int compute_slice_size(struct fec_client *fc, struct vss_task *vsst)
+{