shithub: aacdec

Download patch

ref: a620eaf54c2d009298287d41158bfeb9745ee8f9
parent: 7c7d6306a2f7bbd4ea419277be5f35a35abe8167
author: menno <menno>
date: Thu Jan 29 06:31:11 EST 2004

Added all code to allow Parametric Stereo tools

--- a/libfaad/sbr_dec.c
+++ b/libfaad/sbr_dec.c
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
 **
-** $Id: sbr_dec.c,v 1.25 2004/01/16 20:20:32 menno Exp $
+** $Id: sbr_dec.c,v 1.26 2004/01/29 11:31:11 menno Exp $
 **/
 
 
@@ -102,7 +102,7 @@
     {
         qmfa_end(sbr->qmfa[0]);
         qmfs_end(sbr->qmfs[0]);
-        if (sbr->id_aac == ID_CPE)
+        if (sbr->qmfs[1] != NULL)
         {
             qmfa_end(sbr->qmfa[1]);
             qmfs_end(sbr->qmfs[1]);
@@ -154,12 +154,11 @@
     return 0;
 }
 
-static void sbr_process_channel(sbr_info *sbr, real_t *channel_buf,
+static void sbr_process_channel(sbr_info *sbr, real_t *channel_buf, qmf_t X[MAX_NTSR][64],
                                 uint8_t ch, uint8_t dont_process)
 {
     int16_t i, k, l;
 
-    ALIGN qmf_t X[MAX_NTSR][64];
 #ifdef SBR_LOW_POWER
     ALIGN real_t deg[64];
 #endif
@@ -267,13 +266,6 @@
         }
     }
 
-    /* subband synthesis */
-#ifndef USE_SSE
-    sbr_qmf_synthesis_64(sbr, sbr->qmfs[ch], X, channel_buf);
-#else
-    sbr->qmfs[ch]->qmf_func(sbr, sbr->qmfs[ch], X, channel_buf);
-#endif
-
     for (i = 0; i < sbr->tHFGen; i++)
     {
         memmove(sbr->Xcodec[ch][i], sbr->Xcodec[ch][i+sbr->numTimeSlotsRate], 32 * sizeof(qmf_t));
@@ -286,6 +278,7 @@
 {
     uint8_t dont_process = 0;
     uint8_t ret = 0;
+    ALIGN qmf_t X[MAX_NTSR][64];
 
     if (sbr == NULL)
         return 20;
@@ -311,9 +304,22 @@
         sbr->just_seeked = 0;
     }
 
-    sbr_process_channel(sbr, left_chan, 0, dont_process);
-    sbr_process_channel(sbr, right_chan, 1, dont_process);
+    sbr_process_channel(sbr, left_chan, X, 0, dont_process);
+    /* subband synthesis */
+#ifndef USE_SSE
+    sbr_qmf_synthesis_64(sbr, sbr->qmfs[0], X, left_chan);
+#else
+    sbr->qmfs[ch]->qmf_func(sbr, sbr->qmfs[0], X, left_chan);
+#endif
 
+    sbr_process_channel(sbr, right_chan, X, 1, dont_process);
+    /* subband synthesis */
+#ifndef USE_SSE
+    sbr_qmf_synthesis_64(sbr, sbr->qmfs[1], X, right_chan);
+#else
+    sbr->qmfs[ch]->qmf_func(sbr, sbr->qmfs[1], X, right_chan);
+#endif
+
     if (sbr->bs_header_flag)
         sbr->just_seeked = 0;
 
@@ -335,6 +341,7 @@
 {
     uint8_t dont_process = 0;
     uint8_t ret = 0;
+    ALIGN qmf_t X[MAX_NTSR][64];
 
     if (sbr == NULL)
         return 20;
@@ -360,7 +367,13 @@
         sbr->just_seeked = 0;
     }
 
-    sbr_process_channel(sbr, channel, 0, dont_process);
+    sbr_process_channel(sbr, channel, X, 0, dont_process);
+    /* subband synthesis */
+#ifndef USE_SSE
+    sbr_qmf_synthesis_64(sbr, sbr->qmfs[0], X, channel);
+#else
+    sbr->qmfs[ch]->qmf_func(sbr, sbr->qmfs[0], X, channel);
+#endif
 
     if (sbr->bs_header_flag)
         sbr->just_seeked = 0;
@@ -375,5 +388,92 @@
 
     return 0;
 }
+
+static void ps_dummy_function(qmf_t X_mono[MAX_NTSR][64],
+                              qmf_t X_left[MAX_NTSR][64], qmf_t X_right[MAX_NTSR][64])
+{
+    uint8_t i, j;
+
+    for (i = 0; i < MAX_NTSR; i++)
+    {
+        for (j = 0; j < 64; j++)
+        {
+            QMF_RE(X_left[i][j]) = QMF_RE(X_mono[i][j]);
+            QMF_RE(X_right[i][j]) = QMF_RE(X_mono[i][j]);
+#ifndef SBR_LOW_POWER
+            QMF_IM(X_left[i][j]) = QMF_IM(X_mono[i][j]);
+            QMF_IM(X_right[i][j]) = QMF_IM(X_mono[i][j]);
+#endif
+        }
+    }
+}
+
+#if (defined(PS_DEC) || defined(DRM_PS))
+uint8_t sbrDecodeSingleFramePS(sbr_info *sbr, real_t *left_channel, real_t *right_channel,
+                               const uint8_t just_seeked, const uint8_t upsample_only)
+{
+    uint8_t dont_process = 0;
+    uint8_t ret = 0;
+    ALIGN qmf_t X_mono[MAX_NTSR][64];
+    ALIGN qmf_t X_left[MAX_NTSR][64];
+    ALIGN qmf_t X_right[MAX_NTSR][64];
+
+    if (sbr == NULL)
+        return 20;
+
+    /* case can occur due to bit errors */
+    if (sbr->id_aac != ID_SCE && sbr->id_aac != ID_LFE)
+        return 21;
+
+    if (sbr->ret || (sbr->header_count == 0))
+    {
+        /* don't process just upsample */
+        dont_process = 1;
+
+        /* Re-activate reset for next frame */
+        if (sbr->ret && sbr->Reset)
+            sbr->bs_start_freq_prev = -1;
+    }
+
+    if (just_seeked)
+    {
+        sbr->just_seeked = 1;
+    } else {
+        sbr->just_seeked = 0;
+    }
+
+    if (sbr->frame == 0)
+    {
+        sbr->qmfs[1] = qmfs_init(64);
+    }
+
+    sbr_process_channel(sbr, left_channel, X_mono, 0, dont_process);
+
+    /* perform parametric stereo */
+    ps_dummy_function(X_mono, X_left, X_right);
+
+    /* subband synthesis */
+#ifndef USE_SSE
+    sbr_qmf_synthesis_64(sbr, sbr->qmfs[0], X_left, left_channel);
+    sbr_qmf_synthesis_64(sbr, sbr->qmfs[1], X_right, right_channel);
+#else
+    sbr->qmfs[ch]->qmf_func(sbr, sbr->qmfs[0], X_left, left_channel);
+    sbr->qmfs[ch]->qmf_func(sbr, sbr->qmfs[1], X_right, right_channel);
+#endif
+
+    if (sbr->bs_header_flag)
+        sbr->just_seeked = 0;
+
+    if (sbr->header_count != 0 && sbr->ret == 0)
+    {
+        ret = sbr_save_prev_data(sbr, 0);
+        if (ret) return ret;
+    }
+
+    sbr->frame++;
+
+    return 0;
+}
+#endif
 
 #endif
--- a/libfaad/sbr_dec.h
+++ b/libfaad/sbr_dec.h
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
 **
-** $Id: sbr_dec.h,v 1.21 2004/01/20 18:42:51 menno Exp $
+** $Id: sbr_dec.h,v 1.22 2004/01/29 11:31:11 menno Exp $
 **/
 
 #ifndef __SBR_DEC_H__
@@ -169,6 +169,9 @@
 #ifdef PS_DEC
     ps_info ps;
 #endif
+#if (defined(PS_DEC) || defined(DRM_PS))
+    uint8_t ps_used;
+#endif
 
     /* to get it compiling */
     /* we'll see during the coding of all the tools, whether
@@ -221,6 +224,10 @@
                              const uint8_t just_seeked, const uint8_t upsample_only);
 uint8_t sbrDecodeSingleFrame(sbr_info *sbr, real_t *channel,
                              const uint8_t just_seeked, const uint8_t upsample_only);
+#if (defined(PS_DEC) || defined(DRM_PS))
+uint8_t sbrDecodeSingleFramePS(sbr_info *sbr, real_t *left_channel, real_t *right_channel,
+                               const uint8_t just_seeked, const uint8_t upsample_only);
+#endif
 
 
 #ifdef __cplusplus
--- a/libfaad/sbr_syntax.c
+++ b/libfaad/sbr_syntax.c
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
 **
-** $Id: sbr_syntax.c,v 1.24 2004/01/20 18:42:51 menno Exp $
+** $Id: sbr_syntax.c,v 1.25 2004/01/29 11:31:11 menno Exp $
 **/
 
 #include "common.h"
@@ -693,10 +693,12 @@
     {
 #ifdef PS_DEC
     case EXTENSION_ID_PS:
+        sbr->ps_used = 1;
         return ps_data(&(sbr->ps), ld);
 #endif
 #ifdef DRM_PS
     case DRM_PARAMETRIC_STEREO:
+        sbr->ps_used = 1;
         return drm_ps_data(&(sbr->drm_ps), ld);
 #endif
     default:
--- a/libfaad/specrec.c
+++ b/libfaad/specrec.c
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
 **
-** $Id: specrec.c,v 1.42 2004/01/28 19:17:26 menno Exp $
+** $Id: specrec.c,v 1.43 2004/01/29 11:31:11 menno Exp $
 **/
 
 /*
@@ -688,7 +688,8 @@
 }
 #endif
 
-static uint8_t allocate_single_channel(faacDecHandle hDecoder, uint8_t channel)
+static uint8_t allocate_single_channel(faacDecHandle hDecoder, uint8_t channel,
+                                       uint8_t output_channels)
 {
     uint8_t mul = 1;
 
@@ -732,6 +733,16 @@
         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)
+    {
+        if (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
 
     if (hDecoder->fb_intermed[channel] == NULL)
     {
@@ -868,7 +879,7 @@
 uint8_t reconstruct_single_channel(faacDecHandle hDecoder, ic_stream *ics,
                                    element *sce, int16_t *spec_data)
 {
-    uint8_t retval;
+    uint8_t retval, output_channels;
     ALIGN real_t spec_coef[1024];
 
 #ifdef PROFILE
@@ -875,9 +886,26 @@
     int64_t count = faad_get_ts();
 #endif
 
+
+    /* determine whether some mono->stereo tool is used */
+#if (defined(PS_DEC) || defined(DRM_PS))
+    output_channels = hDecoder->ps_used[hDecoder->fr_ch_ele] ? 2 : 1;
+#else
+    output_channels = 1;
+#endif
+    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 */
+        return 21;
+    }
+
+
     if (hDecoder->element_alloced[hDecoder->fr_ch_ele] == 0)
     {
-        retval = allocate_single_channel(hDecoder, sce->channel);
+        retval = allocate_single_channel(hDecoder, sce->channel, output_channels);
         if (retval > 0)
             return retval;
 
@@ -1013,8 +1041,20 @@
                 );
         }
 
