[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