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 [email protected].
**
-** $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 [email protected].
**
-** $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 [email protected].
**
-** $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 [email protected].
**
-** $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 [email protected].
**
-** $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 [email protected].
**
-** $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 [email protected].
**
-** $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,