-        retval = sbrDecodeSingleFrame(hDecoder->sbr[ele], hDecoder->time_out[ch],
-            hDecoder->postSeekResetFlag, hDecoder->forceUpSampling);
+        /* check if any of the PS tools is used */
+#if (defined(PS_DEC) || defined(DRM_PS))
+        if (output_channels == 1)
+        {
+#endif
+            retval = sbrDecodeSingleFrame(hDecoder->sbr[ele], hDecoder->time_out[ch],
+                hDecoder->postSeekResetFlag, hDecoder->forceUpSampling);
+#if (defined(PS_DEC) || defined(DRM_PS))
+        } else {
+            retval = sbrDecodeSingleFramePS(hDecoder->sbr[ele], hDecoder->time_out[ch],
+                hDecoder->time_out[ch+1], hDecoder->postSeekResetFlag,
+                hDecoder->forceUpSampling);
+        }
+#endif
         if (retval > 0)
             return retval;
     } else if (((hDecoder->sbr_present_flag == 1) || (hDecoder->forceUpSampling == 1))
--- a/libfaad/structs.h
+++ b/libfaad/structs.h
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
 **
-** $Id: structs.h,v 1.30 2004/01/28 19:17:26 menno Exp $
+** $Id: structs.h,v 1.31 2004/01/29 11:31:11 menno Exp $
 **/
 
 #ifndef __STRUCTS_H__
@@ -381,13 +381,27 @@
     uint8_t downMatrix;
     uint8_t first_syn_ele;
     uint8_t has_lfe;
+    /* number of channels in current frame */
     uint8_t fr_channels;
+    /* number of elements in current frame */
     uint8_t fr_ch_ele;
 
-    void *sample_buffer;
-    uint8_t alloced_channels;
+    /* element_output_channels:
+       determines the number of channels the element will output
+    */
+    uint8_t element_output_channels[MAX_SYNTAX_ELEMENTS];
+    /* element_alloced:
+       determines whether the data needed for the element is allocated or not
+    */
     uint8_t element_alloced[MAX_SYNTAX_ELEMENTS];
+    /* alloced_channels:
+       determines the number of channels where output data is allocated for
+    */
+    uint8_t alloced_channels;
 
+    /* output data buffer */
+    void *sample_buffer;
+
     uint8_t window_shape_prev[MAX_CHANNELS];
 #ifdef LTP_DEC
     uint16_t ltp_lag[MAX_CHANNELS];
@@ -401,6 +415,7 @@
 #ifdef SBR_DEC
     int8_t sbr_present_flag;
     int8_t forceUpSampling;
+    /* determines whether SBR data is allocated for the gives element */
     uint8_t sbr_alloced[MAX_SYNTAX_ELEMENTS];
 
     sbr_info *sbr[MAX_SYNTAX_ELEMENTS];
@@ -408,6 +423,9 @@
     int8_t lcstereo_flag;
 #endif
 #endif
+#if (defined(PS_DEC) || defined(DRM_PS))
+    uint8_t ps_used[MAX_SYNTAX_ELEMENTS];
+#endif
 
 #ifdef SSR_DEC
     real_t *ssr_overlap[MAX_CHANNELS];
@@ -426,7 +444,6 @@
     uint8_t pce_set;
     program_config pce;
     uint8_t element_id[MAX_CHANNELS];
-    uint8_t channel_element[MAX_CHANNELS];
     uint8_t internal_channel[MAX_CHANNELS];
 
     /* Configuration data */
--- a/libfaad/syntax.c
+++ b/libfaad/syntax.c
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
 **
-** $Id: syntax.c,v 1.69 2004/01/28 19:17:26 menno Exp $
+** $Id: syntax.c,v 1.70 2004/01/29 11:31:11 menno Exp $
 **/
 
 /*
@@ -52,6 +52,10 @@
 
 
 /* static function declarations */
+static void decode_sce_lfe(faacDecHandle hDecoder, faacDecFrameInfo *hInfo, bitfile *ld,
+                           uint8_t id_syn_ele);
+static void decode_cpe(faacDecHandle hDecoder, faacDecFrameInfo *hInfo, bitfile *ld,
+                       uint8_t id_syn_ele);
 static uint8_t single_lfe_channel_element(faacDecHandle hDecoder, bitfile *ld,
                                           uint8_t channel, uint8_t *tag);
 static uint8_t channel_pair_element(faacDecHandle hDecoder, bitfile *ld,
@@ -310,9 +314,9 @@
     return 0;
 }
 
-void decode_sce_lfe(faacDecHandle hDecoder,
-                    faacDecFrameInfo *hInfo, bitfile *ld,
-                    uint8_t id_syn_ele)
+static void decode_sce_lfe(faacDecHandle hDecoder,
+                           faacDecFrameInfo *hInfo, bitfile *ld,
+                           uint8_t id_syn_ele)
 {
     uint8_t channels = hDecoder->fr_channels;
     uint8_t tag = 0;
@@ -328,25 +332,35 @@
         return;
     }
 
-    if (id_syn_ele == ID_SCE)
-        hDecoder->channel_element[channels] = hDecoder->fr_ch_ele;
-    else /* LFE */
-        hDecoder->channel_element[channels] = hDecoder->fr_ch_ele;
+    /* for SCE hDecoder->element_output_channels[] is not set here because this
+       can become 2 when some form of Parametric Stereo coding is used
+    */
+
+    /* save the syntax element id */
     hDecoder->element_id[hDecoder->fr_ch_ele] = id_syn_ele;
 
+    /* decode the element */
     hInfo->error = single_lfe_channel_element(hDecoder, ld, channels, &tag);
 
-    if (hDecoder->pce_set)
-        hDecoder->internal_channel[hDecoder->pce.sce_channel[tag]] = channels;
-    else
+    /* map output channels position to internal data channels */
+    if (hDecoder->element_output_channels[hDecoder->fr_ch_ele] == 2)
+    {
+        /* this might be faulty when pce_set is true */
         hDecoder->internal_channel[channels] = channels;
+        hDecoder->internal_channel[channels+1] = channels+1;
+    } else {
+        if (hDecoder->pce_set)
+            hDecoder->internal_channel[hDecoder->pce.sce_channel[tag]] = channels;
+        else
+            hDecoder->internal_channel[channels] = channels;
+    }
 
-    hDecoder->fr_channels++;
+    hDecoder->fr_channels += hDecoder->element_output_channels[hDecoder->fr_ch_ele];
     hDecoder->fr_ch_ele++;
 }
 
