Auxiliary functions to parse and validate parts of URIs.
[paraslash.git] / vss.c
diff --git a/vss.c b/vss.c
index 4ed75792185f685e26db278ae88b49ff4d2cd59f..d205349370f69a9445ff1db7bb1c269b2d6431a7 100644 (file)
--- a/vss.c
+++ b/vss.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1997-2008 Andre Noll <maan@systemlinux.org>
+ * Copyright (C) 1997-2009 Andre Noll <maan@systemlinux.org>
  *
  * Licensed under the GPL v2. For licencing details see COPYING.
  */
@@ -32,7 +32,7 @@ extern struct misc_meta_data *mmd;
 
 extern void dccp_send_init(struct sender *);
 extern void http_send_init(struct sender *);
-extern void ortp_send_init(struct sender *);
+extern void udp_send_init(struct sender *);
 
 /** The list of supported senders. */
 struct sender senders[] = {
@@ -44,12 +44,10 @@ struct sender senders[] = {
                .name = "dccp",
                .init = dccp_send_init,
        },
-#ifdef HAVE_ORTP
        {
-               .name = "ortp",
-               .init = ortp_send_init,
+               .name = "udp",
+               .init = udp_send_init,
        },
-#endif
        {
                .name = NULL,
        }
@@ -67,15 +65,25 @@ enum afs_socket_status {
 
 /** The task structure for the virtual streaming system. */
 struct vss_task {
+       /** Copied from the -announce_time command line option. */
        struct timeval announce_tv;
+       /** End of the announcing interval. */
        struct timeval data_send_barrier;
+       /** End of the EOF interval. */
        struct timeval eof_barrier;
+       /** Only used if --autoplay_delay was given. */
        struct timeval autoplay_barrier;
+       /** Used for afs-server communication. */
        int afs_socket;
+       /** The current state of \a afs_socket. */
        enum afs_socket_status afsss;
+       /** The memory mapped audio file. */
        char *map;
+       /** Used by the scheduler. */
        struct task task;
+       /** Pointer to the header of the mapped audio file. */
        const char *header_buf;
+       /** Length of the audio file header. */
        size_t header_len;
 };
 
@@ -238,6 +246,8 @@ struct timeval *vss_chunk_time(void)
 
 static int need_to_request_new_audio_file(struct vss_task *vsst)
 {
+       struct timeval diff;
+
        if (vsst->map) /* have audio file */
                return 0;
        if (!vss_playing()) /* don't need one */
@@ -246,6 +256,9 @@ static int need_to_request_new_audio_file(struct vss_task *vsst)
                return 0;
        if (vsst->afsss == AFS_SOCKET_AFD_PENDING) /* already requested one */
                return 0;
+       if (chk_barrier("autoplay_delay", &vsst->autoplay_barrier,
+                       &diff, 1) < 0)
+               return 0;
        return 1;
 }
 
@@ -288,7 +301,6 @@ static void vss_pre_select(struct sched *s, struct task *t)
                mmd->current_chunk = mmd->repos_request;
                mmd->new_vss_status_flags &= ~VSS_REPOS;
        }
-
        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);
@@ -370,8 +382,10 @@ static void recv_afs_result(struct vss_task *vsst)
        }
        mmd->size = statbuf.st_size;
        mmd->mtime = statbuf.st_mtime;
-       vsst->map = para_mmap(mmd->size, PROT_READ, MAP_PRIVATE,
-               passed_fd, 0);
+       ret = para_mmap(mmd->size, PROT_READ, MAP_PRIVATE, passed_fd,
+               0, &vsst->map);
+       if (ret < 0)
+               goto err;
        close(passed_fd);
        mmd->chunks_sent = 0;
        mmd->current_chunk = 0;
@@ -379,7 +393,6 @@ static void recv_afs_result(struct vss_task *vsst)
        mmd->events++;
        mmd->num_played++;
        mmd->new_vss_status_flags &= (~VSS_NEXT);
-       tv_add(now, &vsst->announce_tv, &vsst->data_send_barrier);
        afh_get_header(&mmd->afd.afhi, vsst->map, &vsst->header_buf,
                &vsst->header_len);
        return;
@@ -468,6 +481,9 @@ static void vss_post_select(struct sched *s, struct task *t)
                        continue;
                senders[i].post_select(&s->rfds, &s->wfds);
        }
+       if ((vss_playing() && !(mmd->vss_status_flags & VSS_PLAYING)) ||
+                       (vss_next() && vss_playing()))
+               tv_add(now, &vsst->announce_tv, &vsst->data_send_barrier);
        vss_send_chunk(vsst);
 }
 
@@ -508,6 +524,8 @@ void init_vss_task(int afs_socket)
                mmd->new_vss_status_flags |= VSS_PLAYING;
                ms2tv(autoplay_delay, &tmp);
                tv_add(now, &tmp, &vsst->autoplay_barrier);
+               tv_add(&vsst->autoplay_barrier, &vsst->announce_tv,
+                       &vsst->data_send_barrier);
        }
        register_task(&vsst->task);
 }