[FFmpeg-devel] [PATCH] atrac decoder

Benjamin Larsson banan
Tue Aug 11 22:01:49 CEST 2009


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.

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

>> Ok. How should the split be done, svn copy or not (complete atrac3.c in
>> history or not) ?
> 
> is there some reason not to do svn copy? if not id say do copy
> 

Ok. I'll use svncopy then.

MvH
Benjamin Larsson



More information about the ffmpeg-devel mailing list