[FFmpeg-devel] [PATCH] AAC decoder round 8
Michael Niedermayer
michaelni
Fri Aug 15 13:09:11 CEST 2008
On Fri, Aug 15, 2008 at 09:04:24AM +0100, Robert Swain wrote:
> 2008/8/15 Michael Niedermayer <michaelni at gmx.at>:
> > On Fri, Aug 15, 2008 at 01:32:08AM +0100, Robert Swain wrote:
> >> $subj
> >>
> >> There's not much left to commit now! :D
> >
> > ok
>
> All committed. Just to make it easier for me and/or you to keep track
> of, here's another patch attached with the remaining hunks.
>
> Regards,
> Rob
> Index: libavcodec/aac.c
> ===================================================================
> --- libavcodec/aac.c (revision 14774)
> +++ libavcodec/aac.c (working copy)
[...]
> @@ -605,6 +616,44 @@
> }
>
> /**
> + * 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 = 0, coef_compress;
useless init ?
> + 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) + 3;
> +
> + for (filt = 0; filt < tns->n_filt[w]; filt++) {
> + tns->length[w][filt] = get_bits(gb, 6 - 2*is8);
> +
> + if ((tns->order[w][filt] = get_bits(gb, 5 - 2*is8)) <= tns_max_order) {
> + tns->direction[w][filt] = get_bits1(gb);
> + coef_compress = get_bits1(gb);
> + coef_len = coef_res - coef_compress;
> + tns->tmp2_map[w][filt] = tns_tmp2_map[2*coef_compress + coef_res - 3];
the 3 can be moved to "coef_len = coef_res - coef_compress + 3"
> +
> + for (i = 0; i < tns->order[w][filt]; i++)
> + tns->coef[w][filt][i] = get_bits(gb, coef_len);
tns->coef is only used to index into tmp2_map thus
tns->coef could already contain the values from tmp2_map
this also would make the tmp2_map field unneeded in the struct
> + } else {
> + 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;
> + }
if(... > tns_max_order){
...
return -1
}
...
seems cleaner to me
> + }
> + }
> + return 0;
> +}
> +
> +/**
> * Decode Mid/Side data; reference: table 4.54.
> *
> * @param ms_present Indicates mid/side stereo presence. [0] mask is all 0s;
> @@ -1067,6 +1116,71 @@
> }
>
> /**
> + * Decode Temporal Noise Shaping filter coefficients and apply all-pole filters; reference: 4.6.9.3.
> + *
> + * @param decode 1 if tool is used normally, 0 if tool is used in LTP.
> + * @param coef spectral coefficients
> + */
> +static void apply_tns(float coef[1024], TemporalNoiseShaping * tns, IndividualChannelStream * ics, int decode) {
> + const int mmm = FFMIN(ics->tns_max_bands, ics->max_sfb);
> + int w, filt, m, i, ib;
> + int bottom, top, order, start, end, size, inc;
> + float tmp;
> + float lpc[TNS_MAX_ORDER + 1], b[2 * TNS_MAX_ORDER];
> +
> + for (w = 0; w < ics->num_windows; w++) {
> + bottom = ics->num_swb;
> + for (filt = 0; filt < tns->n_filt[w]; filt++) {
> + top = bottom;
> + bottom = FFMAX( 0, top - tns->length[w][filt]);
> + order = FFMIN(tns->order[w][filt], TNS_MAX_ORDER);
useless?
> + if (order == 0)
> + continue;
> +
> + // tns_decode_coef
> + lpc[0] = 1;
> + for (m = 1; m <= order; m++) {
> + lpc[m] = tns->tmp2_map[w][filt][tns->coef[w][filt][m - 1]];
> + for (i = 1; i < m; i++)
> + b[i] = lpc[i] + lpc[m] * lpc[m-i];
> + for (i = 1; i < m; i++)
> + lpc[i] = b[i];
> + }
looks a little like eval_coefs from ra144.c
but later is fixedpoint, so this is more a random comment than anything
> +
> + 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
> + memset(b, 0, sizeof(b));
> + ib = 0;
> + for (m = 0; m < size; m++) {
> + tmp = coef[start];
> + if (decode) {
> + for (i = 0; i < order; i++)
> + tmp -= b[ib + i] * lpc[i + 1];
> + } else { // encode
> + for (i = 0; i < order; i++)
> + tmp += b[i] * lpc[i + 1];
> + }
> + if (--ib < 0)
> + ib = order - 1;
> + b[ib] = b[ib + order] = tmp;
> + coef[start] = tmp;
> + start += inc;
> + }
decode is always 1
b is not truly needed, coef[] can be used i its place
also this is likely relevant to overal codec speed so it
should be written more with speed than compactness in mind
[...]
> @@ -232,6 +245,14 @@
> /** @} */
>
> /**
> + * @defgroup temporary aligned temporary buffers (We do not want to have these on the stack.)
> + * @{
> + */
> + DECLARE_ALIGNED_16(float, buf_mdct[2048]);
> + DECLARE_ALIGNED_16(float, revers[1024]);
> + /** @} */
ok, but if you can reduce the amount of arrays or optimize the imdct
stuff that is welcome ...
[...]
> Index: libavcodec/aacdectab.h
> ===================================================================
> --- libavcodec/aacdectab.h (revision 14767)
> +++ libavcodec/aacdectab.h (working copy)
> @@ -156,4 +156,65 @@
>
> // @}
>
> +/* @name tns_max_bands
> + * The maximum number of scalefactor bands on which TNS can operate for the long
> + * and short transforms respectively. The index to these tables is related to
> + * the sample rate of the audio.
> + * @{
> + */
> +static const uint8_t tns_max_bands_1024[] = {
> + 31, 31, 34, 40, 42, 51, 46, 46, 42, 42, 42, 39
> +};
> +
> +static const uint8_t tns_max_bands_128[] = {
> + 9, 9, 10, 14, 14, 14, 14, 14, 14, 14, 14, 14
> +};
> +// @}
ok
> +
> +/* @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[TNS_MAX_ORDER] = {
> + 0.00000000, 0.43388373, -0.64278758, -0.34202015,
> + 0.97492790, 0.78183150, -0.64278758, -0.34202015,
> + -0.43388373, -0.78183150, -0.64278758, -0.34202015,
> + -0.78183150, -0.43388373, -0.64278758, -0.34202015,
> + 0.78183150, 0.97492790, -0.64278758, -0.34202015
> +};
> +
> +static const float tns_tmp2_map_0_3[TNS_MAX_ORDER] = {
> + 0.00000000, 0.43388373, 0.78183150, 0.97492790,
> + -0.98480773, -0.86602539, -0.64278758, -0.34202015,
> + -0.43388373, -0.78183150, -0.97492790, -0.97492790,
> + -0.98480773, -0.86602539, -0.64278758, -0.34202015,
> + 0.78183150, 0.97492790, 0.97492790, 0.78183150
> +};
> +
> +static const float tns_tmp2_map_1_4[TNS_MAX_ORDER] = {
> + 0.00000000, 0.20791170, 0.40673664, 0.58778524,
> + -0.67369562, -0.52643216, -0.36124167, -0.18374951,
> + 0.99452192, 0.95105648, 0.86602539, 0.74314481,
> + -0.67369562, -0.52643216, -0.36124167, -0.18374951,
> + -0.20791176, -0.40673670, -0.58778530, -0.74314487
> +};
> +
> +static const float tns_tmp2_map_0_4[TNS_MAX_ORDER] = {
> + 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,
> + -0.20791176, -0.40673670, -0.58778530, -0.74314487
> +};
iam not sure if the code is correct but i think several of these
elements can never be accessed
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
Good people do not need laws to tell them to act responsibly, while bad
people will find a way around the laws. -- Plato
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20080815/8c787bd1/attachment.pgp>
More information about the ffmpeg-devel
mailing list