Merge branch 'refs/heads/t/play_fix'
[paraslash.git] / vss.c
diff --git a/vss.c b/vss.c
index cfa64a143cb1f5d665990dc6aeb23ef94d064d4c..e0b764ab71d43df3cdbd5b309d5f28e6cab5f7d2 100644 (file)
--- a/vss.c
+++ b/vss.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1997-2013 Andre Noll <maan@systemlinux.org>
+ * Copyright (C) 1997-2014 Andre Noll <maan@systemlinux.org>
  *
  * Licensed under the GPL v2. For licencing details see COPYING.
  */
  * senders.
  */
 
+#include <sys/socket.h>
+#include <netinet/in.h>
 #include <regex.h>
 #include <osl.h>
+#include <sys/types.h>
+#include <arpa/inet.h>
+#include <sys/un.h>
+#include <netdb.h>
 
 #include "para.h"
 #include "error.h"
@@ -83,7 +89,7 @@ struct vss_task {
        /** The memory mapped audio file. */
        char *map;
        /** Used by the scheduler. */
-       struct task task;
+       struct task *task;
        /** Pointer to the header of the mapped audio file. */
        char *header_buf;
        /** Length of the audio file header. */
@@ -565,8 +571,14 @@ static int setup_next_fec_group(struct fec_client *fc, struct vss_task *vsst)
                if (payload_size < g->slice_bytes)
                        memset(fc->extra_header_buf + payload_size, 0,
                                g->slice_bytes - payload_size);
-               fc->src_data[i] = fc->extra_header_buf;
-               assert(i == g->num_header_slices - 1);
+               /*
+                * There might be more than one header slice to fill although
+                * only the first one will be used. Set all header slices to
+                * our extra buffer.
+                */
+               while (i < g->num_header_slices)
+                       fc->src_data[i++] = fc->extra_header_buf;
+               break; /* we don't want i to be increased. */
        }
 
        /*
@@ -873,12 +885,9 @@ static void set_mmd_offset(void)
        mmd->offset = tv2ms(&offset);
 }
 
-/**
+/*
  * Compute the timeout for the main select-loop of the scheduler.
  *
- * \param s Pointer to the server scheduler.
- * \param t Pointer to the vss task structure.
- *
  * 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
@@ -887,10 +896,10 @@ static void set_mmd_offset(void)
  *     - shutdown of all senders (stop/pause command),
  *     - reposition the stream (ff/jmp command).
  */
-static void vss_pre_select(struct sched *s, struct task *t)
+static void vss_pre_select(struct sched *s, void *context)
 {
        int i;
-       struct vss_task *vsst = container_of(t, struct vss_task, task);
+       struct vss_task *vsst = context;
 
        if (!vsst->map || vss_next() || vss_paused() || vss_repos()) {
                struct fec_client *fc, *tmp;
@@ -912,7 +921,8 @@ static void vss_pre_select(struct sched *s, struct task *t)
                tv_add(now, &vsst->announce_tv, &vsst->data_send_barrier);
                set_eof_barrier(vsst);
                mmd->chunks_sent = 0;
-               mmd->current_chunk = mmd->repos_request;
+               mmd->current_chunk = afh_get_start_chunk(mmd->repos_request,
+                       &mmd->afd.afhi);
                mmd->new_vss_status_flags &= ~VSS_REPOS;
                set_mmd_offset();
        }
@@ -1114,11 +1124,10 @@ static void vss_send(struct vss_task *vsst)
        }
 }
 
-static void vss_post_select(struct sched *s, struct task *t)
+static int vss_post_select(struct sched *s, void *context)
 {
        int ret, i;
-       struct vss_task *vsst = container_of(t, struct vss_task, task);
-
+       struct vss_task *vsst = context;
 
        if (mmd->sender_cmd_data.cmd_num >= 0) {
                int num = mmd->sender_cmd_data.cmd_num,
@@ -1151,6 +1160,7 @@ static void vss_post_select(struct sched *s, struct task *t)
                        (vss_next() && vss_playing()))
                tv_add(now, &vsst->announce_tv, &vsst->data_send_barrier);
        vss_send(vsst);
+       return 0;
 }
 
 /**
@@ -1173,8 +1183,6 @@ void init_vss_task(int afs_socket, struct sched *s)
                        conf.autoplay_delay_arg : 0;
        vsst->header_interval.tv_sec = 5; /* should this be configurable? */
        vsst->afs_socket = afs_socket;
-       vsst->task.pre_select = vss_pre_select;
-       vsst->task.post_select = vss_post_select;
        ms2tv(announce_time, &vsst->announce_tv);
        PARA_INFO_LOG("announce timeval: %lums\n", tv2ms(&vsst->announce_tv));
        INIT_LIST_HEAD(&fec_client_list);
@@ -1194,6 +1202,10 @@ void init_vss_task(int afs_socket, struct sched *s)
                tv_add(&vsst->autoplay_barrier, &vsst->announce_tv,
                        &vsst->data_send_barrier);
        }
-       sprintf(vsst->task.status, "vss task");
-       register_task(s, &vsst->task);
+       vsst->task = task_register(&(struct task_info) {
+               .name = "vss task",
+               .pre_select = vss_pre_select,
+               .post_select = vss_post_select,
+               .context = vsst,
+       }, s);
 }