X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=audiod.c;h=a76ee1fdc9866756645caf11f576461343b5bf8c;hp=bde2b1e1299a51548b727c13c2d32df760067fda;hb=d32eb7a5cf569ee842d91f3f830a8562fa0ae12d;hpb=335730538150250f32c0df0b184fb494e2bb0df3 diff --git a/audiod.c b/audiod.c index bde2b1e1..a76ee1fd 100644 --- a/audiod.c +++ b/audiod.c @@ -41,9 +41,9 @@ struct audio_format_info { void *receiver_conf; /** the number of filters that should be activated for this audio format */ unsigned int num_filters; - /** pointer to the array of filters to be activated */ - struct filter **filters; - /** pointer to the array of filter configurations */ + /** Array of filter numbers to be activated. */ + unsigned *filter_nums; + /** Pointer to the array of filter configurations. */ void **filter_conf; /** the number of filters that should be activated for this audio format */ unsigned int num_writers; @@ -268,6 +268,7 @@ static void open_filters(int slot_num) { struct slot_info *s = &slot[slot_num]; struct audio_format_info *a = &afi[s->format]; + struct filter_node *fn; int nf = a->num_filters; int i; @@ -276,26 +277,27 @@ static void open_filters(int slot_num) 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->filter_nodes = para_malloc(nf * sizeof(struct filter_chain)); s->fc->inbuf = 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.error = 0; + s->fc->num_filters = nf; s->receiver_node->output_error = &s->fc->task.error; sprintf(s->fc->task.status, "filter chain"); - for (i = 0; i < nf; i++) { - struct filter_node *fn = para_calloc(sizeof(struct filter_node)); + FOR_EACH_FILTER_NODE(fn, s->fc, i) { + struct filter *f = filters + a->filter_nums[i]; + fn->filter_num = a->filter_nums[i]; fn->conf = a->filter_conf[i]; fn->fc = s->fc; - fn->filter = a->filters[i]; + fn->loaded = 0; INIT_LIST_HEAD(&fn->callbacks); - list_add_tail(&fn->node, &s->fc->filters); - fn->filter->open(fn); + f->open(fn); PARA_NOTICE_LOG("%s filter %d/%d (%s) started in slot %d\n", - audio_formats[s->format], i + 1, nf, - fn->filter->name, slot_num); + audio_formats[s->format], i + 1, nf, f->name, slot_num); s->fc->outbuf = fn->buf; s->fc->out_loaded = &fn->loaded; } @@ -336,7 +338,7 @@ static void open_writers(int slot_num) return; } s->wstime = *now; - activate_inactive_grab_clients(slot_num, s->format, &s->fc->filters); + activate_inactive_grab_clients(slot_num, s->format, s->fc); } #if 0 @@ -651,10 +653,10 @@ static int add_filter(int format, char *cmdline) filter_num = check_filter_arg(cmdline, &a->filter_conf[nf]); if (filter_num < 0) return filter_num; - a->filters[nf] = &filters[filter_num]; + a->filter_nums[nf] = filter_num; a->num_filters++; PARA_INFO_LOG("%s filter %d: %s\n", audio_formats[format], nf + 1, - a->filters[nf]->name); + filters[filter_num].name); return filter_num; } @@ -786,7 +788,7 @@ static int init_filters(void) PARA_INFO_LOG("maximal number of filters: %d\n", nf); FOR_EACH_AUDIO_FORMAT(i) { afi[i].filter_conf = para_malloc(nf * sizeof(void *)); - afi[i].filters = para_malloc(nf * sizeof(struct filter *)); + afi[i].filter_nums = para_malloc(nf * sizeof(unsigned)); } if (!conf.no_default_filters_given) return init_default_filters(); @@ -976,34 +978,18 @@ static void set_stat_task_restart_barrier(void) tv_add(now, &delay, &stat_task->restart_barrier); } -#if 0 -static void client_task_event_handler(__a_unused struct task *t) -{ - int i; - - if (t->ret == -E_HANDSHAKE_COMPLETE) - return; - unregister_task(t); - close_stat_pipe(); - if (t->ret != -E_SERVER_EOF) - stat_task->clock_diff_count = conf.clock_diff_count_arg; - set_stat_task_restart_barrier(); - FOR_EACH_AUDIO_FORMAT(i) - afi[i].restart_barrier = stat_task->restart_barrier; -} -#endif - +/* restart the client task if necessary */ static void status_pre_select(struct sched *s, struct task *t) { struct status_task *st = container_of(t, struct status_task, task); int ret; - if (st->ct || audiod_status == AUDIOD_OFF) + if (st->ct || audiod_status == AUDIOD_OFF) /* no need to restart */ return; if (!st->clock_diff_count && tv_diff(now, &st->restart_barrier, NULL) < 0) return; - if (st->clock_diff_count) { + if (st->clock_diff_count) { /* get status only one time */ char *argv[] = {"audiod", "stat", "1", NULL}; int argc = 3; if (tv_diff(now, &st->clock_diff_barrier, NULL) < 0) @@ -1030,10 +1016,12 @@ static void status_post_select(__a_unused struct sched *s, struct task *t) if (!st->ct || st->ct->status != CL_RECEIVING) return; - if (st->ct && audiod_status == AUDIOD_OFF) { - unregister_task(&st->ct->task); + if (audiod_status == AUDIOD_OFF || st->ct->task.error < 0) { + if (st->ct->task.error >= 0) + unregister_task(&st->ct->task); + if (audiod_status == AUDIOD_OFF) + st->clock_diff_count = conf.clock_diff_count_arg; close_stat_pipe(); - st->clock_diff_count = conf.clock_diff_count_arg; return; } bytes_left = for_each_line(st->ct->buf, st->ct->loaded,