[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