X-Git-Url: http://git.tuebingen.mpg.de/?a=blobdiff_plain;f=oggdec.c;fp=oggdec.c;h=0000000000000000000000000000000000000000;hb=dd0b1f12758ac877de6834b34f8c7f9291d4311d;hp=b4befd01179ec58d2b9dc32afecd45914d3a93a8;hpb=89a0e510df07bc7210ca9e73381763fdd183df75;p=paraslash.git diff --git a/oggdec.c b/oggdec.c deleted file mode 100644 index b4befd01..00000000 --- a/oggdec.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (C) 2005-2008 Andre Noll - * - * Licensed under the GPL v2. For licencing details see COPYING. - */ - -/** \file oggdec.c Paraslash's ogg vorbis decoder. */ - -#include "para.h" - -#include "oggdec_filter.cmdline.h" -#include "list.h" -#include "sched.h" -#include "filter.h" -#include "error.h" -#include "string.h" - -#include - -/** Determine byte sex. */ -#ifdef WORDS_BIGENDIAN -#define ENDIAN 1 -#else -#define ENDIAN 0 -#endif - -/** Data specific to the oggdec filter. */ -struct private_oggdec_data { - /** Describes an ogg vorbis file. */ - OggVorbis_File *vf; - /** The input buffer. */ - char *inbuf; - /** The length of \a inbuf. */ - size_t inbuf_len; - /** The number of bytes consumed from the input buffer. */ - size_t converted; -}; - -static size_t cb_read(void *buf, size_t size, size_t nmemb, void *datasource) -{ - struct filter_node *fn = datasource; - struct private_oggdec_data *pod = fn->private_data; - size_t ret, have = pod->inbuf_len - pod->converted; - char *p = pod->inbuf + pod->converted; - -// PARA_DEBUG_LOG("pod = %p\n", pod); -// PARA_DEBUG_LOG("vorbis requests %d bytes, have %d\n", size * nmemb, have); - if (pod->inbuf_len < size) { - if (*fn->fc->input_error) - return 0; - errno = EAGAIN; - return (size_t)-1; - } - ret = PARA_MIN(nmemb, have / size) * size; - memcpy(buf, p, ret); - pod->converted += ret; - return ret; -} - -/* - * Custom data seeking function. - * - * Since we want the data source to be treated as unseekable at all - * times, the provided seek callback always returns -1 (failure). - */ -static int cb_seek(__a_unused void *datasource, __a_unused ogg_int64_t offset, - __a_unused int whence) -{ - return -1; -} - -static int cb_close(__a_unused void *datasource) -{ - return 0; -} - -static const ov_callbacks ovc = { - .read_func = cb_read, - .seek_func = cb_seek, - .close_func = cb_close, - /* - * The tell function need not be provided if the data IO abstraction is - * not seekable - */ - .tell_func = NULL -}; - -static void ogg_open(struct filter_node *fn) -{ - struct private_oggdec_data *pod = para_calloc( - sizeof(struct private_oggdec_data)); - struct oggdec_filter_args_info *conf = fn->conf; - - fn->private_data = pod; - fn->bufsize = conf->bufsize_arg * 1024; - fn->buf = para_malloc(fn->bufsize); -} - -static void ogg_close(struct filter_node *fn) -{ - struct private_oggdec_data *pod = fn->private_data; - if (pod->vf) { - PARA_DEBUG_LOG("ov_clearing %p, pod = %p\n", pod->vf, pod); - ov_clear(pod->vf); - free(pod->vf); - pod->vf = NULL; - } else - PARA_DEBUG_LOG("nothing to close in fc %p, pod = %p\n", pod->vf, pod); - free(fn->buf); - fn->buf = NULL; - free(fn->private_data); - fn->private_data = NULL; -} - -static ssize_t ogg_convert(char *inbuffer, size_t len, struct filter_node *fn) -{ - ssize_t ret; - struct private_oggdec_data *pod = fn->private_data; - struct oggdec_filter_args_info *conf = fn->conf; - /* make the buffer known to the read callback cb_read() */ - pod->inbuf = inbuffer; - pod->inbuf_len = len; - pod->converted = 0; - - if (!pod->vf) { - int ib = 1024 * conf->initial_buffer_arg; /* initial buffer */ - if (len fc->input_error) { - PARA_DEBUG_LOG("initial input buffer %zd/%d, " - "waiting for more data\n", len, ib); - return 0; - } - pod->vf = para_malloc(sizeof(struct OggVorbis_File)); - PARA_NOTICE_LOG("input buffer: %zd, opening ov callbacks\n", len); - ret = ov_open_callbacks(fn, pod->vf, - NULL, /* no initial buffer */ - 0, /* no initial bytes */ - ovc); /* the ov_open_callbacks */ - if (ret == OV_EREAD) - return -E_OGGDEC_READ; - if (ret == OV_ENOTVORBIS) - return -E_OGGDEC_NOTVORBIS; - if (ret == OV_EVERSION) - return -E_OGGDEC_VERSION; - if (ret == OV_EBADHEADER) - return -E_OGGDEC_BADHEADER; - if (ret < 0) - return -E_OGGDEC_FAULT; - fn->fc->channels = ov_info(pod->vf, 0)->channels; - fn->fc->samplerate = ov_info(pod->vf, 0)->rate; - PARA_NOTICE_LOG("%d channels, %d Hz\n", fn->fc->channels, - fn->fc->samplerate); - } - while (fn->loaded < fn->bufsize) { - int length = fn->bufsize - fn->loaded; - long read_ret = ov_read(pod->vf, fn->buf + fn->loaded, length, - ENDIAN, 2 /* 16 bit */, 1 /* signed */, NULL); - if (read_ret == OV_HOLE || !read_ret) - return pod->converted; - if (read_ret < 0) - return -E_OGGDEC_BADLINK; - fn->loaded += read_ret; - } - return pod->converted; -} - -static int oggdec_parse_config(int argc, char **argv, void **config) -{ - int ret; - struct oggdec_filter_args_info *ogg_conf; - - ogg_conf = para_calloc(sizeof(*ogg_conf)); - ret = -E_OGGDEC_SYNTAX; - if (oggdec_cmdline_parser(argc, argv, ogg_conf)) - goto err; - ret = -ERRNO_TO_PARA_ERROR(EINVAL); - if (ogg_conf->bufsize_arg < 0) - goto err; - if (ogg_conf->bufsize_arg >= INT_MAX / 1024) - goto err; - if (ogg_conf->initial_buffer_arg < 0) - goto err; - if (ogg_conf->initial_buffer_arg >= INT_MAX / 1024) - goto err; - *config = ogg_conf; - return 1; -err: - free(ogg_conf); - return ret; -} - -/** - * The init function of the ogg vorbis decoder. - * - * \param f Its fields are filled in by the function. - */ -void oggdec_filter_init(struct filter *f) -{ - f->open = ogg_open; - f->close = ogg_close; - f->convert = ogg_convert; - f->print_help = oggdec_cmdline_parser_print_help; - f->parse_config = oggdec_parse_config; -}