Sigrid Haflínudóttirplan 9 port, initial versionab3fc376 years agoHistory
1253 lines · 36.9 KB · C
RawDownload
/*** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding** 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** 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 Nero AG through Mpeg4AAClicense@nero.com.**** $Id: decoder.c,v 1.119 2015/01/24 14:21:05 knik Exp $**/ #include "common.h"#include "structs.h"#include "mp4.h"#include "syntax.h"#include "error.h"#include "output.h"#include "filtbank.h"#include "drc.h"#ifdef SBR_DEC#include "sbr_dec.h"#include "sbr_syntax.h"#endif#ifdef SSR_DEC#include "ssr.h"#include "ssr_fb.h"#endif #ifdef ANALYSISuint16_t dbg_count;#endif #if !defined(PACKAGE_VERSION)#error "PACKAGE_VERSION must be defined"#endif /* static function declarations */static void* aac_frame_decode(NeAACDecStruct *hDecoder,                              NeAACDecFrameInfo *hInfo,                              unsigned char *buffer,                              unsigned long buffer_size,                              void **sample_buffer2,                              unsigned long sample_buffer_size);static void create_channel_config(NeAACDecStruct *hDecoder,                                  NeAACDecFrameInfo *hInfo);  int NeAACDecGetVersion(char **faad_id_string,                                   char **faad_copyright_string){    static char *libfaadName = PACKAGE_VERSION;    static char *libCopyright =        " Copyright 2002-2004: Ahead Software AG\n"	" http://www.audiocoding.com\n"	" bug tracking: https://sourceforge.net/p/faac/bugs/\n";     if (faad_id_string)        *faad_id_string = libfaadName;     if (faad_copyright_string)        *faad_copyright_string = libCopyright;     return 0;} char* NeAACDecGetErrorMessage(unsigned char errcode){    if (errcode >= NUM_ERROR_MESSAGES)        return NULL;    return err_msg[errcode];} unsigned long NeAACDecGetCapabilities(void){    uint32_t cap = 0;     /* can't do without it */    cap += LC_DEC_CAP; #ifdef MAIN_DEC    cap += MAIN_DEC_CAP;#endif#ifdef LTP_DEC    cap += LTP_DEC_CAP;#endif#ifdef LD_DEC    cap += LD_DEC_CAP;#endif#ifdef ERROR_RESILIENCE    cap += ERROR_RESILIENCE_CAP;#endif#ifdef FIXED_POINT    cap += FIXED_POINT_CAP;#endif     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 NeAACDecOpen(void){    uint8_t i;    NeAACDecStruct *hDecoder = NULL;     if ((hDecoder = (NeAACDecStruct*)faad_malloc(sizeof(NeAACDecStruct))) == NULL)        return NULL;     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 */    hDecoder->config.downMatrix = 0;    hDecoder->adts_header_present = 0;    hDecoder->adif_header_present = 0;    hDecoder->latm_header_present = 0;#ifdef ERROR_RESILIENCE    hDecoder->aacSectionDataResilienceFlag = 0;    hDecoder->aacScalefactorDataResilienceFlag = 0;    hDecoder->aacSpectralDataResilienceFlag = 0;#endif    hDecoder->frameLength = 1024;     hDecoder->frame = 0;    hDecoder->sample_buffer = NULL;     // Same as (1, 1) after 1024 iterations; otherwise first values does not look random at all.    hDecoder->__r1 = 0x2bb431ea;    hDecoder->__r2 = 0x206155b7;     for (i = 0; i < MAX_CHANNELS; i++)    {        hDecoder->element_id[i] = INVALID_ELEMENT_ID;        hDecoder->window_shape_prev[i] = 0;        hDecoder->time_out[i] = NULL;        hDecoder->fb_intermed[i] = NULL;#ifdef SSR_DEC        hDecoder->ssr_overlap[i] = NULL;        hDecoder->prev_fmd[i] = NULL;#endif#ifdef MAIN_DEC        hDecoder->pred_stat[i] = NULL;#endif#ifdef LTP_DEC        hDecoder->ltp_lag[i] = 0;        hDecoder->lt_pred_stat[i] = NULL;#endif    } #ifdef SBR_DEC    for (i = 0; i < MAX_SYNTAX_ELEMENTS; i++)    {        hDecoder->sbr[i] = NULL;    }#endif     hDecoder->drc = drc_init(REAL_CONST(1.0), REAL_CONST(1.0));     return hDecoder;} NeAACDecConfigurationPtr NeAACDecGetCurrentConfiguration(NeAACDecHandle hpDecoder){    NeAACDecStruct* hDecoder = (NeAACDecStruct*)hpDecoder;    if (hDecoder)    {        NeAACDecConfigurationPtr config = &(hDecoder->config);         return config;    }     return NULL;} unsigned char NeAACDecSetConfiguration(NeAACDecHandle hpDecoder,                                                   NeAACDecConfigurationPtr config){    NeAACDecStruct* hDecoder = (NeAACDecStruct*)hpDecoder;    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 */#ifdef FIXED_POINT        if ((config->outputFormat < 1) || (config->outputFormat > 4))            return 0;#else        if ((config->outputFormat < 1) || (config->outputFormat > 5))            return 0;#endif        hDecoder->config.outputFormat = config->outputFormat;         if (config->downMatrix > 1)            return 0;        hDecoder->config.downMatrix = config->downMatrix;         /* OK */        return 1;    }     return 0;}  #if 0static int latmCheck(latm_header *latm, bitfile *ld){    uint32_t good=0, bad=0, bits, m;     while (ld->bytes_left)    {        bits = faad_latm_frame(latm, ld);        if(bits==0xFFFFFFFF)            bad++;        else        {            good++;            while(bits>0)            {                m = min(bits, 8);                faad_getbits(ld, m);                bits -= m;            }        }    }     return (good>0);}#endif long NeAACDecInit(NeAACDecHandle hpDecoder,                              unsigned char *buffer,                              unsigned long buffer_size,                              unsigned long *samplerate,                              unsigned char *channels){    uint32_t bits = 0;    bitfile ld;    adif_header adif;    adts_header adts;    NeAACDecStruct* hDecoder = (NeAACDecStruct*)hpDecoder;      if ((hDecoder == NULL) || (samplerate == NULL) || (channels == NULL) || (buffer_size == 0))        return -1;     hDecoder->sf_index = get_sr_index(hDecoder->config.defSampleRate);    hDecoder->object_type = hDecoder->config.defObjectType;    *samplerate = get_sample_rate(hDecoder->sf_index);    *channels = 1;     if (buffer != NULL)    {#if 0        int is_latm;        latm_header *l = &hDecoder->latm_config;#endif         faad_initbits(&ld, buffer, buffer_size); #if 0        memset(l, 0, sizeof(latm_header));        is_latm = latmCheck(l, &ld);        l->inited = 0;        l->frameLength = 0;        faad_rewindbits(&ld);        if(is_latm && l->ASCbits>0)        {            int32_t x;            hDecoder->latm_header_present = 1;            x = NeAACDecInit2(hDecoder, l->ASC, (l->ASCbits+7)/8, samplerate, channels);            if(x!=0)                hDecoder->latm_header_present = 0;            return x;        } else#endif        /* Check if an ADIF header is present */        if ((buffer_size >= 8) && (buffer[0] == 'A') && (buffer[1] == 'D') &&            (buffer[2] == 'I') && (buffer[3] == 'F'))        {            hDecoder->adif_header_present = 1;             get_adif_header(&adif, &ld);            faad_byte_align(&ld);             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;             memcpy(&(hDecoder->pce), &(adif.pce[0]), sizeof(program_config));            hDecoder->pce_set = 1;             bits = bit2byte(faad_get_processed_bits(&ld));         /* Check if an ADTS header is present */        } 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 + 1;             *samplerate = get_sample_rate(hDecoder->sf_index);            *channels = (adts.channel_configuration > 6) ?                2 : adts.channel_configuration;        }         if (ld.error)        {            faad_endbits(&ld);            return -1;        }        faad_endbits(&ld);    }     if (!*samplerate)        return -1; #if (defined(PS_DEC) || defined(DRM_PS))    /* check if we have a mono file */    if (*channels == 1)    {        /* upMatrix to 2 channels for implicit signalling of PS */        *channels = 2;    }#endif     hDecoder->channelConfiguration = *channels; #ifdef SBR_DEC    /* implicit signalling */    if (*samplerate <= 24000 && (hDecoder->config.dontUpSampleImplicitSBR == 0))    {        *samplerate *= 2;        hDecoder->forceUpSampling = 1;    } else if (*samplerate > 24000 && (hDecoder->config.dontUpSampleImplicitSBR == 0)) {        hDecoder->downSampledSBR = 1;    }#endif     /* must be done before frameLength is divided by 2 for LD */#ifdef SSR_DEC    if (hDecoder->object_type == SSR)        hDecoder->fb = ssr_filter_bank_init(hDecoder->frameLength/SSR_BANDS);    else#endif        hDecoder->fb = filter_bank_init(hDecoder->frameLength); #ifdef LD_DEC    if (hDecoder->object_type == LD)        hDecoder->frameLength >>= 1;#endif     if (can_decode_ot(hDecoder->object_type) < 0)        return -1;     return bits;} /* Init the library using a DecoderSpecificInfo */char NeAACDecInit2(NeAACDecHandle hpDecoder,                               unsigned char *pBuffer,                               unsigned long SizeOfDecoderSpecificInfo,                               unsigned long *samplerate,                               unsigned char *channels){    NeAACDecStruct* hDecoder = (NeAACDecStruct*)hpDecoder;    int8_t rc;    mp4AudioSpecificConfig mp4ASC;     if((hDecoder == NULL)        || (pBuffer == NULL)        || (SizeOfDecoderSpecificInfo < 2)        || (samplerate == NULL)        || (channels == NULL))    {        return -1;    }     hDecoder->adif_header_present = 0;    hDecoder->adts_header_present = 0;     /* decode the audio specific config */    rc = AudioSpecificConfig2(pBuffer, SizeOfDecoderSpecificInfo, &mp4ASC,        &(hDecoder->pce), hDecoder->latm_header_present);     /* copy the relevant info to the decoder handle */    *samplerate = mp4ASC.samplingFrequency;    if (mp4ASC.channelsConfiguration)    {        *channels = mp4ASC.channelsConfiguration;    } else {        *channels = hDecoder->pce.channels;        hDecoder->pce_set = 1;    }#if (defined(PS_DEC) || defined(DRM_PS))    /* check if we have a mono file */    if (*channels == 1)    {        /* upMatrix to 2 channels for implicit signalling of PS */        *channels = 2;    }#endif    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->downSampledSBR = mp4ASC.downSampledSBR;    if (hDecoder->config.dontUpSampleImplicitSBR == 0)        hDecoder->forceUpSampling = mp4ASC.forceUpSampling;    else        hDecoder->forceUpSampling = 0;     /* AAC core decoder samplerate is 2 times as low */    if (((hDecoder->sbr_present_flag == 1)&&(!hDecoder->downSampledSBR)) || hDecoder->forceUpSampling == 1)    {        hDecoder->sf_index = get_sr_index(mp4ASC.samplingFrequency / 2);    }#endif     if (rc != 0)    {        return rc;    }    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    if (hDecoder->object_type == SSR)        hDecoder->fb = ssr_filter_bank_init(hDecoder->frameLength/SSR_BANDS);    else#endif        hDecoder->fb = filter_bank_init(hDecoder->frameLength); #ifdef LD_DEC    if (hDecoder->object_type == LD)        hDecoder->frameLength >>= 1;#endif     return 0;} #ifdef DRMchar NeAACDecInitDRM(NeAACDecHandle *hpDecoder,                                 unsigned long samplerate,                                 unsigned char channels){    NeAACDecStruct** hDecoder = (NeAACDecStruct**)hpDecoder;    if (hDecoder == NULL)        return 1; /* error */     NeAACDecClose(*hDecoder);     *hDecoder = NeAACDecOpen();     /* Special object type defined for DRM */    (*hDecoder)->config.defObjectType = DRM_ER_LC;

Lines 1–500 of 1253.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t