X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=vss.c;h=bfb0f0a175dc5da0e79bad5ab0497d6f1faff2f2;hp=6db42bdec7356b15a9f971fee16023b947efa13b;hb=a4f75cecaaee538edb7aae3f0ff19168a1dab59d;hpb=3f9051d22fcf6e968259946eaf521ac3daac470e diff --git a/vss.c b/vss.c index 6db42bde..bfb0f0a1 100644 --- a/vss.c +++ b/vss.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1997-2009 Andre Noll + * Copyright (C) 1997-2010 Andre Noll * * Licensed under the GPL v2. For licencing details see COPYING. */ @@ -11,7 +11,9 @@ * senders. */ +#include #include +#include #include "para.h" #include "error.h" @@ -121,6 +123,8 @@ struct fec_group { uint32_t num_chunks; /** When the first chunk was sent. */ struct timeval start; + /** The duration of the full group. */ + struct timeval duration; /** The group duration divided by the number of slices. */ struct timeval slice_duration; /** Group contains the audio file header that occupies that many slices. */ @@ -232,15 +236,16 @@ 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) +/* set group start and group duration */ +static void set_group_timing(struct fec_client *fc, struct fec_group *g) { - struct timeval group_duration, *chunk_tv = vss_chunk_time(); + struct timeval *chunk_tv = vss_chunk_time(); - tv_scale(g->num_chunks, chunk_tv, &group_duration); + tv_scale(g->num_chunks, chunk_tv, &g->duration); tv_divide(fc->fcp->slices_per_group + fc->num_extra_slices, - &group_duration, &g->slice_duration); + &g->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)); + tv2ms(&g->duration), tv2ms(chunk_tv), tv2ms(&g->slice_duration)); } static int setup_next_fec_group(struct fec_client *fc, struct vss_task *vsst) @@ -248,12 +253,10 @@ static int setup_next_fec_group(struct fec_client *fc, struct vss_task *vsst) int ret, i, k, data_slices; size_t len; const char *buf, *start_buf; - struct timeval tmp, *chunk_tv = vss_chunk_time(); struct fec_group *g = &fc->group; unsigned slice_bytes = fc->fcp->max_slice_bytes - FEC_HEADER_SIZE; uint32_t max_data_size; - assert(chunk_tv); if (fc->first_stream_chunk < 0) { uint8_t hs, ds; /* needed header/data slices */ uint8_t rs = fc->fcp->slices_per_group @@ -285,15 +288,22 @@ static int setup_next_fec_group(struct fec_client *fc, struct vss_task *vsst) 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) + return 0; + /* + * Start and duration of this group depend only on the previous + * group. Compute the new group start as g->start += g->duration. + */ + tmp = g->start; + tv_add(&tmp, &g->duration, &g->start); k = fc->fcp->data_slices_per_group + fc->num_extra_slices; - /* use duration of the previous group for the timing of this group */ - set_slice_duration(fc, g); + set_group_timing(fc, g); g->first_chunk += g->num_chunks; g->num++; } - if (g->first_chunk >= mmd->afd.afhi.chunks_total) - return 0; if (need_audio_header(fc, vsst)) { ret = num_slices(vsst->header_len, fc, &g->num_header_slices); if (ret < 0) @@ -316,7 +326,7 @@ static int setup_next_fec_group(struct fec_client *fc, struct vss_task *vsst) assert(g->num_chunks); fc->current_slice_num = 0; if (g->num == 0) - set_slice_duration(fc, g); + set_group_timing(fc, g); /* setup header slices */ buf = vsst->header_buf; @@ -354,14 +364,6 @@ static int setup_next_fec_group(struct fec_client *fc, struct vss_task *vsst) g->first_chunk + g->num_chunks - 1, g->num_header_slices, data_slices ); - /* 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; } @@ -499,8 +501,7 @@ static void compute_slice_timeout(struct timeval *timeout) static void set_eof_barrier(struct vss_task *vsst) { struct fec_client *fc; - struct timeval timeout = mmd->afd.afhi.eof_tv, - *chunk_tv = vss_chunk_time(); + struct timeval timeout = {1, 0}, *chunk_tv = vss_chunk_time(); if (!chunk_tv) goto out; @@ -636,16 +637,12 @@ static void vss_eof(struct vss_task *vsst) para_munmap(vsst->map, mmd->size); vsst->map = NULL; mmd->chunks_sent = 0; - mmd->offset = 0; + //mmd->offset = 0; mmd->afd.afhi.seconds_total = 0; mmd->afd.afhi.chunk_tv.tv_sec = 0; mmd->afd.afhi.chunk_tv.tv_usec = 0; free(mmd->afd.afhi.chunk_table); mmd->afd.afhi.chunk_table = NULL; - free(mmd->afd.afhi.info_string); - mmd->afd.afhi.info_string = make_message("%s:\n%s:\n%s:\n", status_item_list[SI_AUDIO_FILE_INFO], - status_item_list[SI_TAGINFO1], status_item_list[SI_TAGINFO2]); - make_empty_status_items(mmd->afd.verbose_ls_output); mmd->mtime = 0; mmd->size = 0; mmd->events++; @@ -681,6 +678,13 @@ static int need_to_request_new_audio_file(struct vss_task *vsst) return 1; } +static void set_mmd_offset(void) +{ + struct timeval offset; + tv_scale(mmd->current_chunk, &mmd->afd.afhi.chunk_tv, &offset); + mmd->offset = tv2ms(&offset); +} + /** * Compute the timeout for the main select-loop of the scheduler. * @@ -725,6 +729,7 @@ static void vss_pre_select(struct sched *s, struct task *t) mmd->chunks_sent = 0; mmd->current_chunk = mmd->repos_request; mmd->new_vss_status_flags &= ~VSS_REPOS; + set_mmd_offset(); } if (need_to_request_new_audio_file(vsst)) { PARA_DEBUG_LOG("ready and playing, but no audio file\n"); @@ -794,7 +799,6 @@ static void recv_afs_result(struct vss_task *vsst) if (passed_fd < 0) goto err; shmid = afs_data; - free(mmd->afd.afhi.info_string); ret = load_afd(shmid, &mmd->afd); if (ret < 0) goto err; @@ -880,11 +884,9 @@ static void vss_send(struct vss_task *vsst) size_t len; if (!mmd->chunks_sent) { - struct timeval tmp; mmd->stream_start = *now; - tv_scale(mmd->current_chunk, &mmd->afd.afhi.chunk_tv, &tmp); - mmd->offset = tv2ms(&tmp); mmd->events++; + set_mmd_offset(); } /* * We call the send function also in case of empty chunks as @@ -971,7 +973,6 @@ void init_vss_task(int afs_socket) free(hn); free(home); mmd->sender_cmd_data.cmd_num = -1; - make_empty_status_items(mmd->afd.verbose_ls_output); if (conf.autoplay_given) { struct timeval tmp; mmd->vss_status_flags |= VSS_PLAYING;