X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=audiod.c;h=695a6cfd32077e0ee0477078076ab2f8b8f11d29;hp=c9a0ff7f02dd9595b984abfd10f46a59085a9cc4;hb=e2213f2468eb1c6f8ca033c6529ee1b5ceadab7f;hpb=b24869714aed385f04d282f854aaec7e69428cce;ds=sidebyside diff --git a/audiod.c b/audiod.c index c9a0ff7f..695a6cfd 100644 --- a/audiod.c +++ b/audiod.c @@ -153,11 +153,13 @@ static struct audiod_command cmds[] = { .description = "grab the audio stream", .synopsis = "-- grab [grab_options]", .help = + "grab ('splice') the audio stream at any position in the filter \n" -"chain and send that data back to the client. \n" -"Available options:\n\n" -GRAB_HELP_TXT +"chain and send that data back to the client. Try\n" +"\t para_audioc -- grab -h\n" +"for the list of available options.\n" }, + { .name = "help", .handler = com_help, @@ -208,11 +210,10 @@ GRAB_HELP_TXT .name = "stat", .handler = com_stat, .description = "print status information", -.synopsis = "stat", +.synopsis = "stat [item1 ...]", .help = -"Add para_audiod status information to para_server's status information\n" -"and dump everything to stdout.\n" +"Dump given status items (all if none given) to stdout.\n" }, { @@ -302,7 +303,7 @@ static char *get_time_string(struct timeval *newest_stime) if (!playing) { if (length_seconds) return NULL; - return make_message("%s:", status_item_list[SI_PLAY_TIME]); + return make_message("%s:\n", status_item_list[SI_PLAY_TIME]); } if (audiod_status == AUDIOD_OFF) goto out; @@ -329,7 +330,7 @@ static char *get_time_string(struct timeval *newest_stime) total = 0; out: return make_message( - "%s:%s%d:%02d [%d:%02d] (%d%%/%d:%02d)", + "%s:%s%d:%02d [%d:%02d] (%d%%/%d:%02d)\n", status_item_list[SI_PLAY_TIME], use_server_time? "~" : "", total / 60, @@ -343,12 +344,31 @@ out: ); } -static char *audiod_status_string(void) +__malloc static char *audiod_status_string(void) +{ + const char *status = (audiod_status == AUDIOD_ON)? + "on" : (audiod_status == AUDIOD_OFF)? "off": "sb"; + return make_message("%s:%s\n", status_item_list[SI_AUDIOD_STATUS], status); +} + +static struct timeval *wstime(void) { int i; - struct timeval *newest_stime = NULL; - char *ret, *time_string, *uptime_string, *decoder_flags = - para_malloc((MAX_STREAM_SLOTS + 1) * sizeof(char)); + struct timeval *max = NULL; + FOR_EACH_SLOT(i) { + struct slot_info *s = &slot[i]; + if (s->wpid <= 0) + continue; + if (max && tv_diff(&s->wstime, max, NULL) <= 0) + continue; + max = &s->wstime; + } + return max; +} +__malloc static char *decoder_flags(void) +{ + int i; + char decoder_flags[MAX_STREAM_SLOTS + 1]; FOR_EACH_SLOT(i) { struct slot_info *s = &slot[i]; @@ -360,26 +380,10 @@ static char *audiod_status_string(void) if (flag != '0') flag += s->format * 4; decoder_flags[i] = flag; - if (s->wpid <= 0) - continue; - if (newest_stime && tv_diff(&s->wstime, newest_stime, NULL) <= 0) - continue; - newest_stime = &s->wstime; } decoder_flags[MAX_STREAM_SLOTS] = '\0'; - time_string = get_time_string(newest_stime); - uptime_string = uptime_str(); - ret = make_message("%s:%s\n%s:%s\n%s:%s", - status_item_list[SI_AUDIOD_UPTIME], uptime_string, - status_item_list[SI_DECODER_FLAGS], decoder_flags, - status_item_list[SI_AUDIOD_STATUS], audiod_status == AUDIOD_ON? - "on" : (audiod_status == AUDIOD_OFF? "off": "sb")); - if (time_string) - ret = make_message("%s\n%s", ret, time_string); - free(uptime_string); - free(decoder_flags); - free(time_string); - return ret; + return make_message("%s:%s\n", status_item_list[SI_DECODER_FLAGS], + decoder_flags); } static char *configfile_exists(void) @@ -407,13 +411,34 @@ static void setup_signal_handling(void) static void audiod_status_dump(void) { - static char *prev_status; - char *tmp = audiod_status_string(); - - if (!prev_status || strcmp(tmp, prev_status)) - stat_client_write(tmp); - free(prev_status); - prev_status = tmp; + static char *p_ts, *p_us, *p_as, *p_df; + struct timeval *t = wstime(); + char *us, *tmp = get_time_string(t); + + if (tmp && (!p_ts || strcmp(tmp, p_ts))) + stat_client_write(tmp, SI_PLAY_TIME); + free(p_ts); + p_ts = tmp; + + us = uptime_str(); + tmp = make_message("%s:%s\n", status_item_list[SI_AUDIOD_UPTIME], us); + free(us); + if (!p_us || strcmp(p_us, tmp)) + stat_client_write(tmp, SI_AUDIOD_UPTIME); + free(p_us); + p_us = tmp; + + tmp = audiod_status_string(); + if (!p_as || strcmp(p_as, tmp)) + stat_client_write(tmp, SI_AUDIOD_STATUS); + free(p_as); + p_as = tmp; + + tmp = decoder_flags(); + if (!p_df || strcmp(p_df, tmp)) + stat_client_write(tmp, SI_DECODER_FLAGS); + free(p_df); + p_df = tmp; } static void clear_slot(int slot_num) @@ -566,7 +591,7 @@ static void close_stat_pipe(void) playing = 0; 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]); + stat_client_write(stat_item_values[SI_STATUS_BAR], SI_STATUS_BAR); } static void __noreturn clean_exit(int status, const char *msg) @@ -793,6 +818,7 @@ static void check_stat_line(char *line) int itemnum; size_t ilen = 0; struct timeval tv; + char *tmp; if (!line) return; @@ -801,7 +827,9 @@ static void check_stat_line(char *line) PARA_WARNING_LOG("invalid status line: %s\n", line); return; } - stat_client_write(line); + tmp = make_message("%s\n", line); + stat_client_write(tmp, itemnum); + free(tmp); free(stat_item_values[itemnum]); stat_item_values[itemnum] = para_strdup(line); ilen = strlen(status_item_list[itemnum]); @@ -1227,17 +1255,68 @@ out: static int com_stat(int fd, __unused int argc, __unused char **argv) { int i, ret; - char *buf = make_message("%s\n", audiod_status_string()); + char *buf = NULL; + long unsigned mask = ~0LU; + + if (argc > 1) { + mask = 0; + for (i = 1; i < argc; i++) { + ret = stat_item_valid(argv[i]); + if (ret < 0) + return ret; + mask |= (1 << ret); + } + } + PARA_INFO_LOG("mask: 0x%lx\n", mask); + if (mask & (1 << SI_PLAY_TIME)) { + struct timeval *t = wstime(); + char *ts = get_time_string(t); + if (ts) { + ret = client_write(fd, ts); + if (ret < 0) + goto out; + free(ts); + } + } + if (mask & (1 << SI_AUDIOD_UPTIME)) { + char *tmp, *us = uptime_str(); + tmp = make_message("%s:%s\n", + status_item_list[SI_AUDIOD_UPTIME], us); + free(us); + ret = client_write(fd, tmp); + if (ret < 0) + goto out; + free(tmp); + } + if (mask & (1 << SI_AUDIOD_STATUS)) { + char *s = audiod_status_string(); + ret = client_write(fd, s); + if (ret < 0) + goto out; + free(s); + } + if (mask & (1 << SI_DECODER_FLAGS)) { + char *df =decoder_flags(); + ret = client_write(fd, df); + if (ret < 0) + goto out; + free(df); + } for (i = 0; i < NUM_STAT_ITEMS; i++) { - char *tmp, *v = stat_item_values[i]; - tmp = make_message("%s%s%s", buf, v? v : "", v? "\n" : ""); + char *tmp, *v; + if (!((1 << i) & mask)) + continue; + v = stat_item_values[i]; + tmp = make_message("%s%s%s", buf? buf: "", + v? v : "", v? "\n" : ""); free(buf); buf = tmp; } ret = client_write(fd, buf); +out: if (ret > 0) - ret = stat_client_add(fd); + ret = stat_client_add(fd, mask); free(buf); return ret; } @@ -1268,7 +1347,8 @@ static int com_grab(int fd, int argc, char **argv) { struct grab_client *gc; struct filter_node *fn; - int err; + int i, err; + char *msg; PARA_INFO_LOG("argc: %d, argv[0]: %s, optind: %d\n", argc, argv[0], optind); gc = grab_client_new(fd, argc, argv, &err); @@ -1280,13 +1360,22 @@ static int com_grab(int fd, int argc, char **argv) activate_grab_client(gc, fn); return 1; err_out: - if (err != -E_GC_HELP_GIVEN) - return err; - err = client_write(fd, "Usage: para_audioc [audioc_options] -- " - "grab [grab_options]\nAvailable options:\n"); - if (err < 0) + if (err != -E_GC_HELP_GIVEN && err != -E_GC_VERSION_GIVEN) return err; - err = client_write(fd, GRAB_HELP_TXT); + if (err == -E_GC_HELP_GIVEN) { + msg = make_message("%s\n\n", grab_client_args_info_usage); + for (i = 0; grab_client_args_info_help[i]; i++) { + char *tmp = make_message("%s%s\n", msg, + grab_client_args_info_help[i]); + free(msg); + msg = tmp; + } + } else + msg = make_message("%s %s\n", + GRAB_CLIENT_CMDLINE_PARSER_PACKAGE, + GRAB_CLIENT_CMDLINE_PARSER_VERSION); + err = client_write(fd, msg); + free(msg); if (err < 0) return err; close(fd); @@ -1431,7 +1520,7 @@ static int open_stat_pipe(void) return ret; } -static int pre_select(fd_set *rfds, fd_set *wfds, struct timeval *tv) +static int audiod_pre_select(fd_set *rfds, fd_set *wfds, struct timeval *tv) { int i, ret, max = -1; @@ -1482,15 +1571,21 @@ static void __noreturn audiod_mainloop(void) char status_buf[STRINGSIZE] = ""; struct timeval tv; repeat: - FD_ZERO(&rfds); FD_ZERO(&wfds); - max_fileno = 0; + FD_ZERO(&rfds); + /* always check signal pipe and the local socket */ + FD_SET(signal_pipe, &rfds); + max_fileno = signal_pipe; + FD_SET(audiod_socket, &rfds); + max_fileno = MAX(max_fileno, audiod_socket); + if (audiod_status != AUDIOD_ON) kill_all_decoders(); else if (playing) start_current_receiver(); - max_fileno = set_stream_fds(&wfds); - /* stat pipe (read) */ + + max_fileno = MAX(max_fileno, set_stream_fds(&wfds)); + /* status pipe */ if (stat_pipe >= 0 && audiod_status == AUDIOD_OFF) close_stat_pipe(); if (stat_pipe < 0 && audiod_status != AUDIOD_OFF) { @@ -1502,18 +1597,12 @@ repeat: FD_SET(stat_pipe, &rfds); max_fileno = MAX(max_fileno, stat_pipe); } - /* always check signal pipe */ - FD_SET(signal_pipe, &rfds); - max_fileno = MAX(max_fileno, signal_pipe); /* local socket */ - if (audiod_socket < 0) - audiod_get_socket(); /* doesn't return on errors */ - FD_SET(audiod_socket, &rfds); - max_fileno = MAX(max_fileno, audiod_socket); tv.tv_sec = 0; tv.tv_usec = 200 * 1000; - ret = pre_select(&rfds, &wfds, &tv); + ret = audiod_pre_select(&rfds, &wfds, &tv); max_fileno = MAX(max_fileno, ret); + ret = select(max_fileno + 1, &rfds, &wfds, NULL, &tv); if (ret < 0 && errno != EINTR) PARA_ERROR_LOG("select returned %d (%s)\n", ret, @@ -1601,5 +1690,6 @@ int __noreturn main(int argc, char *argv[]) setup_signal_handling(); if (conf.daemon_given) daemon_init(); + audiod_get_socket(); /* doesn't return on errors */ audiod_mainloop(); }