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

Benjamin Larsson banan
Thu Sep 10 20:53:59 CEST 2009


Michael Niedermayer wrote:
> 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?
> 

Fixed.

> 
> [..]
>> +
>> +
>> +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

Fixed.


> 
> 
>> +    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
> 

Fixed.

> 
> [...]
>> +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)];
> 

Fixed.

> 
> [...]
>> +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)
> 

Fixed.

> 
>> +
>> +    /* 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
> 

Fixed.

> 
>> +                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
> 

Fixed.

> 
>> +
>> +    /* 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
> 

Fixed.

> 
>> +                }
>> +            } 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
> 

Code removed.

> 
>> +{
>> +    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
> 

Code removed.


> 
>> +
>> +    /* 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?
> 

The first 256 samples are used in the iqmf the last 23 are used in the
next call. It is a sample delay line.

> 
> [...]
>> +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)
> 


Fixed.


For other issues flame me on cvs-log and I'll fix it so the code can be
hooked into the build system.

MvH
Benjamin Larsson



More information about the ffmpeg-devel mailing list