-void decode_cpe(faacDecHandle hDecoder, faacDecFrameInfo *hInfo, bitfile *ld,
-                uint8_t id_syn_ele)
+static void decode_cpe(faacDecHandle hDecoder, faacDecFrameInfo *hInfo, bitfile *ld,
+                       uint8_t id_syn_ele)
 {
     uint8_t channels = hDecoder->fr_channels;
     uint8_t tag = 0;
@@ -362,12 +376,24 @@
         return;
     }
 
-    hDecoder->channel_element[channels] = hDecoder->fr_ch_ele;
-    hDecoder->channel_element[channels+1] = hDecoder->fr_ch_ele;
+    /* for CPE the number of output channels is always 2 */
+    if (hDecoder->element_output_channels[hDecoder->fr_ch_ele] == 0)
+    {
+        /* element_output_channels not set yet */
+        hDecoder->element_output_channels[hDecoder->fr_ch_ele] = 2;
+    } else if (hDecoder->element_output_channels[hDecoder->fr_ch_ele] != 2) {
+        /* element inconsistency */
+        hInfo->error = 21;
+        return;
+    }
+
+    /* save the syntax element id */
     hDecoder->element_id[hDecoder->fr_ch_ele] = id_syn_ele;
 
+    /* decode the element */
     hInfo->error = channel_pair_element(hDecoder, ld, channels, &tag);
 
