X-Git-Url: http://git.tuebingen.mpg.de/?a=blobdiff_plain;f=audiod.c;h=72276ffe072f1a24fa67ac866e18c4d9a33889cd;hb=0113172c1f18f4a168b0a0fdacb376da2f2a73e3;hp=27eba9e3e584cd06294bef568cc4eb19d1ce1f88;hpb=fc100a582159c001bd5eb2244f314343309bb503;p=paraslash.git diff --git a/audiod.c b/audiod.c index 27eba9e3..72276ffe 100644 --- a/audiod.c +++ b/audiod.c @@ -491,8 +491,8 @@ static void open_filters(struct slot_info *s) register_task(&fn->task); parent = fn->btrn; PARA_NOTICE_LOG("%s filter %d/%d (%s) started in slot %d\n", - audio_formats[s->format], i, nf, f->name, s - slot); - sprintf(fn->task.status, "%s (slot %d)", f->name, s - slot); + audio_formats[s->format], i, nf, f->name, (int)(s - slot)); + sprintf(fn->task.status, "%s (slot %d)", f->name, (int)(s - slot)); } } @@ -603,41 +603,22 @@ struct btr_node *audiod_get_btr_root(void) return slot[newest_slot].receiver_node->btrn; } -/* returns slot num on success. */ -static int open_current_receiver(struct sched *s) +/* whether a new instance of a decoder should be started. */ +static bool must_start_decoder(void) { - struct timeval diff; int ret, cafn = stat_task->current_audio_format_num; if (cafn < 0 || !stat_task->ct) - return -1; + 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) - return -1; + return false; ret = receiver_running(cafn); - if (ret > 0) /* already running and not eof */ - return -1; - if (ret < 0) { /* eof */ - /* - * para_server uses a zero start time during the announcement - * period, i.e. before it sends the first chunk. Wait until - * this period begins to avoid restarting the receiver that - * belongs to the file just completed. - */ - if (stat_task->server_stream_start.tv_sec != 0) { - sched_request_timeout_ms(100, s); - return -1; - } - } - if (tv_diff(now, &afi[cafn].restart_barrier, &diff) < 0) { - if (tv_diff(&s->timeout, &diff, NULL) > 0) - sched_request_timeout(&diff, s); - else - sched_min_delay(s); - return -1; - } - /* start a new receiver */ - return open_receiver(cafn); + if (ret != 0) /* already running */ + return false; + if (tv_diff(now, &afi[cafn].restart_barrier, NULL) < 0) + return false; + return true; } static unsigned compute_time_diff(const struct timeval *status_time) @@ -672,9 +653,9 @@ static unsigned compute_time_diff(const struct timeval *status_time) &tmp); stat_task->sa_time_diff = tmp; PARA_INFO_LOG("time diff (cur/avg): %s%lums/%s%lums\n", - sign > 0? "+" : "-", + sign < 0? "-" : "+", tv2ms(&diff), - sa_time_diff_sign ? "+" : "-", + sa_time_diff_sign < 0? "-" : "+", tv2ms(&stat_task->sa_time_diff) ); out: @@ -1073,52 +1054,52 @@ static void set_stat_task_restart_barrier(unsigned seconds) tv_add(now, &delay, &stat_task->restart_barrier); } -static bool try_to_close_slot(int slot_num) +static void try_to_close_slot(int slot_num) { struct slot_info *s = &slot[slot_num]; struct audio_format_info *a = afi + s->format; int i; if (s->format < 0) - return false; + return; if (s->receiver_node && s->receiver_node->task.error != -E_TASK_UNREGISTERED) - return false; + return; for (i = 0; i < a->num_filters; i++) if (s->fns && s->fns[i].task.error != -E_TASK_UNREGISTERED) - return false; + return; if (a->num_writers > 0) { for (i = 0; i < a->num_writers; i++) if (s->wns && s->wns[i].task.error != -E_TASK_UNREGISTERED) - return false; + return; } else { if (s->wns && s->wns[0].task.error != -E_TASK_UNREGISTERED) - return false; + return; } PARA_INFO_LOG("closing slot %d\n", slot_num); close_writers(s); close_filters(s); close_receiver(slot_num); clear_slot(slot_num); - return true; } /* * Check if any receivers/filters/writers need to be started and do so if * necessary. */ -static void start_stop_decoders(struct sched *s) +static void start_stop_decoders(void) { int i, ret; struct slot_info *sl; struct audio_format_info *a; FOR_EACH_SLOT(i) - if (try_to_close_slot(i)) - sched_min_delay(s); + try_to_close_slot(i); if (audiod_status != AUDIOD_ON || !(stat_task->vss_status & VSS_STATUS_FLAG_PLAYING)) return kill_all_decoders(-E_NOT_PLAYING); - ret = open_current_receiver(s); + if (!must_start_decoder()) + return; + ret = open_receiver(stat_task->current_audio_format_num); if (ret < 0) return; sl = slot + ret; @@ -1128,20 +1109,29 @@ static void start_stop_decoders(struct sched *s) open_writers(sl); activate_grab_clients(); btr_log_tree(sl->receiver_node->btrn, LL_NOTICE); - sched_min_delay(s); } static void status_pre_select(struct sched *s, struct task *t) { struct status_task *st = container_of(t, struct status_task, task); - int ret; + int ret, cafn = stat_task->current_audio_format_num; + if (must_start_decoder()) + goto min_delay; ret = btr_node_status(st->btrn, 0, BTR_NT_LEAF); - sched_request_barrier(&st->restart_barrier, s); + if (ret > 0) + goto min_delay; + if (!st->ct) + sched_request_barrier_or_min_delay(&st->restart_barrier, s); + if (cafn >= 0) + sched_request_barrier(&afi[cafn].restart_barrier, s); + return; +min_delay: + sched_min_delay(s); } /* restart the client task if necessary */ -static void status_post_select(struct sched *s, struct task *t) +static void status_post_select(__a_unused struct sched *s, struct task *t) { struct status_task *st = container_of(t, struct status_task, task); @@ -1200,14 +1190,12 @@ static void status_post_select(struct sched *s, struct task *t) st->clock_diff_count--; client_open(argc, argv, &st->ct, NULL, NULL, st->btrn); set_stat_task_restart_barrier(2); - sched_min_delay(s); } else { char *argv[] = {"audiod", "--", "stat", "-p", NULL}; int argc = 4; client_open(argc, argv, &st->ct, NULL, NULL, st->btrn); set_stat_task_restart_barrier(5); - sched_min_delay(s); } free(stat_item_values[SI_BASENAME]); stat_item_values[SI_BASENAME] = para_strdup( @@ -1215,7 +1203,7 @@ static void status_post_select(struct sched *s, struct task *t) stat_client_write_item(SI_BASENAME); st->last_status_read = *now; out: - start_stop_decoders(s); + start_stop_decoders(); } static void init_status_task(struct status_task *st)