X-Git-Url: http://git.tuebingen.mpg.de/?a=blobdiff_plain;f=buffer_tree.h;h=70fb3055699d3cbf6fd663b9425484f1d29d80f6;hb=refs%2Fheads%2Fpu;hp=3ee469c91b3fe56583b305fbb5dcb92d6ac9a4aa;hpb=9b406cbe5d20ba969713ca3d7a8033e697476d75;p=paraslash.git diff --git a/buffer_tree.h b/buffer_tree.h index 3ee469c9..70fb3055 100644 --- a/buffer_tree.h +++ b/buffer_tree.h @@ -1,51 +1,45 @@ -/* - * Copyright (C) 2009 Andre Noll - * - * Licensed under the GPL v2. For licencing details see COPYING. - */ +/* Copyright (C) 2009 Andre Noll , see file COPYING. */ /** * \file buffer_tree.h Buffer tree management. * - * \par Buffer trees and buffer tree nodes. - * The buffer tree API offers a more powerful method than standard unix pipes - * for managing the data flow from the producer of the data (e.g. the network - * receiver) to its consumer(s) (e.g. a sound card). + * Buffer trees and buffer tree nodes. * - * A buffer tree consists of buffer tree nodes linked via certain parent/child - * relationships. + * The buffer tree API offers an efficient method for managing the data flow + * from a producer (e.g. the network receiver) to the consumer(s) (e.g. a sound + * card). + * + * A buffer tree consists of buffer tree nodes which are linked together via + * parent/child relationships. Data buffers are propagated down without copying. * * Each data buffer starts its way from the root of the buffer tree. At each * node the data is investigated and possibly changed. New data is then fed to - * each child. Everything happens within one single-treaded process. There are - * no file descriptors and no calls to read() or write(). + * each child. There are no file descriptors, no processes/threads and no calls + * to read() or write(). * * Whenever a node in the buffer tree creates output, either by creating a new * buffer or by pushing down buffers received from its parent, references to - * that buffer are created for all children of the node. The buffer tree code - * tries hard to avoid to copy buffer contents, but is forced to do so in case - * there are alignment constraints. + * that buffer are created for all children of the node. The code avoids to + * copy buffer contents when possible. * - * Communication between nodes is possible via the btr_exec_up() function. - * For example, in para_audiod the alsa writer asks all parent nodes - * for for the number of channels and the sample rate of the current - * audio file. + * Communication between nodes is possible via the btr_exec_up() function. For + * example, in para_audiod the alsa writer asks all parent nodes for the number + * of channels and the sample rate of the current audio file. * * Buffer pools - An alternative to malloc/free buffer management. * - * Non-leaf nodes usually create output to be processed by their children. The - * data must be fed through the output channel(s) of the node in order to make - * that data available to each child. + * Non-leaf nodes usually create output to be processed by their child nodes. + * The data must be fed through the output channel(s) of the node in order to + * make that data available to each child. * * The easiest way to do so is to malloc() a buffer, fill it, and then call * btr_add_output(). This adds references to that buffer to all children. The * buffer is automatically freed if no buffer tree node is using it any more. * - * This approach, while being simple, has some drawbacks, especially affecting - * the root nodes of the buffer tree. Often the data source which is - * represented by a root node does not know in advance how much data will be - * available. Therefore the allocated buffer is either larger than what can - * currently be read, or is too small so that multiple buffers have to be used. + * This approach is simple but has some drawbacks. For example the data source + * represented by the root node does not know in advance how much data will be + * available. Therefore the allocated buffer will either be larger than + * necessary or too small so that multiple buffers have to be used. * * While this could be worked around by using a large buffer and calling * realloc() afterwards to shrink the buffer according to how much has been @@ -135,7 +129,7 @@ enum btr_node_type { * know the sample rate of its input known to e.g. the mp3dec node further up * in the buffer tree. */ -typedef int (*btr_command_handler)(struct btr_node *btrn, +typedef int (*btr_command_handler)(const struct btr_node *btrn, const char *command, char **result); /** @@ -170,38 +164,38 @@ struct btr_node_description { void *context; }; -size_t btr_pool_size(struct btr_pool *btrp); +size_t btr_pool_size(const struct btr_pool *btrp); struct btr_pool *btr_pool_new(const char *name, size_t area_size); void btr_pool_free(struct btr_pool *btrp); -size_t btr_pool_get_buffer(struct btr_pool *btrp, char **result); -int btr_pool_get_buffers(struct btr_pool *btrp, struct iovec iov[2]); +size_t btr_pool_get_buffer(const struct btr_pool *btrp, char **result); +int btr_pool_get_buffers(const struct btr_pool *btrp, struct iovec iov[2]); void btr_add_output_pool(struct btr_pool *btrp, size_t size, struct btr_node *btrn); -size_t btr_pool_unused(struct btr_pool *btrp); +size_t btr_pool_unused(const struct btr_pool *btrp); void btr_copy(const void *src, size_t n, struct btr_pool *btrp, struct btr_node *btrn); - struct btr_node *btr_new_node(struct btr_node_description *bnd); void btr_remove_node(struct btr_node **btrnp); void btr_add_output(char *buf, size_t size, struct btr_node *btrn); void btr_add_output_dont_free(const char *buf, size_t size, struct btr_node *btrn); -size_t btr_get_input_queue_size(struct btr_node *btrn); -size_t btr_get_output_queue_size(struct btr_node *btrn); -bool btr_no_parent(struct btr_node *btrn); -size_t btr_next_buffer(struct btr_node *btrn, char **bufp); -size_t btr_next_buffer_omit(struct btr_node *btrn, size_t omit, char **bufp); +size_t btr_get_input_queue_size(const struct btr_node *btrn); +size_t btr_get_output_queue_size(const struct btr_node *btrn); +bool btr_no_parent(const struct btr_node *btrn); +size_t btr_next_buffer(const struct btr_node *btrn, char **bufp); +size_t btr_next_buffer_omit(const struct btr_node *btrn, size_t omit, + char **bufp); void btr_consume(struct btr_node *btrn, size_t numbytes); -int btr_exec_up(struct btr_node *btrn, const char *command, char **value_result); +int btr_exec_up(const struct btr_node *btrn, const char *command, char **value_result); void btr_splice_out_node(struct btr_node **btrnp); void btr_pushdown(struct btr_node *btrn); -void *btr_context(struct btr_node *btrn); +void *btr_context(const struct btr_node *btrn); void btr_merge(struct btr_node *btrn, size_t dest_size); -void btr_log_tree(struct btr_node *btrn, int ll); +void btr_log_tree(const struct btr_node *btrn, int ll); void btr_pushdown_one(struct btr_node *btrn); -bool btr_inplace_ok(struct btr_node *btrn); -int btr_node_status(struct btr_node *btrn, size_t min_iqs, +bool btr_inplace_ok(const struct btr_node *btrn); +int btr_node_status(const struct btr_node *btrn, size_t min_iqs, enum btr_node_type type); -void btr_get_node_start(struct btr_node *btrn, struct timeval *tv); +void btr_get_node_start(const struct btr_node *btrn, struct timeval *tv); struct btr_node *btr_search_node(const char *name, struct btr_node *root); void btr_drain(struct btr_node *btrn); -struct btr_node *btr_parent(struct btr_node *btrn); +struct btr_node *btr_parent(const struct btr_node *btrn);