audiod: Revamp the decoder starting logic.
authorAndre Noll <maan@systemlinux.org>
Sun, 21 Mar 2010 18:16:20 +0000 (19:16 +0100)
committerAndre Noll <maan@systemlinux.org>
Sun, 21 Mar 2010 18:16:20 +0000 (19:16 +0100)
Use an approach that is based on the server start time of the stream. This value
changes whenever para_server announces a new stream.

This makes para_audiod restart the receiver much earlier and should get of timing
problems that cause the UDP sender to remove the UDP target because there
is no listener on the receiving side.

audiod.c

index 41fcdd8..2c27648 100644 (file)
--- a/audiod.c
+++ b/audiod.c
@@ -347,7 +347,6 @@ static void close_receiver(int slot_num)
 {
        struct slot_info *s = &slot[slot_num];
        struct audio_format_info *a;
-       struct timeval restart_delay = {0, 200 * 1000};
 
        if (s->format < 0 || !s->receiver_node)
                return;
@@ -358,7 +357,6 @@ static void close_receiver(int slot_num)
        btr_free_node(s->receiver_node->btrn);
        free(s->receiver_node);
        s->receiver_node = NULL;
-       tv_add(now, &restart_delay, &afi[s->format].restart_barrier);
 }
 
 static void writer_cleanup(struct writer_node *wn)
@@ -577,22 +575,23 @@ static int open_receiver(int format)
        return slot_num;
 }
 
-/* return: 0: Not running, 1: Running, -1: Running but eof (or error) */
-static int receiver_running(int format)
+static bool receiver_running(void)
 {
-       int i, ret = 0;
+       int i;
+       long unsigned ss1 = stat_task->server_stream_start.tv_sec;
 
        FOR_EACH_SLOT(i) {
                struct slot_info *s = &slot[i];
-               if (s->format != format)
-                       continue;
+               long unsigned ss2 = s->server_stream_start.tv_sec;
+
                if (!s->receiver_node)
                        continue;
                if (s->receiver_node->task.error >= 0)
-                       return 1;
-               ret = -1;
+                       return true;
+               if (ss1 == ss2)
+                       return true;
        }
-       return ret;
+       return false;
 }
 
 /**
@@ -630,15 +629,18 @@ struct btr_node *audiod_get_btr_root(void)
 /* whether a new instance of a decoder should be started. */
 static bool must_start_decoder(void)
 {
-       int ret, cafn = stat_task->current_audio_format_num;
+       int cafn = stat_task->current_audio_format_num;
+       unsigned vs = stat_task->vss_status;
 
-       if (cafn < 0 || !stat_task->ct)
+       if (cafn < 0)
+               return false;
+       if (!stat_task->ct)
+               return false;
+       if (vs & VSS_STATUS_FLAG_NEXT)
                return false;
-       /* Do nothing if the 'N' flag is set or the 'P' flag is unset */
-       if (stat_task->vss_status != VSS_STATUS_FLAG_PLAYING)
+       if (!(vs & VSS_STATUS_FLAG_PLAYING))
                return false;
-       ret = receiver_running(cafn);
-       if (ret != 0) /* already running */
+       if (receiver_running())
                return false;
        if (tv_diff(now, &afi[cafn].restart_barrier, NULL) < 0)
                return false;