[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