X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=vss.c;h=5b7ed320aaaa38885f208dda80ad51d690999b2c;hp=a16b006ffa0527d5d4f4301b1e13122457b1756a;hb=ba30bb8d0bb025c0dad80e5ff47352b4bc130423;hpb=245b44acd4f1c16395844683f6aff10699967dc0 diff --git a/vss.c b/vss.c index a16b006f..5b7ed320 100644 --- a/vss.c +++ b/vss.c @@ -11,11 +11,16 @@ * senders. */ -#include "server.h" #include /* mmap */ #include /* gettimeofday */ +#include +#include + +#include "para.h" +#include "afh.h" +#include "server.h" #include "server.cmdline.h" -#include "afs.h" +#include "afs_common.h" #include "vss.h" #include "send.h" #include "error.h" @@ -36,9 +41,8 @@ extern struct sender senders[]; static int audio_file; static char *map; -#if 1 - void mp3_init(struct audio_format_handler *); -#endif +/* The mp3 audio format handler does not need any libs. */ +void mp3_init(struct audio_format_handler *); #ifdef HAVE_OGGVORBIS void ogg_init(struct audio_format_handler *); @@ -48,35 +52,53 @@ static char *map; #endif /** - * the list of supported audio formats + * The list of supported audio formats. + * + * We always define the full array of audio formats even if some audio formats + * were not compiled in. This is because for each audio file the number of its + * audio format is stored in the databse. We don't want that numbers to become + * stale just because the user installed a new version of paraslash that + * supports a different set of audio formats. + * + * It can still be easily detected whether an audio format is compiled in by + * checking if the init function pointer is not \p NULL. */ static struct audio_format_handler afl[] = { -#if 1 { .name = "mp3", .init = mp3_init, }, -#endif -#ifdef HAVE_OGGVORBIS { .name = "ogg", +#ifdef HAVE_OGGVORBIS .init = ogg_init, - }, #endif -#ifdef HAVE_FAAD + }, { .name = "aac", +#ifdef HAVE_FAAD .init = aac_afh_init, - }, #endif + }, { .name = NULL, } }; -/** iterate over each supported audio format */ -#define FOR_EACH_AUDIO_FORMAT(i) for (i = 0; afl[i].name; i++) +static inline int next_audio_format(int format) +{ + for (;;) { + if (!afl[format].name) + return format; + format++; + if (afl[format].init) + return format; + } + +} +/** Iterate over each supported audio format. */ +#define FOR_EACH_AUDIO_FORMAT(i) for (i = 0; afl[i].name; i = next_audio_format(i)) /** @@ -125,14 +147,17 @@ unsigned int vss_paused(void) } /** - * get the name of the given audio format - * \param i the audio format number + * Get the name of the given audio format. + * + * \param i The audio format number. * * This returns a pointer to statically allocated memory so it * must not be freed by the caller. */ const char *audio_format_name(int i) { + //PARA_NOTICE_LOG("array size: %u¸ requested: %d\n", ARRAY_SIZE(afl), i); + assert(i < 0 || i < ARRAY_SIZE(afl) - 1); return i >= 0? afl[i].name : "(none)"; } @@ -153,7 +178,7 @@ void vss_init(void) PARA_DEBUG_LOG("supported audio formats: %s\n", SUPPORTED_AUDIO_FORMATS); - for (i = 0; afl[i].name; i++) { + FOR_EACH_AUDIO_FORMAT(i) { PARA_NOTICE_LOG("initializing %s handler\n", afl[i].name); afl[i].init(&afl[i]); @@ -208,7 +233,7 @@ int guess_audio_format(const char *name) return i; } } - return -1; + return -E_BAD_AUDIO_FILE_SUFFIX; } static int get_audio_format(int omit) @@ -224,6 +249,45 @@ static int get_audio_format(int omit) return -E_AUDIO_FORMAT; } +/** + * Call get_file_info() to obtain an afhi structure. + * + * \param path The full path of the audio file. + * \param data Pointer to the contents of the (mapped) file. + * \param size The file size in bytes. + * \param afhi Result pointer. + * + * \return The number of the audio format on success, \p -E_AUDIO_FORMAT if no + * compiled in audio format handler is able to handler the file. + * + * This function tries to find an audio format handler that can interpret the + * file given by \a data and \a size. + * + * It first tries to determine the audio format from the filename given by \a + * path. If this doesn't work, all other audio format handlers are tried until + * one is found that can handle the file. + */ +int compute_afhi(const char *path, char *data, size_t size, + struct audio_format_info *afhi) +{ + int ret, i, format = guess_audio_format(path); + + if (format >= 0) { + ret = afl[format].get_file_info(data, size, afhi); + if (ret >= 0) + return format; + } + FOR_EACH_AUDIO_FORMAT(i) { + if (i == format) /* we already tried this one to no avail */ + continue; + ret = afl[i].get_file_info(data, size, afhi); + if (ret >= 0) + return i; + PARA_WARNING_LOG("%s\n", PARA_STRERROR(-ret)); + } + return -E_AUDIO_FORMAT; +} + /* * upddate shared mem */ @@ -391,7 +455,7 @@ static void vss_eof(void) } /** - * get the header and of the current audio file + * Get the header of the current audio file. * * \param header_len the length of the header is stored here * @@ -400,7 +464,7 @@ static void vss_eof(void) * treamtment. * */ -char *vss_get_header(unsigned *header_len) +char *vss_get_header(size_t *header_len) { if (mmd->audio_format < 0 || !map || !mmd->afi.header_len) return NULL;