More OKed sections of AAC decoder code

Originally committed as revision 14770 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
Robert Swain 2008-08-15 00:05:09 +00:00
parent e9b9a2f86f
commit 62a57fae59
2 changed files with 347 additions and 0 deletions

View File

@ -99,6 +99,53 @@ static VLC vlc_scalefactors;
static VLC vlc_spectral[11];
/**
* Configure output channel order based on the current program configuration element.
*
* @param che_pos current channel position configuration
* @param new_che_pos New channel position configuration - we only do something if it differs from the current one.
*
* @return Returns error status. 0 - OK, !0 - error
*/
static int output_configure(AACContext *ac, enum ChannelPosition che_pos[4][MAX_ELEM_ID],
enum ChannelPosition new_che_pos[4][MAX_ELEM_ID]) {
AVCodecContext *avctx = ac->avccontext;
int i, type, channels = 0;
if(!memcmp(che_pos, new_che_pos, 4 * MAX_ELEM_ID * sizeof(new_che_pos[0][0])))
return 0; /* no change */
memcpy(che_pos, new_che_pos, 4 * MAX_ELEM_ID * sizeof(new_che_pos[0][0]));
/* Allocate or free elements depending on if they are in the
* current program configuration.
*
* Set up default 1:1 output mapping.
*
* For a 5.1 stream the output order will be:
* [ Front Left ] [ Front Right ] [ Center ] [ LFE ] [ Surround Left ] [ Surround Right ]
*/
for(i = 0; i < MAX_ELEM_ID; i++) {
for(type = 0; type < 4; type++) {
if(che_pos[type][i]) {
if(!ac->che[type][i] && !(ac->che[type][i] = av_mallocz(sizeof(ChannelElement))))
return AVERROR(ENOMEM);
if(type != TYPE_CCE) {
ac->output_data[channels++] = ac->che[type][i]->ch[0].ret;
if(type == TYPE_CPE) {
ac->output_data[channels++] = ac->che[type][i]->ch[1].ret;
}
}
} else
av_freep(&ac->che[type][i]);
}
}
avctx->channels = channels;
return 0;
}
/**
* Decode an array of 4 bit element IDs, optionally interleaved with a stereo/mono switching bit.
*
@ -209,6 +256,17 @@ static int set_default_channel_config(AACContext *ac, enum ChannelPosition new_c
return 0;
}
/**
* Decode GA "General Audio" specific configuration; reference: table 4.1.
*
* @return Returns error status. 0 - OK, !0 - error
*/
static int decode_ga_specific_config(AACContext * ac, GetBitContext * gb, int channel_config) {
enum ChannelPosition new_che_pos[4][MAX_ELEM_ID];
int extension_flag, ret;
if(get_bits1(gb)) { // frameLengthFlag
av_log_missing_feature(ac->avccontext, "960/120 MDCT window is", 1);
return -1;
}
@ -289,6 +347,17 @@ static int decode_audio_specific_config(AACContext * ac, void *data, int data_si
return 0;
}
/**
* linear congruential pseudorandom number generator
*
* @param previous_val pointer to the current state of the generator
*
* @return Returns a 32-bit pseudorandom integer
*/
static av_always_inline int lcg_random(int previous_val) {
return previous_val * 1664525 + 1013904223;
}
static av_cold int aac_decode_init(AVCodecContext * avccontext) {
AACContext * ac = avccontext->priv_data;
int i;
@ -381,6 +450,21 @@ static int decode_ics_info(AACContext * ac, IndividualChannelStream * ics, GetBi
ics->num_window_groups = 1;
ics->group_len[0] = 1;
if (get_bits1(gb)) {
av_log_missing_feature(ac->avccontext, "Predictor bit set but LTP is", 1);
memset(ics, 0, sizeof(IndividualChannelStream));
return -1;
}
}
if(ics->max_sfb > ics->num_swb) {
av_log(ac->avccontext, AV_LOG_ERROR,
"Number of scalefactor bands in group (%d) exceeds limit (%d).\n",
ics->max_sfb, ics->num_swb);
memset(ics, 0, sizeof(IndividualChannelStream));
return -1;
}
return 0;
}
@ -520,6 +604,14 @@ static void decode_pulses(Pulse * pulse, GetBitContext * gb) {
*/
static void decode_mid_side_stereo(ChannelElement * cpe, GetBitContext * gb,
int ms_present) {
int idx;
if (ms_present == 1) {
for (idx = 0; idx < cpe->ch[0].ics.num_window_groups * cpe->ch[0].ics.max_sfb; idx++)
cpe->ms_mask[idx] = get_bits1(gb);
} else if (ms_present == 2) {
memset(cpe->ms_mask, 1, cpe->ch[0].ics.num_window_groups * cpe->ch[0].ics.max_sfb * sizeof(cpe->ms_mask[0]));
}
}
/**
* Add pulses with particular amplitudes to the quantized spectral data; reference: 4.6.3.3.
@ -635,6 +727,64 @@ static int decode_cpe(AACContext * ac, GetBitContext * gb, int elem_id) {
return 0;
}
coup->coupling_point = 2*get_bits1(gb);
coup->num_coupled = get_bits(gb, 3);
for (c = 0; c <= coup->num_coupled; c++) {
num_gain++;
coup->type[c] = get_bits1(gb) ? TYPE_CPE : TYPE_SCE;
coup->id_select[c] = get_bits(gb, 4);
if (coup->type[c] == TYPE_CPE) {
coup->ch_select[c] = get_bits(gb, 2);
if (coup->ch_select[c] == 3)
num_gain++;
} else
coup->ch_select[c] = 1;
}
coup->coupling_point += get_bits1(gb);
if (coup->coupling_point == 2) {
av_log(ac->avccontext, AV_LOG_ERROR,
"Independently switched CCE with 'invalid' domain signalled.\n");
memset(coup, 0, sizeof(ChannelCoupling));
return -1;
}
sign = get_bits(gb, 1);
scale = pow(2., pow(2., get_bits(gb, 2) - 3));
if ((ret = decode_ics(ac, sce, gb, 0, 0)))
return ret;
for (c = 0; c < num_gain; c++) {
int cge = 1;
int gain = 0;
float gain_cache = 1.;
if (c) {
cge = coup->coupling_point == AFTER_IMDCT ? 1 : get_bits1(gb);
gain = cge ? get_vlc2(gb, vlc_scalefactors.table, 7, 3) - 60: 0;
gain_cache = pow(scale, gain);
}
for (g = 0; g < sce->ics.num_window_groups; g++)
for (sfb = 0; sfb < sce->ics.max_sfb; sfb++, idx++)
if (sce->band_type[idx] != ZERO_BT) {
if (!cge) {
int t = get_vlc2(gb, vlc_scalefactors.table, 7, 3) - 60;
if (t) {
int s = 1;
if (sign) {
s -= 2 * (t & 0x1);
t >>= 1;
}
gain += t;
gain_cache = pow(scale, gain) * s;
}
}
coup->gain[c][idx] = gain_cache;
}
}
return 0;
}
/**
* Decode Spectral Band Replication extension data; reference: table 4.55.
*
@ -650,6 +800,23 @@ static int decode_sbr_extension(AACContext * ac, GetBitContext * gb, int crc, in
return cnt;
}
/**
* Parse whether channels are to be excluded from Dynamic Range Compression; reference: table 4.53.
*
* @return Returns number of bytes consumed.
*/
static int decode_drc_channel_exclusions(DynamicRangeControl *che_drc, GetBitContext * gb) {
int i;
int num_excl_chan = 0;
do {
for (i = 0; i < 7; i++)
che_drc->exclude_mask[num_excl_chan++] = get_bits1(gb);
} while (num_excl_chan < MAX_CHANNELS - 7 && get_bits1(gb));
return num_excl_chan / 7;
}
/**
* Decode dynamic range information; reference: table 4.52.
*
@ -746,6 +913,55 @@ static void imdct_and_windowing(AACContext * ac, SingleChannelElement * sce) {
float * buf = ac->buf_mdct;
int i;
if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
if (ics->window_sequence[1] == ONLY_LONG_SEQUENCE || ics->window_sequence[1] == LONG_STOP_SEQUENCE)
av_log(ac->avccontext, AV_LOG_WARNING,
"Transition from an ONLY_LONG or LONG_STOP to an EIGHT_SHORT sequence detected. "
"If you heard an audible artifact, please submit the sample to the FFmpeg developers.\n");
for (i = 0; i < 2048; i += 256) {
ff_imdct_calc(&ac->mdct_small, buf + i, in + i/2);
ac->dsp.vector_fmul_reverse(ac->revers + i/2, buf + i + 128, swindow, 128);
}
for (i = 0; i < 448; i++) out[i] = saved[i] + ac->add_bias;
ac->dsp.vector_fmul_add_add(out + 448 + 0*128, buf + 0*128, swindow_prev, saved + 448 , ac->add_bias, 128, 1);
ac->dsp.vector_fmul_add_add(out + 448 + 1*128, buf + 2*128, swindow, ac->revers + 0*128, ac->add_bias, 128, 1);
ac->dsp.vector_fmul_add_add(out + 448 + 2*128, buf + 4*128, swindow, ac->revers + 1*128, ac->add_bias, 128, 1);
ac->dsp.vector_fmul_add_add(out + 448 + 3*128, buf + 6*128, swindow, ac->revers + 2*128, ac->add_bias, 128, 1);
ac->dsp.vector_fmul_add_add(out + 448 + 4*128, buf + 8*128, swindow, ac->revers + 3*128, ac->add_bias, 64, 1);
#if 0
vector_fmul_add_add_add(&ac->dsp, out + 448 + 1*128, buf + 2*128, swindow, saved + 448 + 1*128, ac->revers + 0*128, ac->add_bias, 128);
vector_fmul_add_add_add(&ac->dsp, out + 448 + 2*128, buf + 4*128, swindow, saved + 448 + 2*128, ac->revers + 1*128, ac->add_bias, 128);
vector_fmul_add_add_add(&ac->dsp, out + 448 + 3*128, buf + 6*128, swindow, saved + 448 + 3*128, ac->revers + 2*128, ac->add_bias, 128);
vector_fmul_add_add_add(&ac->dsp, out + 448 + 4*128, buf + 8*128, swindow, saved + 448 + 4*128, ac->revers + 3*128, ac->add_bias, 64);
#endif
ac->dsp.vector_fmul_add_add(saved, buf + 1024 + 64, swindow + 64, ac->revers + 3*128+64, 0, 64, 1);
ac->dsp.vector_fmul_add_add(saved + 64, buf + 1024 + 2*128, swindow, ac->revers + 4*128, 0, 128, 1);
ac->dsp.vector_fmul_add_add(saved + 192, buf + 1024 + 4*128, swindow, ac->revers + 5*128, 0, 128, 1);
ac->dsp.vector_fmul_add_add(saved + 320, buf + 1024 + 6*128, swindow, ac->revers + 6*128, 0, 128, 1);
memcpy( saved + 448, ac->revers + 7*128, 128 * sizeof(float));
memset( saved + 576, 0, 448 * sizeof(float));
} else {
ff_imdct_calc(&ac->mdct, buf, in);
if (ics->window_sequence[0] == LONG_STOP_SEQUENCE) {
for (i = 0; i < 448; i++) out[i] = saved[i] + ac->add_bias;
ac->dsp.vector_fmul_add_add(out + 448, buf + 448, swindow_prev, saved + 448, ac->add_bias, 128, 1);
for (i = 576; i < 1024; i++) out[i] = buf[i] + saved[i] + ac->add_bias;
} else {
ac->dsp.vector_fmul_add_add(out, buf, lwindow_prev, saved, ac->add_bias, 1024, 1);
}
if (ics->window_sequence[0] == LONG_START_SEQUENCE) {
memcpy(saved, buf + 1024, 448 * sizeof(float));
ac->dsp.vector_fmul_reverse(saved + 448, buf + 1024 + 448, swindow, 128);
memset(saved + 576, 0, 448 * sizeof(float));
} else {
ac->dsp.vector_fmul_reverse(saved, buf + 1024, lwindow, 1024);
}
}
}
/**
* Apply dependent channel coupling (applied before IMDCT).
*
@ -789,6 +1005,91 @@ static void apply_independent_coupling(AACContext * ac, SingleChannelElement * s
sce->ret[i] += cc->coup.gain[index][0] * (cc->ch[0].ret[i] - ac->add_bias);
}
}
}
}
}
static int aac_decode_frame(AVCodecContext * avccontext, void * data, int * data_size, const uint8_t * buf, int buf_size) {
AACContext * ac = avccontext->priv_data;
GetBitContext gb;
enum RawDataBlockType elem_type;
int err, elem_id, data_size_tmp;
init_get_bits(&gb, buf, buf_size*8);
// parse
while ((elem_type = get_bits(&gb, 3)) != TYPE_END) {
elem_id = get_bits(&gb, 4);
err = -1;
if(elem_type == TYPE_SCE && elem_id == 1 &&
!ac->che[TYPE_SCE][elem_id] && ac->che[TYPE_LFE][0]) {
/* Some streams incorrectly code 5.1 audio as SCE[0] CPE[0] CPE[1] SCE[1]
instead of SCE[0] CPE[0] CPE[0] LFE[0]. If we seem to have
encountered such a stream, transfer the LFE[0] element to SCE[1] */
ac->che[TYPE_SCE][elem_id] = ac->che[TYPE_LFE][0];
ac->che[TYPE_LFE][0] = NULL;
}
if(elem_type && elem_type < TYPE_DSE) {
if(!ac->che[elem_type][elem_id])
return -1;
if(elem_type != TYPE_CCE)
ac->che[elem_type][elem_id]->coup.coupling_point = 4;
}
switch (elem_type) {
case TYPE_SCE:
err = decode_ics(ac, &ac->che[TYPE_SCE][elem_id]->ch[0], &gb, 0, 0);
break;
case TYPE_CPE:
err = decode_cpe(ac, &gb, elem_id);
break;
case TYPE_CCE:
err = decode_cce(ac, &gb, ac->che[TYPE_SCE][elem_id]);
break;
case TYPE_LFE:
err = decode_ics(ac, &ac->che[TYPE_LFE][elem_id]->ch[0], &gb, 0, 0);
break;
case TYPE_DSE:
skip_data_stream_element(&gb);
err = 0;
break;
case TYPE_PCE:
{
enum ChannelPosition new_che_pos[4][MAX_ELEM_ID];
memset(new_che_pos, 0, 4 * MAX_ELEM_ID * sizeof(new_che_pos[0][0]));
if((err = decode_pce(ac, new_che_pos, &gb)))
break;
err = output_configure(ac, ac->che_pos, new_che_pos);
break;
}
case TYPE_FIL:
if (elem_id == 15)
elem_id += get_bits(&gb, 8) - 1;
while (elem_id > 0)
elem_id -= decode_extension_payload(ac, &gb, elem_id);
err = 0; /* FIXME */
break;
default:
err = -1; /* should not happen, but keeps compiler happy */
break;
}
if(err)
return err;
}
spectral_to_sample(ac);
if (!ac->is_saved) {
ac->is_saved = 1;
*data_size = 0;

View File

@ -135,6 +135,17 @@ enum CouplingPoint {
/**
* Individual Channel Stream
*/
typedef struct {
uint8_t max_sfb; ///< number of scalefactor bands per group
enum WindowSequence window_sequence[2];
uint8_t use_kb_window[2]; ///< If set, use Kaiser-Bessel window, otherwise use a sinus window.
int num_window_groups;
uint8_t group_len[8];
const uint16_t *swb_offset; ///< table of offsets to the lowest spectral coefficient of a scalefactor band, sfb, for a particular window
int num_swb; ///< number of scalefactor window bands
int num_windows;
int tns_max_bands;
} IndividualChannelStream;
/**
* Dynamic Range Control - decoded from the bitstream but not processed further.
@ -163,6 +174,41 @@ typedef struct {
* coupling parameters
*/
typedef struct {
enum CouplingPoint coupling_point; ///< The point during decoding at which coupling is applied.
int num_coupled; ///< number of target elements
enum RawDataBlockType type[8]; ///< Type of channel element to be coupled - SCE or CPE.
int id_select[8]; ///< element id
int ch_select[8]; /**< [0] shared list of gains; [1] list of gains for left channel;
* [2] list of gains for right channel; [3] lists of gains for both channels
*/
float gain[16][120];
} ChannelCoupling;
/**
* Single Channel Element - used for both SCE and LFE elements.
*/
typedef struct {
IndividualChannelStream ics;
TemporalNoiseShaping tns;
enum BandType band_type[120]; ///< band types
int band_type_run_end[120]; ///< band type run end points
float sf[120]; ///< scalefactors
DECLARE_ALIGNED_16(float, coeffs[1024]); ///< coefficients for IMDCT
DECLARE_ALIGNED_16(float, saved[1024]); ///< overlap
DECLARE_ALIGNED_16(float, ret[1024]); ///< PCM output
} SingleChannelElement;
/**
* channel element - generic struct for SCE/CPE/CCE/LFE
*/
typedef struct {
// CPE specific
uint8_t ms_mask[120]; ///< Set if mid/side stereo is used for each scalefactor window band
// shared
SingleChannelElement ch[2];
// CCE specific
ChannelCoupling coup;
} ChannelElement;
/**
* main AAC context