X-Git-Url: http://git.tuebingen.mpg.de/?a=blobdiff_plain;ds=sidebyside;f=aacdec_filter.c;h=d85f33746d76c0a10e64303b15658c53fc8b4eda;hb=198d80de3be06f39f316f516fba655392d7b885a;hp=9791175ecd72d6dcd22ee719f90d1e59481668b3;hpb=2557001e2e0a6c078c7907a021362e29e534822a;p=paraslash.git diff --git a/aacdec_filter.c b/aacdec_filter.c index 9791175e..d85f3374 100644 --- a/aacdec_filter.c +++ b/aacdec_filter.c @@ -11,8 +11,10 @@ /** \file aacdec_filter.c paraslash's aac (m4a) decoder. */ #include +#include #include "para.h" +#include "portable_io.h" #include "list.h" #include "sched.h" #include "ggo.h" @@ -20,7 +22,6 @@ #include "filter.h" #include "error.h" #include "string.h" -#include "aac.h" /** Give up decoding after that many errors. */ #define MAX_ERRORS 20 @@ -54,6 +55,122 @@ struct private_aacdec_data { unsigned int sample_rate; }; +/* + * Get a new libfaad decoder handle. + * + * \return The handle returned by NeAACDecOpen(). + */ +static NeAACDecHandle aac_open(void) +{ + NeAACDecHandle h = NeAACDecOpen(); + NeAACDecConfigurationPtr c = NeAACDecGetCurrentConfiguration(h); + + c->defObjectType = LC; + c->outputFormat = FAAD_FMT_16BIT; + c->downMatrix = 0; + NeAACDecSetConfiguration(h, c); + return h; +} + +static unsigned long aac_read_decoder_length(char *buf, int *description_len) +{ + uint8_t b; + uint8_t numBytes = 0; + unsigned long length = 0; + + do { + b = buf[numBytes]; + numBytes++; + length = (length << 7) | (b & 0x7F); + } while + ((b & 0x80) && numBytes < 4); + *description_len = numBytes; + return length; +} + +/* + * Search for the position and the length of the decoder configuration. + * + * \param buf Buffer to seach. + * \param buflen Length of \a buf. + * \param skip Upon succesful return, this contains the offset in \a buf where + * the decoder config starts. + * \param decoder_length Result pointer that is filled in with the length of + * the decoder configuration on success. + * + * \return Standard. + */ +static int aac_find_esds(char *buf, size_t buflen, size_t *skip, + unsigned long *decoder_length) +{ + size_t i; + + for (i = 0; i + 4 < buflen; i++) { + char *p = buf + i; + int description_len; + + if (p[0] != 'e' || p[1] != 's' || p[2] != 'd' || p[3] != 's') + continue; + i += 8; + p = buf + i; + PARA_INFO_LOG("found esds@%zu, next: %x\n", i, *p); + if (*p == 3) + i += 8; + else + i += 6; + p = buf + i; + PARA_INFO_LOG("next: %x\n", *p); + if (*p != 4) + continue; + i += 18; + p = buf + i; + PARA_INFO_LOG("next: %x\n", *p); + if (*p != 5) + continue; + i++; + p = buf + i; + *decoder_length = aac_read_decoder_length(p, &description_len); + PARA_INFO_LOG("decoder length: %lu\n", *decoder_length); + i += description_len; + *skip = i; + return 1; + } + return -E_ESDS; +} + +/* + * Search for the first entry in the stco table. + * + * \param buf Buffer to seach. + * \param buflen Length of \a buf. + * \param skip Upon succesful return, this contains the number + * of bytes to skip from the input buffer. + * + * \return The position of the first entry in the table on success, + * -E_STCO on errors. + */ +static ssize_t aac_find_entry_point(char *buf, size_t buflen, size_t *skip) +{ + ssize_t ret; + size_t i; + + for (i = 0; i + 20 < buflen; i++) { + char *p = buf + i; + + if (p[0] != 's' || p[1] != 't' || p[2] != 'c' || p[3] != 'o') + continue; + PARA_INFO_LOG("found stco@%zu\n", i); + i += 12; + ret = read_u32_be(buf + i); /* first offset */ + i += 4; + PARA_INFO_LOG("entry point: %zd\n", ret); + *skip = i; + return ret; + } + PARA_WARNING_LOG("stco not found, buflen: %zu\n", buflen); + return -E_STCO; +} + static int aacdec_execute(struct btr_node *btrn, const char *cmd, char **result) { struct filter_node *fn = btr_context(btrn); @@ -127,7 +244,7 @@ next_buffer: } padd->sample_rate = rate; padd->channels = channels; - PARA_INFO_LOG("rate: %u, channels: %d\n", + PARA_INFO_LOG("rate: %u, channels: %u\n", padd->sample_rate, padd->channels); padd->initialized = 1; } @@ -150,9 +267,6 @@ next_buffer: if (padd->consumed_total < padd->entry) consumed = padd->entry - padd->consumed_total; } - for (; consumed < len; consumed++) - if ((inbuf[consumed] & 0xfe) == 0x20) - break; if (consumed >= len) goto success; p = inbuf + consumed; @@ -165,13 +279,8 @@ next_buffer: ret = -E_AAC_DECODE; if (padd->error_count++ > MAX_ERRORS) goto err; - /* Suppress non-fatal bitstream error message at BOF/EOF */ - if (len < fn->min_iqs || padd->consumed_total == 0) { - consumed = len; - goto success; - } PARA_ERROR_LOG("%s\n", NeAACDecGetErrorMessage(err)); - PARA_ERROR_LOG("consumed: %zu + %zd + %lu\n", + PARA_ERROR_LOG("consumed: %zu + %zu + %lu\n", padd->consumed_total, consumed, padd->frame_info.bytesconsumed); if (consumed < len)