[FFmpeg-devel] atrac1 decoder and aea demuxer rev 6

Michael Niedermayer michaelni
Wed Sep 9 22:00:10 CEST 2009


On Sun, Sep 06, 2009 at 08:12:04PM +0200, Benjamin Larsson wrote:
> Changes:
[...]
> Changed some code.

:)


> 
> Did not do anything to the qmf routines that will be shared with atrac3
> as it will be a svn copy and I'll take comments on that when the code is
>  split out in it's own file.
> 
> Thanks for all the comments so far.
[...]

> +
> +static const uint8_t bfu_bands_t[4]  = {0, 20, 36, 52}; // number of BFUs in each QMF band
> +
> +/* number of spectral lines in each BFU */
> +static const uint8_t specs_per_bfu[52] = {
> +     8,  8,  8,  8,  4,  4,  4,  4,  8,  8,  8,  8,  6,  6,  6,  6, 6, 6, 6, 6, // low band
> +     6,  6,  6,  6,  7,  7,  7,  7,  9,  9,  9,  9, 10, 10, 10, 10,             // midle band
> +    12, 12, 12, 12, 12, 12, 12, 12, 20, 20, 20, 20, 20, 20, 20, 20              // high band
> +};

i guess i knew it once but what is a bfu? ill probably figure it out in a
few seconds when looking at the use of these but i think it could help if
its written out here somewhere

also coments are not doxygen compatible
has patcheck not found these?


[..]
> +
> +
> +typedef struct {
> +    int                 bsm[AT1_QMF_BANDS];                 ///< block size mode (1 byte large in bitstream)

if that is the log2 of the number of blocks then it should be called
log2_block_count if not then what "block size mode" means should be
clarified


> +    int                 num_bfus;                           ///< number of Block Floating Units
> +    int                 idwls[AT1_MAX_BFU];                 ///< the word length indexes for each BFU
> +    int                 idsfs[AT1_MAX_BFU];                 ///< the scalefactor indexes for each BFU
> +    float*              spectrum[2];
> +    DECLARE_ALIGNED_16(float,spec1[AT1_SU_SAMPLES]);        ///< mdct buffer
> +    DECLARE_ALIGNED_16(float,spec2[AT1_SU_SAMPLES]);        ///< mdct buffer
> +    DECLARE_ALIGNED_16(float,fst_qmf_delay[46]);            ///< delay line for the 1st stacked QMF filter
> +    DECLARE_ALIGNED_16(float,snd_qmf_delay[46]);            ///< delay line for the 2nd stacked QMF filter
> +    DECLARE_ALIGNED_16(float,last_qmf_delay[256+23]);       ///< delay line for the last stacked QMF filter
> +} AT1SUCtx;

the struct itself is missing a doxy commnet explaining what it represents