+    /* map output channel position to internal data channels */
     if (hDecoder->pce_set)
     {
         hDecoder->internal_channel[hDecoder->pce.cpe_channel[tag]] = channels;
@@ -971,6 +997,12 @@
 
             /* parse the SBR data */
             hDecoder->sbr[sbr_ele]->ret = sbr_extension_data(ld, hDecoder->sbr[sbr_ele], count);
+#if (defined(PS_DEC) || defined(DRM_PS))
+            if (hDecoder->sbr[sbr_ele]->ps_used)
+            {
+                hDecoder->ps_used[sbr_ele] = 1;
+            }
+#endif
         } else {
 #endif
             while (count > 0)
@@ -1122,7 +1154,6 @@
         }
 
         hDecoder->internal_channel[channels+ch] = channels+ch;
-        hDecoder->channel_element[channels+ch] = hDecoder->fr_ch_ele;
 
         hInfo->error = individual_channel_stream(hDecoder, &cpe, ld, ics, 1, spec_data);
         if (hInfo->error > 0)
@@ -1178,6 +1209,12 @@
         faad_getbits(&ld_sbr, 8); /* Skip 8-bit CRC */
 
         hDecoder->sbr[0]->ret = sbr_extension_data(&ld_sbr, hDecoder->sbr[0], count);
