From: Andre Noll Date: Sun, 2 Aug 2009 13:31:16 +0000 (+0200) Subject: Merge branch 'master' into next X-Git-Tag: v0.4.0~39 X-Git-Url: http://git.tuebingen.mpg.de/?a=commitdiff_plain;h=b9c2428555a2a6edb038234a33e5072dc8c5ba7a;hp=-c;p=paraslash.git Merge branch 'master' into next --- b9c2428555a2a6edb038234a33e5072dc8c5ba7a diff --combined audiod.c index 27c153d7,d39f0f57..0479e1e1 --- a/audiod.c +++ b/audiod.c @@@ -5,21 -5,19 +5,21 @@@ */ /** \file audiod.c the paraslash's audio daemon */ +#include #include #include #include +#include #include "para.h" #include "error.h" +#include "crypt.h" #include "audiod.cmdline.h" #include "list.h" #include "sched.h" #include "ggo.h" #include "recv.h" #include "filter.h" -#include "grab_client.cmdline.h" #include "grab_client.h" #include "client.cmdline.h" #include "client.h" @@@ -162,7 -160,7 +162,7 @@@ struct command_task * \return The audio format number on success, -E_UNSUPPORTED_AUDIO_FORMAT if * \a name is not a supported audio format. */ -int get_audio_format_num(char *name) +int get_audio_format_num(const char *name) { int i; @@@ -221,7 -219,8 +221,7 @@@ out seconds = PARA_MIN(seconds, length); seconds = PARA_MAX(seconds, 0); return make_message( - "%s: %s%d:%02d [%d:%02d] (%d%%/%d:%02d)\n", - status_item_list[SI_PLAY_TIME], + "%s%d:%02d [%d:%02d] (%d%%/%d:%02d)", s? "" : "~", seconds / 60, seconds % 60, @@@ -232,7 -231,7 +232,7 @@@ length % 60 ); empty: - return make_message("%s:\n", status_item_list[SI_PLAY_TIME]); + return para_strdup(NULL); } static int want_colors(void) @@@ -386,8 -385,8 +386,8 @@@ static void open_filters(int slot_num s->fc->inbufp = &s->receiver_node->buf; s->fc->in_loaded = &s->receiver_node->loaded; s->fc->input_error = &s->receiver_node->task.error; - s->fc->task.pre_select = filter_pre_select; - s->fc->task.post_select = NULL; + s->fc->task.pre_select = NULL; + s->fc->task.post_select = filter_post_select; s->fc->task.error = 0; s->fc->num_filters = nf; @@@ -445,7 -444,7 +445,7 @@@ static void open_writers(int slot_num stat_task->server_stream_start : *now; s->offset_seconds = stat_task->offset_seconds; s->seconds_total = stat_task->length_seconds; - activate_inactive_grab_clients(slot_num, s->format, s->fc); + activate_inactive_grab_clients(s->format, s->fc); } static int open_receiver(int format) @@@ -579,31 -578,45 +579,31 @@@ out return count; } -static int check_stat_line(char *line, __a_unused void *data) +static int update_item(int itemnum, char *buf) { - int itemnum; - size_t ilen = 0; long unsigned sec, usec; - char *tmp; - //PARA_INFO_LOG("line: %s\n", line); - if (!line) - return 1; - itemnum = stat_line_valid(line); - if (itemnum < 0) { - PARA_WARNING_LOG("invalid status line: %s\n", line); - return 1; - } if (stat_task->clock_diff_count && itemnum != SI_CURRENT_TIME) return 1; - 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]); + stat_item_values[itemnum] = para_strdup(buf); + stat_client_write_item(itemnum); switch (itemnum) { case SI_STATUS_FLAGS: stat_task->vss_status = 0; - if (strchr(line, 'N')) + if (strchr(buf, 'N')) stat_task->vss_status |= VSS_STATUS_FLAG_NEXT; - if (strchr(line, 'P')) + if (strchr(buf, 'P')) stat_task->vss_status |= VSS_STATUS_FLAG_PLAYING; break; case SI_OFFSET: - stat_task->offset_seconds = atoi(line + ilen + 1); + stat_task->offset_seconds = atoi(buf); break; case SI_SECONDS_TOTAL: - stat_task->length_seconds = atoi(line + ilen + 1); + stat_task->length_seconds = atoi(buf); break; case SI_STREAM_START: - if (sscanf(line + ilen + 1, "%lu.%lu", &sec, &usec) == 2) { + if (sscanf(buf, "%lu.%lu", &sec, &usec) == 2) { struct timeval a_start, delay; delay.tv_sec = conf.stream_delay_arg / 1000; delay.tv_usec = (conf.stream_delay_arg % 1000) * 1000; @@@ -621,14 -634,14 +621,14 @@@ } break; case SI_CURRENT_TIME: - if (sscanf(line + ilen + 1, "%lu.%lu", &sec, &usec) == 2) { + if (sscanf(buf, "%lu.%lu", &sec, &usec) == 2) { struct timeval tv = {sec, usec}; compute_time_diff(&tv); } break; case SI_FORMAT: - stat_task->current_audio_format_num = get_audio_format_num( - line + ilen + 1); + stat_task->current_audio_format_num + = get_audio_format_num(buf); } return 1; } @@@ -902,15 -915,8 +902,15 @@@ static void command_post_select(struct { int ret; struct command_task *ct = container_of(t, struct command_task, task); + static struct timeval last_status_dump; + struct timeval tmp; + + tv_add(&last_status_dump, &(struct timeval){0, 500 * 1000}, &tmp); + if (tv_diff(&tmp, now, NULL) < 0) { + audiod_status_dump(); + last_status_dump = *now; + } - audiod_status_dump(); if (!FD_ISSET(ct->fd, &s->rfds)) return; ret = handle_connect(ct->fd); @@@ -929,11 -935,17 +929,11 @@@ static void init_command_task(struct co static void close_stat_pipe(void) { - int i; - if (!stat_task->ct) return; client_close(stat_task->ct); stat_task->ct = NULL; - FOR_EACH_STATUS_ITEM(i) { - free(stat_item_values[i]); - stat_item_values[i] = NULL; - } - dump_empty_status(); + clear_and_dump_items(); stat_task->length_seconds = 0; stat_task->offset_seconds = 0; stat_task->vss_status = 0; @@@ -1057,7 -1069,7 +1057,7 @@@ static void status_pre_select(struct sc goto out; } if (st->ct) { - unsigned bytes_left; + int ret; if (st->ct->task.error < 0) { if (st->ct->task.error != -E_TASK_UNREGISTERED) goto out; @@@ -1066,15 -1078,11 +1066,15 @@@ } if (st->ct->status != CL_RECEIVING) goto out; - bytes_left = for_each_line(st->ct->buf, st->ct->loaded, - &check_stat_line, NULL); - if (st->ct->loaded != bytes_left) { + ret = for_each_stat_item(st->ct->buf, st->ct->loaded, + update_item); + if (ret < 0) { + st->ct->task.error = ret; + goto out; + } + if (st->ct->loaded != ret) { st->last_status_read = *now; - st->ct->loaded = bytes_left; + st->ct->loaded = ret; } else { struct timeval diff; tv_diff(now, &st->last_status_read, &diff); @@@ -1086,23 -1094,25 +1086,23 @@@ 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", "1", NULL}; - int argc = 3; + char *argv[] = {"audiod", "--", "stat", "-p", "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); } else { - char *argv[] = {"audiod", "stat", NULL}; - int argc = 2; + char *argv[] = {"audiod", "--", "stat", "-p", NULL}; + int argc = 4; client_open(argc, argv, &st->ct, NULL); set_stat_task_restart_barrier(5); } free(stat_item_values[SI_BASENAME]); - stat_item_values[SI_BASENAME] = make_message( - "%s: no connection to para_server\n", - status_item_list[SI_BASENAME]); - stat_client_write(stat_item_values[SI_BASENAME], - SI_BASENAME); + stat_item_values[SI_BASENAME] = para_strdup( + "no connection to para_server"); + stat_client_write_item(SI_BASENAME); st->last_status_read = *now; out: start_stop_decoders(s); @@@ -1234,7 -1244,7 +1234,7 @@@ int main(int argc, char *argv[] register_task(&cmd_task->task); register_task(&stat_task->task); s.default_timeout.tv_sec = 0; - s.default_timeout.tv_usec = 99 * 1000; + s.default_timeout.tv_usec = 999 * 1000; ret = schedule(&s); PARA_EMERG_LOG("%s\n", para_strerror(-ret)); diff --combined filter.c index 796e445a,88e2336b..1ea7ac89 --- a/filter.c +++ b/filter.c @@@ -6,9 -6,8 +6,9 @@@ /** \file filter.c The stand-alone filter program. */ -#include "para.h" +#include +#include "para.h" #include "filter.cmdline.h" #include "list.h" #include "sched.h" @@@ -85,7 -84,7 +85,7 @@@ static int init_filter_chain(void fc->input_error = &sit->task.error; fc->task.error = 0; fc->output_error = &sot->task.error; - fc->task.pre_select = filter_pre_select; + fc->task.post_select = filter_post_select; sprintf(fc->task.status, "filter chain"); FOR_EACH_FILTER_NODE(fn, fc, i) { diff --combined filter.h index 23f47f44,b877b649..15bfaf8c --- a/filter.h +++ b/filter.h @@@ -95,10 -95,18 +95,10 @@@ struct filter_chain struct filter_callback { /** All callbacks are organized in a doubly linked list. */ struct list_head node; - /** - * Private data. - * - * May be initialized by the application before registering the callback. This - * pointer is not used by the filter subsystem. It is provided for use within - * the input/output/close callback functions. - */ - void *data; /** * The input callback. * - * In not \p NULL, the filter subsystem calls this function whenever the filter + * If not \p NULL, the filter subsystem calls this function whenever the filter * consumed some or all of its input buffer. A pointer to the buffer of consumed * data, its length and a pointer to the own \a filter_callback structure are passed * to \a input_cb. The input callback is expected to return a negative value on errors. @@@ -196,7 -204,7 +196,7 @@@ struct filter void close_filters(struct filter_chain *fc); void filter_init(void); int check_filter_arg(char *filter_arg, void **conf); - void filter_pre_select(__a_unused struct sched *s, struct task *t); + void filter_post_select(__a_unused struct sched *s, struct task *t); void print_filter_helps(int detailed); static inline void write_int16_host_endian(char *buf, int val) diff --combined filter_common.c index cfe08dd1,2fa774c0..7c71ff39 --- a/filter_common.c +++ b/filter_common.c @@@ -6,7 -6,6 +6,7 @@@ /** \file filter_common.c Common helper functions for filter input/output. */ +#include #include #include @@@ -44,7 -43,7 +44,7 @@@ void filter_init(void */ static void close_filter_callback(struct filter_callback *fcb) { - PARA_NOTICE_LOG("closing filter_callback %p, data: %p\n", fcb, fcb->data); + PARA_NOTICE_LOG("closing filter_callback %p\n", fcb); list_del(&fcb->node); fcb->close(fcb); } @@@ -106,7 -105,7 +106,7 @@@ static void call_callbacks(struct filte * * \sa filter_node, filter#convert, filter_callback. */ - void filter_pre_select(__a_unused struct sched *s, struct task *t) + void filter_post_select(__a_unused struct sched *s, struct task *t) { struct filter_chain *fc = container_of(t, struct filter_chain, task); struct filter_node *fn; @@@ -143,19 -142,6 +143,6 @@@ again conv_total += conv; if (conv) goto again; - if (conv_total) { - /* - * Other pre_select functions might have already been called by - * now and decided to do nothing, e.g. because their output - * buffer was full or the input buffer was empty. We just - * converted something which caused these buffers to change but - * we can't make the other tasks reconsider their decision at - * this point. So force a minimal timeout for the next select - * call to avoid unnecessary delays. - */ - s->timeout.tv_sec = 0; - s->timeout.tv_usec = 1; - } if (*fc->input_error >= 0) return; if (*fc->out_loaded) @@@ -209,18 -195,15 +196,18 @@@ static int parse_filter_args(int filter if (!f->parse_config) return strlen(options)? -E_BAD_FILTER_OPTIONS : filter_num; // PARA_DEBUG_LOG("options: %s\n", options); - argc = split_args(options, &argv, " \t"); -// PARA_DEBUG_LOG("argc = %d, argv[0]: %s\n", argc, argv[0]); + argc = create_argv(options, " \t", &argv); + if (argc < 0) + return -E_BAD_FILTER_OPTIONS; + PARA_DEBUG_LOG("argc = %d, argv[0]: %s\n", argc, argv[0]); for (i = argc - 1; i >= 0; i--) argv[i + 1] = argv[i]; argv[0] = para_strdup(f->name); - argc += 1; + argc++; ret = f->parse_config(argc, argv, conf); - free(argv[0]); - free(argv); + free(argv[argc - 1]); + argv[argc - 1] = NULL; + free_argv(argv); return ret < 0? ret : filter_num; }