X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=vss.c;h=aae601d14153d6973a8a86f8f8a93e69cd6c8bbd;hp=6304fc531d63e5dbbfca69d2bec9bcac60c419d0;hb=ddd7cd853044105f329a2c70cce2d8f1470f559e;hpb=a2872df1d181fe8ed736fcf2bda09134c380d5d2 diff --git a/vss.c b/vss.c index 6304fc53..aae601d1 100644 --- a/vss.c +++ b/vss.c @@ -232,6 +232,17 @@ static int num_slices(long unsigned bytes, struct fec_client *fc, uint8_t *resul return 1; } +static void set_slice_duration(struct fec_client *fc, struct fec_group *g) +{ + struct timeval group_duration, *chunk_tv = vss_chunk_time(); + + tv_scale(g->num_chunks, chunk_tv, &group_duration); + tv_divide(fc->fcp->slices_per_group + fc->num_extra_slices, + &group_duration, &g->slice_duration); + PARA_DEBUG_LOG("durations (group/chunk/slice): %lu/%lu/%lu\n", + tv2ms(&group_duration), tv2ms(chunk_tv), tv2ms(&g->slice_duration)); +} + static int setup_next_fec_group(struct fec_client *fc, struct vss_task *vsst) { int ret, i, k, data_slices; @@ -275,6 +286,8 @@ static int setup_next_fec_group(struct fec_client *fc, struct vss_task *vsst) g->first_chunk = mmd->current_chunk; g->num = 0; } else { + /* use duration of the previous group for the timing of this group */ + set_slice_duration(fc, g); g->first_chunk += g->num_chunks; g->num++; } @@ -301,6 +314,8 @@ static int setup_next_fec_group(struct fec_client *fc, struct vss_task *vsst) g->num_chunks = i - g->first_chunk; assert(g->num_chunks); fc->current_slice_num = 0; + if (g->num == 0) + set_slice_duration(fc, g); /* setup header slices */ buf = vsst->header_buf; @@ -332,23 +347,20 @@ static int setup_next_fec_group(struct fec_client *fc, struct vss_task *vsst) for (; i < k; i++) fc->src_data[i] = (const unsigned char *)buf; } - - /* setup group timing */ - tv_scale(g->first_chunk - fc->first_stream_chunk, chunk_tv, &tmp); - tv_add(&fc->stream_start, &tmp, &g->start); - if (g->num) /* quick hack to avoid buffer underruns */ - g->start.tv_sec--; - tv_scale(g->num_chunks, chunk_tv, &tmp); /* group duration */ - tv_divide(fc->fcp->slices_per_group + fc->num_extra_slices, - &tmp, &g->slice_duration); - - PARA_DEBUG_LOG("FEC group %d: %d chunks (%d - %d), %d header slices, %d data slices\n", + PARA_DEBUG_LOG("FEC group %d: %d chunks (%d - %d), " + "%d header slices, %d data slices\n", g->num, g->num_chunks, g->first_chunk, g->first_chunk + g->num_chunks - 1, g->num_header_slices, data_slices ); - PARA_DEBUG_LOG("durations (group/chunk/slice): %lu/%lu/%lu\n", - tv2ms(&tmp), tv2ms(chunk_tv), tv2ms(&g->slice_duration)); + /* set group start */ + if (g->num != 0 && vsst->header_len != 0 && fc->first_stream_chunk == 0) + /* chunk #0 is the audio file header */ + tv_scale(g->first_chunk - 1, chunk_tv, &tmp); + else + tv_scale(g->first_chunk - fc->first_stream_chunk, + chunk_tv, &tmp); + tv_add(&fc->stream_start, &tmp, &g->start); return 1; } @@ -827,7 +839,7 @@ err: */ static void vss_send(struct vss_task *vsst) { - int i, sent_something = 0; + int i, fec_active = 0; struct timeval due; struct fec_client *fc, *tmp_fc; @@ -841,8 +853,10 @@ static void vss_send(struct vss_task *vsst) list_for_each_entry_safe(fc, tmp_fc, &fec_client_list, node) { if (fc->error < 0) continue; - if (!next_slice_is_due(fc, NULL)) + if (!next_slice_is_due(fc, NULL)) { + fec_active = 1; continue; + } if (compute_next_fec_slice(fc, vsst) <= 0) continue; PARA_DEBUG_LOG("sending %d:%d (%u bytes)\n", fc->group.num, @@ -851,10 +865,10 @@ static void vss_send(struct vss_task *vsst) fc->fcp->max_slice_bytes, fc->fcp->private_data); fc->current_slice_num++; - sent_something = 1; + fec_active = 1; } if (mmd->current_chunk >= mmd->afd.afhi.chunks_total) { /* eof */ - if (!sent_something) + if (!fec_active) mmd->new_vss_status_flags |= VSS_NEXT; return; }