http_recv: set the eof flag on buffer overruns.
[paraslash.git] / audiod.c
index d635fbfc334316b9dd78ab2b67e266dd757c828c..68c84fb4df31bf54266643e709b40918bce53fb7 100644 (file)
--- a/audiod.c
+++ b/audiod.c
@@ -105,7 +105,7 @@ static char *af_status, /* the audio format announced in server status */
        *socket_name, *hostname;
 static char *stat_item_values[NUM_STAT_ITEMS];
 static FILE *logfile;
-static const struct timeval restart_delay = {0, 300 * 1000};
+static const struct timeval restart_delay = {0, 200 * 1000};
 static struct audio_format_info afi[NUM_AUDIO_FORMATS];
 static struct timeval *now;
 
@@ -499,8 +499,22 @@ static void kill_all_decoders(void)
 
        FOR_EACH_SLOT(i) {
                struct slot_info *s = &slot[i];
-               if (s->receiver_node)
+               if (s->wng && !s->wng->eof) {
+                       PARA_INFO_LOG("unregistering writer node group in slot %d\n",
+                               i);
+                       wng_unregister(s->wng);
+                       s->wng->eof = 1;
+               }
+               if (s->fc && !s->fc->eof) {
+                       PARA_INFO_LOG("unregistering filter chain in slot %d\n", i);
+                       unregister_task(&s->fc->task);
+                       s->fc->eof = 1;
+               }
+               if (s->receiver_node && !s->receiver_node->eof) {
+                       PARA_INFO_LOG("unregistering receiver_node in slot %d\n", i);
+                       unregister_task(&s->receiver_node->task);
                        s->receiver_node->eof = 1;
+               }
        }
 }
 
@@ -610,12 +624,13 @@ static void open_filters(int slot_num)
        s->fc->inbuf = s->receiver_node->buf;
        s->fc->in_loaded = &s->receiver_node->loaded;
        s->fc->input_eof = &s->receiver_node->eof;
-
        s->fc->task.pre_select = filter_pre_select;
        s->fc->task.event_handler = filter_event_handler;
        s->fc->task.private_data = s->fc;
        s->fc->task.flags = 0;
        s->fc->eof = 0;
+
+       s->receiver_node->output_eof = &s->fc->eof;
        sprintf(s->fc->task.status, "filter chain");
        for (i = 0; i < nf; i++) {
                struct filter_node *fn = para_calloc(sizeof(struct filter_node));
@@ -661,8 +676,16 @@ static struct filter_node *find_filter_node(int slot_num, int format, int filter
 
 static void wng_event_handler(struct task *t)
 {
-       PARA_INFO_LOG("%s\n", PARA_STRERROR(-t->ret));
-       unregister_task(t);
+       struct writer_node_group *wng = t->private_data;
+       int i;
+
+       wng_unregister(wng);
+       FOR_EACH_SLOT(i) {
+               struct slot_info *s = &slot[i];
+               if (s->wng != wng)
+                       continue;
+               PARA_INFO_LOG("slot %d: %s\n", i, PARA_STRERROR(-t->ret));
+       }
 }
 
 static void open_writers(int slot_num)
@@ -680,7 +703,10 @@ static void open_writers(int slot_num)
                s->wng->buf = s->fc->outbuf;
                s->wng->loaded = s->fc->out_loaded;
                s->wng->input_eof = &s->fc->eof;
+               s->wng->channels = &s->fc->channels;
+               s->wng->samplerate = &s->fc->samplerate;
                s->fc->output_eof = &s->wng->eof;
+               PARA_INFO_LOG("samplerate: %d\n", *s->wng->samplerate);
        } else {
                s->wng->buf = s->receiver_node->buf;
                s->wng->loaded = &s->receiver_node->loaded;
@@ -693,6 +719,10 @@ static void open_writers(int slot_num)
                sprintf(s->wng->writer_nodes[i].task.status, "writer_node");
        }
        ret = wng_open(s->wng);
+       if (ret < 0) {
+               PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret));
+               return;
+       }
        s->wstime = *now;
        current_decoder = slot_num;
        activate_inactive_grab_clients(slot_num, s->format, &s->fc->filters);
@@ -790,7 +820,7 @@ static void compute_time_diff(const struct timeval *status_time)
                count > 10? sign : sign * time_smooth, &diff,
                &tmp);
        sa_time_diff = tmp;
-       PARA_INFO_LOG("time diff (cur/avg): %s%lums/%s%lums\n",
+       PARA_DEBUG_LOG("time diff (cur/avg): %s%lums/%s%lums\n",
                sign > 0? "+" : "-",
                tv2ms(&diff),
                sa_time_diff_sign ? "+" : "-",
@@ -881,7 +911,6 @@ static void try_to_close_slot(int slot_num)
                return;
        PARA_INFO_LOG("closing slot %d \n", slot_num);
        wng_close(s->wng);
-       wng_destroy(s->wng);
        close_filters(s->fc);
        free(s->fc);
        close_receiver(slot_num);
@@ -892,22 +921,33 @@ static void audiod_pre_select(struct sched *s, __a_unused struct task *t)
 {
        int i;
 
+       t->ret = 1;
        now = &s->now;
        if (audiod_status != AUDIOD_ON)
                kill_all_decoders();
        else if (playing)
                open_current_receiver();
        FOR_EACH_SLOT(i) {
-               struct receiver_node *rn;
+               struct slot_info *s = &slot[i];
+               struct audio_format_info *a;
 
                try_to_close_slot(i);
-               if (slot[i].format < 0)
+               if (s->format < 0)
                        continue;
-               rn = slot[i].receiver_node;
-               if (rn && rn->loaded && !slot[i].wng) {
+               a = &afi[s->format];
+               if (!s->receiver_node)
+                       continue;
+               if (!a->num_filters) {
+                       if (s->receiver_node->loaded && !s->wng)
+                               open_writers(i);
+                       continue;
+               }
+               if (s->receiver_node->loaded && !s->fc) {
                        open_filters(i);
-                       open_writers(i);
+                       continue;
                }
+               if (s->fc && *s->fc->out_loaded && !s->wng)
+                       open_writers(i);
        }
 }
 
@@ -915,6 +955,7 @@ static void audiod_post_select(struct sched *s, __a_unused struct task *t)
 {
        /* only save away the current time for other users */
        now = &s->now;
+       t->ret = 1;
 }
 
 static void init_audiod_task(struct task *t)
@@ -1483,6 +1524,7 @@ void signal_setup_default(struct signal_task *st)
 static void command_pre_select(struct sched *s, struct task *t)
 {
        struct command_task *ct = t->private_data;
+       t->ret = 1;
        para_fd_set(ct->fd, &s->rfds, &s->max_fileno);
 
 }
@@ -1492,9 +1534,9 @@ static void command_post_select(struct sched *s, struct task *t)
        int ret;
        struct command_task *ct = t->private_data;
 
+       t->ret = 1; /* always successful */
        if (audiod_status != AUDIOD_OFF)
                audiod_status_dump();
-       t->ret = 1; /* always successful */
        if (!FD_ISSET(ct->fd, &s->rfds))
                return;
        ret = handle_connect(ct->fd);