X-Git-Url: http://git.tuebingen.mpg.de/?a=blobdiff_plain;f=filter.h;h=ab98c2442b9d13ae5158716fc2fe7f24904685e6;hb=408371cd5c6c06cdbd51513ab49ff0bc376cda26;hp=456a50de3a79c942299ddea50f21fc2169fac9f4;hpb=203bfcadc14507f4d01f99099efec8ee976556b1;p=paraslash.git diff --git a/filter.h b/filter.h index 456a50de..ab98c244 100644 --- a/filter.h +++ b/filter.h @@ -1,307 +1,138 @@ /* - * Copyright (C) 2005-2007 Andre Noll + * Copyright (C) 2005 Andre Noll * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + * 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. */ /** - * describes one running instance of a chain of filters + * Describes one running instance of a filter. +*/ +struct filter_node { + /** The number in the array of available filters. */ + unsigned filter_num; + /** + * Each filter may store any filter-specific information about the particular + * instance of the filter here. + */ + void *private_data; + /** 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; + /** The task corresponding to this filter node. */ + struct task *task; + /** The minimal input queue size, see \ref btr_node_status(). */ + size_t min_iqs; +}; + +/** + * The structure associated with a paraslash 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 \ref filter_node. */ -struct filter_chain { +struct filter { /** + * Open one instance of this filter. * - * - * the number of channels of the current stream - * - * Set by the decoding 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 + * optional, If it is provided, it is assumed to succeed. */ - unsigned int channels; + void (*open)(struct filter_node *fn); /** + * Close one instance of this filter. * - * - * current samplerate in Hz - * - * Set by the decoding filter + * 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. */ - unsigned int samplerate; + void (*close)(struct filter_node *fn); /** + * Prepare the filter according to command line options. + * + * 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. * - * the list containing all filter nodes in this filter chain + * Filters are supposed to abort if the setup fails. If the function + * returns, it is assumed to have succeeded. */ - struct list_head filters; + void *(*setup)(const struct lls_parse_result *lpr); /** + * Deallocate precomputed resources. * - * - * 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) + * This should free whatever ->setup() has allocated. */ - char *inbuf; + void (*teardown)(const struct lls_parse_result *lpr, void *conf); /** - * - * - * the output buffer of the filter chain - * - * Points to the output buffer of the last filter in the filter chain - **/ - char *outbuf; + * 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 variable containing the number of bytes loaded in the input buffer + * Pointer to the converting function of the filter. On errors, the + * post_select function is supposed to return a negative error code. */ - size_t *in_loaded; + int (*post_select)(struct sched *s, void *context); /** + * Answer a buffer tree query. * - * - * pointer to variable containing the number of bytes loaded in the output buffer + * This optional function pointer is used for inter node communications + * of the buffer tree nodes. See \ref btr_command_handler for details. */ - size_t *out_loaded; - /** non-zero if this filter wont' produce any more output */ - int eof; - /** pointer to the eof flag of the receiving application */ - int *input_eof; - /** pointer to the eof flag of the writing application */ - int *output_eof; - /** the task associated with the filter chain */ - struct task task; + btr_command_handler execute; }; -/** - * describes one running instance of a filter -*/ -struct filter_node { -/** - * - * - * a pointer to the corresponding filter struct - */ - struct filter *filter; -/** - * - * - * the filter chain this filter node belongs to - */ - struct filter_chain *fc; -/** - * - * - * the position of the filter in the corresponding filter chain - * - * all filters that make up the filter chains are organized in a doubly - * linked list. - */ - struct list_head node; -/** - * - * - * 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; -}; - -/** - * 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; -/** - * - * - * 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/ouput/close callback functions. - */ - void *data; -/** - * - * - * the input callback - * - * In 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/ouput callback returned an error, or if - * the filter chain is going to be destroyed, e.g. because the end of the - * stream was encounterd. It is assumed to succeed. - */ - void (*close)(struct filter_callback *fc); -}; - - -void close_filters(struct filter_chain *fc); -void filter_init(struct filter *all_filters); -int check_filter_arg(char *filter_arg, void **conf); -void filter_pre_select(__a_unused struct sched *s, struct task *t); - -/** - * 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). - * - * 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.c, oggdec.c, wav.c, compress.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 \a f. - */ -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. - */ -void (*open)(struct filter_node *fn); -/** - * - * - * convert (filter) the given data - * - * Pointer to the converting function of the filter. It should convert the - * given input buffer \a inbuf which is of length \a len to the previoulsy - * reserved output buffer of \a fn. On success, it must return the number of - * bytes it consumed from \a inbuf. On errors, a negative number indicating the - * kind of the error must be returned. - * - * A zero return value just means that nothing was converted (probably because - * the input buffer was too small). This is not interpreted as an error. - */ -ssize_t (*convert)(char *inbuf, size_t len, 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. - */ -void (*close)(struct filter_node *fn); -/** - * - * - * print the help text for this filter and exit - * - * This is optional and it is not necessary to initialize this pointer if - * the filter does not have a help text. - */ -void (*print_help)(void); -/** - * - * - * a pointer to the filter's command line parser - * - * If this optional function pointer is not NULL, any filter options are passed - * from the main propgram 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. On success, it should return a - * pointer to the filter-specific configuration data determined by \a argc and - * \a argv. - */ -void *(*parse_config)(int argc, char **argv); -}; - - -static inline void write_int16_host_endian(char *buf, int16_t val) +void print_filter_helps(bool detailed); +void print_filter_list(void); +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(_cmd, _opt) (lls_opt( \ + LSG_FILTER_CMD_ ## _cmd ## _OPT_ ## _opt, \ + FILTER_CMD(LSG_FILTER_CMD_CMD_ ## _cmd))) +#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) { #ifdef WORDS_BIGENDIAN *buf = val >> 8; @@ -312,55 +143,5 @@ static inline void write_int16_host_endian(char *buf, int16_t val) #endif } - -/** \cond */ -extern struct filter filters[]; -#define DECLARE_EXTERN_FILTER_INIT(name) \ - extern void name ## _init(struct filter *f) - -#define FILTER_INIT(filter) { \ - .name = #filter, \ - .init = filter ## _init, \ - .parse_config = NULL, \ - .print_help = NULL \ -}, - -/* filters that are always present */ -DECLARE_EXTERN_FILTER_INIT(wav); -/* wav is always the first filter */ -#define WAV_FILTER_NUM 0 -DECLARE_EXTERN_FILTER_INIT(compress); - -/* next the optional filters */ -#ifdef HAVE_MAD -DECLARE_EXTERN_FILTER_INIT(mp3dec); -#define MP3DEC_FILTER FILTER_INIT(mp3dec) -#else -#define MP3DEC_FILTER -#endif - -#ifdef HAVE_FAAD -DECLARE_EXTERN_FILTER_INIT(aacdec); -#define AACDEC_FILTER FILTER_INIT(aacdec) -#else -#define AACDEC_FILTER -#endif - -#ifdef HAVE_OGGVORBIS -DECLARE_EXTERN_FILTER_INIT(oggdec); -#define OGGDEC_FILTER FILTER_INIT(oggdec) -#else -#define OGGDEC_FILTER -#endif -/** \endcond */ - -/** define an array of all available filters */ -#define DEFINE_FILTER_ARRAY(filters) struct filter filters[] = { \ - FILTER_INIT(wav) \ - FILTER_INIT(compress) \ - MP3DEC_FILTER \ - AACDEC_FILTER \ - OGGDEC_FILTER \ - { .name = NULL } }; - - +const struct filter *filter_get(int filter_num); +const char *filter_name(int filter_num);