[FFmpeg-devel] [PATCH] atrac decoder

Michael Niedermayer michaelni
Tue Aug 11 22:22:09 CEST 2009


On Tue, Aug 11, 2009 at 10:01:49PM +0200, Benjamin Larsson wrote:
> Michael Niedermayer wrote:
> > On Tue, Aug 11, 2009 at 07:32:30PM +0200, Benjamin Larsson wrote:
> >> Michael Niedermayer wrote:
> >>> On Mon, Aug 10, 2009 at 11:10:40PM +0200, Benjamin Larsson wrote:
> >>>> Michael Niedermayer wrote:
> >>>>> On Mon, Jun 08, 2009 at 09:40:18PM +0200, Benjamin Larsson wrote:
> >>> [...]
> >>>>> [...]
> >>>>>> +static void at1_imdct_transform(ATRAC1Context *q, float *spec, float *out, int nbits, int reverse_spectrum)
> >>>>>> +{
> >>>>>> +    float* window;
> >>>>>> +    MDCTContext* mdct_context;
> >>>>>> +    int transf_size = 1 << nbits;
> >>>>>> +
> >>>>>> +    switch(nbits) {
> >>>>>> +        case 5:
> >>>>>> +            window = short_window;
> >>>>>> +            mdct_context = &q->mdct_ctx[0];
> >>>>>> +            break;
> >>>>>> +        case 7:
> >>>>>> +            window = mid_window;
> >>>>>> +            mdct_context = &q->mdct_ctx[1];
> >>>>>> +            break;
> >>>>>> +        case 8:
> >>>>>> +        default:
> >>>>>> +            window = long_window;
> >>>>>> +            mdct_context = &q->mdct_ctx[2];
> >>>>>> +    }
> >>>>>> +
> >>>>>> +    if (reverse_spectrum) {
> >>>>>> +        int i;
> >>>>>> +        for (i=0; i<transf_size/2; i++)
> >>>>>> +            FFSWAP(float, spec[i], spec[transf_size-1-i]);
> >>>>>> +    }
> >>>>> i think that can be avoided by decong in reverse order ...
> >>>>>
> >>>> Would be possible if there where no short blocks. The logic to untangle
> >>>> those are not worth it.
> >>> elabrate please
> >> A subband that is reversed can use short or long mdct sizes. If it is
> >> long then decoding in reverse order would work.
> >>
> >> 12,11,10,9,8,7,6,5,4,3,2,1
> >>
> >> But when the short order is used (to code transients), the blocks are
> >> reversed in groups.
> >>
> >> 3,2,1,6,5,4,9,8,7,12,11,10
> > 
> > these groups dont coincide with some for loop ?
> > and they arent powers of 2 ? 4321 8765 ...
> 
> They are, the numbers where just an illustration of how the bitstream is
> formated in different modes.
> 
> Following is the code logic.
> 
> bsm is parsed from the bitstream.
> 
> num_blocks = 1 << bsm;
> for (; num_blocks != 0; num_blocks--) {
>     at1_imdct_transform(q, &q->spec[pos], q->short_buf, 5, band_num);
>     pos += 32;
> }
> 
> 32 samples.
> 
> at1_imdct_transform is the function that reverses the &q->spec[pos]
> buffer. So to properly reverse the buffer during bitstream parsing you
> need to decode the spectrum in 32 sample blocks. The following logic
> (simplified) is used to requant short blocks.
> 
> num_specs = specs_per_bfu[bfu_num];
> pos = bfu_start_short[bfu_num];
> 
> for (i=0 ; i<num_specs ; i++)
> 	spec[pos + i] = get_sbits(gb, word_len)
> 
> So for long blocks, just count backwards from 512 and everything is
> fine. For short blocks now we would need to calculate every index if it
> in the right position or try to count backwards and adjust the index in
> some nice way. The second suggestion doesn't work to well as num_specs
> can be odd. Thus the first suggestion has to be used, and as this code
> is used for long blocks also it would slow them down if the index
> recalculation is added or it would lead to code duplication. All in all
> lots of complication and work for something that could be solved by
> reverse reading in the mdct. But as I'm one of the few people who care
> about atrac I see no need to add that. Just swapping the buffer would be
> my prefered solution.

if the groups are a power of 2 you can do
0123456789ABCDEF
^3
32107654...

thats just a ^C in the index and can be omited when filling whole
blocks of size C with zeros


> 
> > 
> > 
> > 
> >>>
> >>>>>> +
> >>>>>> +    ff_imdct_calc(mdct_context,out,spec);
> >>>>> cant imdct_half be used?
> >>>>>
> >>>> Changed to
> >>>>
> >>>> memset
> >>>> fmul
> >>>> fmul_rev
> >>>> memset
> >>>>
> >>>> It was slightly faster and uses less memory.
> >>> you still use the full imdct
> >> Yes, that has to do with windowing. As I shouldn't multiply with 0 and 1
> >> I have to do it this way. To use imdct_half I need to build the complete
> >> windows again (Use more memory etc).
> > 
> > iam not convinced but i didnt verify it can be done ...
> > 
> 
> Well as vector_fmul_window is defined now you need to use the complete
> windows.

and when window is 0 or 1 some other function could be used, besides
is vector_fmul_window + half_imdct slower than the cutrrent code?

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

Thouse who are best at talking, realize last or never when they are wrong.
-------------- 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/20090811/0141a380/attachment.pgp>



More information about the ffmpeg-devel mailing list