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 | |
parent | 8552b9dc0cfcead7cfda847cfe63d4bb4d369e16 (diff) |
procqueue: Add some mechanism to queue 'processing items' on the frames
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
-rw-r--r-- | include/gapk/procqueue.h | 43 | ||||
-rw-r--r-- | src/Makefile.am | 1 | ||||
-rw-r--r-- | src/procqueue.c | 132 |
3 files changed, 176 insertions, 0 deletions
diff --git a/include/gapk/procqueue.h b/include/gapk/procqueue.h new file mode 100644 index 0000000..59f567e --- /dev/null +++ b/include/gapk/procqueue.h @@ -0,0 +1,43 @@ +/* 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/>. + */ + +#ifndef __GAPK_PROCQUEUE_H__ +#define __GAPK_PROCQUEUE_H__ + +#include <stdint.h> +#include <stdio.h> /* for FILE */ + +struct pq; + +struct pq_item { + int len_in; + int len_out; + void *state; + int (*proc)(void *state, uint8_t *out, const uint8_t *in); + void (*exit)(void *state); +}; + +/* Management */ +struct pq * pq_create(void); +void pq_destroy(struct pq *pq); +struct pq_item * pq_add_item(struct pq *pq); +int pq_prepare(struct pq *pq); +int pq_execute(struct pq *pq); + +#endif /* __GAPK_PROCQUEUE_H__ */ diff --git a/src/Makefile.am b/src/Makefile.am index dedb3f0..1a0531f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -4,5 +4,6 @@ AM_LDFLAGS=$(LIBOSMOCODEC_LIBS) ${OPENCORE_AMRNB_LIBS} ${LIBGSM_LIBS} bin_PROGRAMS = gapk gapk_SOURCES = main.c \ + procqueue.c \ formats.c fmt_amr.c fmt_gsm.c fmt_hr_ref.c fmt_racal.c \ codecs.c codec_pcm.c codec_hr.c codec_fr.c codec_efr.c 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; +} |