[FFmpeg-devel] [PATCH] Bink file demuxer and audio decoder

Michael Niedermayer michaelni
Fri Jan 22 22:49:42 CET 2010


On Wed, Jan 20, 2010 at 09:15:24PM +1100, pross at xvid.org wrote:
> On Thu, Jun 25, 2009 at 12:11:54AM +0200, Diego Biurrun wrote:
> > On Sat, Jun 20, 2009 at 11:49:05PM +1000, Peter Ross wrote:
> > > 
> > > --- libavcodec/Makefile	(revision 19182)
> > > +++ libavcodec/Makefile	(working copy)
> > > @@ -27,6 +27,7 @@
> > >  # parts needed for many different codecs
> > >  OBJS-$(CONFIG_AANDCT)                  += aandcttab.o
> > >  OBJS-$(CONFIG_ENCODERS)                += faandct.o jfdctfst.o jfdctint.o
> > > +OBJS-$(CONFIG_DCT)                     += dct.o
> > >  OBJS-$(CONFIG_FFT)                     += fft.o
> > >  OBJS-$(CONFIG_GOLOMB)                  += golomb.o
> > >  OBJS-$(CONFIG_MDCT)                    += mdct.o
> > 
> > Ahem...
> > 
> > > --- libavcodec/dct.c	(revision 0)
> > > +++ libavcodec/dct.c	(revision 0)
> > > @@ -0,0 +1,95 @@
> > > +
> > > +static void ff_dct_calc_c(DCTContext *s, FFTSample *data)
> > 
> > There is no need to give static functions ff_ prefixes.
> > 
> > > +        for(i=0; i < n; i++) {
> > 
> > consistent application of K&R please..
> > 
> > > +        for(i=0; i<n-1; i++) {
> > 
> > ditto
> > 
> > > +    }else{
> > 
> > ditto
> > 
> > > +        for(i=0; i < n; i++) {
> > 
> > ditto
> > 
> > > +    if (s->inverse) {
> > > +        for(i=0; i < n; i++)
> > 
> > ditto
> > 
> > > +            data[i] = s->data[n-(i+1)].re / (2 * n);
> > > +    }else {
> > 
> > ditto
> > 
> > > +        for(i=0; i < n; i++)
> > 
> > ditto
> > 
> > > --- libavcodec/binkaudio.c	(revision 0)
> > > +++ libavcodec/binkaudio.c	(revision 0)
> > > @@ -0,0 +1,307 @@
> > > +static void decode_block(BinkAudioContext *s, short *out)
> > > +{
> > > +    int ch, i, j, k;
> > > +    float q, quant[25];
> > > +    int width, coeff;
> > > +    GetBitContext *gb = &s->gb;
> > > +
> > > +    if (s->use_dct) {
> > > +        skip_bits(gb, 2);
> > > +    }
> > 
> > useless {}
> > 
> > > +        // find band (k)
> > > +        for (k = 0; s->bands[k] * 2 < 2; k++) {
> > > +            q = quant[k];
> > > +        }
> > 
> > ditto
> > 
> > > +AVCodec binkaudio1_decoder = {
> > > +    "binkaudio1",
> > > +    CODEC_TYPE_AUDIO,
> > > +    CODEC_ID_BINKAUDIO1,
> > > +    sizeof(BinkAudioContext),
> > > +    decode_init,
> > > +    NULL,
> > > +    decode_end,
> > > +    decode_frame
> > > +};
> > > +
> > > +AVCodec binkaudio2_decoder = {
> > > +    "binkaudio2",
> > > +    CODEC_TYPE_AUDIO,
> > > +    CODEC_ID_BINKAUDIO2,
> > > +    sizeof(BinkAudioContext),
> > > +    decode_init,
> > > +    NULL,
> > > +    decode_end,
> > > +    decode_frame
> > > +};
> > 
> > Long names are missing.
> > 
> > > --- doc/general.texi	(revision 19236)
> > > +++ doc/general.texi	(working copy)
> > > @@ -544,6 +544,8 @@
> > >  @item Apple lossless audio   @tab  X  @tab  X
> > >      @tab QuickTime fourcc 'alac'
> > >  @item Atrac 3                @tab     @tab  X
> > > + at item Bink Audio             @tab     @tab  X
> > > +    @tab Used in Bink and Smacker files in many games.
> > 
> > Is it worth mentioning that both types are supported?  I guess only if
> > other types remain..
> > 
> > > --- libavformat/bink.c	(revision 0)
> > > +++ libavformat/bink.c	(revision 0)
> > > @@ -0,0 +1,245 @@
> > > +    if (b[0] == 'B' && b[1] == 'I' && b[2] == 'K' &&
> > > +        (b[3] == 'b' || b[3] == 'f' || b[3] == 'g' || b[3] == 'h' || b[3] == 'i') &&
> > > +        AV_RL32(b+8) > 0 &&  // num_frames
> > > +        AV_RL32(b+20) > 0 && AV_RL32(b+20) <= BINK_MAX_WIDTH &&
> > > +        AV_RL32(b+24) > 0 && AV_RL32(b+24) <= BINK_MAX_HEIGHT &&
> > > +        AV_RL32(b+28) > 0 && AV_RL32(b+32) > 0)  // fps num,den
> > 
> > This could be more readable nicely aligned.
> > 
> > > +AVInputFormat bink_demuxer = {
> > > +    "bink",
> > > +    "Bink",
> > > +    sizeof(BinkDemuxContext),
> > > +    probe,
> > > +    read_header,
> > > +    read_packet,
> > > +};
> > 
> > Long name is missing.
> 
> Fixes incorporated. Revised patchset enclosed.
> 
> -- Peter
> (A907 E02F A6E5 0CD2 34CD 20D2 6760 79C5 AC40 DD6B)

>  smacker.c |   14 +++++++++++---
>  1 file changed, 11 insertions(+), 3 deletions(-)
> 35c4d928a5245a41d669ad2baa261044e7423496  smacker-decoder-r300.diff

> Index: libavformat/smacker.c

not maintained by me

[...]
> diff --git a/libavformat/bink.c b/libavformat/bink.c
> new file mode 100644
> index 0000000..c84a34c
> --- /dev/null
> +++ b/libavformat/bink.c

ok

[...]
> +static void decode_block(BinkAudioContext *s, short *out, int use_dct)
> +{
> +    int ch, i, j, k;
> +    float q, quant[25];
> +    int width, coeff;
> +    GetBitContext *gb = &s->gb;
> +
> +    if (use_dct)
> +        skip_bits(gb, 2);
> +
> +    for (ch = 0; ch < s->channels; ch++) {
> +        FFTSample *coeffs = s->coeffs_ptr[ch];
> +        q = 0.0;
> +        coeffs[0] = get_float(gb);
> +        coeffs[1] = get_float(gb);
> +
> +        for (i = 0; i < s->num_bands; i++) {
> +            int value = get_bits(gb, 8);
> +            quant[i] = pow(10.0, FFMIN(value, 95) * 0.066399999);
> +        }
> +

> +        // find band (k)
> +        for (k = 0; s->bands[k] * 2 < 2; k++) {

for (k = 0; s->bands[k] < 1; k++) {



> +            q = quant[k];
> +        }
> +
> +        // parse coefficients
> +        i = 2;
> +        while (i < s->frame_len) {
> +            if (get_bits1(gb)) {
> +                j = i + rle_length_tab[get_bits(gb, 4)] * 8;
> +            } else {
> +                j = i + 8;
> +            }
> +

> +            if (j > s->frame_len)
> +                j = s->frame_len;

FFMIN


> +
> +            width = get_bits(gb, 4);
> +            if (width == 0) {
> +                memset(coeffs + i, 0, (j - i) * sizeof(*coeffs));
> +                i = j;
> +                while (s->bands[k] * 2 < i)
> +                    q = quant[k++];
> +            } else {
> +                while (i < j) {
> +                    if (s->bands[k] * 2 == i)
> +                        q = quant[k++];
> +                    coeff = get_bits(gb, width);
> +                    if (coeff) {
> +                        if (get_bits1(gb))
> +                            coeffs[i] = -q * coeff;
> +                        else
> +                            coeffs[i] =  q * coeff;
> +                    } else {
> +                        coeffs[i] = 0.0;
> +                    }
> +                    i++;
> +                }
> +            }
> +        }
> +
> +        if (use_dct)
> +            ff_dct_calc (&s->trans.dct,  coeffs);
> +        else
> +            ff_rdft_calc(&s->trans.rdft, coeffs);
> +

> +        for (i = 0; i < s->frame_len; i++)
> +            coeffs[i] *= s->root;

looks like it could be merged in q


> +    }
> +
> +    s->dsp.float_to_int16_interleave(out, (const float **)s->coeffs_ptr, s->frame_len, s->channels);
> +
> +    if (!s->first) {
> +        int count = s->overlap_len * s->channels;
> +        int shift = av_log2(count);
> +        for (i = 0; i < count; i++) {
> +            out[i] = (s->previous[i] * (count - i) + out[i] * i) >> shift;
> +        }
> +    }
> +
> +    memcpy(s->previous, out + s->block_size,
> +           s->overlap_len * s->channels * sizeof(*out));
> +
> +    s->first = 0;
> +}
> +

> +static av_cold int decode_end(AVCodecContext *avctx)
> +{
> +    BinkAudioContext * s = avctx->priv_data;

> +    av_free(s->bands);

av_freep() is safer against double frees


> +    if (avctx->codec->id == CODEC_ID_BINKAUDIO1)
> +        ff_rdft_end(&s->trans.rdft);
> +    else
{}


> +        ff_dct_end(&s->trans.dct);
> +    return 0;
> +}
> +
> +static void get_bits_align32(GetBitContext *s)
> +{
> +    int n = (-get_bits_count(s)) & 31;
> +    if (n) skip_bits(s, n);
> +}
> +
> +static int decode_frame(AVCodecContext *avctx,
> +                        void *data, int *data_size,
> +                        AVPacket *avpkt)
> +{
> +    BinkAudioContext *s = avctx->priv_data;
> +    const uint8_t *buf  = avpkt->data;
> +    int buf_size        = avpkt->size;
> +    short *samples      = data;


> +    short *samples_end  = (void*)((uint8_t*)data + *data_size);

the void cast looks strange in there


[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

I have often repented speaking, but never of holding my tongue.
-- Xenocrates
-------------- 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/20100122/2a0f0827/attachment.pgp>



More information about the ffmpeg-devel mailing list