X-Git-Url: http://git.tuebingen.mpg.de/?a=blobdiff_plain;f=audiod.c;h=5f4acb4364abe09ecc77923d37e378bbd6b57791;hb=4adde8dae3317fa83b81e7a860c9ed9133e99bb0;hp=fa4019160bf8148a8503fa856c5dac3f9103b260;hpb=f5cf47f2bc4bb76d0d21e2467c5846cade38558f;p=paraslash.git diff --git a/audiod.c b/audiod.c index fa401916..5f4acb43 100644 --- a/audiod.c +++ b/audiod.c @@ -17,6 +17,8 @@ #include #include +#include "recv_cmd.lsg.h" +#include "client.lsg.h" #include "para.h" #include "error.h" #include "crypt.h" @@ -28,7 +30,6 @@ #include "recv.h" #include "filter.h" #include "grab_client.h" -#include "client.cmdline.h" #include "client.h" #include "audiod.h" #include "net.h" @@ -47,20 +48,20 @@ __printf_2_3 void (*para_log)(int, const char*, ...) = daemon_log; /** define the array containing all supported audio formats */ const char *audio_formats[] = {AUDIOD_AUDIO_FORMAT_ARRAY NULL}; -DEFINE_RECEIVER_ARRAY; - /** Defines how audiod handles one supported audio format. */ struct audio_format_info { - /** pointer to the receiver for this audio format */ - struct receiver *receiver; - /** the receiver configuration */ - void *receiver_conf; + /** the receiver for this audio format */ + int receiver_num; + /** Parsed receiver command line. */ + struct lls_parse_result *receiver_lpr; /** the number of filters that should be activated for this audio format */ unsigned int num_filters; /** Array of filter numbers to be activated. */ unsigned *filter_nums; /** Pointer to the array of filter configurations. */ void **filter_conf; + /** Parsed filter command line, one parse result per filter. */ + struct lls_parse_result **filter_lpr; /** the number of filters that should be activated for this audio format */ unsigned int num_writers; /** Array of writer numbers to be activated. */ @@ -89,6 +90,9 @@ struct slot_info { struct writer_node *wns; }; +#define RECEIVER_CMD(_a) lls_cmd((_a)->receiver_num, recv_cmd_suite) +#define RECEIVER(_a) ((const struct receiver *)lls_user_data(RECEIVER_CMD(_a))) + /** Maximal number of simultaneous instances. */ #define MAX_STREAM_SLOTS 5 @@ -477,7 +481,7 @@ static void close_receiver(int slot_num) a = &afi[s->format]; PARA_NOTICE_LOG("closing %s receiver in slot %d\n", audio_formats[s->format], slot_num); - a->receiver->close(s->receiver_node); + RECEIVER(a)->close(s->receiver_node); btr_remove_node(&s->receiver_node->btrn); task_reap(&s->receiver_node->task); free(s->receiver_node); @@ -590,17 +594,20 @@ static void open_filters(struct slot_info *s) parent = s->receiver_node->btrn; for (i = 0; i < nf; i++) { char buf[20]; + const char *name; const struct filter *f = filter_get(a->filter_nums[i]); fn = s->fns + i; fn->filter_num = a->filter_nums[i]; fn->conf = a->filter_conf[i]; + fn->lpr = a->filter_lpr[i]; + name = filter_name(fn->filter_num); fn->btrn = btr_new_node(&(struct btr_node_description) - EMBRACE(.name = f->name, .parent = parent, + EMBRACE(.name = name, .parent = parent, .handler = f->execute, .context = fn)); if (f->open) f->open(fn); - sprintf(buf, "%s (slot %d)", f->name, (int)(s - slot)); + sprintf(buf, "%s (slot %d)", name, (int)(s - slot)); fn->task = task_register(&(struct task_info) { .name = buf, .pre_select = f->pre_select, @@ -609,7 +616,7 @@ static void open_filters(struct slot_info *s) }, &sched); parent = fn->btrn; PARA_NOTICE_LOG("%s filter %d/%d (%s) started in slot %d\n", - audio_formats[s->format], i, nf, f->name, (int)(s - slot)); + audio_formats[s->format], i, nf, name, (int)(s - slot)); } } @@ -639,7 +646,8 @@ static int open_receiver(int format) struct audio_format_info *a = &afi[format]; struct slot_info *s; int ret, slot_num; - struct receiver *r = a->receiver; + const struct receiver *r = RECEIVER(a); + const char *name = lls_command_name(RECEIVER_CMD(a)); struct receiver_node *rn; tv_add(now, &(struct timeval)EMBRACE(2, 0), &a->restart_barrier); @@ -649,9 +657,9 @@ static int open_receiver(int format) slot_num = ret; rn = para_calloc(sizeof(*rn)); rn->receiver = r; - rn->conf = a->receiver_conf; + rn->lpr = a->receiver_lpr; rn->btrn = btr_new_node(&(struct btr_node_description) - EMBRACE(.name = r->name, .context = rn)); + EMBRACE(.name = name, .context = rn)); ret = r->open(rn); if (ret < 0) { btr_remove_node(&rn->btrn); @@ -662,9 +670,9 @@ static int open_receiver(int format) s->format = format; s->receiver_node = rn; PARA_NOTICE_LOG("started %s: %s receiver in slot %d\n", - audio_formats[format], r->name, slot_num); + audio_formats[format], name, slot_num); rn->task = task_register(&(struct task_info) { - .name = r->name, + .name = name, .pre_select = r->pre_select, .post_select = r->post_select, .context = rn, @@ -827,7 +835,7 @@ static int update_item(int itemnum, char *buf) return 1; } -static int parse_stream_command(const char *txt, char **cmd) +static int parse_stream_command(const char *txt, const char **cmd) { int ret, len; char *re, *p = strchr(txt, ':'); @@ -844,31 +852,34 @@ static int parse_stream_command(const char *txt, char **cmd) return ret; } -static int add_filter(int format, char *cmdline) +static int add_filter(int format, const char *cmdline) { struct audio_format_info *a = &afi[format]; int filter_num, nf = a->num_filters; void *cfg; + struct lls_parse_result *flpr; - filter_num = check_filter_arg(cmdline, &cfg); - if (filter_num < 0) - return filter_num; + filter_num = filter_setup(cmdline, &cfg, &flpr); + a->filter_lpr = para_realloc(a->filter_lpr, + (nf + 1) * sizeof(flpr)); a->filter_conf = para_realloc(a->filter_conf, (nf + 1) * sizeof(void *)); a->filter_nums = para_realloc(a->filter_nums, (nf + 1) * sizeof(unsigned)); + a->filter_nums[nf] = filter_num; a->filter_conf[nf] = cfg; + a->filter_lpr[nf] = flpr; a->num_filters++; PARA_INFO_LOG("%s filter %d: %s\n", audio_formats[format], nf, - filter_get(filter_num)->name); + filter_name(filter_num)); return filter_num; } static int parse_writer_args(void) { int i, ret; - char *cmd; + const char *cmd; struct audio_format_info *a; for (i = 0; i < conf.writer_given; i++) { @@ -915,12 +926,13 @@ static int parse_writer_args(void) static int parse_receiver_args(void) { - int i, ret, receiver_num; - char *cmd = NULL; + int i, ret; + const char *arg; struct audio_format_info *a; + FOR_EACH_AUDIO_FORMAT(i) + afi[i].receiver_num = -1; for (i = conf.receiver_given - 1; i >= 0; i--) { - char *arg; int j, af_mask; ret = parse_stream_command(conf.receiver_arg[i], &arg); @@ -937,37 +949,27 @@ static int parse_receiver_args(void) * config here. Since we are iterating backwards, the winning * receiver arg is in fact the first one given. */ - if (a->receiver_conf) - a->receiver->free_config(a->receiver_conf); - a->receiver_conf = check_receiver_arg(arg, &receiver_num); - ret = -E_RECV_SYNTAX; - if (!a->receiver_conf) - goto out; - a->receiver = receivers + receiver_num; + lls_free_parse_result(a->receiver_lpr, RECEIVER_CMD(a)); + a->receiver_num = check_receiver_arg(arg, &a->receiver_lpr); } } /* - * Use the first available receiver with no arguments for those audio - * formats for which no receiver was specified. + * Use the default receiver for those audio formats for which no + * receiver was specified. */ - cmd = para_strdup(receivers[0].name); FOR_EACH_AUDIO_FORMAT(i) { - a = &afi[i]; - if (a->receiver_conf) + a = afi + i; + if (a->receiver_num >= 0) continue; - a->receiver_conf = check_receiver_arg(cmd, &receiver_num); - if (!a->receiver_conf) - return -E_RECV_SYNTAX; - a->receiver = &receivers[receiver_num]; + a->receiver_num = check_receiver_arg(NULL, &a->receiver_lpr); } FOR_EACH_AUDIO_FORMAT(i) { a = afi + i; PARA_INFO_LOG("receiving %s streams via %s receiver\n", - audio_formats[i], a->receiver->name); + audio_formats[i], lls_command_name(RECEIVER_CMD(a))); } ret = 1; out: - free(cmd); return ret; } @@ -977,6 +979,7 @@ static int init_default_filters(void) FOR_EACH_AUDIO_FORMAT(i) { struct audio_format_info *a = &afi[i]; + const char *name = lls_command_name(RECEIVER_CMD(a)); char *tmp; int j; @@ -986,8 +989,7 @@ static int init_default_filters(void) * udp and dccp streams are fec-encoded, so add fecdec as the * first filter. */ - if (strcmp(afi[i].receiver->name, "udp") == 0 || - strcmp(afi[i].receiver->name, "dccp") == 0) { + if (strcmp(name, "udp") == 0 || strcmp(name, "dccp") == 0) { tmp = para_strdup("fecdec"); add_filter(i, tmp); free(tmp); @@ -997,19 +999,19 @@ static int init_default_filters(void) /* add "dec" to audio format name */ tmp = make_message("%sdec", audio_formats[i]); for (j = 0; filter_get(j); j++) - if (!strcmp(tmp, filter_get(j)->name)) + if (!strcmp(tmp, filter_name(j))) break; free(tmp); ret = -E_UNSUPPORTED_FILTER; if (!filter_get(j)) goto out; - tmp = para_strdup(filter_get(j)->name); + tmp = para_strdup(filter_name(j)); ret = add_filter(i, tmp); free(tmp); if (ret < 0) goto out; PARA_INFO_LOG("%s -> default filter: %s\n", audio_formats[i], - filter_get(j)->name); + filter_name(j)); } out: return ret; @@ -1020,7 +1022,7 @@ static int parse_filter_args(void) int i, j, ret, af_mask, num_matches; for (i = 0; i < conf.filter_given; i++) { - char *arg; + const char *arg; ret = parse_stream_command(conf.filter_arg[i], &arg); if (ret < 0) goto out; @@ -1502,7 +1504,6 @@ int main(int argc, char *argv[]) version_handle_flag("audiod", conf.version_given); /* 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();