X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=audiod.c;h=9bb40e073b885c88216054d322c5cf4dd950e23e;hp=f805b00e1f399c87390f943621312d55c7f19a5c;hb=810761a3cdf3f75dd8e07a5d903793048c36df1d;hpb=e2c65e016f5fb330e0360a6fcea60b6ded845460 diff --git a/audiod.c b/audiod.c index f805b00e..9bb40e07 100644 --- a/audiod.c +++ b/audiod.c @@ -196,13 +196,25 @@ char *get_time_string(int slot_num) } if (audiod_status == AUDIOD_ON && !s) goto empty; - /* valid status items and playing */ + /* + * Valid status items and playing, set length and tmp to the stream + * start. We use the slot info and fall back to the info from current + * status items if no slot info is available. + */ + length = stat_task->length_seconds; + tmp = &stat_task->server_stream_start; if (s && s->wns) { /* writer active in this slot */ - length = s->seconds_total; - tmp = &s->server_stream_start; - } else { /* standby mode, rely on status items */ - length = stat_task->length_seconds; - tmp = &stat_task->server_stream_start; + btr_get_node_start(s->wns[0].btrn, &wstime); + if (wstime.tv_sec != 0) { /* writer wrote something */ + if (s->server_stream_start.tv_sec == 0) { + /* copy status info to slot */ + s->server_stream_start = stat_task->server_stream_start; + s->offset_seconds = stat_task->offset_seconds; + s->seconds_total = stat_task->length_seconds; + } + length = s->seconds_total; + tmp = &s->server_stream_start; + } } if (stat_task->sa_time_diff_sign > 0) tv_diff(tmp, &stat_task->sa_time_diff, &sss); @@ -214,7 +226,6 @@ char *get_time_string(int slot_num) seconds = diff.tv_sec + stat_task->offset_seconds; goto out; } - btr_get_node_start(s->wns[0].btrn, &wstime); tv_diff(now, &wstime, &wtime); //PARA_CRIT_LOG("offset %d\n", s->offset_seconds); seconds = s->offset_seconds; @@ -313,6 +324,7 @@ 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; @@ -323,13 +335,17 @@ static void close_receiver(int slot_num) btr_free_node(s->receiver_node->btrn); free(s->receiver_node); s->receiver_node = NULL; - stat_task->current_audio_format_num = -1; + tv_add(now, &restart_delay, &afi[s->format].restart_barrier); } static void writer_cleanup(struct writer_node *wn) { - struct writer *w = writers + wn->writer_num; + struct writer *w; + if (!wn) + return; + w = writers + wn->writer_num; + PARA_INFO_LOG("closing %s\n", writer_names[wn->writer_num]); w->close(wn); btr_free_node(wn->btrn); } @@ -352,7 +368,7 @@ static void close_writers(struct slot_info *s) s->wns = NULL; } -static void _close_filters(struct slot_info *s) +static void close_filters(struct slot_info *s) { int i; struct audio_format_info *a = afi + s->format; @@ -360,8 +376,11 @@ static void _close_filters(struct slot_info *s) return; for (i = 0; i < a->num_filters; i++) { struct filter_node *fn = s->fns + i; - struct filter *f = filters + fn->filter_num; + struct filter *f; + if (!fn) + continue; + f = filters + fn->filter_num; f->close(fn); btr_free_node(fn->btrn); } @@ -475,10 +494,6 @@ static void open_writers(struct slot_info *s) register_writer_node(wn, parent); } } - s->server_stream_start = stat_task->server_stream_start.tv_sec? - stat_task->server_stream_start : *now; - s->offset_seconds = stat_task->offset_seconds; - s->seconds_total = stat_task->length_seconds; } /* returns slot num on success */ @@ -585,12 +600,16 @@ static int open_current_receiver(struct sched *s) * this period begins to avoid restarting the receiver that * belongs to the file just completed. */ - if (stat_task->server_stream_start.tv_sec != 0) + 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) { - /* avoid busy loop */ - s->timeout = diff; + if (tv_diff(&s->timeout, &diff, NULL) > 0) + sched_request_timeout(&diff, s); + else + sched_min_delay(s); return -1; } /* start a new receiver */ @@ -1029,27 +1048,33 @@ static void set_stat_task_restart_barrier(unsigned seconds) tv_add(now, &delay, &stat_task->restart_barrier); } -static void try_to_close_slot(int slot_num) +static bool 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; + return false; if (s->receiver_node && s->receiver_node->task.error != -E_TASK_UNREGISTERED) - return; + return false; for (i = 0; i < a->num_filters; i++) if (s->fns && s->fns[i].task.error != -E_TASK_UNREGISTERED) - return; - for (i = 0; i < a->num_writers; i++) - if (s->wns && s->wns[i].task.error != -E_TASK_UNREGISTERED) - return; + return false; + 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; + } else { + if (s->wns && s->wns[0].task.error != -E_TASK_UNREGISTERED) + return false; + } PARA_INFO_LOG("closing slot %d\n", slot_num); close_writers(s); - _close_filters(s); + close_filters(s); close_receiver(slot_num); clear_slot(slot_num); + return true; } /* @@ -1063,7 +1088,8 @@ static void start_stop_decoders(struct sched *s) struct audio_format_info *a; FOR_EACH_SLOT(i) - try_to_close_slot(i); + if (try_to_close_slot(i)) + sched_min_delay(s); // if (audiod_status != AUDIOD_ON || // !(stat_task->vss_status & VSS_STATUS_FLAG_PLAYING)) // return kill_all_decoders(-E_NOT_PLAYING); @@ -1077,8 +1103,7 @@ static void start_stop_decoders(struct sched *s) open_writers(sl); activate_grab_clients(); btr_log_tree(sl->receiver_node->btrn, LL_NOTICE); - s->timeout.tv_sec = 0; - s->timeout.tv_usec = 1; + sched_min_delay(s); } /* restart the client task if necessary */ @@ -1129,18 +1154,20 @@ static void status_pre_select(struct sched *s, struct task *t) if (tv_diff(now, &st->restart_barrier, NULL) < 0) goto out; if (st->clock_diff_count) { /* get status only one time */ - char *argv[] = {"audiod", "--", "stat", "-p", "1", NULL}; + char *argv[] = {"audiod", "--", "stat", "-p", "-n=1", NULL}; int argc = 5; PARA_INFO_LOG("clock diff count: %d\n", st->clock_diff_count); st->clock_diff_count--; client_open(argc, argv, &st->ct, NULL); 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); set_stat_task_restart_barrier(5); + sched_min_delay(s); } free(stat_item_values[SI_BASENAME]); stat_item_values[SI_BASENAME] = para_strdup(