summaryrefslogtreecommitdiff
path: root/src/libfaad/decoder.c
diff options
context:
space:
mode:
authorDarren Salt <linux@youmustbejoking.demon.co.uk>2008-08-13 14:28:30 +0100
committerDarren Salt <linux@youmustbejoking.demon.co.uk>2008-08-13 14:28:30 +0100
commite8cc3903fc5be11c0e326fc23650599dbb1d07a0 (patch)
tree45c2bff1062583269fc745a54dcc1df048cbd62a /src/libfaad/decoder.c
parent3a6da3fcaef64afe71e1e1a0d41baca0872e98f8 (diff)
downloadxine-lib-e8cc3903fc5be11c0e326fc23650599dbb1d07a0.tar.gz
xine-lib-e8cc3903fc5be11c0e326fc23650599dbb1d07a0.tar.bz2
Update to libfaad 2.6.1, fixing a crash with a corrupted AAC file.
Source is the version in the 1.2 branch.
Diffstat (limited to 'src/libfaad/decoder.c')
-rw-r--r--src/libfaad/decoder.c125
1 files changed, 109 insertions, 16 deletions
diff --git a/src/libfaad/decoder.c b/src/libfaad/decoder.c
index 33aee247e..7fb4b1965 100644
--- a/src/libfaad/decoder.c
+++ b/src/libfaad/decoder.c
@@ -1,28 +1,31 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
-**
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
+**
** This program 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 2 of the License, or
** (at your option) any later version.
-**
+**
** This program 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 this program; if not, write to the Free Software
+** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: decoder.c,v 1.10 2005/10/29 23:57:06 tmmm Exp $
+** $Id: decoder.c,v 1.111 2007/11/01 12:33:30 menno Exp $
**/
#include "common.h"
@@ -90,6 +93,7 @@ uint32_t NEAACDECAPI NeAACDecGetCapabilities(void)
return cap;
}
+const unsigned char mes[] = { 0x67,0x20,0x61,0x20,0x20,0x20,0x6f,0x20,0x72,0x20,0x65,0x20,0x6e,0x20,0x20,0x20,0x74,0x20,0x68,0x20,0x67,0x20,0x69,0x20,0x72,0x20,0x79,0x20,0x70,0x20,0x6f,0x20,0x63 };
NeAACDecHandle NEAACDECAPI NeAACDecOpen(void)
{
uint8_t i;
@@ -100,6 +104,7 @@ NeAACDecHandle NEAACDECAPI NeAACDecOpen(void)
memset(hDecoder, 0, sizeof(NeAACDecStruct));
+ hDecoder->cmes = mes;
hDecoder->config.outputFormat = FAAD_FMT_16BIT;
hDecoder->config.defObjectType = MAIN;
hDecoder->config.defSampleRate = 44100; /* Default: 44.1kHz */
@@ -116,6 +121,9 @@ NeAACDecHandle NEAACDECAPI NeAACDecOpen(void)
hDecoder->frame = 0;
hDecoder->sample_buffer = NULL;
+ hDecoder->__r1 = 1;
+ hDecoder->__r2 = 1;
+
for (i = 0; i < MAX_CHANNELS; i++)
{
hDecoder->window_shape_prev[i] = 0;
@@ -194,6 +202,7 @@ uint8_t NEAACDECAPI NeAACDecSetConfiguration(NeAACDecHandle hDecoder,
return 0;
}
+
int32_t NEAACDECAPI NeAACDecInit(NeAACDecHandle hDecoder, uint8_t *buffer,
uint32_t buffer_size,
uint32_t *samplerate, uint8_t *channels)
@@ -203,6 +212,7 @@ int32_t NEAACDECAPI NeAACDecInit(NeAACDecHandle hDecoder, uint8_t *buffer,
adif_header adif;
adts_header adts;
+
if ((hDecoder == NULL) || (samplerate == NULL) || (channels == NULL))
return -1;
@@ -257,7 +267,6 @@ int32_t NEAACDECAPI NeAACDecInit(NeAACDecHandle hDecoder, uint8_t *buffer,
}
faad_endbits(&ld);
}
- hDecoder->channelConfiguration = *channels;
#if (defined(PS_DEC) || defined(DRM_PS))
/* check if we have a mono file */
@@ -268,6 +277,8 @@ int32_t NEAACDECAPI NeAACDecInit(NeAACDecHandle hDecoder, uint8_t *buffer,
}
#endif
+ hDecoder->channelConfiguration = *channels;
+
#ifdef SBR_DEC
/* implicit signalling */
if (*samplerate <= 24000 && !(hDecoder->config.dontUpSampleImplicitSBR))
@@ -422,8 +433,8 @@ int8_t NEAACDECAPI NeAACDecInitDRM(NeAACDecHandle *hDecoder, uint32_t samplerate
if ((channels == DRMCH_MONO) || (channels == DRMCH_STEREO))
(*hDecoder)->sbr_present_flag = 0;
else
- (*hDecoder)->sbr_present_flag = 1;
-#endif
+ (*hDecoder)->sbr_present_flag = 1;
+#endif
(*hDecoder)->fb = filter_bank_init((*hDecoder)->frameLength);
@@ -525,8 +536,14 @@ static void create_channel_config(NeAACDecHandle hDecoder, NeAACDecFrameInfo *hI
chdir = hInfo->num_front_channels;
if (chdir & 1)
{
+#if (defined(PS_DEC) || defined(DRM_PS))
+ /* When PS is enabled output is always stereo */
+ hInfo->channel_position[chpos++] = FRONT_CHANNEL_LEFT;
+ hInfo->channel_position[chpos++] = FRONT_CHANNEL_RIGHT;
+#else
hInfo->channel_position[chpos++] = FRONT_CHANNEL_CENTER;
chdir--;
+#endif
}
for (i = 0; i < chdir; i += 2)
{
@@ -565,8 +582,15 @@ static void create_channel_config(NeAACDecHandle hDecoder, NeAACDecFrameInfo *hI
switch (hDecoder->channelConfiguration)
{
case 1:
+#if (defined(PS_DEC) || defined(DRM_PS))
+ /* When PS is enabled output is always stereo */
+ hInfo->num_front_channels = 2;
+ hInfo->channel_position[0] = FRONT_CHANNEL_LEFT;
+ hInfo->channel_position[1] = FRONT_CHANNEL_RIGHT;
+#else
hInfo->num_front_channels = 1;
hInfo->channel_position[0] = FRONT_CHANNEL_CENTER;
+#endif
break;
case 2:
hInfo->num_front_channels = 2;
@@ -722,13 +746,25 @@ void* NEAACDECAPI NeAACDecDecode2(NeAACDecHandle hDecoder,
sample_buffer, sample_buffer_size);
}
+#ifdef DRM
+
+#define ERROR_STATE_INIT 6
+
+static void conceal_output(NeAACDecHandle hDecoder, uint16_t frame_len,
+ uint8_t out_ch, void *sample_buffer)
+{
+ return;
+}
+#endif
+
static void* aac_frame_decode(NeAACDecHandle hDecoder, NeAACDecFrameInfo *hInfo,
uint8_t *buffer, uint32_t buffer_size,
void **sample_buffer2, uint32_t sample_buffer_size)
{
+ uint16_t i;
uint8_t channels = 0;
uint8_t output_channels = 0;
- bitfile ld;
+ bitfile ld = {0};
uint32_t bitsconsumed;
uint16_t frame_len;
void *sample_buffer;
@@ -753,6 +789,33 @@ static void* aac_frame_decode(NeAACDecHandle hDecoder, NeAACDecFrameInfo *hInfo,
memset(hInfo, 0, sizeof(NeAACDecFrameInfo));
memset(hDecoder->internal_channel, 0, MAX_CHANNELS*sizeof(hDecoder->internal_channel[0]));
+#ifdef USE_TIME_LIMIT
+ if ((TIME_LIMIT * get_sample_rate(hDecoder->sf_index)) > hDecoder->TL_count)
+ {
+ hDecoder->TL_count += 1024;
+ } else {
+ hInfo->error = (NUM_ERROR_MESSAGES-1);
+ goto error;
+ }
+#endif
+
+
+ /* check for some common metadata tag types in the bitstream
+ * No need to return an error
+ */
+ /* ID3 */
+ if (buffer_size >= 128)
+ {
+ if (memcmp(buffer, "TAG", 3) == 0)
+ {
+ /* found it */
+ hInfo->bytesconsumed = 128; /* 128 bytes fixed size */
+ /* no error, but no output either */
+ return NULL;
+ }
+ }
+
+
/* initialize the bitstream */
faad_initbits(&ld, buffer, buffer_size);
@@ -780,7 +843,7 @@ static void* aac_frame_decode(NeAACDecHandle hDecoder, NeAACDecFrameInfo *hInfo,
/* We do not support stereo right now */
if (0) //(hDecoder->channelConfiguration == 2)
{
- hInfo->error = 8; // Throw CRC error
+ hInfo->error = 28; // Throw CRC error
goto error;
}
@@ -808,14 +871,14 @@ static void* aac_frame_decode(NeAACDecHandle hDecoder, NeAACDecFrameInfo *hInfo,
#endif
/* decode the complete bitstream */
-#ifdef SCALABLE_DEC
- if ((hDecoder->object_type == 6) || (hDecoder->object_type == DRM_ER_LC))
+#ifdef DRM
+ if (/*(hDecoder->object_type == 6) ||*/ (hDecoder->object_type == DRM_ER_LC))
{
- aac_scalable_main_element(hDecoder, hInfo, &ld, &hDecoder->pce, hDecoder->drc);
+ DRM_aac_scalable_main_element(hDecoder, hInfo, &ld, &hDecoder->pce, hDecoder->drc);
} else {
#endif
raw_data_block(hDecoder, hInfo, &ld, &hDecoder->pce, hDecoder->drc);
-#ifdef SCALABLE_DEC
+#ifdef DRM
}
#endif
@@ -978,10 +1041,16 @@ static void* aac_frame_decode(NeAACDecHandle hDecoder, NeAACDecFrameInfo *hInfo,
}
#endif
+
sample_buffer = output_to_PCM(hDecoder, hDecoder->time_out, sample_buffer,
output_channels, frame_len, hDecoder->config.outputFormat);
+#ifdef DRM
+ //conceal_output(hDecoder, frame_len, output_channels, sample_buffer);
+#endif
+
+
hDecoder->postSeekResetFlag = 0;
hDecoder->frame++;
@@ -1013,6 +1082,30 @@ static void* aac_frame_decode(NeAACDecHandle hDecoder, NeAACDecFrameInfo *hInfo,
error:
+
+#ifdef DRM
+ hDecoder->error_state = ERROR_STATE_INIT;
+#endif
+
+ /* reset filterbank state */
+ for (i = 0; i < MAX_CHANNELS; i++)
+ {
+ if (hDecoder->fb_intermed[i] != NULL)
+ {
+ memset(hDecoder->fb_intermed[i], 0, hDecoder->frameLength*sizeof(real_t));
+ }
+ }
+#ifdef SBR_DEC
+ for (i = 0; i < MAX_SYNTAX_ELEMENTS; i++)
+ {
+ if (hDecoder->sbr[i] != NULL)
+ {
+ sbrReset(hDecoder->sbr[i]);
+ }
+ }
+#endif
+
+
faad_endbits(&ld);
/* cleanup */