[FFmpeg-devel] [PATCH] wmapro decoder

Sascha Sommer saschasommer
Fri Jun 5 19:06:32 CEST 2009


Hi,

On Freitag, 5. Juni 2009, Michael Niedermayer wrote:
> On Mon, Jun 01, 2009 at 05:28:07PM +0200, Sascha Sommer wrote:
> > Hi,
> >
> > attached patch adds support for decoding wmapro.
> >
> > I'm awaiting your review so that we can sort out the remaining issues.
>
> I think the first thing to do is to compare it to wma and merge what is
> similar
> rle decoding for example looks very similar
>
> ill do a proper review in the next days, of course if you can reduce
> code duplication relative to wma, that would make my review easier
> and ill insist on all code duplication to be removed anyway when i
> find some.
>
> [...]

Well, let's see

Parsing the start of a packet:

wmadec.c:

        skip_bits(&s->gb, 4); /* super frame index */
        nb_frames = get_bits(&s->gb, 4) - 1;



wmapro:

    /** parse packet header */
    init_get_bits(&gb, buf, s->buf_bit_size);
    packet_sequence_number    = get_bits(&gb, 4);
    s->bit5                   = get_bits1(&gb);
    s->bit6                   = get_bits1(&gb);

    /** get number of bits that need to be added to the previous frame */
    num_bits_prev_frame = get_bits(&gb, s->log2_frame_size);

=> not similar


The same is true for the included packet headers. (Wma1/2 for example store 
the length of the previous subframe in the header wmapro has some header that 
contains the sizes of all subframes, wma1/2 only supports M/S stereo to 
improve compression for multichannel streams, wmapro supports channel 
grouping...)

Decoding of the scale factors:

The vlc version of wmadec.c is similar to the one of wmapro apart from the 
first value and the used vlc table. Also wmapro does the pow before the imdct 
because the decoded scale factors can be recycled for other subframes.
The run level coding is not part of wmadec.c. The lsp coding not part of 
wmapro.

When it comes to coefficient decoding, you are right that the run level part 
(wmadec does not have the vector coding part like wmapro that happens before 
this step) also uses more than one run and level tables and uses code==1 to 
exit the loop, code > 1 for normal coefficients and code == 0 for escape 
decoding. Unfortunatelly the escape decoding is different: 


                } else if (code == 0) {
                    /* escape */
                    level = get_bits(&s->gb, coef_nb_bits);
                    /* NOTE: this is rather suboptimal. reading
                       block_len_bits would be better */
                    run = get_bits(&s->gb, s->frame_len_bits);
                } else {

vs. 
                val = wma_get_large_val(s);
                /** escape decode */
                if (get_bits1(&s->gb)) {
                    if (get_bits1(&s->gb)) {
                        if (get_bits1(&s->gb)) {
                            av_log(s->avctx,AV_LOG_ERROR,
                                   "broken escape sequence\n");
                            return 0;
                        }else
                            cur_coeff += get_bits(&s->gb,s->esc_len) + 4;
                    }else
                        cur_coeff += get_bits(&s->gb,2) + 1;
                }
            }

As this loop should be quit speed critical, I don't know if an if(codec == 
wmapro) is a good idea.


Tansformations:
M/S stereo coding can probably be shared but it is only a
            a = s->coefs[0][i];
            b = s->coefs[1][i];
            s->coefs[0][i] = a + b;
            s->coefs[1][i] = a - b;


The imdct and windowing should be the same but one would first have to make 
wmadec.c use ff_imdct_half. But then this are only a few calls to the imdct 
and dsp functions that are probably similar for other imdct based codecs like 
AAC (for the sine window case), too.
Apart from that, the float to short conversion and the memcpy of the second 
half of the output buffer for the next iteration are identical. I'm not sure 
here, if the decoders should not be changed to output floats instead or at 
least use the appropriate dsp helper function.
  
All in all I don't see so many code duplications that would make it a 
requirement that the decoder is twiddled into the existing wma1/2 decoder but 
it is possible that I missed a few things...

Regards

Sascha







More information about the ffmpeg-devel mailing list