diff src/aac/libfaad2/syntax.c @ 3004:8867d3491f60

Sync with FAAD 2.7; will fix warnings in separate commits.
author Tony Vroon <chainsaw@gentoo.org>
date Wed, 08 Apr 2009 20:12:57 +0100
parents f1b6f1b2cdb3
children
line wrap: on
line diff
--- a/src/aac/libfaad2/syntax.c	Sat Feb 28 02:34:13 2009 +0000
+++ b/src/aac/libfaad2/syntax.c	Wed Apr 08 20:12:57 2009 +0100
@@ -1,6 +1,6 @@
 /*
 ** 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
@@ -13,16 +13,19 @@
 ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+** 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: syntax.c,v 1.82 2004/09/04 14:56:29 menno Exp $
+** $Id: syntax.c,v 1.93 2009/01/26 23:51:15 menno Exp $
 **/
 
 /*
@@ -33,9 +36,9 @@
 #include "structs.h"
 
 #include <stdlib.h>
+#include <stdio.h>
 #include <string.h>
 
-#include "decoder.h"
 #include "syntax.h"
 #include "specrec.h"
 #include "huffman.h"
@@ -49,53 +52,56 @@
 #ifdef SBR_DEC
 #include "sbr_syntax.h"
 #endif
+#include "mp4.h"
 
 
 /* static function declarations */
