From 1dece0d2cda1898dc33b4f4a18766840b76831af Mon Sep 17 00:00:00 2001 From: Robert Swain Date: Mon, 18 Aug 2008 21:36:58 +0000 Subject: [PATCH] More OKed AAC decoder code hunks Originally committed as revision 14829 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libavcodec/aac.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++ libavcodec/aac.h | 12 +++++++++++ libavcodec/aacdectab.h | 35 +++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+) diff --git a/libavcodec/aac.c b/libavcodec/aac.c index 7dd0c5e..27d8cee 100644 --- a/libavcodec/aac.c +++ b/libavcodec/aac.c @@ -605,6 +605,44 @@ static void decode_pulses(Pulse * pulse, GetBitContext * gb, const uint16_t * sw } /** + * Decode Temporal Noise Shaping data; reference: table 4.48. + * + * @return Returns error status. 0 - OK, !0 - error + */ +static int decode_tns(AACContext * ac, TemporalNoiseShaping * tns, + GetBitContext * gb, const IndividualChannelStream * ics) { + int w, filt, i, coef_len, coef_res, coef_compress; + const int is8 = ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE; + const int tns_max_order = is8 ? 7 : ac->m4ac.object_type == AOT_AAC_MAIN ? 20 : 12; + for (w = 0; w < ics->num_windows; w++) { + tns->n_filt[w] = get_bits(gb, 2 - is8); + + if (tns->n_filt[w]) + coef_res = get_bits1(gb); + + for (filt = 0; filt < tns->n_filt[w]; filt++) { + int tmp2_idx; + tns->length[w][filt] = get_bits(gb, 6 - 2*is8); + + if ((tns->order[w][filt] = get_bits(gb, 5 - 2*is8)) > tns_max_order) { + av_log(ac->avccontext, AV_LOG_ERROR, "TNS filter order %d is greater than maximum %d.", + tns->order[w][filt], tns_max_order); + tns->order[w][filt] = 0; + return -1; + } + tns->direction[w][filt] = get_bits1(gb); + coef_compress = get_bits1(gb); + coef_len = coef_res + 3 - coef_compress; + tmp2_idx = 2*coef_compress + coef_res; + + for (i = 0; i < tns->order[w][filt]; i++) + tns->coef[w][filt][i] = tns_tmp2_map[tmp2_idx][get_bits(gb, coef_len)]; + } + } + return 0; +} + +/** * Decode Mid/Side data; reference: table 4.54. * * @param ms_present Indicates mid/side stereo presence. [0] mask is all 0s; @@ -1066,6 +1104,25 @@ static int decode_extension_payload(AACContext * ac, GetBitContext * gb, int cnt return res; } + start = ics->swb_offset[FFMIN(bottom, mmm)]; + end = ics->swb_offset[FFMIN( top, mmm)]; + if ((size = end - start) <= 0) + continue; + if (tns->direction[w][filt]) { + inc = -1; start = end - 1; + } else { + inc = 1; + } + start += w * 128; + + // ar filter + for (m = 0; m < size; m++, start += inc) + for (i = 1; i <= FFMIN(m, order); i++) + coef[start] -= coef[start - i*inc] * lpc[i]; + } + } +} + /** * Conduct IMDCT and windowing. */ diff --git a/libavcodec/aac.h b/libavcodec/aac.h index a64497d..57bf09e 100644 --- a/libavcodec/aac.h +++ b/libavcodec/aac.h @@ -149,6 +149,18 @@ typedef struct { } IndividualChannelStream; /** + * Temporal Noise Shaping + */ +typedef struct { + int present; + int n_filt[8]; + int length[8][4]; + int direction[8][4]; + int order[8][4]; + float coef[8][4][TNS_MAX_ORDER]; +} TemporalNoiseShaping; + +/** * Dynamic Range Control - decoded from the bitstream but not processed further. */ typedef struct { diff --git a/libavcodec/aacdectab.h b/libavcodec/aacdectab.h index c10eb71..3c27c38 100644 --- a/libavcodec/aacdectab.h +++ b/libavcodec/aacdectab.h @@ -171,4 +171,39 @@ static const uint8_t tns_max_bands_128[] = { }; // @} +/* @name tns_tmp2_map + * Tables of the tmp2[] arrays of LPC coefficients used for TNS. + * The suffix _M_N[] indicate the values of coef_compress and coef_res + * respectively. + * @{ + */ +static const float tns_tmp2_map_1_3[4] = { + 0.00000000, 0.43388373, -0.64278758, -0.34202015, +}; + +static const float tns_tmp2_map_0_3[8] = { + 0.00000000, 0.43388373, 0.78183150, 0.97492790, + -0.98480773, -0.86602539, -0.64278758, -0.34202015, +}; + +static const float tns_tmp2_map_1_4[8] = { + 0.00000000, 0.20791170, 0.40673664, 0.58778524, + -0.67369562, -0.52643216, -0.36124167, -0.18374951, +}; + +static const float tns_tmp2_map_0_4[16] = { + 0.00000000, 0.20791170, 0.40673664, 0.58778524, + 0.74314481, 0.86602539, 0.95105654, 0.99452192, + -0.99573416, -0.96182561, -0.89516330, -0.79801720, + -0.67369562, -0.52643216, -0.36124167, -0.18374951, +}; + +static const float *tns_tmp2_map[4] = { + tns_tmp2_map_0_3, + tns_tmp2_map_0_4, + tns_tmp2_map_1_3, + tns_tmp2_map_1_4 +}; +// @} + #endif /* FFMPEG_AACDECTAB_H */ -- 2.7.4