From: Andre Noll Date: Sun, 30 Nov 2008 22:11:45 +0000 (+0100) Subject: Rename filter_chain.c to filter_common.c. X-Git-Tag: v0.3.4~96 X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=commitdiff_plain;h=0c8556a2efd78a16d130370c351138faeae7cd33 Rename filter_chain.c to filter_common.c. --- diff --git a/configure.ac b/configure.ac index 7cba9450..c80b2610 100644 --- a/configure.ac +++ b/configure.ac @@ -81,7 +81,7 @@ AC_CHECK_FUNCS([atexit dup2 memchr memmove memset \ all_errlist_objs="server mp3_afh afh_common vss command net string signal time daemon stat crypt http_send close_on_fork ipc acl afh fade amp_filter dccp_send fd user_list chunk_queue afs osl aft mood score attribute blob ringbuffer -playlist sha1 rbtree sched audiod grab_client filter_chain wav_filter compress_filter +playlist sha1 rbtree sched audiod grab_client filter_common wav_filter compress_filter http_recv dccp_recv recv_common write_common file_write audiod_command client_common recv stdout filter stdin audioc write client fsck exec send_common" @@ -96,7 +96,7 @@ receivers=" http dccp" senders=" http dccp" filter_cmdline_objs="filter.cmdline compress_filter.cmdline amp_filter.cmdline" -filter_errlist_objs="filter_chain wav_filter compress_filter filter string stdin stdout sched fd amp_filter" +filter_errlist_objs="filter_common wav_filter compress_filter filter string stdin stdout sched fd amp_filter" filter_ldflags="" filters=" compress wav amp" @@ -108,7 +108,7 @@ audiod_cmdline_objs="audiod.cmdline grab_client.cmdline compress_filter.cmdline http_recv.cmdline dccp_recv.cmdline file_write.cmdline client.cmdline audiod_command_list amp_filter.cmdline" audiod_errlist_objs="audiod signal string daemon stat net - time grab_client filter_chain wav_filter compress_filter amp_filter http_recv dccp_recv + time grab_client filter_common wav_filter compress_filter amp_filter http_recv dccp_recv recv_common fd sched write_common file_write audiod_command crypt client_common" audiod_ldflags="" diff --git a/error.h b/error.h index 92aaff5d..7259a4cc 100644 --- a/error.h +++ b/error.h @@ -240,7 +240,7 @@ extern const char **para_errlist[]; PARA_ERROR(INVALID_AUDIOD_CMD, "invalid command"), \ -#define FILTER_CHAIN_ERRORS \ +#define FILTER_COMMON_ERRORS \ PARA_ERROR(UNSUPPORTED_FILTER, "given filter not supported"), \ PARA_ERROR(BAD_FILTER_OPTIONS, "invalid filter option given"), \ PARA_ERROR(FC_EOF, "filter chain: eof"), \ diff --git a/filter.h b/filter.h index 3425ae85..39cec9ba 100644 --- a/filter.h +++ b/filter.h @@ -4,7 +4,7 @@ * Licensed under the GPL v2. For licencing details see COPYING. */ -/** \file filter.h Filter-related structures and exported symbols from filter_chain.c. */ +/** \file filter.h Filter-related structures and exported symbols from filter_common.c. */ /** The list of supported filters. */ enum filter_enum {FILTER_ENUM}; diff --git a/filter_chain.c b/filter_chain.c deleted file mode 100644 index 0da4533f..00000000 --- a/filter_chain.c +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright (C) 2005-2008 Andre Noll - * - * Licensed under the GPL v2. For licencing details see COPYING. - */ - -/** \file filter_chain.c Common helper functions for filter input/output. */ - -#include -#include - -#include "para.h" -#include "list.h" -#include "sched.h" -#include "fd.h" -#include "filter.h" -#include "error.h" -#include "string.h" - -/** The array of supported filters. */ -struct filter filters[NUM_SUPPORTED_FILTERS] = {FILTER_ARRAY}; - -/** - * Call the init function of each supported filter. - * - * \param all_filters the array of all supported filters. - * - * \sa filter::init - */ -void filter_init(struct filter *all_filters) -{ - int i; - - FOR_EACH_SUPPORTED_FILTER(i) - all_filters[i].init(all_filters + i); -} - -/** - * Close and destroy a filter callback. - * - * \param fcb The filter callback to close. - * - * This removes \a fcb from the list of filter callbacks and calls - * the close callback associated with \a fcb. - */ -static void close_filter_callback(struct filter_callback *fcb) -{ - PARA_NOTICE_LOG("closing filter_callback %p, data: %p\n", fcb, fcb->data); - list_del(&fcb->node); - fcb->close(fcb); -} - -/** - * Close all callbacks of a filter node. - * - * \param fn The filter node which contains the filter callbacks to be closed. - * - * Call close_filter_callback() for each entry in the filter callback list - * of \a fn. - */ -static void close_callbacks(struct filter_node *fn) -{ - struct filter_callback *fcb, *tmp; - - list_for_each_entry_safe(fcb, tmp, &fn->callbacks, node) { - PARA_INFO_LOG("closing %s filter callback\n", - filters[fn->filter_num].name); - close_filter_callback(fcb); - } -} - -static void call_callbacks(struct filter_node *fn, char *inbuf, size_t inlen, - char *outbuf, size_t outlen) -{ - struct filter_callback *fcb, *tmp; - list_for_each_entry_safe(fcb, tmp, &fn->callbacks, node) { - int ret; - if (inlen && fcb->input_cb) { - ret = fcb->input_cb(inbuf, inlen, fcb); - if (ret < 0) { - close_filter_callback(fcb); - continue; - } - } - if (!outlen || !fcb->output_cb) - continue; - ret = fcb->output_cb(outbuf, outlen, fcb); - if (ret < 0) - close_filter_callback(fcb); - } -} - -/** - * Call the convert function of each filter. - * - * \param s Unused. - * \param t The task identifying the filter chain. - * - * This is the core function of the filter subsystem. It loops over the list of - * filter nodes determined by \a t and calls the filter's convert function if - * there is input available for the filter node in question. If the convert - * function consumed some or all of its input data, all registered input - * callbacks are called. Similarly, if a convert function produced output, all - * registerd output callbacks get called. - * - * On errors a (negative) error code is stored in t->error. - * - * \sa filter_node, filter#convert, filter_callback. - */ -void filter_pre_select(__a_unused struct sched *s, struct task *t) -{ - struct filter_chain *fc = container_of(t, struct filter_chain, task); - struct filter_node *fn; - char *ib; - size_t *loaded; - int i, conv, conv_total = 0; - - if (fc->output_error && *fc->output_error < 0) { - t->error = *fc->output_error; - return; - } -again: - ib = fc->inbuf; - loaded = fc->in_loaded; - conv = 0; - FOR_EACH_FILTER_NODE(fn, fc, i) { - struct filter *f = filters + fn->filter_num; - if (fn->loaded < fn->bufsize) { - size_t size, old_fn_loaded = fn->loaded; -// PARA_DEBUG_LOG("fc %p loaded: %zd, calling %s convert\n", -// fc, *loaded, fn->filter->name); - t->error = f->convert(ib, *loaded, fn); - if (t->error < 0) - return; - size = t->error; - call_callbacks(fn, ib, size, fn->buf + old_fn_loaded, - fn->loaded - old_fn_loaded); - *loaded -= size; - conv += size; - if (*loaded && size) { -// PARA_DEBUG_LOG("moving %zd bytes in input " -// "buffer for %s filter\n", -// *loaded, fn->filter->name); - memmove(ib, ib + size, *loaded); - } - } - ib = fn->buf; - loaded = &fn->loaded; - } - conv_total += conv; -// PARA_DEBUG_LOG("eof (in/out/fc): %d/%d/%d out_loaded: %zd, " -// "conv: %d, conv_total: %d\n", *fc->input_eof, -// fc->output_eof? *fc->output_eof : -42, -// fc->eof, *fc->out_loaded, conv, conv_total); - if (conv) - goto again; - if (!*fc->input_error) - return; - if (*fc->out_loaded) - return; - if (*fc->in_loaded && conv_total) - return; - t->error = -E_FC_EOF; -} - -/** - * Close all filter nodes and their callbacks. - * - * \param fc The filter chain to close. - * - * For each filter node determined by \a fc, call the close function of each - * registered filter callback as well as the close function of the - * corresponding filter. Free all resources and destroy all callback lists and - * the filter node list. - * - * \sa filter::close, filter_callback::close - */ -void close_filters(struct filter_chain *fc) -{ - struct filter_node *fn; - int i; - - if (!fc) - return; - PARA_NOTICE_LOG("closing filter chain %p\n", fc); - FOR_EACH_FILTER_NODE(fn, fc, i) { - struct filter *f = filters + fn->filter_num; - close_callbacks(fn); - PARA_INFO_LOG("closing %s filter\n", f->name); - f->close(fn); - } - free(fc->filter_nodes); -} - -/* - * If the filter has a command line parser and options is not NULL, run it. - * Returns filter_num on success, negative on errors - */ -static int parse_filter_args(int filter_num, char *options, void **conf) -{ - struct filter *f = &filters[filter_num]; - int ret, i, argc = 2; - char **argv; - -// PARA_DEBUG_LOG("%s, options: %s, parser: %p\n", f->name, -// options? options : "(none)", f->parse_config); - 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]); - for (i = argc - 1; i >= 0; i--) - argv[i + 1] = argv[i]; - argv[0] = para_strdup(f->name); - argc += 1; - ret = f->parse_config(argc, argv, conf); - free(argv[0]); - free(argv); - return ret < 0? ret : filter_num; -} - -/** - * Check the filter command line options. - * - * \param fa The command line options. - * \param conf Points to the filter configuration upon successful return. - * - * Check if \a fa starts with a the name of a supported filter, followed by - * a colon. If yes, call the command line parser of that filter. - * - * \return On success, the number of the filter is returned and \a conf - * is initialized to point to the filter configuration determined by \a fa. - * On errors, a negative value is returned. - * - * Note: If \a fa specifies a filter that has no command line parser success is - * returned, and \a conf is initialized to \p NULL. - * - * \sa filter::parse_config - */ -int check_filter_arg(char *fa, void **conf) -{ - int j; - - *conf = NULL; -// PARA_DEBUG_LOG("arg: %s\n", fa); - FOR_EACH_SUPPORTED_FILTER(j) { - const char *name = filters[j].name; - size_t len = strlen(name); - char c; - if (strlen(fa) < len) - continue; - if (strncmp(name, fa, len)) - continue; - c = fa[len]; - if (c && c != ' ') - continue; - if (c && !filters[j].parse_config) - return -E_BAD_FILTER_OPTIONS; - return parse_filter_args(j, c? fa + len + 1 : - fa + strlen(fa), conf); - } - return -E_UNSUPPORTED_FILTER; -} - diff --git a/filter_common.c b/filter_common.c new file mode 100644 index 00000000..29d6c957 --- /dev/null +++ b/filter_common.c @@ -0,0 +1,264 @@ +/* + * Copyright (C) 2005-2008 Andre Noll + * + * Licensed under the GPL v2. For licencing details see COPYING. + */ + +/** \file filter_common.c Common helper functions for filter input/output. */ + +#include +#include + +#include "para.h" +#include "list.h" +#include "sched.h" +#include "fd.h" +#include "filter.h" +#include "error.h" +#include "string.h" + +/** The array of supported filters. */ +struct filter filters[NUM_SUPPORTED_FILTERS] = {FILTER_ARRAY}; + +/** + * Call the init function of each supported filter. + * + * \param all_filters the array of all supported filters. + * + * \sa filter::init + */ +void filter_init(struct filter *all_filters) +{ + int i; + + FOR_EACH_SUPPORTED_FILTER(i) + all_filters[i].init(all_filters + i); +} + +/** + * Close and destroy a filter callback. + * + * \param fcb The filter callback to close. + * + * This removes \a fcb from the list of filter callbacks and calls + * the close callback associated with \a fcb. + */ +static void close_filter_callback(struct filter_callback *fcb) +{ + PARA_NOTICE_LOG("closing filter_callback %p, data: %p\n", fcb, fcb->data); + list_del(&fcb->node); + fcb->close(fcb); +} + +/** + * Close all callbacks of a filter node. + * + * \param fn The filter node which contains the filter callbacks to be closed. + * + * Call close_filter_callback() for each entry in the filter callback list + * of \a fn. + */ +static void close_callbacks(struct filter_node *fn) +{ + struct filter_callback *fcb, *tmp; + + list_for_each_entry_safe(fcb, tmp, &fn->callbacks, node) { + PARA_INFO_LOG("closing %s filter callback\n", + filters[fn->filter_num].name); + close_filter_callback(fcb); + } +} + +static void call_callbacks(struct filter_node *fn, char *inbuf, size_t inlen, + char *outbuf, size_t outlen) +{ + struct filter_callback *fcb, *tmp; + list_for_each_entry_safe(fcb, tmp, &fn->callbacks, node) { + int ret; + if (inlen && fcb->input_cb) { + ret = fcb->input_cb(inbuf, inlen, fcb); + if (ret < 0) { + close_filter_callback(fcb); + continue; + } + } + if (!outlen || !fcb->output_cb) + continue; + ret = fcb->output_cb(outbuf, outlen, fcb); + if (ret < 0) + close_filter_callback(fcb); + } +} + +/** + * Call the convert function of each filter. + * + * \param s Unused. + * \param t The task identifying the filter chain. + * + * This is the core function of the filter subsystem. It loops over the list of + * filter nodes determined by \a t and calls the filter's convert function if + * there is input available for the filter node in question. If the convert + * function consumed some or all of its input data, all registered input + * callbacks are called. Similarly, if a convert function produced output, all + * registerd output callbacks get called. + * + * On errors a (negative) error code is stored in t->error. + * + * \sa filter_node, filter#convert, filter_callback. + */ +void filter_pre_select(__a_unused struct sched *s, struct task *t) +{ + struct filter_chain *fc = container_of(t, struct filter_chain, task); + struct filter_node *fn; + char *ib; + size_t *loaded; + int i, conv, conv_total = 0; + + if (fc->output_error && *fc->output_error < 0) { + t->error = *fc->output_error; + return; + } +again: + ib = fc->inbuf; + loaded = fc->in_loaded; + conv = 0; + FOR_EACH_FILTER_NODE(fn, fc, i) { + struct filter *f = filters + fn->filter_num; + if (fn->loaded < fn->bufsize) { + size_t size, old_fn_loaded = fn->loaded; +// PARA_DEBUG_LOG("fc %p loaded: %zd, calling %s convert\n", +// fc, *loaded, fn->filter->name); + t->error = f->convert(ib, *loaded, fn); + if (t->error < 0) + return; + size = t->error; + call_callbacks(fn, ib, size, fn->buf + old_fn_loaded, + fn->loaded - old_fn_loaded); + *loaded -= size; + conv += size; + if (*loaded && size) { +// PARA_DEBUG_LOG("moving %zd bytes in input " +// "buffer for %s filter\n", +// *loaded, fn->filter->name); + memmove(ib, ib + size, *loaded); + } + } + ib = fn->buf; + loaded = &fn->loaded; + } + conv_total += conv; +// PARA_DEBUG_LOG("eof (in/out/fc): %d/%d/%d out_loaded: %zd, " +// "conv: %d, conv_total: %d\n", *fc->input_eof, +// fc->output_eof? *fc->output_eof : -42, +// fc->eof, *fc->out_loaded, conv, conv_total); + if (conv) + goto again; + if (!*fc->input_error) + return; + if (*fc->out_loaded) + return; + if (*fc->in_loaded && conv_total) + return; + t->error = -E_FC_EOF; +} + +/** + * Close all filter nodes and their callbacks. + * + * \param fc The filter chain to close. + * + * For each filter node determined by \a fc, call the close function of each + * registered filter callback as well as the close function of the + * corresponding filter. Free all resources and destroy all callback lists and + * the filter node list. + * + * \sa filter::close, filter_callback::close + */ +void close_filters(struct filter_chain *fc) +{ + struct filter_node *fn; + int i; + + if (!fc) + return; + PARA_NOTICE_LOG("closing filter chain %p\n", fc); + FOR_EACH_FILTER_NODE(fn, fc, i) { + struct filter *f = filters + fn->filter_num; + close_callbacks(fn); + PARA_INFO_LOG("closing %s filter\n", f->name); + f->close(fn); + } + free(fc->filter_nodes); +} + +/* + * If the filter has a command line parser and options is not NULL, run it. + * Returns filter_num on success, negative on errors + */ +static int parse_filter_args(int filter_num, char *options, void **conf) +{ + struct filter *f = &filters[filter_num]; + int ret, i, argc = 2; + char **argv; + +// PARA_DEBUG_LOG("%s, options: %s, parser: %p\n", f->name, +// options? options : "(none)", f->parse_config); + 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]); + for (i = argc - 1; i >= 0; i--) + argv[i + 1] = argv[i]; + argv[0] = para_strdup(f->name); + argc += 1; + ret = f->parse_config(argc, argv, conf); + free(argv[0]); + free(argv); + return ret < 0? ret : filter_num; +} + +/** + * Check the filter command line options. + * + * \param fa The command line options. + * \param conf Points to the filter configuration upon successful return. + * + * Check if \a fa starts with a the name of a supported filter, followed by + * a colon. If yes, call the command line parser of that filter. + * + * \return On success, the number of the filter is returned and \a conf + * is initialized to point to the filter configuration determined by \a fa. + * On errors, a negative value is returned. + * + * Note: If \a fa specifies a filter that has no command line parser success is + * returned, and \a conf is initialized to \p NULL. + * + * \sa filter::parse_config + */ +int check_filter_arg(char *fa, void **conf) +{ + int j; + + *conf = NULL; +// PARA_DEBUG_LOG("arg: %s\n", fa); + FOR_EACH_SUPPORTED_FILTER(j) { + const char *name = filters[j].name; + size_t len = strlen(name); + char c; + if (strlen(fa) < len) + continue; + if (strncmp(name, fa, len)) + continue; + c = fa[len]; + if (c && c != ' ') + continue; + if (c && !filters[j].parse_config) + return -E_BAD_FILTER_OPTIONS; + return parse_filter_args(j, c? fa + len + 1 : + fa + strlen(fa), conf); + } + return -E_UNSUPPORTED_FILTER; +} +