X-Git-Url: http://git.tuebingen.mpg.de/?a=blobdiff_plain;f=vss.c;h=792a7393c443590f06ebe469ee95c789c5947278;hb=234647bb5139513bdf36c1afec46f5c43ba27adc;hp=ea075df923a9e7b551ffc5cb220fb5bfe8a6e7c5;hpb=1a8e3628040a94a8c06027335962a6cb2f827a63;p=paraslash.git diff --git a/vss.c b/vss.c index ea075df9..792a7393 100644 --- a/vss.c +++ b/vss.c @@ -88,6 +88,8 @@ struct vss_task { enum afs_socket_status afsss; /** The memory mapped audio file. */ char *map; + /** The size of the memory mapping. */ + size_t mapsize; /** Used by the scheduler. */ struct task *task; /** Pointer to the header of the mapped audio file. */ @@ -611,7 +613,7 @@ 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; } - PARA_DEBUG_LOG("FEC group %d: %d chunks (%d - %d), %d bytes\n", + PARA_DEBUG_LOG("FEC group %u: %u chunks (%u - %u), %u bytes\n", g->num, g->num_chunks, g->first_chunk, g->first_chunk + g->num_chunks - 1, g->bytes ); @@ -846,7 +848,7 @@ static void vss_eof(struct vss_task *vsst) 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); + para_munmap(vsst->map, vsst->mapsize); vsst->map = NULL; mmd->chunks_sent = 0; //mmd->offset = 0; @@ -855,7 +857,7 @@ static void vss_eof(struct vss_task *vsst) mmd->afd.afhi.chunk_tv.tv_usec = 0; free(mmd->afd.afhi.chunk_table); mmd->afd.afhi.chunk_table = NULL; - mmd->size = 0; + vsst->mapsize = 0; mmd->events++; } @@ -884,47 +886,11 @@ static void set_mmd_offset(void) mmd->offset = tv2ms(&offset); } -/* - * Compute the timeout for the main select-loop of the scheduler. - * - * Before the timeout is computed, the current vss status flags are evaluated - * and acted upon by calling appropriate functions from the lower layers. - * Possible actions include - * - * - request a new audio file from afs, - * - shutdown of all senders (stop/pause command), - * - reposition the stream (ff/jmp command). - */ static void vss_pre_select(struct sched *s, void *context) { int i; struct vss_task *vsst = context; - if (!vsst->map || vss_next() || vss_paused() || vss_repos()) { - struct fec_client *fc, *tmp; - for (i = 0; senders[i].name; i++) - if (senders[i].shutdown_clients) - senders[i].shutdown_clients(); - list_for_each_entry_safe(fc, tmp, &fec_client_list, node) - fc->state = FEC_STATE_NONE; - mmd->stream_start.tv_sec = 0; - mmd->stream_start.tv_usec = 0; - } - if (vss_next()) - vss_eof(vsst); - else if (vss_paused()) { - if (mmd->chunks_sent) - set_eof_barrier(vsst); - mmd->chunks_sent = 0; - } else if (vss_repos()) { - tv_add(now, &vsst->announce_tv, &vsst->data_send_barrier); - set_eof_barrier(vsst); - mmd->chunks_sent = 0; - mmd->current_chunk = afh_get_start_chunk(mmd->repos_request, - &mmd->afd.afhi); - 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"); para_fd_set(vsst->afs_socket, &s->wfds, &s->max_fileno); @@ -941,7 +907,7 @@ static void vss_pre_select(struct sched *s, void *context) static int recv_afs_msg(int afs_socket, int *fd, uint32_t *code, uint32_t *data) { - char control[255], buf[8]; + char control[255] __a_aligned(8), buf[8]; struct msghdr msg = {.msg_iov = NULL}; struct cmsghdr *cmsg; struct iovec iov; @@ -1009,11 +975,11 @@ static void recv_afs_result(struct vss_task *vsst, fd_set *rfds) ret = -ERRNO_TO_PARA_ERROR(errno); goto err; } - mmd->size = statbuf.st_size; - ret = para_mmap(mmd->size, PROT_READ, MAP_PRIVATE | MAP_POPULATE, + ret = para_mmap(statbuf.st_size, PROT_READ, MAP_PRIVATE | MAP_POPULATE, passed_fd, 0, &vsst->map); if (ret < 0) goto err; + vsst->mapsize = statbuf.st_size; close(passed_fd); mmd->chunks_sent = 0; mmd->current_chunk = 0; @@ -1022,7 +988,7 @@ static void recv_afs_result(struct vss_task *vsst, fd_set *rfds) mmd->num_played++; mmd->new_vss_status_flags &= (~VSS_NEXT); afh_get_header(&mmd->afd.afhi, mmd->afd.audio_format_id, - vsst->map, mmd->size, &vsst->header_buf, &vsst->header_len); + vsst->map, vsst->mapsize, &vsst->header_buf, &vsst->header_len); return; err: free(mmd->afd.afhi.chunk_table); @@ -1063,7 +1029,7 @@ static void vss_send(struct vss_task *vsst) } if (compute_next_fec_slice(fc, vsst) <= 0) continue; - PARA_DEBUG_LOG("sending %d:%d (%u bytes)\n", fc->group.num, + PARA_DEBUG_LOG("sending %u:%u (%u bytes)\n", fc->group.num, fc->current_slice_num, fc->group.slice_bytes); fc->fcp->send_fec(fc->sc, (char *)fc->enc_buf, fc->group.slice_bytes + FEC_HEADER_SIZE); @@ -1112,7 +1078,7 @@ static void vss_send(struct vss_task *vsst) */ if (mmd->current_chunk > 0) { /* chunk 0 might be on the heap */ buf += len; - for (i = 0; i < 5 && buf < vsst->map + mmd->size; i++) { + for (i = 0; i < 5 && buf < vsst->map + vsst->mapsize; i++) { __a_unused volatile char x = *buf; buf += 4096; } @@ -1127,6 +1093,33 @@ static int vss_post_select(struct sched *s, void *context) int ret, i; struct vss_task *vsst = context; + if (!vsst->map || vss_next() || vss_paused() || vss_repos()) { + /* shut down senders and fec clients */ + struct fec_client *fc, *tmp; + for (i = 0; senders[i].name; i++) + if (senders[i].shutdown_clients) + senders[i].shutdown_clients(); + list_for_each_entry_safe(fc, tmp, &fec_client_list, node) + fc->state = FEC_STATE_NONE; + mmd->stream_start.tv_sec = 0; + mmd->stream_start.tv_usec = 0; + } + if (vss_next()) + vss_eof(vsst); + else if (vss_paused()) { + if (mmd->chunks_sent) + set_eof_barrier(vsst); + mmd->chunks_sent = 0; + } else if (vss_repos()) { /* repositioning due to ff/jmp command */ + tv_add(now, &vsst->announce_tv, &vsst->data_send_barrier); + set_eof_barrier(vsst); + mmd->chunks_sent = 0; + mmd->current_chunk = afh_get_start_chunk(mmd->repos_request, + &mmd->afd.afhi); + mmd->new_vss_status_flags &= ~VSS_REPOS; + set_mmd_offset(); + } + /* If a sender command is pending, run it. */ if (mmd->sender_cmd_data.cmd_num >= 0) { int num = mmd->sender_cmd_data.cmd_num, sender_num = mmd->sender_cmd_data.sender_num; @@ -1196,7 +1189,7 @@ void init_vss_task(int afs_socket, struct sched *s) mmd->vss_status_flags |= VSS_PLAYING; mmd->new_vss_status_flags |= VSS_PLAYING; ms2tv(autoplay_delay, &tmp); - tv_add(now, &tmp, &vsst->autoplay_barrier); + tv_add(clock_get_realtime(NULL), &tmp, &vsst->autoplay_barrier); tv_add(&vsst->autoplay_barrier, &vsst->announce_tv, &vsst->data_send_barrier); }