X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=audiod.c;h=d78841336893c170f9da7472c717b1e70c9c45bc;hp=631bcf5e0ff7174fe10a12ab11acc273ceedeaef;hb=af2518cf1943cb1b6b4b4a32ca687e8f416ed563;hpb=e122abcdde0cde522b891315b5cbb680b74fa021 diff --git a/audiod.c b/audiod.c index 631bcf5e..d7884133 100644 --- a/audiod.c +++ b/audiod.c @@ -18,7 +18,6 @@ /** \file audiod.c the paraslash's audio daemon */ -#include /* gettimeofday */ #include "para.h" #include "audiod.cmdline.h" @@ -111,8 +110,8 @@ static char *af_status, /* the audio format announced in server status */ static char *stat_item_values[NUM_STAT_ITEMS]; static FILE *logfile; static const struct timeval restart_delay = {0, 300 * 1000}; - static struct audio_format_info afi[NUM_AUDIO_FORMATS]; +static struct timeval *now; static struct signal_task signal_task_struct, *sig_task = &signal_task_struct; @@ -315,7 +314,7 @@ static int client_write(int fd, const char *buf) static char *get_time_string(struct timeval *newest_stime) { - struct timeval now, diff, adj_stream_start, tmp; + struct timeval diff, adj_stream_start, tmp; int total = 0, use_server_time = 1; if (!playing) { @@ -339,8 +338,7 @@ static char *get_time_string(struct timeval *newest_stime) use_server_time = 0; } } - gettimeofday(&now, NULL); - tv_diff(&now, &tmp, &diff); + tv_diff(now, &tmp, &diff); total = diff.tv_sec + offset_seconds; if (total > length_seconds) total = length_seconds; @@ -466,17 +464,6 @@ static void clear_slot(int slot_num) s->format = -1; } -static void set_restart_barrier(int format, struct timeval *now) -{ - struct timeval tmp; - - if (now) - tmp = *now; - else - gettimeofday(&tmp, NULL); - tv_add(&tmp, &restart_delay, &afi[format].restart_barrier); -} - static void close_receiver(int slot_num) { struct slot_info *s = &slot[slot_num]; @@ -485,14 +472,15 @@ static void close_receiver(int slot_num) if (s->format < 0 || !s->receiver_node) return; a = &afi[s->format]; - PARA_NOTICE_LOG("closing %s recevier in slot %d (eof = %d)\n", + PARA_NOTICE_LOG("closing %s receiver in slot %d (eof = %d)\n", audio_formats[s->format] , slot_num, s->receiver_node->eof); if (!s->receiver_node->eof) unregister_task(&s->receiver_node->task); a->receiver->close(s->receiver_node); free(s->receiver_node); s->receiver_node = NULL; - set_restart_barrier(s->format, NULL); + /* set restart barrier */ + tv_add(now, &restart_delay, &afi[s->format].restart_barrier); } static void kill_all_decoders(void) @@ -506,20 +494,6 @@ static void kill_all_decoders(void) } } -static void check_sigchld(void) -{ - pid_t pid; - struct timeval now; - gettimeofday(&now, NULL); - -reap_next_child: - pid = para_reap_child(); - if (pid <= 0) - return; - PARA_CRIT_LOG("para_client died (pid %d)\n", pid); - goto reap_next_child; -} - static int get_empty_slot(void) { int i; @@ -531,11 +505,7 @@ static int get_empty_slot(void) clear_slot(i); return i; } - if (s->wng) - continue; - if (s->receiver_node) - continue; - if (s->fc) + if (s->wng || s->receiver_node || s->fc) continue; clear_slot(i); return i; @@ -578,7 +548,8 @@ static void close_stat_pipe(void) offset_seconds = 0; audiod_status_dump(); playing = 0; - stat_item_values[SI_STATUS_BAR] = make_message("%s:no connection to para_server\n", + stat_item_values[SI_STATUS_BAR] = make_message( + "%s:no connection to para_server\n", status_item_list[SI_STATUS_BAR]); stat_client_write(stat_item_values[SI_STATUS_BAR], SI_STATUS_BAR); } @@ -594,13 +565,21 @@ static void __noreturn clean_exit(int status, const char *msg) exit(status); } -/** get the number of filters for the given audio format */ +/** + * get the number of filters + * + * \param audio_format_num the number identifying the audio format + * + * \return the number of filters for the given audio format + * + * \sa struct filter; + */ int num_filters(int audio_format_num) { return afi[audio_format_num].num_filters; } -void filter_event_handler(struct task *t) +static void filter_event_handler(struct task *t) { PARA_NOTICE_LOG("%s\n", PARA_STRERROR(-t->ret)); unregister_task(t); @@ -689,7 +668,7 @@ static void wng_event_handler(struct task *t) } } -static void open_writer(int slot_num, struct timeval *now) +static void open_writer(int slot_num) { int ret, i; struct slot_info *s = &slot[slot_num]; @@ -722,12 +701,13 @@ static void open_writer(int slot_num, struct timeval *now) activate_inactive_grab_clients(slot_num, s->format, &s->fc->filters); } -void rn_event_handler(struct task *t) +static void rn_event_handler(struct task *t) { // struct receiver_node *rn = t->private_data; PARA_NOTICE_LOG("%s\n", PARA_STRERROR(-t->ret)); unregister_task(t); } + static void open_receiver(int format) { struct audio_format_info *a = &afi[format]; @@ -740,7 +720,7 @@ static void open_receiver(int format) clean_exit(EXIT_FAILURE, PARA_STRERROR(-slot_num)); s = &slot[slot_num]; s->format = format; - gettimeofday(&s->rtime, NULL); + s->rtime = *now; s->wtime = s->rtime; s->receiver_node = para_calloc(sizeof(struct receiver_node)); rn = s->receiver_node; @@ -766,14 +746,14 @@ static void open_receiver(int format) register_task(&rn->task); } -static int is_frozen(int format, struct timeval *now) +static int is_frozen(int format) { struct audio_format_info *a = &afi[format]; return (tv_diff(now, &a->restart_barrier, NULL) > 0)? 0 : 1; } -static void open_current_receiver(struct timeval *now) +static void open_current_receiver(void) { int i; @@ -782,21 +762,20 @@ static void open_current_receiver(struct timeval *now) i = get_audio_format_num(af_status); if (i < 0) return; - if ((decoder_running(i) & 1) || is_frozen(i, now)) + if (decoder_running(i) || is_frozen(i)) return; open_receiver(i); } static void compute_time_diff(const struct timeval *status_time) { - struct timeval now, tmp, diff; + struct timeval tmp, diff; static int count; int sign; const struct timeval max_deviation = {0, 500 * 1000}; const int time_smooth = 5; - gettimeofday(&now, NULL); - sign = tv_diff(status_time, &now, &diff); + sign = tv_diff(status_time, now, &diff); // PARA_NOTICE_LOG("%s: sign = %i, sa_time_diff_sign = %i\n", __func__, // sign, sa_time_diff_sign); if (!count) { @@ -879,7 +858,12 @@ static void handle_signal(int sig) { switch (sig) { case SIGCHLD: - return check_sigchld(); + for (;;) { + pid_t pid = para_reap_child(); + if (pid <= 0) + return; + PARA_CRIT_LOG("para_client died (pid %d)\n", pid); + } case SIGINT: case SIGTERM: case SIGHUP: @@ -891,17 +875,16 @@ static void handle_signal(int sig) static void check_timeouts(void) { - struct timeval now; + int slot_num, timeout = conf.stream_timeout_arg; - gettimeofday(&now, NULL); FOR_EACH_SLOT(slot_num) { struct slot_info *s = &slot[slot_num]; if (s->format < 0) continue; /* check read time */ if (s->receiver_node && - now.tv_sec > s->rtime.tv_sec + timeout) { + now->tv_sec > s->rtime.tv_sec + timeout) { PARA_INFO_LOG("%s stream (slot %d) not ready\n", audio_formats[s->format], slot_num); s->receiver_node->eof = 1; @@ -931,10 +914,11 @@ static void audiod_pre_select(struct sched *s, __a_unused struct task *t) { int i; + now = &s->now; if (audiod_status != AUDIOD_ON) kill_all_decoders(); else if (playing) - open_current_receiver(&s->now); + open_current_receiver(); check_timeouts(); FOR_EACH_SLOT(i) { struct receiver_node *rn; @@ -945,7 +929,7 @@ static void audiod_pre_select(struct sched *s, __a_unused struct task *t) rn = slot[i].receiver_node; if (rn && rn->loaded && !slot[i].wng) { open_filters(i); - open_writer(i, &s->now); + open_writer(i); } } } @@ -954,11 +938,12 @@ static void audiod_post_select(struct sched *s, __a_unused struct task *t) { int i; + now = &s->now; FOR_EACH_SLOT(i) { struct receiver_node *rn = slot[i].receiver_node; if (rn && rn->loaded) - slot[i].rtime = s->now; + slot[i].rtime = *now; } } @@ -1003,41 +988,6 @@ static int add_filter(int format, char *cmdline) return filter_num; } -static int setup_default_filters(void) -{ - int i, ret = 1; - - FOR_EACH_AUDIO_FORMAT(i) { - struct audio_format_info *a = &afi[i]; - char *tmp; - int j; - if (a->num_filters) - continue; - /* add "dec" to audio format name */ - tmp = make_message("%sdec", audio_formats[i]); - for (j = 0; filters[j].name; j++) - if (!strcmp(tmp, filters[j].name)) - break; - free(tmp); - ret = -E_UNSUPPORTED_FILTER; - if (!filters[j].name) - goto out; - tmp = para_strdup(filters[j].name); - ret = add_filter(i, tmp); - free(tmp); - if (ret < 0) - goto out; - PARA_INFO_LOG("%s -> default filter: %s\n", audio_formats[i], - filters[j].name); - ret = add_filter(i, "wav"); - if (ret < 0) - goto out; - PARA_INFO_LOG("%s -> default filter: wav\n", audio_formats[i]); - } -out: - return ret; -} - static int init_writers(void) { int i, ret, nw; @@ -1046,7 +996,7 @@ static int init_writers(void) init_supported_writers(); nw = PARA_MAX(1, conf.writer_given); - PARA_INFO_LOG("allocating space for %d writers\n", nw); + PARA_INFO_LOG("maximal number of writers: %d\n", nw); FOR_EACH_AUDIO_FORMAT(i) { a = &afi[i]; a->writer_conf = para_malloc(nw * sizeof(void *)); @@ -1124,19 +1074,52 @@ out: free(cmd); return ret; } + +static int init_default_filters(void) +{ + int i, ret = 1; + + FOR_EACH_AUDIO_FORMAT(i) { + struct audio_format_info *a = &afi[i]; + char *tmp; + int j; + + if (a->num_filters) + continue; /* no default -- nothing to to */ + /* add "dec" to audio format name */ + tmp = make_message("%sdec", audio_formats[i]); + for (j = 0; filters[j].name; j++) + if (!strcmp(tmp, filters[j].name)) + break; + free(tmp); + ret = -E_UNSUPPORTED_FILTER; + if (!filters[j].name) + goto out; + tmp = para_strdup(filters[j].name); + ret = add_filter(i, tmp); + free(tmp); + if (ret < 0) + goto out; + PARA_INFO_LOG("%s -> default filter: %s\n", audio_formats[i], + filters[j].name); + } +out: + return ret; +} + static int init_filters(void) { int i, ret, nf; filter_init(filters); - nf = PARA_MAX(2, conf.filter_given) + 1; - PARA_INFO_LOG("allocating space for %d filters\n", nf); + nf = PARA_MAX(1, conf.filter_given); + PARA_INFO_LOG("maximal number of filters: %d\n", nf); FOR_EACH_AUDIO_FORMAT(i) { afi[i].filter_conf = para_malloc(nf * sizeof(void *)); afi[i].filters = para_malloc(nf * sizeof(struct filter *)); } if (!conf.no_default_filters_given) - return setup_default_filters(); + return init_default_filters(); for (i = 0; i < conf.filter_given; i++) { char *arg = conf.filter_arg[i]; char *filter_name = strchr(arg, ':'); @@ -1152,7 +1135,7 @@ static int init_filters(void) if (ret < 0) goto out; } - ret = 1; + ret = init_default_filters(); /* use default values for the rest */ out: return ret; } @@ -1546,7 +1529,7 @@ static void command_post_select(struct sched *s, struct task *t) PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret)); } -void init_command_task(struct command_task *ct) +static void init_command_task(struct command_task *ct) { ct->task.pre_select = command_pre_select; ct->task.post_select = command_post_select; @@ -1583,7 +1566,7 @@ static void status_post_select(struct sched *s, struct task *t) if (ret <= 0) { close_stat_pipe(); /* avoid busy loop if server is down */ - while (sleep(1) > 0) + while (sleep(1) > 0) /* FIXME */ ; /* try again*/ } else { st->buf[ret + st->loaded] = '\0';