summaryrefslogtreecommitdiff
path: root/src/libfaad/specrec.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libfaad/specrec.c')
-rw-r--r--src/libfaad/specrec.c174
1 files changed, 130 insertions, 44 deletions
diff --git a/src/libfaad/specrec.c b/src/libfaad/specrec.c
index fd4b0653c..ea6ca94b9 100644
--- a/src/libfaad/specrec.c
+++ b/src/libfaad/specrec.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: specrec.c,v 1.10 2006/06/17 20:43:57 dgp85 Exp $
+** $Id: specrec.c,v 1.60 2007/11/01 12:33:36 menno Exp $
**/
/*
@@ -327,6 +330,11 @@ uint8_t window_grouping_info(NeAACDecHandle hDecoder, ic_stream *ics)
}
#endif
+ if (ics->max_sfb > ics->num_swb)
+ {
+ return 32;
+ }
+
/* preparation of sect_sfb_offset for long blocks */
/* also copy the last value! */
#ifdef LD_DEC
@@ -348,6 +356,7 @@ uint8_t window_grouping_info(NeAACDecHandle hDecoder, ic_stream *ics)
}
ics->sect_sfb_offset[0][ics->num_swb] = hDecoder->frameLength;
ics->swb_offset[ics->num_swb] = hDecoder->frameLength;
+ ics->swb_offset_max = hDecoder->frameLength;
} else {
#endif
for (i = 0; i < ics->num_swb; i++)
@@ -357,6 +366,7 @@ uint8_t window_grouping_info(NeAACDecHandle hDecoder, ic_stream *ics)
}
ics->sect_sfb_offset[0][ics->num_swb] = hDecoder->frameLength;
ics->swb_offset[ics->num_swb] = hDecoder->frameLength;
+ ics->swb_offset_max = hDecoder->frameLength;
#ifdef LD_DEC
}
#endif
@@ -367,9 +377,15 @@ uint8_t window_grouping_info(NeAACDecHandle hDecoder, ic_stream *ics)
ics->window_group_length[ics->num_window_groups-1] = 1;
ics->num_swb = num_swb_128_window[sf_index];
+ if (ics->max_sfb > ics->num_swb)
+ {
+ return 32;
+ }
+
for (i = 0; i < ics->num_swb; i++)
ics->swb_offset[i] = swb_offset_128_window[sf_index][i];
ics->swb_offset[ics->num_swb] = hDecoder->frameLength/8;
+ ics->swb_offset_max = hDecoder->frameLength/8;
for (i = 0; i < ics->num_windows-1; i++) {
if (bit_set(ics->scale_factor_grouping, 6-i) == 0)
@@ -405,7 +421,7 @@ uint8_t window_grouping_info(NeAACDecHandle hDecoder, ic_stream *ics)
}
return 0;
default:
- return 1;
+ return 32;
}
}
@@ -667,25 +683,46 @@ static uint8_t quant_to_spec(NeAACDecHandle hDecoder,
static uint8_t allocate_single_channel(NeAACDecHandle hDecoder, uint8_t channel,
uint8_t output_channels)
{
- uint8_t mul = 1;
+ int mul = 1;
#ifdef MAIN_DEC
/* MAIN object type prediction */
if (hDecoder->object_type == MAIN)
{
- hDecoder->pred_stat[channel] = (pred_state*)realloc(hDecoder->pred_stat[channel], hDecoder->frameLength * sizeof(pred_state));
- reset_all_predictors(hDecoder->pred_stat[channel], hDecoder->frameLength);
+ /* allocate the state only when needed */
+ if (hDecoder->pred_stat[channel] != NULL)
+ {
+ faad_free(hDecoder->pred_stat[channel]);
+ hDecoder->pred_stat[channel] = NULL;
+ }
+
+ hDecoder->pred_stat[channel] = (pred_state*)faad_malloc(hDecoder->frameLength * sizeof(pred_state));
+ reset_all_predictors(hDecoder->pred_stat[channel], hDecoder->frameLength);
}
#endif
#ifdef LTP_DEC
if (is_ltp_ot(hDecoder->object_type))
{
- hDecoder->lt_pred_stat[channel] = (int16_t*)realloc(hDecoder->lt_pred_stat[channel], hDecoder->frameLength*4 * sizeof(int16_t));
- memset(hDecoder->lt_pred_stat[channel], 0, hDecoder->frameLength*4 * sizeof(int16_t));
+ /* allocate the state only when needed */
+ if (hDecoder->lt_pred_stat[channel] != NULL)
+ {
+ faad_free(hDecoder->lt_pred_stat[channel]);
+ hDecoder->lt_pred_stat[channel] = NULL;
+ }
+
+ hDecoder->lt_pred_stat[channel] = (int16_t*)faad_malloc(hDecoder->frameLength*4 * sizeof(int16_t));
+ memset(hDecoder->lt_pred_stat[channel], 0, hDecoder->frameLength*4 * sizeof(int16_t));
}
#endif
+ if (hDecoder->time_out[channel] != NULL)
+ {
+ faad_free(hDecoder->time_out[channel]);
+ hDecoder->time_out[channel] = NULL;
+ }
+
+ {
mul = 1;
#ifdef SBR_DEC
hDecoder->sbr_alloced[hDecoder->fr_ch_ele] = 0;
@@ -696,28 +733,48 @@ static uint8_t allocate_single_channel(NeAACDecHandle hDecoder, uint8_t channel,
hDecoder->sbr_alloced[hDecoder->fr_ch_ele] = 1;
}
#endif
- hDecoder->time_out[channel] = (real_t*)realloc(hDecoder->time_out[channel], mul*hDecoder->frameLength*sizeof(real_t));
+ hDecoder->time_out[channel] = (real_t*)faad_malloc(mul*hDecoder->frameLength*sizeof(real_t));
memset(hDecoder->time_out[channel], 0, mul*hDecoder->frameLength*sizeof(real_t));
+ }
+
#if (defined(PS_DEC) || defined(DRM_PS))
if (output_channels == 2)
{
- hDecoder->time_out[channel+1] = (real_t*)realloc(hDecoder->time_out[channel+1], mul*hDecoder->frameLength*sizeof(real_t));
- memset(hDecoder->time_out[channel+1], 0, mul*hDecoder->frameLength*sizeof(real_t));
+ if (hDecoder->time_out[channel+1] != NULL)
+ {
+ faad_free(hDecoder->time_out[channel+1]);
+ hDecoder->time_out[channel+1] = NULL;
+ }
+
+ hDecoder->time_out[channel+1] = (real_t*)faad_malloc(mul*hDecoder->frameLength*sizeof(real_t));
+ memset(hDecoder->time_out[channel+1], 0, mul*hDecoder->frameLength*sizeof(real_t));
}
#endif
- hDecoder->fb_intermed[channel] = (real_t*)realloc(hDecoder->fb_intermed[channel], hDecoder->frameLength*sizeof(real_t));
- memset(hDecoder->fb_intermed[channel], 0, hDecoder->frameLength*sizeof(real_t));
+ if (hDecoder->fb_intermed[channel] != NULL)
+ {
+ faad_free(hDecoder->fb_intermed[channel]);
+ hDecoder->fb_intermed[channel] = NULL;
+ }
+
+ hDecoder->fb_intermed[channel] = (real_t*)faad_malloc(hDecoder->frameLength*sizeof(real_t));
+ memset(hDecoder->fb_intermed[channel], 0, hDecoder->frameLength*sizeof(real_t));
#ifdef SSR_DEC
if (hDecoder->object_type == SSR)
{
- uint16_t k;
- hDecoder->ssr_overlap[channel] = (real_t*)realloc(hDecoder->ssr_overlap[channel], 2*hDecoder->frameLength*sizeof(real_t));
+ if (hDecoder->ssr_overlap[channel] == NULL)
+ {
+ hDecoder->ssr_overlap[channel] = (real_t*)faad_malloc(2*hDecoder->frameLength*sizeof(real_t));
memset(hDecoder->ssr_overlap[channel], 0, 2*hDecoder->frameLength*sizeof(real_t));
- hDecoder->prev_fmd[channel] = (real_t*)realloc(hDecoder->prev_fmd[channel], 2*hDecoder->frameLength*sizeof(real_t));
+ }
+ if (hDecoder->prev_fmd[channel] == NULL)
+ {
+ uint16_t k;
+ hDecoder->prev_fmd[channel] = (real_t*)faad_malloc(2*hDecoder->frameLength*sizeof(real_t));
for (k = 0; k < 2*hDecoder->frameLength; k++)
hDecoder->prev_fmd[channel][k] = REAL_CONST(-1);
+ }
}
#endif
@@ -727,7 +784,7 @@ static uint8_t allocate_single_channel(NeAACDecHandle hDecoder, uint8_t channel,
static uint8_t allocate_channel_pair(NeAACDecHandle hDecoder,
uint8_t channel, uint8_t paired_channel)
{
- uint8_t mul = 1;
+ int mul = 1;
#ifdef MAIN_DEC
/* MAIN object type prediction */
@@ -832,7 +889,8 @@ static uint8_t allocate_channel_pair(NeAACDecHandle hDecoder,
uint8_t reconstruct_single_channel(NeAACDecHandle hDecoder, ic_stream *ics,
element *sce, int16_t *spec_data)
{
- uint8_t retval, output_channels;
+ uint8_t retval;
+ int output_channels;
ALIGN real_t spec_coef[1024];
#ifdef PROFILE
@@ -841,15 +899,38 @@ uint8_t reconstruct_single_channel(NeAACDecHandle hDecoder, ic_stream *ics,
/* always allocate 2 channels, PS can always "suddenly" turn up */
-#if (defined(PS_DEC) || defined(DRM_PS))
- output_channels = hDecoder->ps_used[hDecoder->fr_ch_ele] ? 2 : 1;
+#if ( (defined(DRM) && defined(DRM_PS)) )
+ output_channels = 2;
+#elif defined(PS_DEC)
+ if (hDecoder->ps_used[hDecoder->fr_ch_ele])
+ output_channels = 2;
+ else
+ output_channels = 1;
#else
output_channels = 1;
#endif
- if (hDecoder->element_output_channels[hDecoder->fr_ch_ele] < output_channels)
+ if (hDecoder->element_output_channels[hDecoder->fr_ch_ele] == 0)
{
+ /* element_output_channels not set yet */
hDecoder->element_output_channels[hDecoder->fr_ch_ele] = output_channels;
+ } else if (hDecoder->element_output_channels[hDecoder->fr_ch_ele] != output_channels) {
+ /* element inconsistency */
+
+ /* this only happens if PS is actually found but not in the first frame
+ * this means that there is only 1 bitstream element!
+ */
+
+ /* reset the allocation */
+ hDecoder->element_alloced[hDecoder->fr_ch_ele] = 0;
+
+ hDecoder->element_output_channels[hDecoder->fr_ch_ele] = output_channels;
+
+ //return 21;
+ }
+
+ if (hDecoder->element_alloced[hDecoder->fr_ch_ele] == 0)
+ {
retval = allocate_single_channel(hDecoder, sce->channel, output_channels);
if (retval > 0)
return retval;
@@ -870,7 +951,8 @@ uint8_t reconstruct_single_channel(NeAACDecHandle hDecoder, ic_stream *ics,
/* pns decoding */
- pns_decode(ics, NULL, spec_coef, NULL, hDecoder->frameLength, 0, hDecoder->object_type);
+ pns_decode(ics, NULL, spec_coef, NULL, hDecoder->frameLength, 0, hDecoder->object_type,
+ &(hDecoder->__r1), &(hDecoder->__r2));
#ifdef MAIN_DEC
/* MAIN object type prediction */
@@ -954,8 +1036,8 @@ uint8_t reconstruct_single_channel(NeAACDecHandle hDecoder, ic_stream *ics,
if (((hDecoder->sbr_present_flag == 1) || (hDecoder->forceUpSampling == 1))
&& hDecoder->sbr_alloced[hDecoder->fr_ch_ele])
{
- uint8_t ele = hDecoder->fr_ch_ele;
- uint8_t ch = sce->channel;
+ int ele = hDecoder->fr_ch_ele;
+ int ch = sce->channel;
/* following case can happen when forceUpSampling == 1 */
if (hDecoder->sbr[ele] == NULL)
@@ -970,9 +1052,9 @@ uint8_t reconstruct_single_channel(NeAACDecHandle hDecoder, ic_stream *ics,
}
if (sce->ics1.window_sequence == EIGHT_SHORT_SEQUENCE)
- hDecoder->sbr[ele]->maxAACLine = 8*sce->ics1.swb_offset[max(sce->ics1.max_sfb-1, 0)];
+ hDecoder->sbr[ele]->maxAACLine = 8*min(sce->ics1.swb_offset[max(sce->ics1.max_sfb-1, 0)], sce->ics1.swb_offset_max);
else
- hDecoder->sbr[ele]->maxAACLine = sce->ics1.swb_offset[max(sce->ics1.max_sfb-1, 0)];
+ hDecoder->sbr[ele]->maxAACLine = min(sce->ics1.swb_offset[max(sce->ics1.max_sfb-1, 0)], sce->ics1.swb_offset_max);
/* check if any of the PS tools is used */
#if (defined(PS_DEC) || defined(DRM_PS))
@@ -995,20 +1077,21 @@ uint8_t reconstruct_single_channel(NeAACDecHandle hDecoder, ic_stream *ics,
{
return 23;
}
+#endif
/* copy L to R when no PS is used */
#if (defined(PS_DEC) || defined(DRM_PS))
- if ((hDecoder->ps_used[hDecoder->fr_ch_ele] == 0) && (output_channels == 2))
+ if ((hDecoder->ps_used[hDecoder->fr_ch_ele] == 0) &&
+ (hDecoder->element_output_channels[hDecoder->fr_ch_ele] == 2))
{
- uint8_t ele = hDecoder->fr_ch_ele;
- uint8_t ch = sce->channel;
- uint16_t frame_size = (hDecoder->sbr_alloced[ele]) ? 2 : 1;
+ int ele = hDecoder->fr_ch_ele;
+ int ch = sce->channel;
+ int frame_size = (hDecoder->sbr_alloced[ele]) ? 2 : 1;
frame_size *= hDecoder->frameLength*sizeof(real_t);
memcpy(hDecoder->time_out[ch+1], hDecoder->time_out[ch], frame_size);
}
#endif
-#endif
return 0;
}
@@ -1049,10 +1132,13 @@ uint8_t reconstruct_channel_pair(NeAACDecHandle hDecoder, ic_stream *ics1, ic_st
/* pns decoding */
if (ics1->ms_mask_present)
{
- pns_decode(ics1, ics2, spec_coef1, spec_coef2, hDecoder->frameLength, 1, hDecoder->object_type);
+ pns_decode(ics1, ics2, spec_coef1, spec_coef2, hDecoder->frameLength, 1, hDecoder->object_type,
+ &(hDecoder->__r1), &(hDecoder->__r2));
} else {
- pns_decode(ics1, NULL, spec_coef1, NULL, hDecoder->frameLength, 0, hDecoder->object_type);
- pns_decode(ics2, NULL, spec_coef2, NULL, hDecoder->frameLength, 0, hDecoder->object_type);
+ pns_decode(ics1, NULL, spec_coef1, NULL, hDecoder->frameLength, 0, hDecoder->object_type,
+ &(hDecoder->__r1), &(hDecoder->__r2));
+ pns_decode(ics2, NULL, spec_coef2, NULL, hDecoder->frameLength, 0, hDecoder->object_type,
+ &(hDecoder->__r1), &(hDecoder->__r2));
}
/* mid/side decoding */
@@ -1204,9 +1290,9 @@ uint8_t reconstruct_channel_pair(NeAACDecHandle hDecoder, ic_stream *ics1, ic_st
if (((hDecoder->sbr_present_flag == 1) || (hDecoder->forceUpSampling == 1))
&& hDecoder->sbr_alloced[hDecoder->fr_ch_ele])
{
- uint8_t ele = hDecoder->fr_ch_ele;
- uint8_t ch0 = cpe->channel;
- uint8_t ch1 = cpe->paired_channel;
+ int ele = hDecoder->fr_ch_ele;
+ int ch0 = cpe->channel;
+ int ch1 = cpe->paired_channel;
/* following case can happen when forceUpSampling == 1 */
if (hDecoder->sbr[ele] == NULL)
@@ -1221,9 +1307,9 @@ uint8_t reconstruct_channel_pair(NeAACDecHandle hDecoder, ic_stream *ics1, ic_st
}
if (cpe->ics1.window_sequence == EIGHT_SHORT_SEQUENCE)
- hDecoder->sbr[ele]->maxAACLine = 8*cpe->ics1.swb_offset[max(cpe->ics1.max_sfb-1, 0)];
+ hDecoder->sbr[ele]->maxAACLine = 8*min(cpe->ics1.swb_offset[max(cpe->ics1.max_sfb-1, 0)], cpe->ics1.swb_offset_max);
else
- hDecoder->sbr[ele]->maxAACLine = cpe->ics1.swb_offset[max(cpe->ics1.max_sfb-1, 0)];
+ hDecoder->sbr[ele]->maxAACLine = min(cpe->ics1.swb_offset[max(cpe->ics1.max_sfb-1, 0)], cpe->ics1.swb_offset_max);
retval = sbrDecodeCoupleFrame(hDecoder->sbr[ele],
hDecoder->time_out[ch0], hDecoder->time_out[ch1],