From 27ce02fa9146601ab4a0210cc85c2d5f50b833f4 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 26 Aug 2008 08:27:03 +0200 Subject: clean up CPP includes Include only headers which are really required. This speeds up compilation and helps detect cross-layer accesses. [ew: minor fixups to not break on new core] --- src/inputPlugins/aac_plugin.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src/inputPlugins/aac_plugin.c') diff --git a/src/inputPlugins/aac_plugin.c b/src/inputPlugins/aac_plugin.c index 98329a4b3..dd255903a 100644 --- a/src/inputPlugins/aac_plugin.c +++ b/src/inputPlugins/aac_plugin.c @@ -23,11 +23,7 @@ #define AAC_MAX_CHANNELS 6 #include "../utils.h" -#include "../audio.h" #include "../log.h" -#include "../inputStream.h" -#include "../outputBuffer.h" -#include "../os_compat.h" #include -- cgit v1.2.3 From 360c188c9d0460aff44f9c78bec25fcbab1cbead Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 26 Aug 2008 08:27:06 +0200 Subject: aac/mp4: removed local variable "eof" because it is unused "break" is so much easier than "eof=1; continue;", when "!eof" is the loop condition. --- src/inputPlugins/aac_plugin.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'src/inputPlugins/aac_plugin.c') diff --git a/src/inputPlugins/aac_plugin.c b/src/inputPlugins/aac_plugin.c index dd255903a..7cff31d40 100644 --- a/src/inputPlugins/aac_plugin.c +++ b/src/inputPlugins/aac_plugin.c @@ -288,7 +288,6 @@ static int aac_decode(char *path) long bread; uint32_t sampleRate; unsigned char channels; - int eof = 0; unsigned int sampleCount; char *sampleBuffer; size_t sampleBufferLen; @@ -342,13 +341,12 @@ static int aac_decode(char *path) advanceAacBuffer(&b, bread); - while (!eof) { + while (1) { fillAacBuffer(&b); - if (b.bytesIntoBuffer == 0) { - eof = 1; + if (b.bytesIntoBuffer == 0) break; - } + #ifdef HAVE_FAAD_BUFLEN_FUNCS sampleBuffer = faacDecDecode(decoder, &frameInfo, b.buffer, b.bytesIntoBuffer); @@ -360,7 +358,6 @@ static int aac_decode(char *path) ERROR("error decoding AAC file: %s\n", path); ERROR("faad2 error: %s\n", faacDecGetErrorMessage(frameInfo.error)); - eof = 1; break; } #ifdef HAVE_FAACDECFRAMEINFO_SAMPLERATE @@ -395,9 +392,10 @@ static int aac_decode(char *path) */ dc_action_seek_fail(DC_SEEK_ERROR); break; - default: eof = 1; + default: goto out; } } +out: faacDecClose(decoder); if (b.buffer) -- cgit v1.2.3 From 5cabe3399b7e1b47ad62b57815987742b424c5dc Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 26 Aug 2008 08:27:10 +0200 Subject: eliminate unused variables in the AAC decoder --- src/inputPlugins/aac_plugin.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'src/inputPlugins/aac_plugin.c') diff --git a/src/inputPlugins/aac_plugin.c b/src/inputPlugins/aac_plugin.c index 7cff31d40..400b43f28 100644 --- a/src/inputPlugins/aac_plugin.c +++ b/src/inputPlugins/aac_plugin.c @@ -93,9 +93,8 @@ static int adtsSampleRates[] = static int adtsParse(AacBuffer * b, float *length) { int frames, frameLength; - int tFrameLength = 0; int sampleRate = 0; - float framesPerSec, bytesPerFrame; + float framesPerSec; /* Read all frames to ensure correct time and bitrate */ for (frames = 0;; frames++) { @@ -118,8 +117,6 @@ static int adtsParse(AacBuffer * b, float *length) << 11) | (((unsigned int)b->buffer[4]) << 3) | (b->buffer[5] >> 5); - tFrameLength += frameLength; - if (frameLength > b->bytesIntoBuffer) break; @@ -129,10 +126,6 @@ static int adtsParse(AacBuffer * b, float *length) } framesPerSec = (float)sampleRate / 1024.0; - if (frames != 0) { - bytesPerFrame = (float)tFrameLength / (float)(frames * 1000); - } else - bytesPerFrame = 0; if (framesPerSec != 0) *length = (float)frames / framesPerSec; @@ -227,7 +220,6 @@ static float getAacFloatTotalTime(char *file) { AacBuffer b; float length; - size_t fileread, tagsize; faacDecHandle decoder; faacDecConfigurationPtr config; uint32_t sampleRate; @@ -238,7 +230,7 @@ static float getAacFloatTotalTime(char *file) if (openInputStream(&inStream, file) < 0) return -1; - initAacBuffer(&inStream, &b, &length, &fileread, &tagsize); + initAacBuffer(&inStream, &b, &length, NULL, NULL); if (length < 0) { decoder = faacDecOpen(); -- cgit v1.2.3 From c917b19a2afb6916daf5aa8ae73697c2528b2cf3 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 26 Aug 2008 08:27:10 +0200 Subject: aac: removed unused initAacBuffer() parameters Since we eliminated the parameters retFileread and retTagsize in all callers, we can now safely remove it from the function prototype. --- src/inputPlugins/aac_plugin.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'src/inputPlugins/aac_plugin.c') diff --git a/src/inputPlugins/aac_plugin.c b/src/inputPlugins/aac_plugin.c index 400b43f28..f398a822d 100644 --- a/src/inputPlugins/aac_plugin.c +++ b/src/inputPlugins/aac_plugin.c @@ -132,8 +132,7 @@ static int adtsParse(AacBuffer * b, float *length) return 1; } -static void initAacBuffer(InputStream * inStream, AacBuffer * b, float *length, - size_t * retFileread, size_t * retTagsize) +static void initAacBuffer(InputStream * inStream, AacBuffer * b, float *length) { size_t fileread; size_t bread; @@ -170,11 +169,6 @@ static void initAacBuffer(InputStream * inStream, AacBuffer * b, float *length, fillAacBuffer(b); } - if (retFileread) - *retFileread = fileread; - if (retTagsize) - *retTagsize = tagsize; - if (length == NULL) return; @@ -230,7 +224,7 @@ static float getAacFloatTotalTime(char *file) if (openInputStream(&inStream, file) < 0) return -1; - initAacBuffer(&inStream, &b, &length, NULL, NULL); + initAacBuffer(&inStream, &b, &length); if (length < 0) { decoder = faacDecOpen(); @@ -296,7 +290,7 @@ static int aac_decode(char *path) if (openInputStream(&inStream, path) < 0) return -1; - initAacBuffer(&inStream, &b, NULL, NULL, NULL); + initAacBuffer(&inStream, &b, NULL); decoder = faacDecOpen(); -- cgit v1.2.3 From d9ae11d885acdca92ce0f17cc455e891e88a0f77 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 26 Aug 2008 08:27:10 +0200 Subject: aac: use size_t --- src/inputPlugins/aac_plugin.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/inputPlugins/aac_plugin.c') diff --git a/src/inputPlugins/aac_plugin.c b/src/inputPlugins/aac_plugin.c index f398a822d..1487a6c2f 100644 --- a/src/inputPlugins/aac_plugin.c +++ b/src/inputPlugins/aac_plugin.c @@ -30,9 +30,9 @@ /* all code here is either based on or copied from FAAD2's frontend code */ typedef struct { InputStream *inStream; - long bytesIntoBuffer; - long bytesConsumed; - long fileOffset; + size_t bytesIntoBuffer; + size_t bytesConsumed; + off_t fileOffset; unsigned char *buffer; int atEof; } AacBuffer; @@ -40,7 +40,7 @@ typedef struct { static void fillAacBuffer(AacBuffer * b) { if (b->bytesConsumed > 0) { - int bread; + size_t bread; if (b->bytesIntoBuffer) { memmove((void *)b->buffer, (void *)(b->buffer + @@ -78,7 +78,7 @@ static void fillAacBuffer(AacBuffer * b) } } -static void advanceAacBuffer(AacBuffer * b, int bytes) +static void advanceAacBuffer(AacBuffer * b, size_t bytes) { b->fileOffset += bytes; b->bytesConsumed = bytes; @@ -92,7 +92,7 @@ static int adtsSampleRates[] = static int adtsParse(AacBuffer * b, float *length) { - int frames, frameLength; + unsigned int frames, frameLength; int sampleRate = 0; float framesPerSec; -- cgit v1.2.3 From 15e76670b40a223ee58c5aae26b2d9540a1b87b8 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 26 Aug 2008 08:27:10 +0200 Subject: aac: make adtsParse() void adtsParse() always returns 1, and its caller does not use the return value. --- src/inputPlugins/aac_plugin.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/inputPlugins/aac_plugin.c') diff --git a/src/inputPlugins/aac_plugin.c b/src/inputPlugins/aac_plugin.c index 1487a6c2f..353fafd40 100644 --- a/src/inputPlugins/aac_plugin.c +++ b/src/inputPlugins/aac_plugin.c @@ -90,7 +90,7 @@ static int adtsSampleRates[] = 16000, 12000, 11025, 8000, 7350, 0, 0, 0 }; -static int adtsParse(AacBuffer * b, float *length) +static void adtsParse(AacBuffer * b, float *length) { unsigned int frames, frameLength; int sampleRate = 0; @@ -128,8 +128,6 @@ static int adtsParse(AacBuffer * b, float *length) framesPerSec = (float)sampleRate / 1024.0; if (framesPerSec != 0) *length = (float)frames / framesPerSec; - - return 1; } static void initAacBuffer(InputStream * inStream, AacBuffer * b, float *length) -- cgit v1.2.3 From d1015501dffd383b9ab9428303999615fde0fc66 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 26 Aug 2008 08:27:10 +0200 Subject: aac: simplified fillAacBuffer() Return instead of putting all the code into a if-closure. That saves one level of indentation. --- src/inputPlugins/aac_plugin.c | 58 +++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 33 deletions(-) (limited to 'src/inputPlugins/aac_plugin.c') diff --git a/src/inputPlugins/aac_plugin.c b/src/inputPlugins/aac_plugin.c index 353fafd40..de611b1ce 100644 --- a/src/inputPlugins/aac_plugin.c +++ b/src/inputPlugins/aac_plugin.c @@ -39,43 +39,35 @@ typedef struct { static void fillAacBuffer(AacBuffer * b) { - if (b->bytesConsumed > 0) { - size_t bread; - - if (b->bytesIntoBuffer) { - memmove((void *)b->buffer, (void *)(b->buffer + - b->bytesConsumed), - b->bytesIntoBuffer); - } + size_t bread; - if (!b->atEof) { - bread = readFromInputStream(b->inStream, - (void *)(b->buffer + - b-> - bytesIntoBuffer), - 1, b->bytesConsumed); - if (bread != b->bytesConsumed) - b->atEof = 1; - b->bytesIntoBuffer += bread; - } + if (b->bytesConsumed == 0) + return; - b->bytesConsumed = 0; + if (b->bytesIntoBuffer) { + memmove((void *)b->buffer, (void *)(b->buffer + + b->bytesConsumed), + b->bytesIntoBuffer); + } - if (b->bytesIntoBuffer > 3) { - if (memcmp(b->buffer, "TAG", 3) == 0) - b->bytesIntoBuffer = 0; - } - if (b->bytesIntoBuffer > 11) { - if (memcmp(b->buffer, "LYRICSBEGIN", 11) == 0) { - b->bytesIntoBuffer = 0; - } - } - if (b->bytesIntoBuffer > 8) { - if (memcmp(b->buffer, "APETAGEX", 8) == 0) { - b->bytesIntoBuffer = 0; - } - } + if (!b->atEof) { + bread = readFromInputStream(b->inStream, + (void *)(b->buffer + + b-> + bytesIntoBuffer), + 1, b->bytesConsumed); + if (bread != b->bytesConsumed) + b->atEof = 1; + b->bytesIntoBuffer += bread; } + + b->bytesConsumed = 0; + + if ((b->bytesIntoBuffer > 3 && memcmp(b->buffer, "TAG", 3) == 0) || + (b->bytesIntoBuffer > 11 && + memcmp(b->buffer, "LYRICSBEGIN", 11) == 0) || + (b->bytesIntoBuffer > 8 && memcmp(b->buffer, "APETAGEX", 8) == 0)) + b->bytesIntoBuffer = 0; } static void advanceAacBuffer(AacBuffer * b, size_t bytes) -- cgit v1.2.3 From 7b47338ca996f8fda1bd0f8c743555a25409c200 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 26 Aug 2008 08:27:10 +0200 Subject: aac: don't depend on consumed data in fillAacBuffer() Fill the AacBuffer even when nothing has been consumed yet. The function should not check for consumed data, but for free space at the end of the buffer. --- src/inputPlugins/aac_plugin.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'src/inputPlugins/aac_plugin.c') diff --git a/src/inputPlugins/aac_plugin.c b/src/inputPlugins/aac_plugin.c index de611b1ce..15a7da0ef 100644 --- a/src/inputPlugins/aac_plugin.c +++ b/src/inputPlugins/aac_plugin.c @@ -41,28 +41,32 @@ static void fillAacBuffer(AacBuffer * b) { size_t bread; - if (b->bytesConsumed == 0) + if (b->bytesIntoBuffer >= FAAD_MIN_STREAMSIZE * AAC_MAX_CHANNELS) + /* buffer already full */ return; - if (b->bytesIntoBuffer) { + if (b->bytesConsumed > 0 && b->bytesIntoBuffer > 0) { memmove((void *)b->buffer, (void *)(b->buffer + b->bytesConsumed), b->bytesIntoBuffer); } + b->bytesConsumed = 0; + if (!b->atEof) { + size_t rest = FAAD_MIN_STREAMSIZE * AAC_MAX_CHANNELS - + b->bytesIntoBuffer; + bread = readFromInputStream(b->inStream, (void *)(b->buffer + b-> bytesIntoBuffer), - 1, b->bytesConsumed); - if (bread != b->bytesConsumed) + 1, rest); + if (bread != rest) b->atEof = 1; b->bytesIntoBuffer += bread; } - b->bytesConsumed = 0; - if ((b->bytesIntoBuffer > 3 && memcmp(b->buffer, "TAG", 3) == 0) || (b->bytesIntoBuffer > 11 && memcmp(b->buffer, "LYRICSBEGIN", 11) == 0) || -- cgit v1.2.3 From d39395f3cdd937fc38d794de8706c9bc4cb96bd2 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 26 Aug 2008 08:27:10 +0200 Subject: aac: use inputStreamAtEOF() When checking for EOF, we should not check whether the read request has been fully satisified. The InputStream API does not guarantee that readFromInputStream() always fills the whole buffer, if EOF is not reached. Since there is the function inputStreamAtEOF() dedicated for this purpose, we should use it for EOF checking after readFromInputStream()==0. --- src/inputPlugins/aac_plugin.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'src/inputPlugins/aac_plugin.c') diff --git a/src/inputPlugins/aac_plugin.c b/src/inputPlugins/aac_plugin.c index 15a7da0ef..b6e7e3fe4 100644 --- a/src/inputPlugins/aac_plugin.c +++ b/src/inputPlugins/aac_plugin.c @@ -62,7 +62,7 @@ static void fillAacBuffer(AacBuffer * b) b-> bytesIntoBuffer), 1, rest); - if (bread != rest) + if (bread == 0 && inputStreamAtEOF(b->inStream)) b->atEof = 1; b->bytesIntoBuffer += bread; } @@ -150,7 +150,7 @@ static void initAacBuffer(InputStream * inStream, AacBuffer * b, float *length) b->bytesConsumed = 0; b->fileOffset = 0; - if (bread != FAAD_MIN_STREAMSIZE * AAC_MAX_CHANNELS) + if (bread == 0 && inputStreamAtEOF(inStream)) b->atEof = 1; tagsize = 0; @@ -173,10 +173,9 @@ static void initAacBuffer(InputStream * inStream, AacBuffer * b, float *length) bread = readFromInputStream(b->inStream, b->buffer, 1, FAAD_MIN_STREAMSIZE * AAC_MAX_CHANNELS); - if (bread != FAAD_MIN_STREAMSIZE * AAC_MAX_CHANNELS) + if (bread == 0 && inputStreamAtEOF(inStream)) b->atEof = 1; - else - b->atEof = 0; + b->bytesIntoBuffer = bread; b->bytesConsumed = 0; b->fileOffset = tagsize; -- cgit v1.2.3 From c7e1a79a6b10f6714db31bb65d17db479b4a69d2 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 26 Aug 2008 08:27:11 +0200 Subject: aac: moved code to aac_buffer_shift() Shifting from the buffer queue is a common operation, and should be provided as a separate function. Move code to aac_buffer_shift() and add a bunch of assertions. --- src/inputPlugins/aac_plugin.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'src/inputPlugins/aac_plugin.c') diff --git a/src/inputPlugins/aac_plugin.c b/src/inputPlugins/aac_plugin.c index b6e7e3fe4..3d6c40fb6 100644 --- a/src/inputPlugins/aac_plugin.c +++ b/src/inputPlugins/aac_plugin.c @@ -37,6 +37,19 @@ typedef struct { int atEof; } AacBuffer; +static void aac_buffer_shift(AacBuffer * b, size_t length) +{ + assert(length >= b->bytesConsumed); + assert(length <= b->bytesConsumed + b->bytesIntoBuffer); + + memmove(b->buffer, b->buffer + length, + b->bytesConsumed + b->bytesIntoBuffer - length); + + length -= b->bytesConsumed; + b->bytesConsumed = 0; + b->bytesIntoBuffer -= length; +} + static void fillAacBuffer(AacBuffer * b) { size_t bread; @@ -45,13 +58,7 @@ static void fillAacBuffer(AacBuffer * b) /* buffer already full */ return; - if (b->bytesConsumed > 0 && b->bytesIntoBuffer > 0) { - memmove((void *)b->buffer, (void *)(b->buffer + - b->bytesConsumed), - b->bytesIntoBuffer); - } - - b->bytesConsumed = 0; + aac_buffer_shift(b, b->bytesConsumed); if (!b->atEof) { size_t rest = FAAD_MIN_STREAMSIZE * AAC_MAX_CHANNELS - -- cgit v1.2.3 From 5afa07de0569e2993532b77581dd03ae04653591 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 26 Aug 2008 08:27:11 +0200 Subject: aac: moved code to adts_check_frame() adts_check_frame() checks whether the buffer head is an AAC frame, and returns the frame length. --- src/inputPlugins/aac_plugin.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) (limited to 'src/inputPlugins/aac_plugin.c') diff --git a/src/inputPlugins/aac_plugin.c b/src/inputPlugins/aac_plugin.c index 3d6c40fb6..82ebecafc 100644 --- a/src/inputPlugins/aac_plugin.c +++ b/src/inputPlugins/aac_plugin.c @@ -93,6 +93,24 @@ static int adtsSampleRates[] = 16000, 12000, 11025, 8000, 7350, 0, 0, 0 }; +/** + * Check whether the buffer head is an AAC frame, and return the frame + * length. Returns 0 if it is not a frame. + */ +static size_t adts_check_frame(AacBuffer * b) +{ + if (b->bytesIntoBuffer <= 7) + return 0; + + /* check syncword */ + if (!((b->buffer[0] == 0xFF) && ((b->buffer[1] & 0xF6) == 0xF0))) + return 0; + + return (((unsigned int)b->buffer[3] & 0x3) << 11) | + (((unsigned int)b->buffer[4]) << 3) | + (b->buffer[5] >> 5); +} + static void adtsParse(AacBuffer * b, float *length) { unsigned int frames, frameLength; @@ -103,23 +121,14 @@ static void adtsParse(AacBuffer * b, float *length) for (frames = 0;; frames++) { fillAacBuffer(b); - if (b->bytesIntoBuffer > 7) { - /* check syncword */ - if (!((b->buffer[0] == 0xFF) && - ((b->buffer[1] & 0xF6) == 0xF0))) { - break; - } - + frameLength = adts_check_frame(b); + if (frameLength > 0) { if (frames == 0) { sampleRate = adtsSampleRates[(b-> buffer[2] & 0x3c) >> 2]; } - frameLength = ((((unsigned int)b->buffer[3] & 0x3)) - << 11) | (((unsigned int)b->buffer[4]) - << 3) | (b->buffer[5] >> 5); - if (frameLength > b->bytesIntoBuffer) break; -- cgit v1.2.3 From 0db89f3e2cc7375273e32f77628ca0583d7a7026 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 26 Aug 2008 08:27:11 +0200 Subject: find AAC frames Find AAC frames in the input and skip invalid data. This prepares AAC streaming. --- src/inputPlugins/aac_plugin.c | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) (limited to 'src/inputPlugins/aac_plugin.c') diff --git a/src/inputPlugins/aac_plugin.c b/src/inputPlugins/aac_plugin.c index 82ebecafc..f6f731332 100644 --- a/src/inputPlugins/aac_plugin.c +++ b/src/inputPlugins/aac_plugin.c @@ -111,6 +111,40 @@ static size_t adts_check_frame(AacBuffer * b) (b->buffer[5] >> 5); } +/** + * Find the next AAC frame in the buffer. Returns 0 if no frame is + * found or if not enough data is available. + */ +static size_t adts_find_frame(AacBuffer * b) +{ + const unsigned char *p; + size_t frame_length; + + while ((p = memchr(b->buffer, 0xff, b->bytesIntoBuffer)) != NULL) { + /* discard data before 0xff */ + if (p > b->buffer) + aac_buffer_shift(b, p - b->buffer); + + if (b->bytesIntoBuffer <= 7) + /* not enough data yet */ + return 0; + + /* is it a frame? */ + frame_length = adts_check_frame(b); + if (frame_length > 0) + /* yes, it is */ + return frame_length; + + /* it's just some random 0xff byte; discard and and + continue searching */ + aac_buffer_shift(b, 1); + } + + /* nothing at all; discard the whole buffer */ + aac_buffer_shift(b, b->bytesIntoBuffer); + return 0; +} + static void adtsParse(AacBuffer * b, float *length) { unsigned int frames, frameLength; @@ -121,7 +155,7 @@ static void adtsParse(AacBuffer * b, float *length) for (frames = 0;; frames++) { fillAacBuffer(b); - frameLength = adts_check_frame(b); + frameLength = adts_find_frame(b); if (frameLength > 0) { if (frames == 0) { sampleRate = adtsSampleRates[(b-> -- cgit v1.2.3 From 20755291951a9cb9e21afba763a80015229e7655 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 26 Aug 2008 08:27:11 +0200 Subject: aac: use fillAacBuffer() instead of manual reading Eliminate some duplicated code by using fillAacBuffer(). --- src/inputPlugins/aac_plugin.c | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) (limited to 'src/inputPlugins/aac_plugin.c') diff --git a/src/inputPlugins/aac_plugin.c b/src/inputPlugins/aac_plugin.c index f6f731332..e9eccf31a 100644 --- a/src/inputPlugins/aac_plugin.c +++ b/src/inputPlugins/aac_plugin.c @@ -179,7 +179,6 @@ static void adtsParse(AacBuffer * b, float *length) static void initAacBuffer(InputStream * inStream, AacBuffer * b, float *length) { size_t fileread; - size_t bread; size_t tagsize; if (length) @@ -194,14 +193,7 @@ static void initAacBuffer(InputStream * inStream, AacBuffer * b, float *length) b->buffer = xmalloc(FAAD_MIN_STREAMSIZE * AAC_MAX_CHANNELS); memset(b->buffer, 0, FAAD_MIN_STREAMSIZE * AAC_MAX_CHANNELS); - bread = readFromInputStream(inStream, b->buffer, 1, - FAAD_MIN_STREAMSIZE * AAC_MAX_CHANNELS); - b->bytesIntoBuffer = bread; - b->bytesConsumed = 0; - b->fileOffset = 0; - - if (bread == 0 && inputStreamAtEOF(inStream)) - b->atEof = 1; + fillAacBuffer(b); tagsize = 0; if (!memcmp(b->buffer, "ID3", 3)) { @@ -220,15 +212,11 @@ static void initAacBuffer(InputStream * inStream, AacBuffer * b, float *length) adtsParse(b, length); seekInputStream(b->inStream, tagsize, SEEK_SET); - bread = readFromInputStream(b->inStream, b->buffer, 1, - FAAD_MIN_STREAMSIZE * - AAC_MAX_CHANNELS); - if (bread == 0 && inputStreamAtEOF(inStream)) - b->atEof = 1; - - b->bytesIntoBuffer = bread; + b->bytesIntoBuffer = 0; b->bytesConsumed = 0; b->fileOffset = tagsize; + + fillAacBuffer(b); } else if (memcmp(b->buffer, "ADIF", 4) == 0) { int bitRate; int skipSize = (b->buffer[4] & 0x80) ? 9 : 0; -- cgit v1.2.3 From ca5eaffc16b9ace0ea7af519ef949bf014f42120 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 26 Aug 2008 08:27:11 +0200 Subject: aac: check buffer lengths The AAC plugin sometimes does not check the length of available data when checking for magic prefixes. Add length checks. --- src/inputPlugins/aac_plugin.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/inputPlugins/aac_plugin.c') diff --git a/src/inputPlugins/aac_plugin.c b/src/inputPlugins/aac_plugin.c index e9eccf31a..faddb78c6 100644 --- a/src/inputPlugins/aac_plugin.c +++ b/src/inputPlugins/aac_plugin.c @@ -196,7 +196,7 @@ static void initAacBuffer(InputStream * inStream, AacBuffer * b, float *length) fillAacBuffer(b); tagsize = 0; - if (!memcmp(b->buffer, "ID3", 3)) { + if (b->bytesIntoBuffer >= 10 && !memcmp(b->buffer, "ID3", 3)) { tagsize = (b->buffer[6] << 21) | (b->buffer[7] << 14) | (b->buffer[8] << 7) | (b->buffer[9] << 0); @@ -208,7 +208,8 @@ static void initAacBuffer(InputStream * inStream, AacBuffer * b, float *length) if (length == NULL) return; - if ((b->buffer[0] == 0xFF) && ((b->buffer[1] & 0xF6) == 0xF0)) { + if (b->bytesIntoBuffer >= 2 && + (b->buffer[0] == 0xFF) && ((b->buffer[1] & 0xF6) == 0xF0)) { adtsParse(b, length); seekInputStream(b->inStream, tagsize, SEEK_SET); -- cgit v1.2.3 From 4c8ae1ffa7e9c0b4fdd2247ea1cc851691386f14 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 26 Aug 2008 08:27:11 +0200 Subject: aac: splitted aac_parse_header() from initAacBuffer() initAacBuffer() should really only initialize the buffer; currently, it also reads data from the input stream and parses the header. All of the AAC buffer code should probably be moved to a separate library anyway. --- src/inputPlugins/aac_plugin.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'src/inputPlugins/aac_plugin.c') diff --git a/src/inputPlugins/aac_plugin.c b/src/inputPlugins/aac_plugin.c index faddb78c6..26e55aa57 100644 --- a/src/inputPlugins/aac_plugin.c +++ b/src/inputPlugins/aac_plugin.c @@ -176,22 +176,25 @@ static void adtsParse(AacBuffer * b, float *length) *length = (float)frames / framesPerSec; } -static void initAacBuffer(InputStream * inStream, AacBuffer * b, float *length) +static void initAacBuffer(InputStream * inStream, AacBuffer * b) { - size_t fileread; - size_t tagsize; - - if (length) - *length = -1; - memset(b, 0, sizeof(AacBuffer)); b->inStream = inStream; - fileread = inStream->size; - b->buffer = xmalloc(FAAD_MIN_STREAMSIZE * AAC_MAX_CHANNELS); memset(b->buffer, 0, FAAD_MIN_STREAMSIZE * AAC_MAX_CHANNELS); +} + +static void aac_parse_header(AacBuffer * b, float *length) +{ + size_t fileread; + size_t tagsize; + + if (length) + *length = -1; + + fileread = b->inStream->size; fillAacBuffer(b); @@ -256,7 +259,8 @@ static float getAacFloatTotalTime(char *file) if (openInputStream(&inStream, file) < 0) return -1; - initAacBuffer(&inStream, &b, &length); + initAacBuffer(&inStream, &b); + aac_parse_header(&b, &length); if (length < 0) { decoder = faacDecOpen(); @@ -322,7 +326,8 @@ static int aac_decode(char *path) if (openInputStream(&inStream, path) < 0) return -1; - initAacBuffer(&inStream, &b, NULL); + initAacBuffer(&inStream, &b); + aac_parse_header(&b, NULL); decoder = faacDecOpen(); -- cgit v1.2.3 From 6fb3490015d6d0c3433e259cb2099d4bb9e58b7f Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 26 Aug 2008 08:27:11 +0200 Subject: aac: support decoding AAC streams Copy some code from aac_decode() to aac_stream_decode() and apply necessary changes to allow streaming audio data. Both functions might be merged later. --- src/inputPlugins/aac_plugin.c | 130 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 128 insertions(+), 2 deletions(-) (limited to 'src/inputPlugins/aac_plugin.c') diff --git a/src/inputPlugins/aac_plugin.c b/src/inputPlugins/aac_plugin.c index 26e55aa57..512e73e53 100644 --- a/src/inputPlugins/aac_plugin.c +++ b/src/inputPlugins/aac_plugin.c @@ -300,6 +300,132 @@ static int getAacTotalTime(char *file) return file_time; } +static int aac_stream_decode(InputStream *inStream) +{ + float file_time; + float totalTime = 0; + faacDecHandle decoder; + faacDecFrameInfo frameInfo; + faacDecConfigurationPtr config; + long bread; + uint32_t sampleRate; + unsigned char channels; + unsigned int sampleCount; + char *sampleBuffer; + size_t sampleBufferLen; + mpd_uint16 bitRate = 0; + AacBuffer b; + + initAacBuffer(inStream, &b); + aac_parse_header(&b, NULL); + + decoder = faacDecOpen(); + + config = faacDecGetCurrentConfiguration(decoder); + config->outputFormat = FAAD_FMT_16BIT; +#ifdef HAVE_FAACDECCONFIGURATION_DOWNMATRIX + config->downMatrix = 1; +#endif +#ifdef HAVE_FAACDECCONFIGURATION_DONTUPSAMPLEIMPLICITSBR + config->dontUpSampleImplicitSBR = 0; +#endif + faacDecSetConfiguration(decoder, config); + + while (b.bytesIntoBuffer < FAAD_MIN_STREAMSIZE * AAC_MAX_CHANNELS && + !b.atEof && !dc_intr()) { + fillAacBuffer(&b); + adts_find_frame(&b); + fillAacBuffer(&b); + } + +#ifdef HAVE_FAAD_BUFLEN_FUNCS + bread = faacDecInit(decoder, b.buffer, b.bytesIntoBuffer, + &sampleRate, &channels); +#else + bread = faacDecInit(decoder, b.buffer, &sampleRate, &channels); +#endif + if (bread < 0) { + ERROR("Error not a AAC stream.\n"); + faacDecClose(decoder); + if (b.buffer) + free(b.buffer); + return -1; + } + + dc.audio_format.bits = 16; + dc.total_time = totalTime; + + file_time = 0.0; + + advanceAacBuffer(&b, bread); + + while (1) { + fillAacBuffer(&b); + adts_find_frame(&b); + fillAacBuffer(&b); + + if (b.bytesIntoBuffer == 0) + break; + +#ifdef HAVE_FAAD_BUFLEN_FUNCS + sampleBuffer = faacDecDecode(decoder, &frameInfo, b.buffer, + b.bytesIntoBuffer); +#else + sampleBuffer = faacDecDecode(decoder, &frameInfo, b.buffer); +#endif + + if (frameInfo.error > 0) { + ERROR("error decoding AAC stream\n"); + ERROR("faad2 error: %s\n", + faacDecGetErrorMessage(frameInfo.error)); + break; + } +#ifdef HAVE_FAACDECFRAMEINFO_SAMPLERATE + sampleRate = frameInfo.samplerate; +#endif + + dc.audio_format.channels = frameInfo.channels; + dc.audio_format.sampleRate = sampleRate; + + advanceAacBuffer(&b, frameInfo.bytesconsumed); + + sampleCount = (unsigned long)(frameInfo.samples); + + if (sampleCount > 0) { + bitRate = frameInfo.bytesconsumed * 8.0 * + frameInfo.channels * sampleRate / + frameInfo.samples / 1000 + 0.5; + file_time += + (float)(frameInfo.samples) / frameInfo.channels / + sampleRate; + } + + sampleBufferLen = sampleCount * 2; + + switch (ob_send(sampleBuffer, sampleBufferLen, + file_time, bitRate, NULL)) { + case DC_ACTION_NONE: break; + case DC_ACTION_SEEK: + /* + * this plugin doesn't support seek because nobody + * has bothered, yet... + */ + dc_action_seek_fail(DC_SEEK_ERROR); + break; + default: goto out; + } + } +out: + + faacDecClose(decoder); + if (b.buffer) + free(b.buffer); + + return 0; +} + + + static int aac_decode(char *path) { float file_time; @@ -452,10 +578,10 @@ InputPlugin aacPlugin = { NULL, NULL, NULL, - NULL, + aac_stream_decode, aac_decode, aacTagDup, - INPUT_PLUGIN_STREAM_FILE, + INPUT_PLUGIN_STREAM_FILE | INPUT_PLUGIN_STREAM_URL, aac_suffixes, aac_mimeTypes }; -- cgit v1.2.3