[...]
> +static void at1_imdct(AT1Ctx *q, float *spec, float *out, int nbits, int rev_spec)
> +{
> +    MDCTContext* mdct_context;
> +    int transf_size = 1 << nbits;
> +

> +    switch (nbits) {
> +        case 5:
> +            mdct_context = &q->mdct_ctx[0];
> +            break;
> +        case 7:
> +            mdct_context = &q->mdct_ctx[1];
> +            break;
> +        case 8:
> +        default:
> +            mdct_context = &q->mdct_ctx[2];
> +            break;
> +    }

mdct_context = &q->mdct_ctx[nbits - 5 - (nbits>6)];


[...]
> +static int at1_parse_block_size_mode(GetBitContext* gb, int bsm[AT1_QMF_BANDS])
> +{
> +    int bsm_tmp;
> +

> +    /* low band */
> +    bsm_tmp = get_bits(gb, 2);
> +    if (bsm_tmp & 1)
> +        return -1;
> +    bsm[IDX_LOW_BAND] = 2 - bsm_tmp;
> +
> +    /* middle band */
> +    bsm_tmp = get_bits(gb, 2);
> +    if (bsm_tmp & 1)
> +        return -1;
> +    bsm[IDX_MID_BAND] = 2 - bsm_tmp;

for(2)


> +
> +    /* high band */
> +    bsm_tmp = get_bits(gb, 2);
> +    if (bsm_tmp != 0 && bsm_tmp != 3)
> +        return -1;
> +    bsm[IDX_HIGH_BAND] = 3 - bsm_tmp;
> +
> +    skip_bits(gb, 2);
> +    return 0;
> +}
> +

> +static int at1_unpack_dequant(GetBitContext* gb, AT1SUCtx* su, float spec[AT1_SU_SAMPLES])
> +{
> +    int bits_used, band_num, bfu_num, i;
> +
> +    /* parse the info byte (2nd byte) telling how much BFUs were coded */
> +    su->num_bfus = bfu_amount_tab1[get_bits(gb, 3)];
> +
> +    /* calc number of consumed bits:
> +        num_BFUs * (idwl(4bits) + idsf(6bits)) + bsm(8bits) + info_byte(8bits)
> +        + info_byte_copy(8bits) + bsm_copy(8bits) */
> +    bits_used = su->num_bfus * 10 + 32 +

> +                bfu_amount_tab2[get_bits(gb, 2)] * 4 +

the *4 could be merged into the table


> +                bfu_amount_tab3[get_bits(gb, 3)] * 6;

the *3 could be merged into the table changing this to a shift
these 2 are maybe not worth it if they reduce sanity of the table


> +
> +    /* get word length index (idwl) for each BFU */
> +    for (i=0 ; i<su->num_bfus ; i++)
> +        su->idwls[i] = get_bits(gb, 4);
> +
> +    /* get scalefactor index (idsf) for each BFU */
> +    for (i=0 ; i<su->num_bfus ; i++)
> +        su->idsfs[i] = get_bits(gb, 6);
> +
> +    /* zero idwl/idsf for empty BFUs */
> +    for (i = su->num_bfus; i < AT1_MAX_BFU; i++)
> +        su->idwls[i] = su->idsfs[i] = 0;
> +
> +    /* read in the spectral data and reconstruct MDCT spectrum of this channel */
> +    for (band_num=0 ; band_num<AT1_QMF_BANDS ; band_num++) {
> +        for (bfu_num=bfu_bands_t[band_num] ; bfu_num<bfu_bands_t[band_num+1] ; bfu_num++) {
> +            int pos;
> +
> +            int num_specs = specs_per_bfu[bfu_num];
> +            int word_len  = !!su->idwls[bfu_num] + su->idwls[bfu_num];
> +            bits_used    += word_len * num_specs; /* add number of bits consumed by current BFU */
> +
> +            /* check for bitstream overflow */
> +            if (bits_used > AT1_SU_MAX_BITS)
> +                return -1;
> +
> +            /* get the position of the 1st spec according to the block size mode */
> +            pos = su->bsm[band_num] ? bfu_start_short[bfu_num] : bfu_start_long[bfu_num];
> +
> +            if (word_len) {
> +                float   max_quant = 1.0/(float)((1 << (word_len - 1)) - 1);
> +

> +                for (i=0 ; i<num_specs ; i++) {
> +                    /* read in a quantized spec and convert it to
> +                     * signed int and then inverse quantization
> +                     */
> +                    spec[pos+i] = get_sbits(gb, word_len) *
> +                                            sf_tab[su->idsfs[bfu_num]] * max_quant;

sf_tab[su->idsfs[bfu_num]] can be factored out


> +                }
> +            } else { /* word_len = 0 -> empty BFU, zero all specs in the emty BFU */
> +                memset(&spec[pos], 0, num_specs*sizeof(float));
> +            }
> +        }
> +    }
> +
> +    return 0;
> +}
> +

> +//Same as atrac3 will be moved to a common file
> +void at1_iqmf(float *inlo, float *inhi, int32_t nIn, float *pOut, float *delayBuf, float *temp)

some of these should be const, and int32_t seems wrong


> +{
> +    int   i, j;
> +    float   *p1, *p3;
> +
> +    memcpy(temp, delayBuf, 46*sizeof(float));
> +
> +    p3 = temp + 46;
> +
> +    /* loop1 */
> +    for(i=0; i<nIn; i+=2){
> +        p3[2*i+0] = inlo[i  ] + inhi[i  ];
> +        p3[2*i+1] = inlo[i  ] - inhi[i  ];
> +        p3[2*i+2] = inlo[i+1] + inhi[i+1];
> +        p3[2*i+3] = inlo[i+1] - inhi[i+1];
> +    }
> +

> +    /* loop2 */
> +    p1 = temp;
> +    for (j = nIn; j != 0; j--) {
> +        float s1 = 0.0;
> +        float s2 = 0.0;
> +
> +        for (i = 0; i < 48; i += 2) {
> +            s1 += p1[i] * qmf_window[i];
> +            s2 += p1[i+1] * qmf_window[i+1];
> +        }
> +
> +        pOut[0] = s2;
> +        pOut[1] = s1;
> +
> +        p1 += 2;
> +        pOut += 2;
> +    }

this looks like a convolution, maybe that can be done more efficiently


> +
> +    /* Update the delay buffer. */
> +    memcpy(delayBuf, temp + nIn*2, 46*sizeof(float));
> +}
> +

> +void at1_subband_synthesis(AT1Ctx *q, AT1SUCtx* su, float *pOut)
> +{
> +    float   temp[256];
> +    float   iqmf_temp[512 + 46];
> +
> +    /* combine low and middle bands */
> +    at1_iqmf(q->bands[0], q->bands[1], 128, temp, su->fst_qmf_delay, iqmf_temp);
> +
> +    /* delay the signal of the high band by 23 samples */
> +    memcpy( su->last_qmf_delay,     &su->last_qmf_delay[256], sizeof(float)*23);
> +    memcpy(&su->last_qmf_delay[23], q->bands[2],       sizeof(float)*256);

the memcpy of the delay of 23 samples, that i understand but why are the
whole 256 samples copied too?


[...]
> +static int aea_read_probe(AVProbeData *p)
> +{
> +    if (p->buf_size <= 2048+212)
> +        return 0;
> +
> +    /* Magic is '00 08 00 00' in Little Endian*/
> +    if(AV_RL32(p->buf)==0x800) {
> +        int bsm_s, bsm_e, inb_s, inb_e;
> +        bsm_s = p->buf[2048];
> +        inb_s = p->buf[2048+1];
> +        inb_e = p->buf[2048+210];
> +        bsm_e = p->buf[2048+211];
> +
> +
> +        /* Check so that the redundant bsm bytes and info bytes are valid
> +         * the block size mode bytes have to be the same
> +         * the info bytes have to be the same
> +         * the block size mode and info byte can't be the same
> +         */
> +        if ((bsm_s == bsm_e) && (inb_s == inb_e) && (bsm_s != inb_s))

the () are useless
also this can be simplified to
a= AV_RL16()
b= AV_RL16()
if(a == bswap16(b) && a != b)


[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

It is dangerous to be right in matters on which the established authorities
are wrong. -- Voltaire
-------------- 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/20090909/f12e7c2b/attachment.pgp>



More information about the ffmpeg-devel mailing list