X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=audiod.c;h=3194501bfc7e6e0a5e687842be70a57cb84e76b2;hp=a92c4e3b1ebca665a3804bc168472673fd733037;hb=4d3f9f6c22281f9abb5d59d378a10303420641b7;hpb=00e4d4da1b2c00da139b09d3ed4ab9ad9fba2691 diff --git a/audiod.c b/audiod.c index a92c4e3b..3194501b 100644 --- a/audiod.c +++ b/audiod.c @@ -66,6 +66,39 @@ struct audio_format_info { * */ struct slot_info slot[MAX_STREAM_SLOTS]; +/** + * The task for obtaining para_server's status (para_client stat). + * + * \sa struct task, struct sched. + */ +struct status_task { + /** The associated task structure of audiod. */ + struct task task; + /** Client data associated with the stat task. */ + struct client_task *ct; + /** Do not restart client command until this time. */ + struct timeval restart_barrier; + /** Last time we received status data from para_server. */ + struct timeval last_status_read; + /** The offset value announced by para_server. */ + int offset_seconds; + /** The length of the current audio file as announced by para_server. */ + int length_seconds; + /** The start of the current stream from the view of para_server. */ + struct timeval server_stream_start; + /** The average time deviation between para_server and para_audiod. */ + struct timeval sa_time_diff; + /** Whether client time is ahead of server time. */ + int sa_time_diff_sign; + /** Non-zero if para_server's status is "playing". */ + int playing; + /** Number of times the clock difference is to be checked. */ + unsigned clock_diff_count; + /** When to start the next check for clock difference. */ + struct timeval clock_diff_barrier; + /** Number of the audio format as announced by para_server. */ + int current_audio_format_num; +}; /** The array of status items sent by para_server. */ char *stat_item_values[NUM_STAT_ITEMS] = {NULL}; @@ -193,6 +226,7 @@ static int want_colors(void) static void parse_config_or_die(void) { + int ret; char *config_file; struct audiod_cmdline_parser_params params = { .override = 0, @@ -209,14 +243,13 @@ static void parse_config_or_die(void) config_file = make_message("%s/.paraslash/audiod.conf", home); free(home); } - if (conf.config_file_given && !file_exists(config_file)) { + ret = file_exists(config_file); + if (conf.config_file_given && !ret) { PARA_EMERG_LOG("can not read config file %s\n", config_file); goto err; } - if (audiod_cmdline_parser_config_file(config_file, &conf, ¶ms)) { - PARA_EMERG_LOG("parse error in config file\n"); - goto err; - } + if (ret) + audiod_cmdline_parser_config_file(config_file, &conf, ¶ms); free(config_file); daemon_set_loglevel(conf.loglevel_arg); return; @@ -596,13 +629,12 @@ static int add_filter(int format, char *cmdline) return filter_num; } -static int init_writers(void) +static int parse_writer_args(void) { int i, ret, nw; char *cmd; struct audio_format_info *a; - init_supported_writers(); nw = PARA_MAX(1U, conf.writer_given); PARA_INFO_LOG("maximal number of writers: %d\n", nw); FOR_EACH_AUDIO_FORMAT(i) { @@ -635,16 +667,12 @@ out: return ret; } -static int init_receivers(void) +static int parse_receiver_args(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]); - } for (i = conf.receiver_given - 1; i >= 0; i--) { char *arg = conf.receiver_arg[i]; char *recv_arg = strchr(arg, ':'); @@ -715,11 +743,10 @@ out: return ret; } -static int init_filters(void) +static int parse_filter_args(void) { int i, ret, nf; - filter_init(filters); nf = PARA_MAX(1U, conf.filter_given); PARA_INFO_LOG("maximal number of filters: %d\n", nf); FOR_EACH_AUDIO_FORMAT(i) { @@ -748,17 +775,17 @@ out: return ret; } -static int init_stream_io(void) +static int parse_stream_args(void) { int ret; - ret = init_writers(); + ret = parse_receiver_args(); if (ret < 0) return ret; - ret = init_receivers(); + ret = parse_filter_args(); if (ret < 0) return ret; - ret = init_filters(); + ret = parse_writer_args(); if (ret < 0) return ret; return 1; @@ -1021,13 +1048,13 @@ static void status_pre_select(struct sched *s, struct task *t) int argc = 3; PARA_INFO_LOG("clock diff count: %d\n", st->clock_diff_count); st->clock_diff_count--; - client_open(argc, argv, &st->ct); + client_open(argc, argv, &st->ct, NULL); set_stat_task_restart_barrier(2); } else { char *argv[] = {"audiod", "stat", NULL}; int argc = 2; - client_open(argc, argv, &st->ct); + client_open(argc, argv, &st->ct, NULL); set_stat_task_restart_barrier(5); } free(stat_item_values[SI_BASENAME]); @@ -1124,12 +1151,18 @@ int main(int argc, char *argv[]) }; valid_fd_012(); - audiod_cmdline_parser_ext(argc, argv, &conf, ¶ms); + if (audiod_cmdline_parser_ext(argc, argv, &conf, ¶ms)) + exit(EXIT_FAILURE); HANDLE_VERSION_FLAG("audiod", conf); - drop_privileges_or_die(conf.user_arg, conf.group_arg); - parse_config_or_die(); + /* init receivers/filters/writers early to make help work */ + recv_init(); + filter_init(); + writer_init(); if (conf.help_given || conf.detailed_help_given) print_help_and_die(); + drop_privileges_or_die(conf.user_arg, conf.group_arg); + parse_config_or_die(); + init_colors_or_die(); daemon_set_flag(DF_LOG_TIME); daemon_set_flag(DF_LOG_HOSTNAME); daemon_set_flag(DF_LOG_LL); @@ -1137,10 +1170,9 @@ int main(int argc, char *argv[]) daemon_set_logfile(conf.logfile_arg); daemon_open_log_or_die(); } - init_colors_or_die(); - i = init_stream_io(); - if (i < 0) { - PARA_EMERG_LOG("init stream io error: %s\n", para_strerror(-i)); + ret = parse_stream_args(); + if (ret < 0) { + PARA_EMERG_LOG("%s\n", para_strerror(-ret)); exit(EXIT_FAILURE); } log_welcome("para_audiod");