+#if (defined(PS_DEC) || defined(DRM_PS))
+        if (hDecoder->sbr[0]->ps_used)
+        {
+            hDecoder->ps_used[0] = 1;
+        }
+#endif
 
         /* check CRC */
         /* no need to check it if there was already an error */
--- a/libfaad/syntax.h
+++ b/libfaad/syntax.h
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
 **
-** $Id: syntax.h,v 1.47 2004/01/28 19:17:26 menno Exp $
+** $Id: syntax.h,v 1.48 2004/01/29 11:31:11 menno Exp $
 **/
 
 #ifndef __SYNTAX_H__
@@ -110,10 +110,6 @@
 
 uint8_t adts_frame(adts_header *adts, bitfile *ld);
 void get_adif_header(adif_header *adif, bitfile *ld);
-void decode_sce_lfe(faacDecHandle hDecoder, faacDecFrameInfo *hInfo, bitfile *ld,
-                    uint8_t id_syn_ele);
-void decode_cpe(faacDecHandle hDecoder, faacDecFrameInfo *hInfo, bitfile *ld,
-                uint8_t id_syn_ele);
 void raw_data_block(faacDecHandle hDecoder, faacDecFrameInfo *hInfo,
                     bitfile *ld, program_config *pce, drc_info *drc);
 uint8_t reordered_spectral_data(faacDecHandle hDecoder, ic_stream *ics, bitfile *ld,