X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=audiod.c;h=bd7bb5b1ac704357e3639ebbe4716bf495797404;hp=7f10378945e899656f036e5d8e16fa7da34c01d6;hb=2742af12a1a8cd99302f60521efe47cfbf16e963;hpb=4b6458e9fc11eb741200dfebd8dc96a333956e4b diff --git a/audiod.c b/audiod.c index 7f103789..bd7bb5b1 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]; @@ -492,35 +479,24 @@ static void close_receiver(int slot_num) a->receiver->close(s->receiver_node); free(s->receiver_node); s->receiver_node = NULL; - set_restart_barrier(s->format, NULL); -} -static void close_writer(int slot_num) -{ - struct slot_info *s = &slot[slot_num]; - if (s->wng) { - PARA_INFO_LOG("slot %d: closing writer node group\n", - slot_num); - wng_close(s->wng); - s->wng = NULL; - } - if (s->fc) - *s->fc->output_eof = 1; /* FIXME */ + /* set restart barrier */ + tv_add(now, &restart_delay, &afi[s->format].restart_barrier); } - static void kill_all_decoders(void) { int i; - FOR_EACH_SLOT(i) - close_writer(i); + FOR_EACH_SLOT(i) { + struct slot_info *s = &slot[i]; + if (s->receiver_node) + s->receiver_node->eof = 1; + } } static void check_sigchld(void) { pid_t pid; - struct timeval now; - gettimeofday(&now, NULL); reap_next_child: pid = para_reap_child(); @@ -604,33 +580,6 @@ static void __noreturn clean_exit(int status, const char *msg) exit(status); } -#if 0 -__malloc static char *glob_cmd(char *cmd) -{ - char *ret, *replacement; - struct timeval tmp, delay, rss; /* real stream start */ - - delay.tv_sec = conf.stream_delay_arg / 1000; - delay.tv_usec = (conf.stream_delay_arg % 1000) * 1000; -// PARA_INFO_LOG("delay: %lu:%lu\n", delay.tv_sec, delay.tv_usec); - if (sa_time_diff_sign < 0) - tv_add(&server_stream_start, &sa_time_diff, &rss); - else - tv_diff(&server_stream_start, &sa_time_diff, &rss); - tv_add(&rss, &delay, &tmp); - replacement = make_message("%lu:%lu", - (long unsigned)tmp.tv_sec, - (long unsigned)tmp.tv_usec); - ret = s_a_r(cmd, "STREAM_START", replacement); - free(replacement); - if (!ret) - goto out; - PARA_INFO_LOG("cmd: %s, repl: %s\n", cmd, ret); -out: - return ret; -} -#endif - /** get the number of filters for the given audio format */ int num_filters(int audio_format_num) { @@ -653,6 +602,7 @@ static void open_filters(int slot_num) s->fc = NULL; if (!nf) return; + PARA_INFO_LOG("opening %s filters\n", audio_formats[s->format]); s->fc = para_calloc(sizeof(struct filter_chain)); INIT_LIST_HEAD(&s->fc->filters); s->fc->inbuf = s->receiver_node->buf; @@ -725,14 +675,12 @@ static void wng_event_handler(struct task *t) } } -static void start_stream_writer(int slot_num, struct timeval *now) +static void open_writer(int slot_num) { int ret, i; struct slot_info *s = &slot[slot_num]; struct audio_format_info *a = &afi[s->format]; - PARA_INFO_LOG("opening %s filters\n", audio_formats[s->format]); - open_filters(slot_num); PARA_INFO_LOG("opening %s writers\n", audio_formats[s->format]); if (!a->num_writers) s->wng = setup_default_wng(); @@ -766,6 +714,7 @@ void rn_event_handler(struct task *t) 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]; @@ -778,7 +727,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; @@ -806,14 +755,12 @@ static void open_receiver(int format) static int is_frozen(int format) { - struct timeval now; struct audio_format_info *a = &afi[format]; - gettimeofday(&now, NULL); - return (tv_diff(&now, &a->restart_barrier, NULL) > 0)? 0 : 1; + return (tv_diff(now, &a->restart_barrier, NULL) > 0)? 0 : 1; } -static void start_current_receiver(void) +static void open_current_receiver(void) { int i; @@ -822,21 +769,20 @@ static void start_current_receiver(void) i = get_audio_format_num(af_status); if (i < 0) return; - if ((decoder_running(i) & 1) || is_frozen(i)) + 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) { @@ -931,17 +877,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; @@ -967,14 +912,15 @@ static void close_decoder_if_idle(int slot_num) clear_slot(slot_num); } -static void audiod_pre_select(__a_unused struct sched *s, __a_unused struct task *t) +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) - start_current_receiver(); + open_current_receiver(); check_timeouts(); FOR_EACH_SLOT(i) { struct receiver_node *rn; @@ -984,65 +930,22 @@ static void audiod_pre_select(__a_unused struct sched *s, __a_unused struct task continue; rn = slot[i].receiver_node; if (rn && rn->loaded && !slot[i].wng) { - PARA_INFO_LOG("no writer in slot %d\n", i); - start_stream_writer(i, &s->now); + open_filters(i); + open_writer(i); } } } -#if 0 -static int write_audio_data(int slot_num) -{ - struct slot_info *s = &slot[slot_num]; - struct audio_format_info *a = &afi[s->format]; - struct receiver_node *rn = s->receiver_node; - int ret; - char **buf; - size_t *len; - - if (a->num_filters) { - buf = &s->fc->outbuf; - len = s->fc->out_loaded; - } else { - buf = &rn->buf; - len = &rn->loaded; - } - PARA_DEBUG_LOG("writing %p (%zd bytes)\n", *buf, *len); - ret = write(s->write_fd, *buf, *len); - PARA_DEBUG_LOG("wrote %d/%zd\n", ret, *len); - if (ret < 0) { - PARA_WARNING_LOG("write error in slot %d (fd %d): %s\n", - slot_num, s->write_fd, strerror(errno)); - *len = 0; - close_writer(slot_num); -// s->fc->error = E_WRITE_AUDIO_DATA; - } else if (ret != *len) { - PARA_DEBUG_LOG("partial %s write (%i/%zd) for slot %d\n", - audio_formats[s->format], ret, *len, slot_num); - *len -= ret; - memmove(*buf, *buf + ret, *len); - } else - *len = 0; - if (ret > 0) - gettimeofday(&s->wtime, NULL); - return ret; -} -#endif - - 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; -// if (slot[i].write_fd <= 0 || !slot[i].wcheck -// || !FD_ISSET(slot[i].write_fd, &s->wfds)) -// continue; -// ret = write_audio_data(i); + slot[i].rtime = *now; } } @@ -1122,9 +1025,9 @@ out: return ret; } -static int init_stream_io(void) +static int init_writers(void) { - int i, ret, receiver_num, nf, nw; + int i, ret, nw; char *cmd; struct audio_format_info *a; @@ -1156,6 +1059,17 @@ static int init_stream_io(void) nw, writer_names[writer_num]); a->num_writers++; } + ret = 1; +out: + return ret; +} + +static int init_receivers(void) +{ + int i, ret, receiver_num; + char *cmd = NULL; + struct audio_format_info *a; + for (i = 0; receivers[i].name; i++) { PARA_INFO_LOG("initializing %s receiver\n", receivers[i].name); receivers[i].init(&receivers[i]); @@ -1192,8 +1106,15 @@ static int init_stream_io(void) return -E_RECV_SYNTAX; a->receiver = &receivers[receiver_num]; } + ret = 1; +out: free(cmd); - /* filters */ + 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); @@ -1223,6 +1144,22 @@ out: return ret; } +static int init_stream_io(void) +{ + int ret; + + ret = init_writers(); + if (ret < 0) + return ret; + ret = init_receivers(); + if (ret < 0) + return ret; + ret = init_filters(); + if (ret < 0) + return ret; + return 1; +} + static int dump_commands(int fd) { char *buf = para_strdup(""), *tmp = NULL; @@ -1350,29 +1287,6 @@ out: return ret; } -#if 0 -static char *list_filters(void) -{ - int i, j; - char *tmp, *msg = make_message("format\tnum\tcmd\n"); - - FOR_EACH_AUDIO_FORMAT(i) { - for (j = 0; j < afi[i].num_filters; j++) { - tmp = make_message("%s\t%i\t%s\n", - afi[i].name, j, afi[i].filter_cmds[j]); - msg = para_strcat(msg, tmp); - free(tmp); - } - tmp = make_message("%s\t%i\t%s\n", afi[i].name, - j, afi[i].write_cmd); - msg = para_strcat(msg, tmp); - free(tmp); - } - return msg; -} -#endif - - static int com_grab(int fd, char *cmdline) { struct grab_client *gc; @@ -1677,84 +1591,6 @@ static void init_status_task(struct status_task *st) sprintf(st->task.status, "status task"); } - - -#if 0 -/* TODO: move everything before the select call to pre_select() */ -static void __noreturn audiod_mainloop(void) -{ - fd_set rfds, wfds; - int ret, max_fileno, sbo = 0; - char status_buf[STRINGSIZE] = ""; - struct timeval tv; - - - -repeat: - FD_ZERO(&wfds); - FD_ZERO(&rfds); - max_fileno = -1; - /* always check signal pipe and the local socket */ - para_fd_set(signal_pipe, &rfds, &max_fileno); - para_fd_set(audiod_socket, &rfds, &max_fileno); - - if (audiod_status != AUDIOD_ON) - kill_all_decoders(); - else if (playing) - start_current_receiver(); - - set_stream_fds(&wfds, &max_fileno); - /* status pipe */ - if (stat_pipe >= 0 && audiod_status == AUDIOD_OFF) - close_stat_pipe(); - if (stat_pipe < 0 && audiod_status != AUDIOD_OFF) { - stat_pipe = open_stat_pipe(); - sbo = 0; - status_buf[0] = '\0'; - } - if (stat_pipe >= 0 && audiod_status != AUDIOD_OFF) - para_fd_set(stat_pipe, &rfds, &max_fileno); - /* local socket */ - tv.tv_sec = 0; - tv.tv_usec = 200 * 1000; - audiod_pre_select(&rfds, &wfds, &tv, &max_fileno); - ret = para_select(max_fileno + 1, &rfds, &wfds, &tv); - if (ret < 0) - goto repeat; - if (audiod_status != AUDIOD_OFF) - audiod_status_dump(); - audiod_post_select(ret, &rfds, &wfds); - /* read status pipe */ - if (stat_pipe >=0 && FD_ISSET(stat_pipe, &rfds)) { - ret = read(stat_pipe, status_buf + sbo, STRINGSIZE - 1 - sbo); - if (ret <= 0) { - close_stat_pipe(); - /* avoid busy loop if server is down */ - while (sleep(1) > 0) - ; /* try again*/ - } else { - status_buf[ret + sbo] = '\0'; - sbo = for_each_line(status_buf, ret + sbo, - &check_stat_line); - } - } - slot_io(&wfds); - if (FD_ISSET(audiod_socket, &rfds)) { - ret = handle_connect(); - if (ret < 0) { - PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret)); - } - } - /* signals */ - if (FD_ISSET(signal_pipe, &rfds)) { - int sig_nr = para_next_signal(); - if (sig_nr > 0) - handle_signal(sig_nr); - } - goto repeat; -} -#endif - static void set_initial_status(void) { audiod_status = AUDIOD_ON; @@ -1799,7 +1635,6 @@ int main(int argc, char *argv[]) PARA_EMERG_LOG("init stream io error: %s\n", PARA_STRERROR(-i)); exit(EXIT_FAILURE); } -// return 0; server_uptime(UPTIME_SET); set_initial_status(); FOR_EACH_SLOT(i)