[FFmpeg-devel] [PATCH] WMAPRO packet parser
Michael Niedermayer
michaelni
Thu Aug 14 21:03:52 CEST 2008
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 ...
[...]
> +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
> +
> +
> +/**
> + *@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
> +
> + /** 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
[...]
> +/**
> + *@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
[...]
> + /** 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
[...]
> + 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()
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
I know you won't believe me, but the highest form of Human Excellence is
to question oneself and others. -- Socrates
-------------- 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/20080814/9eedfb24/attachment.pgp>
More information about the ffmpeg-devel
mailing list