X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=filter.h;h=94657a738a4ae1b620148d28400c20ed4c27a710;hp=1b916eecf632cc834b46703007097d6a02e6413a;hb=bda95f9508b456dcea89d300f6d4104e30ab9f3e;hpb=d32eb7a5cf569ee842d91f3f830a8562fa0ae12d diff --git a/filter.h b/filter.h index 1b916eec..94657a73 100644 --- a/filter.h +++ b/filter.h @@ -1,11 +1,13 @@ /* - * Copyright (C) 2005-2008 Andre Noll + * Copyright (C) 2005-2011 Andre Noll * * 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}; /** * Describes one running instance of a filter. @@ -13,122 +15,23 @@ 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; -}; - -/** Describes one running instance of a chain of filters */ -struct 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 *inbuf; - /** - * The output buffer of the filter chain. - * - * Points to the output buffer of the last filter in the filter chain. - */ - char *outbuf; - /** 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. */ + /** 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; }; -#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; - /** - * 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/output/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/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. * @@ -140,7 +43,7 @@ struct filter_callback { * 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 + * \sa mp3dec_filter.c, oggdec_filter.c, wav_filter.c, compress_filter.c, filter_node */ struct filter { /** The name of the filter. */ @@ -161,50 +64,67 @@ struct filter { */ void (*open)(struct filter_node *fn); /** - * Convert (filter) the given data. + * Close one instance of this filter. * - * 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 previously - * 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. + * Free all resources of associated with \a fn that were previously allocated + * by the open() function. It's OK to leave this alone if the filter does not + * need any cleanups. + */ + void (*close)(struct filter_node *fn); + /** + * A pointer to the filter's command line parser. * - * 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. + * 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. */ - ssize_t (*convert)(char *inbuf, size_t len, struct filter_node *fn); + int (*parse_config)(int argc, char **argv, void **config); /** - * Close one instance of this filter. + * Deallocate the memory for the configuration. * - * Free all resources of associated with \a fn that were previously allocated - * by the open() function. + * This is called to free whatever ->parse_config() has allocated. */ - void (*close)(struct filter_node *fn); + void (*free_config)(void *conf); + + /** The help texts for this filter. */ + struct ggo_help help; /** - * Print the help text for this filter and exit. + * Set scheduler timeout and add file descriptors to fd sets. * - * This is optional and it is not necessary to initialize this pointer if - * the filter does not have a help text. + * This function is used to control the timeout value for select. It + * only allowed to decrease the current value. The second purpose of + * this function is to set file descriptors to be watched by the + * subsequent select call to the two fd sets. */ - void (*print_help)(void); + void (*pre_select)(struct sched *s, struct task *t); /** - * A pointer to the filter's command line parser. + * Convert (filter) the given data. + * + * Pointer to the converting function of the filter. On errors, the + * post_select function is supposed to set t->error to a (negative) + * error code. + */ + void (*post_select)(struct sched *s, struct task *t); + /** + * Answer a buffer tree query. * - * 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. On success, it should return a - * pointer to the filter-specific configuration data determined by \a argc and - * \a argv. + * This optional function pointer is used for inter node communications + * of the buffer tree nodes. See \ref btr_command_handler for details. */ - void *(*parse_config)(int argc, char **argv); + btr_command_handler execute; }; -void close_filters(struct filter_chain *fc); -void filter_init(struct filter *all_filters); +void filter_init(void); int check_filter_arg(char *filter_arg, void **conf); -void filter_pre_select(__a_unused struct sched *s, struct task *t); - +void print_filter_helps(int detailed); +void generic_filter_pre_select(struct sched *s, struct task *t); +int decoder_execute(const char *cmd, unsigned sample_rate, unsigned channels, + char **result); static inline void write_int16_host_endian(char *buf, int val) { @@ -217,55 +137,10 @@ static inline void write_int16_host_endian(char *buf, int val) #endif } +DECLARE_FILTER_INITS -/** \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 } }; - +/** Iterate over the array of supported filters. */ +#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];