diff options
author | Miguel Freitas <miguelfreitas@users.sourceforge.net> | 2003-12-30 02:00:10 +0000 |
---|---|---|
committer | Miguel Freitas <miguelfreitas@users.sourceforge.net> | 2003-12-30 02:00:10 +0000 |
commit | f260c2ac3661143bfdfbcc4c7a3574acdd831894 (patch) | |
tree | 644ed0104c63c64b7346681ca5e212a81876458c /src/libfaad/decoder.c | |
parent | 33f6c0d77b5dfafcbafd09fc05d700fb66c9cb47 (diff) | |
download | xine-lib-f260c2ac3661143bfdfbcc4c7a3574acdd831894.tar.gz xine-lib-f260c2ac3661143bfdfbcc4c7a3574acdd831894.tar.bz2 |
- update to libfaad 2.0 rc3
- some fixes to xine_decoder.c
CVS patchset: 5959
CVS date: 2003/12/30 02:00:10
Diffstat (limited to 'src/libfaad/decoder.c')
-rw-r--r-- | src/libfaad/decoder.c | 964 |
1 files changed, 639 insertions, 325 deletions
diff --git a/src/libfaad/decoder.c b/src/libfaad/decoder.c index dbe691f77..8c824ff3d 100644 --- a/src/libfaad/decoder.c +++ b/src/libfaad/decoder.c @@ -1,22 +1,28 @@ /* -** FAAD - Freeware Advanced Audio Decoder -** Copyright (C) 2002 M. Bakker -** +** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding +** Copyright (C) 2003 M. Bakker, Ahead Software 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. ** -** $Id: decoder.c,v 1.5 2003/08/25 21:51:41 f1rmb Exp $ +** Any non-GPL usage of this software or parts of this software is strictly +** forbidden. +** +** Commercial non-GPL licensing of this software is possible. +** For more info contact Ahead Software through Mpeg4AAClicense@nero.com. +** +** $Id: decoder.c,v 1.6 2003/12/30 02:00:10 miguelfreitas Exp $ **/ #include "common.h" @@ -28,21 +34,13 @@ #include "decoder.h" #include "mp4.h" #include "syntax.h" -#include "specrec.h" -#include "data.h" -#include "tns.h" -#include "pns.h" -#include "is.h" -#include "ms.h" -#include "ic_predict.h" -#include "lt_predict.h" -#include "drc.h" #include "error.h" #include "output.h" -#include "dither.h" +#ifdef SBR_DEC +#include "sbr_dec.h" +#endif #ifdef SSR_DEC #include "ssr.h" -#include "ssr_fb.h" #endif #ifdef ANALYSIS @@ -51,10 +49,12 @@ uint16_t dbg_count; int8_t* FAADAPI faacDecGetErrorMessage(uint8_t errcode) { + if (errcode >= NUM_ERROR_MESSAGES) + return NULL; return err_msg[errcode]; } -uint32_t FAADAPI faacDecGetCapabilities(void) +uint32_t FAADAPI faacDecGetCapabilities() { uint32_t cap = 0; @@ -80,12 +80,12 @@ uint32_t FAADAPI faacDecGetCapabilities(void) return cap; } -faacDecHandle FAADAPI faacDecOpen(void) +faacDecHandle FAADAPI faacDecOpen() { uint8_t i; faacDecHandle hDecoder = NULL; - if ((hDecoder = (faacDecHandle)malloc(sizeof(faacDecStruct))) == NULL) + if ((hDecoder = (faacDecHandle)faad_malloc(sizeof(faacDecStruct))) == NULL) return NULL; memset(hDecoder, 0, sizeof(faacDecStruct)); @@ -93,6 +93,7 @@ faacDecHandle FAADAPI faacDecOpen(void) hDecoder->config.outputFormat = FAAD_FMT_16BIT; hDecoder->config.defObjectType = MAIN; hDecoder->config.defSampleRate = 44100; /* Default: 44.1kHz */ + hDecoder->config.downMatrix = 0; hDecoder->adts_header_present = 0; hDecoder->adif_header_present = 0; #ifdef ERROR_RESILIENCE @@ -109,6 +110,9 @@ faacDecHandle FAADAPI faacDecOpen(void) { hDecoder->window_shape_prev[i] = 0; hDecoder->time_out[i] = NULL; +#ifdef SBR_DEC + hDecoder->time_out2[i] = NULL; +#endif #ifdef SSR_DEC hDecoder->ssr_overlap[i] = NULL; hDecoder->prev_fmd[i] = NULL; @@ -122,11 +126,22 @@ faacDecHandle FAADAPI faacDecOpen(void) #endif } +#ifdef SBR_DEC + for (i = 0; i < 32; i++) + { + hDecoder->sbr[i] = NULL; + } +#endif + hDecoder->drc = drc_init(REAL_CONST(1.0), REAL_CONST(1.0)); -#if POW_TABLE_SIZE - hDecoder->pow2_table = (real_t*)malloc(POW_TABLE_SIZE*sizeof(real_t)); - build_tables(hDecoder->pow2_table); +#ifdef USE_SSE + if (cpu_has_sse()) + { + hDecoder->apply_sf_func = apply_scalefactors_sse; + } else { + hDecoder->apply_sf_func = apply_scalefactors; + } #endif return hDecoder; @@ -134,20 +149,44 @@ faacDecHandle FAADAPI faacDecOpen(void) faacDecConfigurationPtr FAADAPI faacDecGetCurrentConfiguration(faacDecHandle hDecoder) { - faacDecConfigurationPtr config = &(hDecoder->config); + if (hDecoder) + { + faacDecConfigurationPtr config = &(hDecoder->config); + + return config; + } - return config; + return NULL; } uint8_t FAADAPI faacDecSetConfiguration(faacDecHandle hDecoder, faacDecConfigurationPtr config) { - hDecoder->config.defObjectType = config->defObjectType; - hDecoder->config.defSampleRate = config->defSampleRate; - hDecoder->config.outputFormat = config->outputFormat; + if (hDecoder && config) + { + /* check if we can decode this object type */ + if (can_decode_ot(config->defObjectType) < 0) + return 0; + hDecoder->config.defObjectType = config->defObjectType; + + /* samplerate: anything but 0 should be possible */ + if (config->defSampleRate == 0) + return 0; + hDecoder->config.defSampleRate = config->defSampleRate; + + /* check output format */ + if ((config->outputFormat < 1) || (config->outputFormat > 9)) + return 0; + hDecoder->config.outputFormat = config->outputFormat; + + if (config->downMatrix > 1) + hDecoder->config.downMatrix = config->downMatrix; + + /* OK */ + return 1; + } - /* OK */ - return 1; + return 0; } int32_t FAADAPI faacDecInit(faacDecHandle hDecoder, uint8_t *buffer, @@ -159,9 +198,12 @@ int32_t FAADAPI faacDecInit(faacDecHandle hDecoder, uint8_t *buffer, adif_header adif; adts_header adts; + if ((hDecoder == NULL) || (samplerate == NULL) || (channels == NULL)) + return -1; + hDecoder->sf_index = get_sr_index(hDecoder->config.defSampleRate); hDecoder->object_type = hDecoder->config.defObjectType; - *samplerate = sample_rates[hDecoder->sf_index]; + *samplerate = get_sample_rate(hDecoder->sf_index); *channels = 1; if (buffer != NULL) @@ -177,11 +219,14 @@ int32_t FAADAPI faacDecInit(faacDecHandle hDecoder, uint8_t *buffer, get_adif_header(&adif, &ld); faad_byte_align(&ld); - hDecoder->sf_index = adif.pce.sf_index; - hDecoder->object_type = adif.pce.object_type; + hDecoder->sf_index = adif.pce[0].sf_index; + hDecoder->object_type = adif.pce[0].object_type + 1; + + *samplerate = get_sample_rate(hDecoder->sf_index); + *channels = adif.pce[0].channels; - *samplerate = sample_rates[hDecoder->sf_index]; - *channels = adif.pce.channels; + memcpy(&(hDecoder->pce), &(adif.pce[0]), sizeof(program_config)); + hDecoder->pce_set = 1; bits = bit2byte(faad_get_processed_bits(&ld)); @@ -189,12 +234,13 @@ int32_t FAADAPI faacDecInit(faacDecHandle hDecoder, uint8_t *buffer, } else if (faad_showbits(&ld, 12) == 0xfff) { hDecoder->adts_header_present = 1; + adts.old_format = hDecoder->config.useOldADTSFormat; adts_frame(&adts, &ld); hDecoder->sf_index = adts.sf_index; - hDecoder->object_type = adts.profile; + hDecoder->object_type = adts.profile + 1; - *samplerate = sample_rates[hDecoder->sf_index]; + *samplerate = get_sample_rate(hDecoder->sf_index); *channels = (adts.channel_configuration > 6) ? 2 : adts.channel_configuration; } @@ -208,6 +254,15 @@ int32_t FAADAPI faacDecInit(faacDecHandle hDecoder, uint8_t *buffer, } hDecoder->channelConfiguration = *channels; +#ifdef SBR_DEC + /* implicit signalling */ + if (*samplerate <= 24000) + { + *samplerate *= 2; + hDecoder->forceUpSampling = 1; + } +#endif + /* must be done before frameLength is divided by 2 for LD */ #ifdef SSR_DEC if (hDecoder->object_type == SSR) @@ -224,11 +279,6 @@ int32_t FAADAPI faacDecInit(faacDecHandle hDecoder, uint8_t *buffer, if (can_decode_ot(hDecoder->object_type) < 0) return -1; -#ifndef FIXED_POINT - if (hDecoder->config.outputFormat >= FAAD_FMT_DITHER_LOWEST) - Init_Dither(16, hDecoder->config.outputFormat - FAAD_FMT_DITHER_LOWEST); -#endif - return bits; } @@ -240,9 +290,6 @@ int8_t FAADAPI faacDecInit2(faacDecHandle hDecoder, uint8_t *pBuffer, int8_t rc; mp4AudioSpecificConfig mp4ASC; - hDecoder->adif_header_present = 0; - hDecoder->adts_header_present = 0; - if((hDecoder == NULL) || (pBuffer == NULL) || (SizeOfDecoderSpecificInfo < 2) @@ -252,27 +299,51 @@ int8_t FAADAPI faacDecInit2(faacDecHandle hDecoder, uint8_t *pBuffer, return -1; } + hDecoder->adif_header_present = 0; + hDecoder->adts_header_present = 0; + /* decode the audio specific config */ - rc = AudioSpecificConfig(pBuffer, SizeOfDecoderSpecificInfo, &mp4ASC); + rc = AudioSpecificConfig2(pBuffer, SizeOfDecoderSpecificInfo, &mp4ASC, + &(hDecoder->pce)); /* copy the relevant info to the decoder handle */ *samplerate = mp4ASC.samplingFrequency; - *channels = mp4ASC.channelsConfiguration; + if (mp4ASC.channelsConfiguration) + { + *channels = mp4ASC.channelsConfiguration; + } else { + *channels = hDecoder->pce.channels; + hDecoder->pce_set = 1; + } hDecoder->sf_index = mp4ASC.samplingFrequencyIndex; hDecoder->object_type = mp4ASC.objectTypeIndex; +#ifdef ERROR_RESILIENCE hDecoder->aacSectionDataResilienceFlag = mp4ASC.aacSectionDataResilienceFlag; hDecoder->aacScalefactorDataResilienceFlag = mp4ASC.aacScalefactorDataResilienceFlag; hDecoder->aacSpectralDataResilienceFlag = mp4ASC.aacSpectralDataResilienceFlag; +#endif +#ifdef SBR_DEC + hDecoder->sbr_present_flag = mp4ASC.sbr_present_flag; + hDecoder->forceUpSampling = mp4ASC.forceUpSampling; + + /* AAC core decoder samplerate is 2 times as low */ + if (hDecoder->sbr_present_flag == 1 || hDecoder->forceUpSampling == 1) + { + hDecoder->sf_index = get_sr_index(mp4ASC.samplingFrequency / 2); + } +#endif - if (hDecoder->object_type < 5) - hDecoder->object_type--; /* For AAC differs from MPEG-4 */ if (rc != 0) { return rc; } - hDecoder->channelConfiguration = *channels; + hDecoder->channelConfiguration = mp4ASC.channelsConfiguration; if (mp4ASC.frameLengthFlag) +#ifdef ALLOW_SMALL_FRAMELENGTH hDecoder->frameLength = 960; +#else + return -1; +#endif /* must be done before frameLength is divided by 2 for LD */ #ifdef SSR_DEC @@ -287,39 +358,86 @@ int8_t FAADAPI faacDecInit2(faacDecHandle hDecoder, uint8_t *pBuffer, hDecoder->frameLength >>= 1; #endif -#ifndef FIXED_POINT - if (hDecoder->config.outputFormat >= FAAD_FMT_DITHER_LOWEST) - Init_Dither(16, hDecoder->config.outputFormat - FAAD_FMT_DITHER_LOWEST); -#endif - return 0; } +#ifdef DRM int8_t FAADAPI faacDecInitDRM(faacDecHandle hDecoder, uint32_t samplerate, uint8_t channels) { + uint8_t i; + /* Special object type defined for DRM */ hDecoder->config.defObjectType = DRM_ER_LC; hDecoder->config.defSampleRate = samplerate; +#ifdef ERROR_RESILIENCE // This shoudl always be defined for DRM hDecoder->aacSectionDataResilienceFlag = 1; /* VCB11 */ hDecoder->aacScalefactorDataResilienceFlag = 0; /* no RVLC */ hDecoder->aacSpectralDataResilienceFlag = 1; /* HCR */ +#endif hDecoder->frameLength = 960; hDecoder->sf_index = get_sr_index(hDecoder->config.defSampleRate); hDecoder->object_type = hDecoder->config.defObjectType; - hDecoder->channelConfiguration = channels; + + if ((channels == DRMCH_STEREO) || (channels == DRMCH_SBR_STEREO)) + hDecoder->channelConfiguration = 2; + else + hDecoder->channelConfiguration = 1; + +#ifdef SBR_DEC + if (channels == DRMCH_SBR_LC_STEREO) + hDecoder->lcstereo_flag = 1; + else + hDecoder->lcstereo_flag = 0; + + if ((channels == DRMCH_MONO) || (channels == DRMCH_STEREO)) + hDecoder->sbr_present_flag = 0; + else + hDecoder->sbr_present_flag = 1; + + /* Reset sbr for new initialization */ + sbrDecodeEnd(hDecoder->sbr[0]); + hDecoder->sbr[0] = NULL; +#endif /* must be done before frameLength is divided by 2 for LD */ hDecoder->fb = filter_bank_init(hDecoder->frameLength); -#ifndef FIXED_POINT - if (hDecoder->config.outputFormat >= FAAD_FMT_DITHER_LOWEST) - Init_Dither(16, hDecoder->config.outputFormat - FAAD_FMT_DITHER_LOWEST); + /* Take care of buffers */ + if (hDecoder->sample_buffer) faad_free(hDecoder->sample_buffer); + hDecoder->sample_buffer = NULL; + + for (i = 0; i < MAX_CHANNELS; i++) + { + hDecoder->window_shape_prev[i] = 0; + + if (hDecoder->time_out[i]) faad_free(hDecoder->time_out[i]); + hDecoder->time_out[i] = NULL; +#ifdef SBR_DEC + if (hDecoder->time_out2[i]) faad_free(hDecoder->time_out2[i]); + hDecoder->time_out2[i] = NULL; +#endif +#ifdef SSR_DEC + if (hDecoder->ssr_overlap[i]) faad_free(hDecoder->ssr_overlap[i]); + hDecoder->ssr_overlap[i] = NULL; + if (hDecoder->prev_fmd[i]) faad_free(hDecoder->prev_fmd[i]); + hDecoder->prev_fmd[i] = NULL; +#endif +#ifdef MAIN_DEC + if (hDecoder->pred_stat[i]) faad_free(hDecoder->pred_stat[i]); + hDecoder->pred_stat[i] = NULL; #endif +#ifdef LTP_DEC + hDecoder->ltp_lag[i] = 0; + if (hDecoder->lt_pred_stat[i]) faad_free(hDecoder->lt_pred_stat[i]); + hDecoder->lt_pred_stat[i] = NULL; +#endif + } return 0; } +#endif void FAADAPI faacDecClose(faacDecHandle hDecoder) { @@ -328,18 +446,29 @@ void FAADAPI faacDecClose(faacDecHandle hDecoder) if (hDecoder == NULL) return; +#ifdef PROFILE + printf("AAC decoder total: %I64d cycles\n", hDecoder->cycles); + printf("requant: %I64d cycles\n", hDecoder->requant_cycles); + printf("spectral_data: %I64d cycles\n", hDecoder->spectral_cycles); + printf("scalefactors: %I64d cycles\n", hDecoder->scalefac_cycles); + printf("output: %I64d cycles\n", hDecoder->output_cycles); +#endif + for (i = 0; i < MAX_CHANNELS; i++) { - if (hDecoder->time_out[i]) free(hDecoder->time_out[i]); + if (hDecoder->time_out[i]) faad_free(hDecoder->time_out[i]); +#ifdef SBR_DEC + if (hDecoder->time_out2[i]) faad_free(hDecoder->time_out2[i]); +#endif #ifdef SSR_DEC - if (hDecoder->ssr_overlap[i]) free(hDecoder->ssr_overlap[i]); - if (hDecoder->prev_fmd[i]) free(hDecoder->prev_fmd[i]); + if (hDecoder->ssr_overlap[i]) faad_free(hDecoder->ssr_overlap[i]); + if (hDecoder->prev_fmd[i]) faad_free(hDecoder->prev_fmd[i]); #endif #ifdef MAIN_DEC - if (hDecoder->pred_stat[i]) free(hDecoder->pred_stat[i]); + if (hDecoder->pred_stat[i]) faad_free(hDecoder->pred_stat[i]); #endif #ifdef LTP_DEC - if (hDecoder->lt_pred_stat[i]) free(hDecoder->lt_pred_stat[i]); + if (hDecoder->lt_pred_stat[i]) faad_free(hDecoder->lt_pred_stat[i]); #endif } @@ -352,84 +481,327 @@ void FAADAPI faacDecClose(faacDecHandle hDecoder) drc_end(hDecoder->drc); -#ifndef FIXED_POINT -#if POW_TABLE_SIZE - if (hDecoder->pow2_table) free(hDecoder->pow2_table); -#endif + if (hDecoder->sample_buffer) faad_free(hDecoder->sample_buffer); + +#ifdef SBR_DEC + for (i = 0; i < 32; i++) + { + if (hDecoder->sbr[i]) + sbrDecodeEnd(hDecoder->sbr[i]); + } #endif - if (hDecoder->sample_buffer) free(hDecoder->sample_buffer); + if (hDecoder) faad_free(hDecoder); +} + +void FAADAPI faacDecPostSeekReset(faacDecHandle hDecoder, int32_t frame) +{ + if (hDecoder) + { + hDecoder->postSeekResetFlag = 1; + + if (frame != -1) + hDecoder->frame = frame; + } +} + +static void create_channel_config(faacDecHandle hDecoder, faacDecFrameInfo *hInfo) +{ + hInfo->num_front_channels = 0; + hInfo->num_side_channels = 0; + hInfo->num_back_channels = 0; + hInfo->num_lfe_channels = 0; + memset(hInfo->channel_position, 0, MAX_CHANNELS*sizeof(uint8_t)); + + if (hDecoder->downMatrix) + { + hInfo->num_front_channels = 2; + hInfo->channel_position[0] = FRONT_CHANNEL_LEFT; + hInfo->channel_position[1] = FRONT_CHANNEL_RIGHT; + return; + } + + /* check if there is a PCE */ + if (hDecoder->pce_set) + { + uint8_t i, chpos = 0; + uint8_t chdir, back_center = 0; + + hInfo->num_front_channels = hDecoder->pce.num_front_channels; + hInfo->num_side_channels = hDecoder->pce.num_side_channels; + hInfo->num_back_channels = hDecoder->pce.num_back_channels; + hInfo->num_lfe_channels = hDecoder->pce.num_lfe_channels; + + chdir = hInfo->num_front_channels; + if (chdir & 1) + { + hInfo->channel_position[chpos++] = FRONT_CHANNEL_CENTER; + chdir--; + } + for (i = 0; i < chdir; i += 2) + { + hInfo->channel_position[chpos++] = FRONT_CHANNEL_LEFT; + hInfo->channel_position[chpos++] = FRONT_CHANNEL_RIGHT; + } + + for (i = 0; i < hInfo->num_side_channels; i += 2) + { + hInfo->channel_position[chpos++] = SIDE_CHANNEL_LEFT; + hInfo->channel_position[chpos++] = SIDE_CHANNEL_RIGHT; + } + + chdir = hInfo->num_back_channels; + if (chdir & 1) + { + back_center = 1; + chdir--; + } + for (i = 0; i < chdir; i += 2) + { + hInfo->channel_position[chpos++] = BACK_CHANNEL_LEFT; + hInfo->channel_position[chpos++] = BACK_CHANNEL_RIGHT; + } + if (back_center) + { + hInfo->channel_position[chpos++] = BACK_CHANNEL_CENTER; + } + + for (i = 0; i < hInfo->num_lfe_channels; i++) + { + hInfo->channel_position[chpos++] = LFE_CHANNEL; + } - if (hDecoder) free(hDecoder); + } else { + switch (hDecoder->channelConfiguration) + { + case 1: + hInfo->num_front_channels = 1; + hInfo->channel_position[0] = FRONT_CHANNEL_CENTER; + break; + case 2: + hInfo->num_front_channels = 2; + hInfo->channel_position[0] = FRONT_CHANNEL_LEFT; + hInfo->channel_position[1] = FRONT_CHANNEL_RIGHT; + break; + case 3: + hInfo->num_front_channels = 3; + hInfo->channel_position[0] = FRONT_CHANNEL_CENTER; + hInfo->channel_position[1] = FRONT_CHANNEL_LEFT; + hInfo->channel_position[2] = FRONT_CHANNEL_RIGHT; + break; + case 4: + hInfo->num_front_channels = 3; + hInfo->num_back_channels = 1; + hInfo->channel_position[0] = FRONT_CHANNEL_CENTER; + hInfo->channel_position[1] = FRONT_CHANNEL_LEFT; + hInfo->channel_position[2] = FRONT_CHANNEL_RIGHT; + hInfo->channel_position[3] = BACK_CHANNEL_CENTER; + break; + case 5: + hInfo->num_front_channels = 3; + hInfo->num_back_channels = 2; + hInfo->channel_position[0] = FRONT_CHANNEL_CENTER; + hInfo->channel_position[1] = FRONT_CHANNEL_LEFT; + hInfo->channel_position[2] = FRONT_CHANNEL_RIGHT; + hInfo->channel_position[3] = BACK_CHANNEL_LEFT; + hInfo->channel_position[4] = BACK_CHANNEL_RIGHT; + break; + case 6: + hInfo->num_front_channels = 3; + hInfo->num_back_channels = 2; + hInfo->num_lfe_channels = 1; + hInfo->channel_position[0] = FRONT_CHANNEL_CENTER; + hInfo->channel_position[1] = FRONT_CHANNEL_LEFT; + hInfo->channel_position[2] = FRONT_CHANNEL_RIGHT; + hInfo->channel_position[3] = BACK_CHANNEL_LEFT; + hInfo->channel_position[4] = BACK_CHANNEL_RIGHT; + hInfo->channel_position[5] = LFE_CHANNEL; + break; + case 7: + hInfo->num_front_channels = 3; + hInfo->num_side_channels = 2; + hInfo->num_back_channels = 2; + hInfo->num_lfe_channels = 1; + hInfo->channel_position[0] = FRONT_CHANNEL_CENTER; + hInfo->channel_position[1] = FRONT_CHANNEL_LEFT; + hInfo->channel_position[2] = FRONT_CHANNEL_RIGHT; + hInfo->channel_position[3] = SIDE_CHANNEL_LEFT; + hInfo->channel_position[4] = SIDE_CHANNEL_RIGHT; + hInfo->channel_position[5] = BACK_CHANNEL_LEFT; + hInfo->channel_position[6] = BACK_CHANNEL_RIGHT; + hInfo->channel_position[7] = LFE_CHANNEL; + break; + default: /* channelConfiguration == 0 || channelConfiguration > 7 */ + { + uint8_t i; + uint8_t ch = hDecoder->fr_channels - hDecoder->has_lfe; + if (ch & 1) /* there's either a center front or a center back channel */ + { + uint8_t ch1 = (ch-1)/2; + if (hDecoder->first_syn_ele == ID_SCE) + { + hInfo->num_front_channels = ch1 + 1; + hInfo->num_back_channels = ch1; + hInfo->channel_position[0] = FRONT_CHANNEL_CENTER; + for (i = 1; i <= ch1; i+=2) + { + hInfo->channel_position[i] = FRONT_CHANNEL_LEFT; + hInfo->channel_position[i+1] = FRONT_CHANNEL_RIGHT; + } + for (i = ch1+1; i < ch; i+=2) + { + hInfo->channel_position[i] = BACK_CHANNEL_LEFT; + hInfo->channel_position[i+1] = BACK_CHANNEL_RIGHT; + } + } else { + hInfo->num_front_channels = ch1; + hInfo->num_back_channels = ch1 + 1; + for (i = 0; i < ch1; i+=2) + { + hInfo->channel_position[i] = FRONT_CHANNEL_LEFT; + hInfo->channel_position[i+1] = FRONT_CHANNEL_RIGHT; + } + for (i = ch1; i < ch-1; i+=2) + { + hInfo->channel_position[i] = BACK_CHANNEL_LEFT; + hInfo->channel_position[i+1] = BACK_CHANNEL_RIGHT; + } + hInfo->channel_position[ch-1] = BACK_CHANNEL_CENTER; + } + } else { + uint8_t ch1 = (ch)/2; + hInfo->num_front_channels = ch1; + hInfo->num_back_channels = ch1; + if (ch1 & 1) + { + hInfo->channel_position[0] = FRONT_CHANNEL_CENTER; + for (i = 1; i <= ch1; i+=2) + { + hInfo->channel_position[i] = FRONT_CHANNEL_LEFT; + hInfo->channel_position[i+1] = FRONT_CHANNEL_RIGHT; + } + for (i = ch1+1; i < ch-1; i+=2) + { + hInfo->channel_position[i] = BACK_CHANNEL_LEFT; + hInfo->channel_position[i+1] = BACK_CHANNEL_RIGHT; + } + hInfo->channel_position[ch-1] = BACK_CHANNEL_CENTER; + } else { + for (i = 0; i < ch1; i+=2) + { + hInfo->channel_position[i] = FRONT_CHANNEL_LEFT; + hInfo->channel_position[i+1] = FRONT_CHANNEL_RIGHT; + } + for (i = ch1; i < ch; i+=2) + { + hInfo->channel_position[i] = BACK_CHANNEL_LEFT; + hInfo->channel_position[i+1] = BACK_CHANNEL_RIGHT; + } + } + } + hInfo->num_lfe_channels = hDecoder->has_lfe; + for (i = ch; i < hDecoder->fr_channels; i++) + { + hInfo->channel_position[i] = LFE_CHANNEL; + } + } + break; + } + } } void* FAADAPI faacDecDecode(faacDecHandle hDecoder, faacDecFrameInfo *hInfo, uint8_t *buffer, uint32_t buffer_size) { - int32_t i; - uint8_t ch; adts_header adts; uint8_t channels = 0, ch_ele = 0; - bitfile *ld = (bitfile*)malloc(sizeof(bitfile)); + uint8_t output_channels = 0; + bitfile ld; + uint32_t bitsconsumed; +#ifdef DRM + uint8_t *revbuffer; + uint8_t *prevbufstart; + uint8_t *pbufend; +#endif - /* local copys of globals */ - uint8_t sf_index = hDecoder->sf_index; - uint8_t object_type = hDecoder->object_type; - uint8_t channelConfiguration = hDecoder->channelConfiguration; + /* local copy of globals */ + uint8_t sf_index, object_type, channelConfiguration, outputFormat; + uint8_t *window_shape_prev; + uint16_t frame_len; #ifdef MAIN_DEC - pred_state **pred_stat = hDecoder->pred_stat; -#endif -#ifdef LTP_DEC - real_t **lt_pred_stat = hDecoder->lt_pred_stat; -#endif -#ifndef FIXED_POINT -#if POW_TABLE_SIZE - real_t *pow2_table = hDecoder->pow2_table; -#else - real_t *pow2_table = NULL; + pred_state **pred_stat; #endif + real_t **time_out; +#ifdef SBR_DEC + real_t **time_out2; #endif - uint8_t *window_shape_prev = hDecoder->window_shape_prev; - real_t **time_out = hDecoder->time_out; #ifdef SSR_DEC - real_t **ssr_overlap = hDecoder->ssr_overlap; - real_t **prev_fmd = hDecoder->prev_fmd; -#endif - fb_info *fb = hDecoder->fb; - drc_info *drc = hDecoder->drc; - uint8_t outputFormat = hDecoder->config.outputFormat; -#ifdef LTP_DEC - uint16_t *ltp_lag = hDecoder->ltp_lag; + real_t **ssr_overlap, **prev_fmd; #endif + fb_info *fb; + drc_info *drc; + program_config *pce; - program_config pce; - element *syntax_elements[MAX_SYNTAX_ELEMENTS]; - element **elements; - int16_t *spec_data[MAX_CHANNELS]; - real_t *spec_coef[MAX_CHANNELS]; + void *sample_buffer; - uint16_t frame_len = hDecoder->frameLength; +#ifdef PROFILE + int64_t count = faad_get_ts(); +#endif - void *sample_buffer; + /* safety checks */ + if ((hDecoder == NULL) || (hInfo == NULL) || (buffer == NULL)) + { + return NULL; + } + + sf_index = hDecoder->sf_index; + object_type = hDecoder->object_type; + channelConfiguration = hDecoder->channelConfiguration; +#ifdef MAIN_DEC + pred_stat = hDecoder->pred_stat; +#endif + window_shape_prev = hDecoder->window_shape_prev; + time_out = hDecoder->time_out; +#ifdef SBR_DEC + time_out2 = hDecoder->time_out2; +#endif +#ifdef SSR_DEC + ssr_overlap = hDecoder->ssr_overlap; + prev_fmd = hDecoder->prev_fmd; +#endif + fb = hDecoder->fb; + drc = hDecoder->drc; + outputFormat = hDecoder->config.outputFormat; + pce = &hDecoder->pce; + frame_len = hDecoder->frameLength; memset(hInfo, 0, sizeof(faacDecFrameInfo)); + memset(hDecoder->internal_channel, 0, MAX_CHANNELS*sizeof(hDecoder->internal_channel[0])); /* initialize the bitstream */ - faad_initbits(ld, buffer, buffer_size); + faad_initbits(&ld, buffer, buffer_size); #ifdef DRM if (object_type == DRM_ER_LC) { - faad_getbits(ld, 8 + /* We do not support stereo right now */ + if (hDecoder->channelConfiguration == 2) + { + hInfo->error = 8; // Throw CRC error + goto error; + } + + faad_getbits(&ld, 8 DEBUGVAR(1,1,"faacDecDecode(): skip CRC")); } #endif if (hDecoder->adts_header_present) { - if ((hInfo->error = adts_frame(&adts, ld)) > 0) + adts.old_format = hDecoder->config.useOldADTSFormat; + if ((hInfo->error = adts_frame(&adts, &ld)) > 0) goto error; /* MPEG2 does byte_alignment() here, @@ -442,11 +814,17 @@ void* FAADAPI faacDecDecode(faacDecHandle hDecoder, dbg_count = 0; #endif - elements = syntax_elements; - /* decode the complete bitstream */ - elements = raw_data_block(hDecoder, hInfo, ld, syntax_elements, - spec_data, spec_coef, &pce, drc); +#ifdef SCALABLE_DEC + if ((hDecoder->object_type == 6) || (hDecoder->object_type == DRM_ER_LC)) + { + aac_scalable_main_element(hDecoder, hInfo, &ld, pce, drc); + } else { +#endif + raw_data_block(hDecoder, hInfo, &ld, pce, drc); +#ifdef SCALABLE_DEC + } +#endif ch_ele = hDecoder->fr_ch_ele; channels = hDecoder->fr_channels; @@ -456,22 +834,94 @@ void* FAADAPI faacDecDecode(faacDecHandle hDecoder, /* no more bit reading after this */ - hInfo->bytesconsumed = bit2byte(faad_get_processed_bits(ld)); - if (ld->error) + bitsconsumed = faad_get_processed_bits(&ld); + hInfo->bytesconsumed = bit2byte(bitsconsumed); + if (ld.error) { hInfo->error = 14; goto error; } - faad_endbits(ld); - if (ld) free(ld); - ld = NULL; + faad_endbits(&ld); + +#ifdef DRM +#ifdef SBR_DEC + if ((hDecoder->sbr_present_flag == 1) && (hDecoder->object_type == DRM_ER_LC)) + { + int32_t i; + + if (bitsconsumed + 8 > buffer_size*8) + { + hInfo->error = 14; + goto error; + } + + hDecoder->sbr_used[0] = 1; + + if (!hDecoder->sbr[0]) + hDecoder->sbr[0] = sbrDecodeInit(hDecoder->frameLength, 1); + + /* Reverse bit reading of SBR data in DRM audio frame */ + revbuffer = (uint8_t*)faad_malloc(buffer_size*sizeof(uint8_t)); + prevbufstart = revbuffer; + pbufend = &buffer[buffer_size - 1]; + for (i = 0; i < buffer_size; i++) + *prevbufstart++ = tabFlipbits[*pbufend--]; + + /* Set SBR data */ + hDecoder->sbr[0]->data = revbuffer; + /* consider 8 bits from AAC-CRC */ + hDecoder->sbr[0]->data_size_bits = buffer_size*8 - bitsconsumed - 8; + hDecoder->sbr[0]->data_size = + bit2byte(hDecoder->sbr[0]->data_size_bits + 8); + + hDecoder->sbr[0]->lcstereo_flag = hDecoder->lcstereo_flag; + + hDecoder->sbr[0]->sample_rate = get_sample_rate(hDecoder->sf_index); + hDecoder->sbr[0]->sample_rate *= 2; + + hDecoder->sbr[0]->id_aac = hDecoder->element_id[0]; + } +#endif +#endif + + if (!hDecoder->adts_header_present && !hDecoder->adif_header_present) + { + if (channels != hDecoder->channelConfiguration) + hDecoder->channelConfiguration = channels; + + if (channels == 8) /* 7.1 */ + hDecoder->channelConfiguration = 7; + if (channels == 7) /* not a standard channelConfiguration */ + hDecoder->channelConfiguration = 0; + } + + if ((channels == 5 || channels == 6) && hDecoder->config.downMatrix) + { + hDecoder->downMatrix = 1; + output_channels = 2; + } else { + output_channels = channels; + } + + /* Make a channel configuration based on either a PCE or a channelConfiguration */ + create_channel_config(hDecoder, hInfo); /* number of samples in this frame */ - hInfo->samples = frame_len*channels; + hInfo->samples = frame_len*output_channels; /* number of channels in this frame */ - hInfo->channels = channels; + hInfo->channels = output_channels; /* samplerate */ - hInfo->samplerate = sample_rates[hDecoder->sf_index]; + hInfo->samplerate = get_sample_rate(hDecoder->sf_index); + /* object type */ + hInfo->object_type = hDecoder->object_type; + /* sbr */ + hInfo->sbr = NO_SBR; + /* header type */ + hInfo->header_type = RAW; + if (hDecoder->adif_header_present) + hInfo->header_type = ADIF; + if (hDecoder->adts_header_present) + hInfo->header_type = ADTS; /* check if frame has channel elements */ if (channels == 0) @@ -480,213 +930,98 @@ void* FAADAPI faacDecDecode(faacDecHandle hDecoder, return NULL; } + /* allocate the buffer for the final samples */ if (hDecoder->sample_buffer == NULL) { - if (hDecoder->config.outputFormat == FAAD_FMT_DOUBLE) - hDecoder->sample_buffer = malloc(frame_len*channels*sizeof(double)); - else - hDecoder->sample_buffer = malloc(frame_len*channels*sizeof(real_t)); + static const uint8_t str[] = { sizeof(int16_t), sizeof(int32_t), sizeof(int32_t), + sizeof(float32_t), sizeof(double), sizeof(int16_t), sizeof(int16_t), + sizeof(int16_t), sizeof(int16_t), 0, 0, 0 + }; + uint8_t stride = str[outputFormat-1]; +#ifdef SBR_DEC + if ((hDecoder->sbr_present_flag == 1) || (hDecoder->forceUpSampling == 1)) + stride = 2 * stride; +#endif + hDecoder->sample_buffer = faad_malloc(frame_len*channels*stride); } sample_buffer = hDecoder->sample_buffer; - /* noiseless coding is done, the rest of the tools come now */ - for (ch = 0; ch < channels; ch++) +#ifdef SBR_DEC + if ((hDecoder->sbr_present_flag == 1) || (hDecoder->forceUpSampling == 1)) { - ic_stream *ics; - - /* find the syntax element to which this channel belongs */ + uint8_t i, ch = 0; for (i = 0; i < ch_ele; i++) { - if (syntax_elements[i]->channel == ch) - ics = &(syntax_elements[i]->ics1); - else if (syntax_elements[i]->paired_channel == ch) - ics = &(syntax_elements[i]->ics2); - } - - /* inverse quantization */ - inverse_quantization(spec_coef[ch], spec_data[ch], frame_len); - - /* apply scalefactors */ -#ifdef FIXED_POINT - apply_scalefactors(ics, spec_coef[ch], frame_len); -#else - apply_scalefactors(ics, spec_coef[ch], pow2_table, frame_len); -#endif - - /* deinterleave short block grouping */ - if (ics->window_sequence == EIGHT_SHORT_SEQUENCE) - quant_to_spec(ics, spec_coef[ch], frame_len); - } - - /* Because for ms, is and pns both channels spectral coefficients are needed - we have to restart running through all channels here. - */ - for (ch = 0; ch < channels; ch++) - { - int16_t pch = -1; - uint8_t right_channel; - ic_stream *ics, *icsr; - ltp_info *ltp; - - /* find the syntax element to which this channel belongs */ - for (i = 0; i < ch_ele; i++) - { - if (syntax_elements[i]->channel == ch) + /* following case can happen when forceUpSampling == 1 */ + if (hDecoder->sbr[i] == NULL) { - ics = &(syntax_elements[i]->ics1); - icsr = &(syntax_elements[i]->ics2); - ltp = &(ics->ltp); - pch = syntax_elements[i]->paired_channel; - right_channel = 0; - } else if (syntax_elements[i]->paired_channel == ch) { - ics = &(syntax_elements[i]->ics2); - if (syntax_elements[i]->common_window) - ltp = &(ics->ltp2); - else - ltp = &(ics->ltp); - right_channel = 1; + hDecoder->sbr[i] = sbrDecodeInit(hDecoder->frameLength +#ifdef DRM + , 0 +#endif + ); + hDecoder->sbr[i]->data = NULL; + hDecoder->sbr[i]->data_size = 0; + hDecoder->sbr[i]->id_aac = hDecoder->element_id[i]; } - } - /* pns decoding */ - if ((!right_channel) && (pch != -1) && (ics->ms_mask_present)) - pns_decode(ics, icsr, spec_coef[ch], spec_coef[pch], frame_len, 1); - else if ((pch == -1) || ((pch != -1) && (!ics->ms_mask_present))) - pns_decode(ics, NULL, spec_coef[ch], NULL, frame_len, 0); - - if (!right_channel && (pch != -1)) - { - /* mid/side decoding */ - ms_decode(ics, icsr, spec_coef[ch], spec_coef[pch], frame_len); - - /* intensity stereo decoding */ - is_decode(ics, icsr, spec_coef[ch], spec_coef[pch], frame_len); - } - -#ifdef MAIN_DEC - /* MAIN object type prediction */ - if (object_type == MAIN) - { - /* allocate the state only when needed */ - if (pred_stat[ch] == NULL) + /* Allocate space for SBR output */ + if (hDecoder->time_out2[ch] == NULL) { - pred_stat[ch] = (pred_state*)malloc(frame_len * sizeof(pred_state)); - reset_all_predictors(pred_stat[ch], frame_len); + hDecoder->time_out2[ch] = (real_t*)faad_malloc(hDecoder->frameLength*2*sizeof(real_t)); + memset(hDecoder->time_out2[ch], 0, hDecoder->frameLength*2*sizeof(real_t)); } - /* intra channel prediction */ - ic_prediction(ics, spec_coef[ch], pred_stat[ch], frame_len); - - /* In addition, for scalefactor bands coded by perceptual - noise substitution the predictors belonging to the - corresponding spectral coefficients are reset. - */ - pns_reset_pred_state(ics, pred_stat[ch]); - } -#endif -#ifdef LTP_DEC - if ((object_type == LTP) -#ifdef ERROR_RESILIENCE - || (object_type == ER_LTP) -#endif -#ifdef LD_DEC - || (object_type == LD) -#endif - ) - { -#ifdef LD_DEC - if (object_type == LD) + if (hDecoder->sbr[i]->id_aac == ID_CPE) { - if (ltp->data_present) + /* space for 2 channels needed */ + if (hDecoder->time_out2[ch+1] == NULL) { - if (ltp->lag_update) - ltp_lag[ch] = ltp->lag; + hDecoder->time_out2[ch+1] = (real_t*)faad_malloc(hDecoder->frameLength*2*sizeof(real_t)); + memset(hDecoder->time_out2[ch+1], 0, hDecoder->frameLength*2*sizeof(real_t)); } - ltp->lag = ltp_lag[ch]; - } -#endif - /* allocate the state only when needed */ - if (lt_pred_stat[ch] == NULL) - { - lt_pred_stat[ch] = (real_t*)malloc(frame_len*4 * sizeof(real_t)); - memset(lt_pred_stat[ch], 0, frame_len*4 * sizeof(real_t)); + memcpy(time_out2[ch], + time_out[ch], frame_len*sizeof(real_t)); + memcpy(time_out2[ch+1], + time_out[ch+1], frame_len*sizeof(real_t)); + sbrDecodeFrame(hDecoder->sbr[i], + time_out2[ch], time_out2[ch+1], + hDecoder->postSeekResetFlag, hDecoder->forceUpSampling); + ch += 2; + } else { + memcpy(time_out2[ch], + time_out[ch], frame_len*sizeof(real_t)); + sbrDecodeFrame(hDecoder->sbr[i], + time_out2[ch], NULL, + hDecoder->postSeekResetFlag, hDecoder->forceUpSampling); + ch++; } - - /* long term prediction */ - lt_prediction(ics, ltp, spec_coef[ch], lt_pred_stat[ch], fb, - ics->window_shape, window_shape_prev[ch], - sf_index, object_type, frame_len); - } -#endif - - /* tns decoding */ - tns_decode_frame(ics, &(ics->tns), sf_index, object_type, - spec_coef[ch], frame_len); - - /* drc decoding */ - if (drc->present) - { - if (!drc->exclude_mask[ch] || !drc->excluded_chns_present) - drc_decode(drc, spec_coef[ch]); - } - - if (time_out[ch] == NULL) - { - time_out[ch] = (real_t*)malloc(frame_len*2*sizeof(real_t)); - memset(time_out[ch], 0, frame_len*2*sizeof(real_t)); } - - /* filter bank */ -#ifdef SSR_DEC - if (object_type != SSR) + frame_len *= 2; + hInfo->samples *= 2; + hInfo->samplerate *= 2; + /* sbr */ + if (hDecoder->sbr_present_flag == 1) { -#endif - ifilter_bank(fb, ics->window_sequence, ics->window_shape, - window_shape_prev[ch], spec_coef[ch], - time_out[ch], object_type, frame_len); -#ifdef SSR_DEC + hInfo->object_type = HE_AAC; + hInfo->sbr = SBR_UPSAMPLED; } else { - if (ssr_overlap[ch] == NULL) - { - ssr_overlap[ch] = (real_t*)malloc(2*frame_len*sizeof(real_t)); - memset(ssr_overlap[ch], 0, 2*frame_len*sizeof(real_t)); - } - if (prev_fmd[ch] == NULL) - { - uint16_t k; - prev_fmd[ch] = (real_t*)malloc(2*frame_len*sizeof(real_t)); - for (k = 0; k < 2*frame_len; k++) - prev_fmd[ch][k] = REAL_CONST(-1); - } - - ssr_decode(&(ics->ssr), fb, ics->window_sequence, ics->window_shape, - window_shape_prev[ch], spec_coef[ch], time_out[ch], - ssr_overlap[ch], hDecoder->ipqf_buffer[ch], prev_fmd[ch], frame_len); + hInfo->sbr = NO_SBR_UPSAMPLED; } -#endif - /* save window shape for next frame */ - window_shape_prev[ch] = ics->window_shape; -#ifdef LTP_DEC - if ((object_type == LTP) -#ifdef ERROR_RESILIENCE - || (object_type == ER_LTP) -#endif -#ifdef LD_DEC - || (object_type == LD) -#endif - ) - { - lt_update_state(lt_pred_stat[ch], time_out[ch], time_out[ch]+frame_len, - frame_len, object_type); - } + sample_buffer = output_to_PCM(hDecoder, time_out2, sample_buffer, + output_channels, frame_len, outputFormat); + } else { #endif + sample_buffer = output_to_PCM(hDecoder, time_out, sample_buffer, + output_channels, frame_len, outputFormat); +#ifdef SBR_DEC } +#endif - sample_buffer = output_to_PCM(time_out, sample_buffer, channels, - frame_len, outputFormat); + hDecoder->postSeekResetFlag = 0; hDecoder->frame++; #ifdef LD_DEC @@ -704,40 +1039,19 @@ void* FAADAPI faacDecDecode(faacDecHandle hDecoder, #endif /* cleanup */ - for (ch = 0; ch < channels; ch++) - { - if (spec_coef[ch]) free(spec_coef[ch]); - if (spec_data[ch]) free(spec_data[ch]); - } - - for (i = 0; i < ch_ele; i++) - { - if (syntax_elements[i]) free(syntax_elements[i]); - } - #ifdef ANALYSIS fflush(stdout); #endif +#ifdef PROFILE + count = faad_get_ts() - count; + hDecoder->cycles += count; +#endif + return sample_buffer; error: - /* free all memory that could have been allocated */ - faad_endbits(ld); - if (ld) free(ld); - /* cleanup */ - for (ch = 0; ch < channels; ch++) - { - if (spec_coef[ch]) free(spec_coef[ch]); - if (spec_data[ch]) free(spec_data[ch]); - } - - for (i = 0; i < ch_ele; i++) - { - if (syntax_elements[i]) free(syntax_elements[i]); - } - #ifdef ANALYSIS fflush(stdout); #endif |