[FFmpeg-devel] [PATCH] wmapro decoder

Vitor Sessak vitor1001
Sun Jun 21 15:43:31 CEST 2009


Sascha Sommer wrote:
> Hi Vitor,
> 
> thanks for your comments.
> 
>>> The code still outputs shorts. Float produced clicks all around the
>>> place. I'm not sure yet if the problem is in my code or in ffmpeg.
>> It looks like it works for me, see attached.
> 
> So your code does not produce clicks at second 16-18 for you with the sample 
> file you mentioned below? It does for me when I'm using ffmpeg to produce a 
> 16-bit wav file and play that back with MPlayer.

That's due to the lack of clipping. The attached patch is bit-exact for 
wav output for me for the sample 
http://samples.mplayerhq.hu/A-codecs/WMA9/wmapro/Beethovens%20nionde%20symfoni%20(Scherzo)-2.wma 
.

Note that outputting floats can make the "Output buffer too small" error 
twice as bad, since the decoder will need an output buffer twice the size.

> Also the scaling can be done in the imdct.

Yes, my patch was just a proof-of-concept.

>>> Float output can also be added after the code has been added to svn imho.
>>>
>>> New patch attached.
>>>
>>>
>>> +/**
>>> + * @brief main decoder context
>>> + */
>> The @brief here makes the plain C code harder to read without improving
>> a lot doxy output, so it is better to remove it (happens a lot elsewhere).
>>
> 
> Do others agree?
> I don't think it makes the code any harder to read.
> 
>>> +    /** generic decoder variables */
>>> +    AVCodecContext*  avctx;                         ///< codec context
>>> for av_log +    DSPContext       dsp;                           ///<
>>> accelerated dsp functions +    uint8_t          frame_data[MAX_FRAMESIZE
>>> +
>>> +                      FF_INPUT_BUFFER_PADDING_SIZE];///< compressed
>>> frame data +    MDCTContext      mdct_ctx[WMAPRO_BLOCK_SIZES];  ///< MDCT
>>> context per block size +    DECLARE_ALIGNED_16(float,
>>> tmp[WMAPRO_BLOCK_MAX_SIZE]); ///< imdct output buffer +    float*        
>>>   windows[WMAPRO_BLOCK_SIZES];   ///< window per block size +    int     
>>>         coef_max[2];                   ///< max length of vlc codes
>> The "/** generic decoder variables */" will be misinterpreted by doxygen
>> as been only referent to "AVCodecContext*  avctx;". There is a doxygen
>> syntax for grouping.
>>
> 
> Yes and the grouping syntax leads to the same problem. Looks like a doxygen 
> problem. Any other ideas?

Change /** to /*

>>> +    s->num_sfb = av_mallocz(sizeof(int8_t)*s->num_possible_block_sizes);
>>> +    s->sfb_offsets = av_mallocz(MAX_BANDS *
>>> +                                sizeof(int16_t) *
>>> s->num_possible_block_sizes); +    s->subwoofer_cutoffs =
>>> av_mallocz(sizeof(int16_t) *
>>> +                                      s->num_possible_block_sizes);
>>> +    s->sf_offsets = av_mallocz(MAX_BANDS * s->num_possible_block_sizes *
>>> +                               s->num_possible_block_sizes *
>>> sizeof(int16_t));
>> There is no necessity of clearing s->num_sfb, it will be filled up in
>> the next few lines (is clearing the others needed?), so you can use
>> plain av_malloc().
>>
> 
> I prefer to use av_mallocz on places where speed does not matter.

fine for me.

>>> +/**
>>> + *@brief Calculate a decorrelation matrix from the bitstream parameters.
>>> + *@param s codec context
>>> + *@param chgroup channel group for which the matrix needs to be
>>> calculated + */
>>> +static void decode_decorrelation_matrix(WMA3DecodeContext* s,
>>> +                                            WMA3ChannelGroup* chgroup)
>>> +{
>>> +    int i;
>>> +    int offset = 0;
>>> +    char rotation_offset[WMAPRO_MAX_CHANNELS * WMAPRO_MAX_CHANNELS];
>>> +    memset(chgroup->decorrelation_matrix,0,
>>> +           sizeof(float) *s->num_channels * s->num_channels);
>>> +
>>> +    for (i=0;i<chgroup->num_channels  * (chgroup->num_channels - 1) >>
>>> 1;i++) +        rotation_offset[i] = get_bits(&s->gb,6);
>>> +
>>> +    for (i=0;i<chgroup->num_channels;i++) {
>>> +        if (get_bits1(&s->gb)) {
>>> +            chgroup->decorrelation_matrix[chgroup->num_channels * i +
>>> i]=  1.0; +        } else
>>> +            chgroup->decorrelation_matrix[chgroup->num_channels * i +
>>> i]= -1.0;
>> chgroup->decorrelation_matrix[chgroup->num_channels * i + i] =
>>                                        -1 + get_bits1(&s->gb)<<1;
>>
> 
> That is slower.
> 
>> or
>>
>> chgroup->decorrelation_matrix[chgroup->num_channels * i + i] =
>>
>>                                     get_bits1(&s->gb) ? 1.0, -1.0;
>>
> 
> Thanks. That seems to be slightly faster.
> 
>>> +                    if (s->num_channels == 2) {
>>> +                        chgroup->transform = 1;
>>> +                    } else {
>>> +                        chgroup->transform = 2;
>>> +                        /** cos(pi/4) */
>>> +                        chgroup->decorrelation_matrix[0] = 0.70703125;
>>> +                        chgroup->decorrelation_matrix[1] = -0.70703125;
>>> +                        chgroup->decorrelation_matrix[2] = 0.70703125;
>>> +                        chgroup->decorrelation_matrix[3] = 0.70703125;
>> Already mentioned...
>>
> 
> Yes. These values were used to produce binary identical output in the past. So 
> I will keep using those value.
> 
>>> +
>>> +    if (len <= 0 || buflen > MAX_FRAMESIZE) {
>>> +         ff_log_ask_for_sample(s->avctx, "input buffer to small\n");
>> s/to small/too small/
>>
> 
> Fixed in the soc repository.
> 
>> Note also that the sample at
>> http://samples.mplayerhq.hu/A-codecs/WMA9/wmapro/New%20Stories%20(Highway%2
>> 0Blues)-2.wma trigger this error.
>>
> 
> Hm. Seems to be the same problem that I fixed in revision 4492 in the soc 
> repository.
> 
>>> +    for (i=0;i<s->num_channels;i++) {
>>> +        s->channel[i].decoded_samples = 0;
>>> +        s->channel[i].cur_subframe = 0;
>>> +        s->channel[i].reuse_sf = 0;
>>> +    }
>> memset(...)
>>
> 
> Can't be used because some data like prev_block_len and the out buffer is not 
> supposed to be resetted between the packets. They will be used for windowing.

Indeed. 10l for me.

-Vitor
-------------- next part --------------
A non-text attachment was scrubbed...
Name: wma_use_float2.diff
Type: text/x-diff
Size: 2031 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20090621/ec775ee0/attachment.diff>



More information about the ffmpeg-devel mailing list