diff options
author | Sylvain Munaut <tnt@246tNt.com> | 2010-11-11 20:40:29 +0100 |
---|---|---|
committer | Sylvain Munaut <tnt@246tNt.com> | 2010-11-11 20:45:24 +0100 |
commit | 3c0a4fba8af4bee5c4f05f00f3da33c6a006d928 (patch) | |
tree | b85bdd1d738897196ce598d8f71d9b68aa47c20a /src/procqueue.c | |
parent | 8552b9dc0cfcead7cfda847cfe63d4bb4d369e16 (diff) |
procqueue: Add some mechanism to queue 'processing items' on the frames
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
Diffstat (limited to 'src/procqueue.c')
-rw-r--r-- | src/procqueue.c | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/src/procqueue.c b/src/procqueue.c new file mode 100644 index 0000000..1b2626e --- /dev/null +++ b/src/procqueue.c @@ -0,0 +1,132 @@ +/* Processing Queue Management */ + +/* + * This file is part of gapk (GSM Audio Pocket Knife). + * + * gapk 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 3 of the License, or + * (at your option) any later version. + * + * gapk 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 gapk. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <errno.h> +#include <stdint.h> +#include <stdlib.h> + +#include <gapk/procqueue.h> + + +#define MAX_PQ_ITEMS 8 + +struct pq { + int n_items; + struct pq_item* items[MAX_PQ_ITEMS]; + void * buffers[MAX_PQ_ITEMS+1]; +}; + + +struct pq * +pq_create(void) +{ + return (struct pq *) calloc(1, sizeof(struct pq)); +} + +void +pq_destroy(struct pq *pq) +{ + int i; + + if (!pq) + return; + + for (i=0; i<pq->n_items; i++) { + if (!pq->items[i]) + continue; + if (pq->items[i]->exit) + pq->items[i]->exit(pq->items[i]->state); + free(pq->items[i]); + } + + for (i=0; i<pq->n_items-1; i++) + free(pq->buffers[i]); /* free is NULL safe */ + + free(pq); +} + +struct pq_item * +pq_add_item(struct pq *pq) +{ + struct pq_item *item; + + if (pq->n_items == MAX_PQ_ITEMS) + return NULL; + + item = calloc(1, sizeof(struct pq_item)); + if (!item) + return NULL; + + pq->items[pq->n_items++] = item; + + return item; +} + +int +pq_prepare(struct pq *pq) +{ + int i; + unsigned int len_prev; + + len_prev = 0; + + for (i=0; i<pq->n_items; i++) { + struct pq_item *item = pq->items[i]; + + if (item->len_in != len_prev) + return -EINVAL; + + if (i < (pq->n_items-1)) { + pq->buffers[i] = malloc(item->len_out); + if (!pq->buffers[i]) + return -ENOMEM; + } else{ + if (item->len_out) + return -EINVAL; + } + + len_prev = item->len_out; + } + + return 0; +} + +int +pq_execute(struct pq *pq) +{ + int i; + void *buf_prev, *buf; + + buf_prev = NULL; + + for (i=0; i<pq->n_items; i++) { + int rv; + struct pq_item *item = pq->items[i]; + + buf = i < (pq->n_items-1) ? pq->buffers[i] : NULL; + + rv = item->proc(item->state, buf, buf_prev); + if (rv) + return rv; + + buf_prev = buf; + } + + return 0; +} |