-static void decode_sce_lfe(NeAACDecHandle hDecoder, NeAACDecFrameInfo *hInfo, bitfile *ld,
+static void decode_sce_lfe(NeAACDecStruct *hDecoder, NeAACDecFrameInfo *hInfo, bitfile *ld,
                            uint8_t id_syn_ele);
-static void decode_cpe(NeAACDecHandle hDecoder, NeAACDecFrameInfo *hInfo, bitfile *ld,
+static void decode_cpe(NeAACDecStruct *hDecoder, NeAACDecFrameInfo *hInfo, bitfile *ld,
                        uint8_t id_syn_ele);
-static uint8_t single_lfe_channel_element(NeAACDecHandle hDecoder, bitfile *ld,
+static uint8_t single_lfe_channel_element(NeAACDecStruct *hDecoder, bitfile *ld,
                                           uint8_t channel, uint8_t *tag);
-static uint8_t channel_pair_element(NeAACDecHandle hDecoder, bitfile *ld,
+static uint8_t channel_pair_element(NeAACDecStruct *hDecoder, bitfile *ld,
                                     uint8_t channel, uint8_t *tag);
 #ifdef COUPLING_DEC
-static uint8_t coupling_channel_element(NeAACDecHandle hDecoder, bitfile *ld);
+static uint8_t coupling_channel_element(NeAACDecStruct *hDecoder, bitfile *ld);
 #endif
-static uint16_t data_stream_element(NeAACDecHandle hDecoder, bitfile *ld);
+static uint16_t data_stream_element(NeAACDecStruct *hDecoder, bitfile *ld);
 static uint8_t program_config_element(program_config *pce, bitfile *ld);
-static uint8_t fill_element(NeAACDecHandle hDecoder, bitfile *ld, drc_info *drc
+static uint8_t fill_element(NeAACDecStruct *hDecoder, bitfile *ld, drc_info *drc
 #ifdef SBR_DEC
                             ,uint8_t sbr_ele
 #endif
                             );
-static uint8_t individual_channel_stream(NeAACDecHandle hDecoder, element *ele,
+static uint8_t individual_channel_stream(NeAACDecStruct *hDecoder, element *ele,
                                          bitfile *ld, ic_stream *ics, uint8_t scal_flag,
                                          int16_t *spec_data);
-static uint8_t ics_info(NeAACDecHandle hDecoder, ic_stream *ics, bitfile *ld,
+static uint8_t ics_info(NeAACDecStruct *hDecoder, ic_stream *ics, bitfile *ld,
                         uint8_t common_window);
-static uint8_t section_data(NeAACDecHandle hDecoder, ic_stream *ics, bitfile *ld);
-static uint8_t scale_factor_data(NeAACDecHandle hDecoder, ic_stream *ics, bitfile *ld);
+static uint8_t section_data(NeAACDecStruct *hDecoder, ic_stream *ics, bitfile *ld);
+static uint8_t scale_factor_data(NeAACDecStruct *hDecoder, ic_stream *ics, bitfile *ld);
 #ifdef SSR_DEC
 static void gain_control_data(bitfile *ld, ic_stream *ics);
 #endif
-static uint8_t spectral_data(NeAACDecHandle hDecoder, ic_stream *ics, bitfile *ld,
+static uint8_t spectral_data(NeAACDecStruct *hDecoder, ic_stream *ics, bitfile *ld,
                              int16_t *spectral_data);
 static uint16_t extension_payload(bitfile *ld, drc_info *drc, uint16_t count);
 static uint8_t pulse_data(ic_stream *ics, pulse_info *pul, bitfile *ld);
 static void tns_data(ic_stream *ics, tns_info *tns, bitfile *ld);
 #ifdef LTP_DEC
-static uint8_t ltp_data(NeAACDecHandle hDecoder, ic_stream *ics, ltp_info *ltp, bitfile *ld);
+static uint8_t ltp_data(NeAACDecStruct *hDecoder, ic_stream *ics, ltp_info *ltp, bitfile *ld);
 #endif
 static uint8_t adts_fixed_header(adts_header *adts, bitfile *ld);
 static void adts_variable_header(adts_header *adts, bitfile *ld);
 static void adts_error_check(adts_header *adts, bitfile *ld);
 static uint8_t dynamic_range_info(bitfile *ld, drc_info *drc);
 static uint8_t excluded_channels(bitfile *ld, drc_info *drc);
-#ifdef SCALABLE_DEC
-static int8_t aac_scalable_main_header(NeAACDecHandle hDecoder, ic_stream *ics1, ic_stream *ics2,
-                                       bitfile *ld, uint8_t this_layer_stereo);
+static uint8_t side_info(NeAACDecStruct *hDecoder, element *ele,
+                         bitfile *ld, ic_stream *ics, uint8_t scal_flag);
+#ifdef DRM
+static int8_t DRM_aac_scalable_main_header(NeAACDecStruct *hDecoder, ic_stream *ics1, ic_stream *ics2,
+                                           bitfile *ld, uint8_t this_layer_stereo);
 #endif
 
 
@@ -149,10 +155,10 @@
                 DEBUGVAR(1,145,"GASpecificConfig(): aacScalefactorDataResilienceFlag"));
             mp4ASC->aacSpectralDataResilienceFlag = faad_get1bit(ld
                 DEBUGVAR(1,146,"GASpecificConfig(): aacSpectralDataResilienceFlag"));
-
-            /* 1 bit: extensionFlag3 */
         }
-    }
+        /* 1 bit: extensionFlag3 */
+        faad_getbits(ld, 1);
+	}
 #endif
 
     return 0;
@@ -316,7 +322,7 @@
     return 0;
 }
 
-static void decode_sce_lfe(NeAACDecHandle hDecoder,
+static void decode_sce_lfe(NeAACDecStruct *hDecoder,
                            NeAACDecFrameInfo *hInfo, bitfile *ld,
                            uint8_t id_syn_ele)
 {
@@ -361,7 +367,7 @@
     hDecoder->fr_ch_ele++;
 }
 
-static void decode_cpe(NeAACDecHandle hDecoder, NeAACDecFrameInfo *hInfo, bitfile *ld,
+static void decode_cpe(NeAACDecStruct *hDecoder, NeAACDecFrameInfo *hInfo, bitfile *ld,
                        uint8_t id_syn_ele)
 {
     uint8_t channels = hDecoder->fr_channels;
@@ -409,10 +415,11 @@
     hDecoder->fr_ch_ele++;
 }
 
-void raw_data_block(NeAACDecHandle hDecoder, NeAACDecFrameInfo *hInfo,
+void raw_data_block(NeAACDecStruct *hDecoder, NeAACDecFrameInfo *hInfo,
                     bitfile *ld, program_config *pce, drc_info *drc)
 {
     uint8_t id_syn_ele;
+    uint8_t ele_this_frame = 0;
 
     hDecoder->fr_channels = 0;
     hDecoder->fr_ch_ele = 0;
@@ -429,36 +436,55 @@
         {
             switch (id_syn_ele) {
             case ID_SCE:
+                ele_this_frame++;
                 if (hDecoder->first_syn_ele == 25) hDecoder->first_syn_ele = id_syn_ele;
                 decode_sce_lfe(hDecoder, hInfo, ld, id_syn_ele);
                 if (hInfo->error > 0)
                     return;
                 break;
             case ID_CPE:
+                ele_this_frame++;
                 if (hDecoder->first_syn_ele == 25) hDecoder->first_syn_ele = id_syn_ele;
                 decode_cpe(hDecoder, hInfo, ld, id_syn_ele);
                 if (hInfo->error > 0)
                     return;
                 break;
             case ID_LFE:
+#ifdef DRM
+                hInfo->error = 32;
+#else
+                ele_this_frame++;
                 hDecoder->has_lfe++;
                 decode_sce_lfe(hDecoder, hInfo, ld, id_syn_ele);
+#endif
                 if (hInfo->error > 0)
                     return;
                 break;
             case ID_CCE: /* not implemented yet, but skip the bits */
+#ifdef DRM
+                hInfo->error = 32;
+#else
+                ele_this_frame++;
 #ifdef COUPLING_DEC
                 hInfo->error = coupling_channel_element(hDecoder, ld);
 #else
                 hInfo->error = 6;
 #endif
+#endif
                 if (hInfo->error > 0)
                     return;
                 break;
             case ID_DSE:
+                ele_this_frame++;
                 data_stream_element(hDecoder, ld);
                 break;
             case ID_PCE:
+                if (ele_this_frame != 0)
+                {
+                    hInfo->error = 31;
+                    return;
+                }
+                ele_this_frame++;
                 /* 14496-4: 5.6.4.1.2.1.3: */
                 /* program_configuration_element()'s in access units shall be ignored */
                 program_config_element(pce, ld);
@@ -467,6 +493,7 @@
                 //hDecoder->pce_set = 1;
                 break;
             case ID_FIL:
+                ele_this_frame++;
                 /* one sbr_info describes a channel_element not a channel! */
                 /* if we encounter SBR data here: error */
                 /* SBR data will be read directly in the SCE/LFE/CPE element */
@@ -547,7 +574,11 @@
 
     /* new in corrigendum 14496-3:2002 */
 #ifdef DRM
-    if (hDecoder->object_type != DRM_ER_LC)
+    if (hDecoder->object_type != DRM_ER_LC
+#if 0
+        && !hDecoder->latm_header_present
+#endif
+        )
 #endif
     {
         faad_byte_align(ld);
@@ -558,7 +589,7 @@
 
 /* Table 4.4.4 and */
 /* Table 4.4.9 */
-static uint8_t single_lfe_channel_element(NeAACDecHandle hDecoder, bitfile *ld,
+static uint8_t single_lfe_channel_element(NeAACDecStruct *hDecoder, bitfile *ld,
                                           uint8_t channel, uint8_t *tag)
 {
     uint8_t retval = 0;
@@ -577,6 +608,10 @@
     if (retval > 0)
         return retval;
 
+    /* IS not allowed in single channel */
+    if (ics->is_used)
+        return 32;
+
 #ifdef SBR_DEC
     /* check if next bitstream element is a fill element */
     /* if so, read it now so SBR decoding can be done in case of a file with SBR */
@@ -601,7 +636,7 @@
 }
 
 /* Table 4.4.5 */
-static uint8_t channel_pair_element(NeAACDecHandle hDecoder, bitfile *ld,
+static uint8_t channel_pair_element(NeAACDecStruct *hDecoder, bitfile *ld,
                                     uint8_t channels, uint8_t *tag)
 {
     ALIGN int16_t spec_data1[1024] = {0};
@@ -627,6 +662,11 @@
 
         ics1->ms_mask_present = (uint8_t)faad_getbits(ld, 2
             DEBUGVAR(1,41,"channel_pair_element(): ms_mask_present"));
+        if (ics1->ms_mask_present == 3)
+        {
+            /* bitstream error */
+            return 32;
+        }
         if (ics1->ms_mask_present == 1)
         {
             uint8_t g, sfb;
@@ -726,18 +766,27 @@
 }
 
 /* Table 4.4.6 */
-static uint8_t ics_info(NeAACDecHandle hDecoder, ic_stream *ics, bitfile *ld,
+static uint8_t ics_info(NeAACDecStruct *hDecoder, ic_stream *ics, bitfile *ld,
                         uint8_t common_window)
 {
     uint8_t retval = 0;
+    uint8_t ics_reserved_bit;
 
-    /* ics->ics_reserved_bit = */ faad_get1bit(ld
+    ics_reserved_bit = faad_get1bit(ld
         DEBUGVAR(1,43,"ics_info(): ics_reserved_bit"));
+    if (ics_reserved_bit != 0)
+        return 32;
     ics->window_sequence = (uint8_t)faad_getbits(ld, 2
         DEBUGVAR(1,44,"ics_info(): window_sequence"));
     ics->window_shape = faad_get1bit(ld
         DEBUGVAR(1,45,"ics_info(): window_shape"));
 
+#ifdef LD_DEC
+    /* No block switching in LD */
+    if ((hDecoder->object_type == LD) && (ics->window_sequence != ONLY_LONG_SEQUENCE))
+        return 32;
+#endif
+
     if (ics->window_sequence == EIGHT_SHORT_SEQUENCE)
     {
         ics->max_sfb = (uint8_t)faad_getbits(ld, 4
@@ -753,6 +802,7 @@
     if ((retval = window_grouping_info(hDecoder, ics)) > 0)
         return retval;
 
+
     /* should be an error */
     /* check the range of max_sfb */
     if (ics->max_sfb > ics->num_swb)
@@ -867,7 +917,7 @@
 
 #ifdef COUPLING_DEC
 /* Table 4.4.8: Currently just for skipping the bits... */
-static uint8_t coupling_channel_element(NeAACDecHandle hDecoder, bitfile *ld)
+static uint8_t coupling_channel_element(NeAACDecStruct *hDecoder, bitfile *ld)
 {
     uint8_t c, result = 0;
     uint8_t ind_sw_cce_flag = 0;
@@ -922,6 +972,10 @@
         return result;
     }
 
+    /* IS not allowed in single channel */
+    if (ics->is_used)
+        return 32;
+
     for (c = 1; c < num_gain_element_lists; c++)
     {
         uint8_t cge;
@@ -956,7 +1010,7 @@
 #endif
 
 /* Table 4.4.10 */
-static uint16_t data_stream_element(NeAACDecHandle hDecoder, bitfile *ld)
+static uint16_t data_stream_element(NeAACDecStruct *hDecoder, bitfile *ld)
 {
     uint8_t byte_aligned;
     uint16_t i, count;
@@ -985,7 +1039,7 @@
 }
 
 /* Table 4.4.11 */
-static uint8_t fill_element(NeAACDecHandle hDecoder, bitfile *ld, drc_info *drc
+static uint8_t fill_element(NeAACDecStruct *hDecoder, bitfile *ld, drc_info *drc
 #ifdef SBR_DEC
                             ,uint8_t sbr_ele
 #endif
@@ -1029,7 +1083,8 @@
             hDecoder->sbr_present_flag = 1;
 
             /* parse the SBR data */
-            hDecoder->sbr[sbr_ele]->ret = sbr_extension_data(ld, hDecoder->sbr[sbr_ele], count);
+            hDecoder->sbr[sbr_ele]->ret = sbr_extension_data(ld, hDecoder->sbr[sbr_ele], count,
+                hDecoder->postSeekResetFlag);
 
 #if 0
             if (hDecoder->sbr[sbr_ele]->ret > 0)
@@ -1049,10 +1104,14 @@
 #endif
         } else {
 #endif
+#ifndef DRM
             while (count > 0)
             {
                 count -= extension_payload(ld, drc, count);
             }
+#else
+            return 30;
+#endif
 #ifdef SBR_DEC
         }
 #endif
@@ -1157,10 +1216,10 @@
 }
 #endif
 
-#ifdef SCALABLE_DEC
+#ifdef DRM
 /* Table 4.4.13 ASME */
-void aac_scalable_main_element(NeAACDecHandle hDecoder, NeAACDecFrameInfo *hInfo,
-                               bitfile *ld, program_config *pce, drc_info *drc)
+void DRM_aac_scalable_main_element(NeAACDecStruct *hDecoder, NeAACDecFrameInfo *hInfo,
+                                   bitfile *ld, program_config *pce, drc_info *drc)
 {
     uint8_t retval = 0;
     uint8_t channels = hDecoder->fr_channels = 0;
@@ -1175,7 +1234,7 @@
 
     hDecoder->fr_ch_ele = 0;
 
-    hInfo->error = aac_scalable_main_header(hDecoder, ics1, ics2, ld, this_layer_stereo);
+    hInfo->error = DRM_aac_scalable_main_header(hDecoder, ics1, ics2, ld, this_layer_stereo);
     if (hInfo->error > 0)
         return;
 
@@ -1189,22 +1248,77 @@
         hDecoder->element_id[0] = ID_SCE;
     }
 
-    for (ch = 0; ch < (this_layer_stereo ? 2 : 1); ch++)
+    if (this_layer_stereo)
     {
-        ic_stream *ics;
-        if (ch == 0)
-        {
-            ics = ics1;
-            spec_data = spec_data1;
-        } else {
-            ics = ics2;
-            spec_data = spec_data2;
-        }
+        cpe.channel        = 0;
+        cpe.paired_channel = 1;
+    }
+
+
+    /* Stereo2 / Mono1 */
+    ics1->tns_data_present = faad_get1bit(ld);
 
-        hInfo->error = individual_channel_stream(hDecoder, &cpe, ld, ics, 1, spec_data);
+#if defined(LTP_DEC)
+    ics1->ltp.data_present = faad_get1bit(ld);
+#elif defined (DRM)
+    if(faad_get1bit(ld)) {
+         hInfo->error = 26;
+         return;
+    }
+#else
+    faad_get1bit(ld);
+#endif    
+
+    hInfo->error = side_info(hDecoder, &cpe, ld, ics1, 1);
+    if (hInfo->error > 0)
+        return;
+    if (this_layer_stereo)
+    {
+        /* Stereo3 */
+        ics2->tns_data_present = faad_get1bit(ld);
+#ifdef LTP_DEC
+        ics1->ltp.data_present =
+#endif
+            faad_get1bit(ld);
+        hInfo->error = side_info(hDecoder, &cpe, ld, ics2, 1);
         if (hInfo->error > 0)
             return;
     }
+    /* Stereo4 / Mono2 */
+    if (ics1->tns_data_present)
+        tns_data(ics1, &(ics1->tns), ld);
+    if (this_layer_stereo)
+    {
+        /* Stereo5 */
+        if (ics2->tns_data_present)
+            tns_data(ics2, &(ics2->tns), ld);
+    }
+
+#ifdef DRM
+    /* CRC check */
+    if (hDecoder->object_type == DRM_ER_LC)
+    {
+        if ((hInfo->error = (uint8_t)faad_check_CRC(ld, (uint16_t)faad_get_processed_bits(ld) - 8)) > 0)
+            return;
+    }
+#endif
+
+    /* Stereo6 / Mono3 */
+    /* error resilient spectral data decoding */
+    if ((hInfo->error = reordered_spectral_data(hDecoder, ics1, ld, spec_data1)) > 0)
+    {
+        return;
+    }
+    if (this_layer_stereo)
+    {
+        /* Stereo7 */
+        /* error resilient spectral data decoding */
+        if ((hInfo->error = reordered_spectral_data(hDecoder, ics2, ld, spec_data2)) > 0)
+        {
+            return;
+        }
+    }
+
 
 #ifdef DRM
 #ifdef SBR_DEC
@@ -1244,6 +1358,7 @@
 
         /* Set SBR data */
         /* consider 8 bits from AAC-CRC */
+        /* SBR buffer size is original buffer size minus AAC buffer size */
         count = (uint16_t)bit2byte(buffer_size*8 - bitsconsumed);
         faad_initbits(&ld_sbr, revbuffer, count);
 
@@ -1252,7 +1367,7 @@
 
         faad_getbits(&ld_sbr, 8); /* Skip 8-bit CRC */
 
-        hDecoder->sbr[0]->ret = sbr_extension_data(&ld_sbr, hDecoder->sbr[0], count);
+        hDecoder->sbr[0]->ret = sbr_extension_data(&ld_sbr, hDecoder->sbr[0], count, hDecoder->postSeekResetFlag);
 #if (defined(PS_DEC) || defined(DRM_PS))
         if (hDecoder->sbr[0]->ps_used)
         {
@@ -1261,6 +1376,11 @@
         }
 #endif
 
+        if (ld_sbr.error)
+        {
+            hDecoder->sbr[0]->ret = 1;
+        }
+
         /* check CRC */
         /* no need to check it if there was already an error */
         if (hDecoder->sbr[0]->ret == 0)
@@ -1269,7 +1389,7 @@
         /* SBR data was corrupted, disable it until the next header */
         if (hDecoder->sbr[0]->ret != 0)
         {
-            hDecoder->sbr[0]->header_count = 0;  
+            hDecoder->sbr[0]->header_count = 0;
         }
 
         faad_endbits(&ld_sbr);
@@ -1308,15 +1428,18 @@
 }
 
 /* Table 4.4.15 */
-static int8_t aac_scalable_main_header(NeAACDecHandle hDecoder, ic_stream *ics1, ic_stream *ics2,
-                                       bitfile *ld, uint8_t this_layer_stereo)
+static int8_t DRM_aac_scalable_main_header(NeAACDecStruct *hDecoder, ic_stream *ics1, ic_stream *ics2,
+                                           bitfile *ld, uint8_t this_layer_stereo)
 {
     uint8_t retval = 0;
     uint8_t ch;
     ic_stream *ics;
+    uint8_t ics_reserved_bit;
 
-    /* ics1->ics_reserved_bit = */ faad_get1bit(ld
+    ics_reserved_bit = faad_get1bit(ld
         DEBUGVAR(1,300,"aac_scalable_main_header(): ics_reserved_bits"));
+    if (ics_reserved_bit != 0)
+        return 32;
     ics1->window_sequence = (uint8_t)faad_getbits(ld, 2
         DEBUGVAR(1,301,"aac_scalable_main_header(): window_sequence"));
     ics1->window_shape = faad_get1bit(ld
@@ -1346,6 +1469,11 @@
     {
         ics1->ms_mask_present = (uint8_t)faad_getbits(ld, 2
             DEBUGVAR(1,306,"aac_scalable_main_header(): ms_mask_present"));
+        if (ics1->ms_mask_present == 3)
+        {
+            /* bitstream error */
+            return 32;
+        }
         if (ics1->ms_mask_present == 1)
         {
             uint8_t g, sfb;
@@ -1364,70 +1492,12 @@
         ics1->ms_mask_present = 0;
     }
 
-    if (0)
-    {
-        faad_get1bit(ld
-            DEBUGVAR(1,308,"aac_scalable_main_header(): tns_channel_mono_layer"));
-    }
-
-    for (ch = 0; ch < (this_layer_stereo ? 2 : 1); ch++)
-    {
-        if (ch == 0)
-            ics = ics1;
-        else
-            ics = ics2;
-
-        if ( 1 /*!tvq_layer_pesent || (tns_aac_tvq_en[ch] == 1)*/)
-        {
-            if ((ics->tns_data_present = faad_get1bit(ld
-                DEBUGVAR(1,309,"aac_scalable_main_header(): tns_data_present"))) & 1)
-            {
-#ifdef DRM
-                /* different order of data units in DRM */
-                if (hDecoder->object_type != DRM_ER_LC)
-#endif
-                {
-                    tns_data(ics, &(ics->tns), ld);
-                }
-            }
-        }
-#if 0
-        if (0 /*core_flag || tvq_layer_pesent*/)
-        {
-            if ((ch==0) || ((ch==1) && (core_stereo || tvq_stereo))
-                diff_control_data();
-            if (mono_stereo_flag)
-                diff_control_data_lr();
-        } else {
-#endif
-            if ((
-#ifdef LTP_DEC
-                ics->ltp.data_present =
-#endif
-                faad_get1bit(ld DEBUGVAR(1,310,"aac_scalable_main_header(): ltp.data_present"))) & 1)
-            {
-#ifdef LTP_DEC
-                if ((retval = ltp_data(hDecoder, ics, &(ics->ltp), ld)) > 0)
-                {
-                    return retval;
-                }
-#else
-                return 26;
-#endif
-            }
-#if 0
-        }
-#endif
-    }
-
     return 0;
 }
 #endif
 
-/* Table 4.4.24 */
-static uint8_t individual_channel_stream(NeAACDecHandle hDecoder, element *ele,
-                                         bitfile *ld, ic_stream *ics, uint8_t scal_flag,
-                                         int16_t *spec_data)
+static uint8_t side_info(NeAACDecStruct *hDecoder, element *ele,
+                         bitfile *ld, ic_stream *ics, uint8_t scal_flag)
 {
     uint8_t result;
 
@@ -1513,6 +1583,21 @@
         if ((result = rvlc_decode_scale_factors(ics, ld)) > 0)
             return result;
     }
+#endif
+
+    return 0;
+}
+
+/* Table 4.4.24 */
+static uint8_t individual_channel_stream(NeAACDecStruct *hDecoder, element *ele,
+                                         bitfile *ld, ic_stream *ics, uint8_t scal_flag,
+                                         int16_t *spec_data)
+{
+    uint8_t result;
+
+    result = side_info(hDecoder, ele, ld, ics, scal_flag);
+    if (result > 0)
+        return result;
 
     if (hDecoder->object_type >= ER_OBJECT_START) 
     {
@@ -1523,10 +1608,13 @@
 #ifdef DRM
     /* CRC check */
     if (hDecoder->object_type == DRM_ER_LC)
+    {
         if ((result = (uint8_t)faad_check_CRC(ld, (uint16_t)faad_get_processed_bits(ld) - 8)) > 0)
             return result;
+    }
 #endif
 
+#ifdef ERROR_RESILIENCE
     if (hDecoder->aacSpectralDataResilienceFlag)
     {
         /* error resilient spectral data decoding */
@@ -1561,7 +1649,7 @@
 }
 
 /* Table 4.4.25 */
-static uint8_t section_data(NeAACDecHandle hDecoder, ic_stream *ics, bitfile *ld)
+static uint8_t section_data(NeAACDecStruct *hDecoder, ic_stream *ics, bitfile *ld)
 {
     uint8_t g;
     uint8_t sect_esc_val, sect_bits;
@@ -1594,7 +1682,7 @@
 
             /* if "faad_getbits" detects error and returns "0", "k" is never
                incremented and we cannot leave the while loop */
-            if ((ld->error != 0) || (ld->no_more_reading))
+            if (ld->error != 0)
                 return 14;
 
 #ifdef ERROR_RESILIENCE
@@ -1605,12 +1693,23 @@
             ics->sect_cb[g][i] = (uint8_t)faad_getbits(ld, sect_cb_bits
                 DEBUGVAR(1,71,"section_data(): sect_cb"));
 
+            if (ics->sect_cb[g][i] == 12)
+                return 32;
+
 #if 0
             printf("%d\n", ics->sect_cb[g][i]);
 #endif
 
+#ifndef DRM
             if (ics->sect_cb[g][i] == NOISE_HCB)
                 ics->noise_used = 1;
+#else
+            /* PNS not allowed in DRM */
+            if (ics->sect_cb[g][i] == NOISE_HCB)
+                return 29;
+#endif
+            if (ics->sect_cb[g][i] == INTENSITY_HCB2 || ics->sect_cb[g][i] == INTENSITY_HCB)
+                ics->is_used = 1;
 
 #ifdef ERROR_RESILIENCE
             if (hDecoder->aacSectionDataResilienceFlag)
@@ -1651,10 +1750,18 @@
             printf("%d\n", ics->sect_end[g][i]);
 #endif
 
-            if (k + sect_len >= 8*15)
-                return 15;
-            if (i >= 8*15)
-                return 15;
+            if (ics->window_sequence == EIGHT_SHORT_SEQUENCE)
+            {
+                if (k + sect_len > 8*15)
+                    return 15;
+                if (i >= 8*15)
+                    return 15;
+            } else {
+                if (k + sect_len > MAX_SFB)
+                    return 15;
+                if (i >= MAX_SFB)
+                    return 15;
+            }
 
             for (sfb = k; sfb < k + sect_len; sfb++)
             {
@@ -1675,6 +1782,13 @@
             i++;
         }
         ics->num_sec[g] = i;
+
+        /* the sum of all sect_len_incr elements for a given window
+         * group shall equal max_sfb */
+        if (k != ics->max_sfb)
+        {
+            return 32;
+        }
 #if 0
         printf("%d\n", ics->num_sec[g]);
 #endif
@@ -1735,6 +1849,7 @@
                 break;
             case NOISE_HCB: /* noise books */
 
+#ifndef DRM
                 /* decode noise energy */
                 if (noise_pcm_flag)
                 {
@@ -1750,6 +1865,10 @@
 #ifdef SF_PRINT
                 printf("%d\n", ics->scale_factors[g][sfb]);
 #endif
+#else
+                /* PNS not allowed in DRM */
+                return 29;
+#endif
 
                 break;
             default: /* spectral books */
@@ -1777,7 +1896,7 @@
 }
 
 /* Table 4.4.26 */
-static uint8_t scale_factor_data(NeAACDecHandle hDecoder, ic_stream *ics, bitfile *ld)
+static uint8_t scale_factor_data(NeAACDecStruct *hDecoder, ic_stream *ics, bitfile *ld)
 {
     uint8_t ret = 0;
 #ifdef PROFILE
@@ -1885,7 +2004,7 @@
 
 #ifdef LTP_DEC
 /* Table 4.4.28 */
-static uint8_t ltp_data(NeAACDecHandle hDecoder, ic_stream *ics, ltp_info *ltp, bitfile *ld)
+static uint8_t ltp_data(NeAACDecStruct *hDecoder, ic_stream *ics, ltp_info *ltp, bitfile *ld)
 {
     uint8_t sfb, w;
 
@@ -1948,7 +2067,7 @@
 #endif
 
 /* Table 4.4.29 */
-static uint8_t spectral_data(NeAACDecHandle hDecoder, ic_stream *ics, bitfile *ld,
+static uint8_t spectral_data(NeAACDecStruct *hDecoder, ic_stream *ics, bitfile *ld,
                              int16_t *spectral_data)
 {
     int8_t i;
@@ -2127,7 +2246,7 @@
         n++;
         drc->num_bands += band_incr;
 
-        for (i = 0; i < drc->num_bands; i++);
+        for (i = 0; i < drc->num_bands; i++)
         {
             drc->band_top[i] = (uint8_t)faad_getbits(ld, 8
                 DEBUGVAR(1,97,"dynamic_range_info(): band_top"));
@@ -2328,3 +2447,188 @@
             DEBUGVAR(1,134,"adts_error_check(): crc_check"));
     }
 }
+
+/* LATM parsing functions */
+
+static uint32_t latm_get_value(bitfile *ld)
+{
+    uint32_t l, value;
+    uint8_t bytesForValue;
+
+    bytesForValue = (uint8_t)faad_getbits(ld, 2);
+    value = 0;
+    for(l=0; l<bytesForValue; l++)
+        value = (value << 8) | (uint8_t)faad_getbits(ld, 8);
+
+    return value;
+}
+
+
+static uint32_t latmParsePayload(latm_header *latm, bitfile *ld)
+{
+    //assuming there's only one program with a single layer and 1 subFrame,
+    //allStreamsSametimeframing is set,
+    uint32_t framelen;
+    uint8_t tmp;
+
+    //this should be the payload length field for the current configuration
+    framelen = 0;
+    if(latm->framelen_type==0)
+    {
+        do
+        {
+            tmp = (uint8_t)faad_getbits(ld, 8);
+            framelen += tmp;
+        } while(tmp==0xff);
+    }
+    else if(latm->framelen_type==1)
+        framelen=latm->frameLength;
+
+    return framelen;
+}
+
+
+static uint32_t latmAudioMuxElement(latm_header *latm, bitfile *ld)
+{
+    uint32_t ascLen, asc_bits=0;
+    uint32_t x1, y1, m, n, i;
+    program_config pce;
+    mp4AudioSpecificConfig mp4ASC;
+
+    latm->useSameStreamMux = (uint8_t)faad_getbits(ld, 1);
+    if(!latm->useSameStreamMux)
+    {
+        //parseSameStreamMuxConfig
+        latm->version = (uint8_t) faad_getbits(ld, 1);
+        if(latm->version)
+            latm->versionA = (uint8_t) faad_getbits(ld, 1);
+        if(latm->versionA)
+        {
+            //dunno the payload format for versionA
+            fprintf(stderr, "versionA not supported\n");
+            return 0;
+        }
+        if(latm->version) //read taraBufferFullness
+            latm_get_value(ld);
+        latm->allStreamsSameTimeFraming = (uint8_t)faad_getbits(ld, 1);
+        latm->numSubFrames = (uint8_t)faad_getbits(ld, 6) + 1;
+        latm->numPrograms = (uint8_t)faad_getbits(ld, 4) + 1;
+        latm->numLayers = faad_getbits(ld, 3) + 1;
+        if(latm->numPrograms>1 || !latm->allStreamsSameTimeFraming || latm->numSubFrames>1 || latm->numLayers>1)
+        {
+            fprintf(stderr, "\r\nUnsupported LATM configuration: %d programs/ %d subframes, %d layers, allstreams: %d\n",
+                latm->numPrograms, latm->numSubFrames, latm->numLayers, latm->allStreamsSameTimeFraming);
+            return 0;
+        }
+        ascLen = 0;
+        if(latm->version)
+            ascLen = latm_get_value(ld);
+
+        x1 = faad_get_processed_bits(ld);
+        if(AudioSpecificConfigFromBitfile(ld, &mp4ASC, &pce, 0, 1) < 0)
+            return 0;
+
+        //horrid hack to unread the ASC bits and store them in latm->ASC
+        //the correct code would rely on an ideal faad_ungetbits()
+        y1 = faad_get_processed_bits(ld);
+        if((y1-x1) <= MAX_ASC_BYTES*8)
+        {
+            faad_rewindbits(ld);
+            m = x1;
+            while(m>0)
+            {
+                n = min(m, 32);
+                faad_getbits(ld, n);
+                m -= n;
+            }
+
+            i = 0;
+            m = latm->ASCbits = y1 - x1;
+            while(m > 0)
+            {
+                n = min(m, 8);
+                latm->ASC[i++] = (uint8_t) faad_getbits(ld, n);
+                m -= n;
+            }
+        }
+
+        asc_bits = y1-x1;
+
+        if(ascLen>asc_bits)
+            faad_getbits(ld, ascLen-asc_bits);
+
+        latm->framelen_type = (uint8_t) faad_getbits(ld, 3);
+        if(latm->framelen_type == 0)
+        {
+            latm->frameLength = 0;
+            faad_getbits(ld, 8); //buffer fullness for frame_len_type==0, useless
+        }
+        else if(latm->framelen_type == 1)
+        {
+            latm->frameLength = faad_getbits(ld, 9);
+            if(latm->frameLength==0)
+            {
+                fprintf(stderr, "Invalid frameLength: 0\r\n");
+                return 0;
+            }
+            latm->frameLength = (latm->frameLength+20)*8;
+        }
+        else
+        {   //hellish CELP or HCVX stuff, discard
+            fprintf(stderr, "Unsupported CELP/HCVX framelentype: %d\n", latm->framelen_type);
+            return 0;
+        }
+
+        latm->otherDataLenBits = 0;
+        if(faad_getbits(ld, 1))
+        {   //other data present
+            int esc, tmp;
+            if(latm->version)
+                latm->otherDataLenBits = latm_get_value(ld);
+            else do
+            {
+                esc = faad_getbits(ld, 1);
+                tmp = faad_getbits(ld, 8);
+                latm->otherDataLenBits = (latm->otherDataLenBits << 8) + tmp;
+            } while(esc);
+        }
+        if(faad_getbits(ld, 1)) //crc
+            faad_getbits(ld, 8);
+        latm->inited = 1;
+      }
+
+      //read payload
+      if(latm->inited)
+          return latmParsePayload(latm, ld);
+      else
+          return 0;
+}
+
+
+uint32_t faad_latm_frame(latm_header *latm, bitfile *ld)
+{
+    uint16_t len;
+    uint32_t initpos, endpos, firstpos, ret;
+
+    firstpos = faad_get_processed_bits(ld);
+    while (ld->bytes_left)
+    {
+        faad_byte_align(ld);
+        if(faad_showbits(ld, 11) != 0x2B7)
+        {
+            faad_getbits(ld, 8);
+            continue;
+        }
+        faad_getbits(ld, 11);
+        len = faad_getbits(ld, 13);
+        if(!len)
+            continue;
+        initpos = faad_get_processed_bits(ld);
+        ret = latmAudioMuxElement(latm, ld);
+        endpos = faad_get_processed_bits(ld);
+        if(ret>0)
+            return (len*8)-(endpos-initpos);
+        //faad_getbits(ld, initpos-endpos); //go back to initpos, but is valid a getbits(-N) ? 
+    }
+    return -1U;
+}