[FFmpeg-devel] [PATCH] WMAPRO packet parser

Sascha Sommer saschasommer
Thu Aug 14 22:59:15 CEST 2008


Hi,

On Donnerstag, 14. August 2008, Michael Niedermayer wrote:
> On Thu, Aug 14, 2008 at 08:16:38PM +0200, Sascha Sommer wrote:
> > Hi,
> >
> > attached patch adds support for a wma3 decoder skeleton and packet
> > parser. Basically less than what I expected to do during SOC but before I
> > can continue with the bitstream parsing after SOC I will first have to
> > reverse engineer and understand more of the inner parts of the codec.
>
> well, if you do not have a functional decoder then i think there is only
> limited sense in commiting any of this into svn ...
> anyway, review below, also please see wma/wmadec.c the likely existing
> similarities could help reverse engeneering and understanding. And
> factorizing common code out would be required anyway ...
>

Yes the question will be how similar it will be in the end. I think the 
decoder has to at least to be able to decode some samples before one can 
decide how the wma 1, 2, 3 decoders should be split.

>
> [...]
>
> > +typedef struct {
> > +    uint8_t num_subframes;     //< number of subframes for the current
> > channel +    uint16_t subframe_len[MAX_SUBFRAMES]; //< subframe len in
> > samples +    uint16_t channel_len;                 //< channel len in
> > samples +} wma_channel_t;
>
> vertical align of comments
>

Fixed.

> > +
> > +
> > +/**
> > + *@brief main decoder context
> > + */
> > +typedef struct WMA3DecodeContext {
> > +    AVCodecContext*  avctx;           //< codec context for av_log
> > +    GetBitContext    gb;              //< getbitcontext for the packet
> > +    int              buf_bit_size;    //< buffer size in bits
> > +
> > +    /** Packet info */
> > +    uint8_t          packet_sequence_number; //< current packet nr
> > +    uint8_t          bit5;                   //< padding bit? (cbr
> > files) +    uint8_t          bit6;
> > +    uint8_t          packet_loss;            //< set in case of
> > bitstream error +
> > +    /** Stream info */
> > +    uint16_t         samples_per_frame;     //< nr of outputed samples
> > +    uint8_t          log2_block_align;      //< block align bits
> > +    uint8_t          log2_block_align_bits; //< nr bits for block align
> > len +    uint16_t         log2_frame_size;       //< frame size
> > +    uint8_t          lossless;              //< lossless mode
> > +    uint8_t          no_tiling;             //< frames are split in
> > subframes +    int8_t           nb_channels;           //< nr of channels
> > +    wma_channel_t    channel[MAX_CHANNELS]; //< per channel data
>
> doxygen has special tags for comments covering a block @{ @} IIRC
>

Will have to check that.

> > +
> > +    /** Extradata */
> > +    unsigned int     decode_flags;          //< used compression
> > features +    unsigned int     dwChannelMask;
> > +    uint8_t          sample_bit_depth;      //< bits per sample
> > +
> > +    /** General frame info */
> > +    unsigned int     frame_num;             //< current frame number
> > +    uint8_t          len_prefix;            //< frame is prefixed with
> > its len +    uint8_t          allow_subframes;       //< frames may
> > contain subframes +    uint8_t          max_num_subframes;     //<
> > maximum number of subframes +    uint16_t        
> > min_samples_per_subframe; //< minimum samples per subframe +    uint8_t  
> >        dynamic_range_compression;//< frame contains drc data +    uint8_t
> >          drc_gain;                 //< gain for the drc tool +    uint8_t
> >          update_samples_per_frame; //< recalculate output size +
> > +
> > +    /** Buffered frame data */
> > +    int              prev_frame_bit_size;      //< saved number of bits
> > +    uint8_t*         prev_frame;               //< prev frame data
> > +
> > +} WMA3DecodeContext;
> >
> > +
> > +/**
> > + *@brief helper function to print the most important members of the
> > context + *@param s context
> > + */
> > +static void dump_context(WMA3DecodeContext *s)
> > +{
> > +#define PRINT(a,b) av_log(NULL,AV_LOG_ERROR," %s = %d\n", a, b);
> > +#define PRINT_HEX(a,b) av_log(NULL,AV_LOG_ERROR," %s = %x\n", a, b);
>
> NULL is not a good choice as context
>

Fixed.

>
> [...]
>
> > +/**
> > + *@brief Get the samples per frame for this stream
> > + *@param sample_rate output sample_rate
> > + *@param decode_flags codec compression features
> > + *@return number of output samples per frame
> > + */
> > +static int get_samples_per_frame(int sample_rate, unsigned int
> > decode_flags) { +
> > +    int samples_per_frame;
> > +    int tmp;
> > +
> > +    if (sample_rate <= 16000)
> > +        samples_per_frame = 512;
> > +    else if (sample_rate <= 22050)
> > +        samples_per_frame = 1024;
> > +    else if (sample_rate <= 48000)
> > +        samples_per_frame = 2048;
> > +    else if (sample_rate <= 96000)
> > +        samples_per_frame = 4096;
> > +    else
> > +        samples_per_frame = 8192;
>
> this can be merged with wma.c
>

Ok.

>
> [...]
>
> > +    /** Generic init */
> > +    s->packet_loss = 0;
> > +    s->log2_block_align = av_log2(avctx->block_align);
> >
> > +    s->log2_block_align_bits = av_log2(avctx->block_align*8);
>
> hmm, that looks rather useless
>
> > +    s->log2_frame_size = s->log2_block_align_bits + 1;
>
> that as well
>

I think the number of frame size bits should be enough. The name is misleading 
however.

>
> [...]
>
> > +    while(more_frames && remaining_bits(s) > s->log2_frame_size){
> > +        int frame_size = show_bits(&s->gb, s->log2_frame_size);
> > +
> > +        /** there is enough data for a full frame */
> > +        if(remaining_bits(s) >= frame_size){
> > +            /** decode the frame */
> > +            more_frames = wma_decode_frame(s,&s->gb);
> > +
> > +            if(!more_frames){
> > +                av_log(avctx, AV_LOG_ERROR, "no more frames\n");
> > +            }
> > +        }else
> > +            more_frames = 0;
> > +    }
>
> this reminds me of the first loop in wma_decode_frame()
>

Yeah it should be similar for wma2, 3 and the lossless variant as far as I can 
tell.

Regards

Sascha







More information about the ffmpeg-devel mailing list