X-Git-Url: http://git.tuebingen.mpg.de/?a=blobdiff_plain;f=vss.c;h=8b3745218fe057bd237eb85b1d3e89d39275ae06;hb=0e3764a52eb6af123414ce07bcceb2c8bd2836c1;hp=38e829356e2adf1f866ceaaaa84fbdbe603193ea;hpb=92f089b820b45a5dbdc5b4f69d596105d5acba68;p=paraslash.git diff --git a/vss.c b/vss.c index 38e82935..8b374521 100644 --- a/vss.c +++ b/vss.c @@ -86,7 +86,7 @@ struct vss_task { /** Used by the scheduler. */ struct task task; /** Pointer to the header of the mapped audio file. */ - const char *header_buf; + char *header_buf; /** Length of the audio file header. */ size_t header_len; /** Time between audio file headers are sent. */ @@ -211,10 +211,11 @@ static void write_fec_header(struct fec_client *fc, struct vss_task *vsst) write_u32(buf + 14, g->bytes); write_u8(buf + 18, fc->current_slice_num); + write_u8(buf + 19, 0); /* unused */ write_u16(buf + 20, g->slice_bytes); write_u8(buf + 22, g->first_chunk? 0 : 1); write_u8(buf + 23, vsst->header_len? 1 : 0); - memset(buf + 24, 0, 7); + memset(buf + 24, 0, 8); } static bool need_audio_header(struct fec_client *fc, struct vss_task *vsst) @@ -227,12 +228,29 @@ static bool need_audio_header(struct fec_client *fc, struct vss_task *vsst) return false; if (vsst->header_len == 0) return false; - if (fc->group.num && tv_diff(&fc->next_header_time, now, NULL) > 0) - return false; + if (fc->group.num > 0) { + if (!fc->fcp->need_periodic_header) + return false; + if (tv_diff(&fc->next_header_time, now, NULL) > 0) + return false; + } tv_add(now, &vsst->header_interval, &fc->next_header_time); return true; } +static bool need_data_slices(struct fec_client *fc, struct vss_task *vsst) +{ + if (fc->group.num > 0) + return true; + if (!vsst->header_buf) + return true; + if (vsst->header_len == 0) + return true; + if (fc->fcp->need_periodic_header) + return true; + return false; +} + static int num_slices(long unsigned bytes, int max_payload, int rs) { int ret; @@ -246,11 +264,15 @@ static int num_slices(long unsigned bytes, int max_payload, int rs) } /* set group start and group duration */ -static void set_group_timing(struct fec_client *fc, struct fec_group *g) +static void set_group_timing(struct fec_client *fc, struct vss_task *vsst) { + struct fec_group *g = &fc->group; struct timeval *chunk_tv = vss_chunk_time(); - tv_scale(g->num_chunks, chunk_tv, &g->duration); + if (!need_data_slices(fc, vsst)) + ms2tv(200, &g->duration); + else + tv_scale(g->num_chunks, chunk_tv, &g->duration); tv_divide(fc->fcp->slices_per_group + fc->num_extra_slices, &g->duration, &g->slice_duration); PARA_DEBUG_LOG("durations (group/chunk/slice): %lu/%lu/%lu\n", @@ -288,7 +310,10 @@ static int initialize_fec_client(struct fec_client *fc, struct vss_task *vsst) if (ret < 0) return ret; ds = ret; - k = hs + ds; + if (fc->fcp->need_periodic_header) + k = hs + ds; + else + k = PARA_MAX(hs, ds); if (k < fc->fcp->data_slices_per_group) k = fc->fcp->data_slices_per_group; fc->num_extra_slices = k - fc->fcp->data_slices_per_group; @@ -407,6 +432,13 @@ static int compute_slice_size(struct fec_client *fc, struct vss_task *vsst) g->slice_bytes = 1; return 1; } + if (!need_data_slices(fc, vsst)) { + g->bytes = 0; + g->num_chunks = 0; + g->slice_bytes = DIV_ROUND_UP(vsst->header_len, k); + g->num_header_slices = k; + return 1; + } h = vsst->header_len; max_group_bytes = (k - num_slices(h, max_slice_bytes, n - k)) * max_slice_bytes; @@ -467,7 +499,7 @@ static int setup_next_fec_group(struct fec_client *fc, struct vss_task *vsst) */ tmp = g->start; tv_add(&tmp, &g->duration, &g->start); - set_group_timing(fc, g); + set_group_timing(fc, vsst); g->first_chunk += g->num_chunks; g->num++; } @@ -483,7 +515,7 @@ static int setup_next_fec_group(struct fec_client *fc, struct vss_task *vsst) assert(g->num_header_slices + data_slices <= k); fc->current_slice_num = 0; if (g->num == 0) - set_group_timing(fc, g); + set_group_timing(fc, vsst); /* setup header slices */ buf = vsst->header_buf; @@ -775,6 +807,8 @@ static void vss_eof(struct vss_task *vsst) if (mmd->new_vss_status_flags & VSS_NOMORE) mmd->new_vss_status_flags = VSS_NEXT; set_eof_barrier(vsst); + afh_free_header(vsst->header_buf, mmd->afd.audio_format_id); + vsst->header_buf = NULL; para_munmap(vsst->map, mmd->size); vsst->map = NULL; mmd->chunks_sent = 0; @@ -953,8 +987,8 @@ static void recv_afs_result(struct vss_task *vsst, fd_set *rfds) mmd->events++; mmd->num_played++; mmd->new_vss_status_flags &= (~VSS_NEXT); - afh_get_header(&mmd->afd.afhi, vsst->map, &vsst->header_buf, - &vsst->header_len); + afh_get_header(&mmd->afd.afhi, mmd->afd.audio_format_id, + vsst->map, mmd->size, &vsst->header_buf, &vsst->header_len); return; err: free(mmd->afd.afhi.chunk_table);