X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=filter.h;h=03e79d9167eb1e89b5eb4cd339e3345a6f20ed23;hp=820161303e72f921488027b7fe146bbc344b1d81;hb=4adde8dae3317fa83b81e7a860c9ed9133e99bb0;hpb=5b1e8c76053c57bf3491d4914cb8fd7896c3ff20 diff --git a/filter.h b/filter.h index 82016130..03e79d91 100644 --- a/filter.h +++ b/filter.h @@ -1,204 +1,132 @@ /* - * Copyright (C) 2005-2009 Andre Noll + * Copyright (C) 2005 Andre Noll * * Licensed under the GPL v2. For licencing details see COPYING. */ /** \file filter.h Filter-related structures and exported symbols from filter_common.c. */ -/** The list of supported filters. */ -enum filter_enum {FILTER_ENUM}; - /** * Describes one running instance of a filter. */ struct filter_node { /** The number in the array of available filters. */ unsigned filter_num; - /** The filter chain this filter node belongs to. */ - struct filter_chain *fc; /** * Each filter may store any filter-specific information about the particular * instance of the filter here. */ void *private_data; - /** The output buffer. */ - char *buf; - /** The size of the output buffer. */ - size_t bufsize; - /** The number of bytes currently loaded in \a buf. */ - size_t loaded; /** The list of registered callbacks. */ struct list_head callbacks; /** A pointer to the configuration of this instance. */ void *conf; + /** The parsed command line, merged with options given in the config file. */ + struct lls_parse_result *lpr; + /** The buffer tree node. */ struct btr_node *btrn; - struct task task; + /** The task corresponding to this filter node. */ + struct task *task; + /** The minimal input queue size, see \ref btr_node_status(). */ size_t min_iqs; }; -/** Describes one running instance of a chain of filters */ -struct filter_chain { - /** The length of the filter chain. */ - unsigned int num_filters; - /** - * The number of channels of the current stream. - * - * Set by the decoding filter. - */ - unsigned int channels; - /** - * Current sample rate in Hz. - * - * Set by the decoding filter. - */ - unsigned int samplerate; - /** The list containing all filter nodes in this filter chain. */ - struct filter_node *filter_nodes; - /** - * The input buffer of the filter chain. - * - * This is set to point to the output buffer of the receiving application (the - * buffer used to read from stdin for para_filter; the output buffer of the - * current receiver for para_audiod). - */ - char **inbufp; - /** - * The output buffer of the filter chain. - * - * Points to the output buffer of the last filter in the filter chain. - */ - char **outbufp; - /** Contains the number of bytes loaded in the input buffer. */ - size_t *in_loaded; - /** Contains the number of bytes loaded in the output buffer. */ - size_t *out_loaded; - /** Pointer to the error variable of the receiving application. */ - int *input_error; - /** Pointer to the error variable of the writing application. */ - int *output_error; - /** The task associated with the filter chain. */ - struct task task; -}; - -#define FOR_EACH_FILTER_NODE(fn, fc, i) for (i = 0; i < (fc)->num_filters \ - && (fn = (fc)->filter_nodes + i); i++) - - -/** - * Used to manage grab clients. - * - * An application using paraslash's filter subsystem may register any number of - * callbacks for each filter_node. It is possible to attach a filter callback - * while the filter is running. This is used for stream grabbing in - * para_audiod: Whenever a client sends the 'grab' command, para_audiod adds a - * filter callback to the list of callbacks for the filter node specified in - * the grab command. - */ -struct filter_callback { - /** All callbacks are organized in a doubly linked list. */ - struct list_head node; - /** - * The input callback. - * - * 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. - */ - int (*input_cb)(char *buf, size_t len, struct filter_callback *fc); - /** - * The output callback. - * - * If not NULL, this is called whenever the filter produces output. A pointer - * to the output data, its length and a pointer to the own \a filter_callback - * structure are passed to \a output_cb. Like the input callback, the output - * callback is expected to return a negative value on errors. - */ - int (*output_cb)(char *buf, size_t len, struct filter_callback *fc); - /** - * The callback close function. - * - * This gets called whenever the input/output callback returned an error, or if - * the filter chain is going to be destroyed, e.g. because the end of the - * stream was encountered. It is assumed to succeed. - */ - void (*close)(struct filter_callback *fc); -}; - - /** * The structure associated with a paraslash filter. * - * Paraslash filters are "modules" which are used to transform an audio stream. - * struct filter contains pointers to functions that must be supplied by the - * filter code in order to be used by the driving application (currently - * para_audiod and para_filter). + * Paraslash filters are "modules" which transform an audio stream. struct + * filter contains methods which are implemented by each filter. * * Note: As several instances of the same filter may be running at the same * time, all these filter functions must be reentrant; no static non-constant * variables may be used. + * * \sa mp3dec_filter.c, oggdec_filter.c, wav_filter.c, compress_filter.c, filter_node */ struct filter { - /** The name of the filter. */ - const char *name; - /** - * Pointer to the filter init routine. - * - * This function is only called once at startup. It must initialize the - * other non-optional function pointers of this structure. - */ - void (*init)(struct filter *f); /** * Open one instance of this filter. * - * This should allocate the output buffer of the given filter node and do any - * other filter-specific preparations like initializing the private_data member - * of \a fn suitably. The open function is assumed to succeed. + * This should allocate the output buffer of the given filter node and + * do any other filter-specific preparations like initializing the + * private_data member of \a fn suitably. The open function is + * optional, If it is provided, it is assumed to succeed. */ void (*open)(struct filter_node *fn); /** * Close one instance of this filter. * - * Free all resources of associated with \a fn that were previously allocated - * by the open() function. + * Free all resources associated with \a fn that were previously + * allocated by the open() function. It's OK to set this to NULL if the + * filter does not need to perform any cleanup operation. */ void (*close)(struct filter_node *fn); /** - * A pointer to the filter's command line parser. + * Prepare the filter according to command line options. * - * If this optional function pointer is not NULL, any filter options - * are passed from the main program to this command line parser once at - * application startup. The command line parser should check its - * command line options given by \a argc and \a argv and abort on - * errors. Success must be indicated by a non-negative return value. In - * this case the function should return a pointer to the - * filter-specific configuration data determined by \a argc and \a - * argv. On failure, a negative paraslash error code must be returned. + * In addition to the syntactic checks which are automatically performed + * by the lopsub functions, some filters like to also check the command + * line arguments semantically. Moreover, since applications may open + * the filter many times with the same options, filters need a method + * which allows them to precompute once those parts of the setup which + * depend only on the command line options. + * + * If this function pointer is not NULL, the function is called once at + * startup. The returned pointer value is made available to the ->open + * method via the ->conf pointer of struct filter_node. + * + * Filters are supposed to abort if the setup fails. If the function + * returns, it is assumed to have succeeded. */ - int (*parse_config)(int argc, char **argv, void **config); - void (*free_config)(void *conf); - - /** The help texts for this filter. */ - struct ggo_help help; - void (*pre_select)(struct sched *s, struct task *t); + void *(*setup)(const struct lls_parse_result *lpr); + /** + * Deallocate precomputed resources. + * + * This should free whatever ->setup() has allocated. + */ + void (*teardown)(const struct lls_parse_result *lpr, void *conf); + /** + * Set scheduler timeout and add file descriptors to fd sets. + * + * This function controls the timeout value for the next call to + * select(2). It may decrease the current timeout but shall never + * increase it. The second purpose of this function is to add file + * descriptors to the two fd sets of the sched structure. The + * descriptors in these sets will be watched by the subsequent + * select(2) call. + */ + void (*pre_select)(struct sched *s, void *context); /** * Convert (filter) the given data. * - * Pointer to the converting function of the filter. It should convert as - * input data as possible. On errors, the post_select function is supposed - * to set t->error to a (negative) error code. + * Pointer to the converting function of the filter. On errors, the + * post_select function is supposed to return a negative error code. + */ + int (*post_select)(struct sched *s, void *context); + /** + * Answer a buffer tree query. + * + * This optional function pointer is used for inter node communications + * of the buffer tree nodes. See \ref btr_command_handler for details. */ - void (*post_select)(struct sched *s, struct task *t); btr_command_handler execute; }; -void close_filters(struct filter_chain *fc); -void filter_init(void); -int check_filter_arg(char *filter_arg, void **conf); -void print_filter_helps(int detailed); -void generic_filter_pre_select(struct sched *s, struct task *t); +void print_filter_helps(bool detailed); +int filter_setup(const char *fa, void **conf, struct lls_parse_result **lprp); +#define FILTER_CMD(_num) (lls_cmd(_num, filter_cmd_suite)) +#define FILTER_CMD_OPT_RESULT(_cmd, _opt, _lpr) \ + (lls_opt_result(LSG_FILTER_CMD_ ## _cmd ## _OPT_ ## _opt, _lpr)) +#define FILTER_CMD_OPT_GIVEN(_cmd, _opt, _lpr) \ + (lls_opt_given(FILTER_CMD_OPT_RESULT(_cmd, _opt, _lpr))) +#define FILTER_CMD_OPT_UINT32_VAL(_cmd, _opt, _lpr) \ + (lls_uint32_val(0, FILTER_CMD_OPT_RESULT(_cmd, _opt, _lpr))) +#define FILTER_CMD_OPT_STRING_VAL(_cmd, _opt, _lpr) \ + (lls_string_val(0, FILTER_CMD_OPT_RESULT(_cmd, _opt, _lpr))) + +void generic_filter_pre_select(struct sched *s, void *context); +int decoder_execute(const char *cmd, unsigned sample_rate, unsigned channels, + char **result); static inline void write_int16_host_endian(char *buf, int val) { @@ -211,9 +139,6 @@ static inline void write_int16_host_endian(char *buf, int val) #endif } -DECLARE_FILTER_INITS - -#define FOR_EACH_SUPPORTED_FILTER(j) for (j = 0; j < NUM_SUPPORTED_FILTERS; j++) - -/** The filter array, one structure for each supported filter. */ -extern struct filter filters[NUM_SUPPORTED_FILTERS]; +/** Make a filter pointer from the filter number. */ +const struct filter *filter_get(int filter_num); +const char *filter_name(int filter_num);