/* SPDX-License-Identifier: GPL-2.0 */ /** \file filter.h Filter API * * Filters are part of para_audiod(1), para_filter(1) and para_play(1). * Each filter is implemented in its own file whose name ends in _filter.c. For * example, the file which contains the implementation of the mp3 decoder is * \ref mp3dec_filter.c. Additionally, there is \ref filter_common.c which * contains the few public helpers declared in this header file. * * An instance of a filter is described by struct \ref filter_node. It is * created by calling \ref filter::open(). The simplest possible setup is * a filter chain with a single filter where the data source is stdin and * the data sink is stdout. This is the setup created by para_filter(1) * if only one filter option is specified. * * All users of the filter API create a buffer tree and link the buffer * tree node of the filter instance, \ref filter_node::btrn, into the tree * as an internal node. The instance is then registered to the scheduler by * calling \ref task_register(). */ /** Describes one 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 of to this filter instance. */ struct task *task; /** The minimal input queue size, see \ref btr_node_status(). */ size_t min_iqs; }; /** * Definition of a paraslash filter. * * Filters describe how to transform input data into output data. This * structure contains the methods which have to be defined to implement a * particular filter. * * Since more than one instance of the same filter may be running at the * same time, all filter methods must be reentrant. In particular, no static * non-constant variables must be defined. * * \sa \ref filter_node, struct \ref receiver, struct \ref writer. */ struct filter { /** * 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 * \ref filter_node::private_data member 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 associated with the given filter instance. 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); /** * 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. * * Filters are supposed to abort if the setup fails. If the function * returns, it is assumed to have succeeded. */ 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); /** Force a zero timeout if data is available in the buffer tree. */ void (*pre_monitor)(struct sched *s, void *context); /** Convert (filter) input data into output data. */ int (*post_monitor)(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. */ btr_command_handler execute; }; /** \cond doxygen_ignore */ #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))) /** \endcond */ void print_filter_helps(bool detailed); void print_filter_list(void); int filter_setup(const char *fa, void **conf, struct lls_parse_result **lprp); const struct filter *filter_get(int filter_num); const char *filter_name(int filter_num); void generic_filter_pre_monitor(struct sched *s, void *context); int decoder_execute(const char *cmd, unsigned sample_rate, unsigned channels, char **result); /** * Write the two bytes of a signed 16 bit number in host byte order. * * Little endian means to write the lower eight bits at the lower address. This * is what most architectures do, including x86 and arm. * * \param buf Exactly two bytes are written, so this must be at least two * bytes large. * * \param val Between -32768 and 32767, inclusively. */ _static_inline_ void write_int16_host_endian(char *buf, int val) { /* * Shifting a negative value x is the same as shifting -x - 1, then * negate. then subtract one. For example, -256>>8 is -1 but -257>>8 is -2. */ #ifdef WORDS_BIGENDIAN *buf = val >> 8; *(buf + 1) = val & 0xff; #else *buf = val & 0xff; *(buf + 1) = val >> 8; #endif }