From 5cf6f5f9fbef995c60a9a2e95bd049a0ee256404 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Thu, 31 Dec 2009 05:28:00 +0100 Subject: [PATCH] btr support for the prebuffer filter. --- error.h | 1 + prebuffer_filter.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/error.h b/error.h index 9d0283d1..661602e2 100644 --- a/error.h +++ b/error.h @@ -69,6 +69,7 @@ extern const char **para_errlist[]; #define PREBUFFER_FILTER_ERRORS \ PARA_ERROR(PREBUFFER_SYNTAX, "syntax error in prebuffer filter config"), \ + PARA_ERROR(PREBUFFER_SUCCESS, "prebuffering complete"), \ #define OSS_WRITE_ERRORS \ diff --git a/prebuffer_filter.c b/prebuffer_filter.c index 357e86c7..adfe9de9 100644 --- a/prebuffer_filter.c +++ b/prebuffer_filter.c @@ -75,12 +75,61 @@ out: return inbuf_len; } +static void prebuffer_pre_select(struct sched *s, struct task *t) +{ + struct filter_node *fn = container_of(t, struct filter_node, task); + struct btr_node *btrn = fn->btrn; + size_t iqs = btr_get_input_queue_size(btrn); + struct private_prebuffer_data *ppd = fn->private_data; + struct prebuffer_filter_args_info *conf = ppd->conf; + struct timeval diff; + + t->error = 0; + if (iqs == 0) + return; + if (ppd->barrier.tv_sec == 0) { + struct timeval tv; + PARA_INFO_LOG("prebuffer period %dms\n", + conf->duration_arg); + ms2tv(conf->duration_arg, &tv); + tv_add(&tv, now, &ppd->barrier); + } + if (tv_diff(&ppd->barrier, now, &diff) < 0) + goto min_delay; + if (tv_diff(&diff, &s->timeout, NULL) < 0) + s->timeout = diff; + return; +min_delay: + s->timeout.tv_sec = 0; + s->timeout.tv_usec = 1; +} + static void prebuffer_close(struct filter_node *fn) { free(fn->private_data); free(fn->buf); } +static void prebuffer_post_select(__a_unused struct sched *s, struct task *t) +{ + struct filter_node *fn = container_of(t, struct filter_node, task); + struct btr_node *btrn = fn->btrn; + size_t iqs = btr_get_input_queue_size(btrn); + struct private_prebuffer_data *ppd = fn->private_data; + struct prebuffer_filter_args_info *conf = ppd->conf; + + t->error = 0; + if (ppd->barrier.tv_sec == 0) + return; + if (tv_diff(now, &ppd->barrier, NULL) < 0) + return; + if (iqs < conf->size_arg) + return; + btr_splice_out_node(btrn); + prebuffer_close(fn); + t->error = -E_PREBUFFER_SUCCESS; +} + static int prebuffer_parse_config(int argc, char **argv, void **config) { struct prebuffer_filter_args_info *prebuffer_conf @@ -127,6 +176,8 @@ void prebuffer_filter_init(struct filter *f) f->close = prebuffer_close; f->convert = prebuffer_convert; f->parse_config = prebuffer_parse_config; + f->pre_select = prebuffer_pre_select; + f->post_select = prebuffer_post_select; f->help = (struct ggo_help) { .short_help = prebuffer_filter_args_info_help, .detailed_help = prebuffer_filter_args_info_detailed_help -- 2.39.2