[FFmpeg-devel] [MPlayer-dev-eng] rtp support in mplayer

Vitor Sessak vitor1001
Mon Jun 9 21:23:15 CEST 2008


Hi

Chas Williams (CONTRACTOR) wrote:
> In message <20080516134500.8485095e.tempn at twmi.rr.com>,compn writes:
>> libavcodec patches go to ffmpeg-devel list.
> 
> here is a patch to libavcodec for g722 audio support.

I'll give a quick look, but surely Michael will post a full review soon.


> diff -u mplayer-1.0rc2.orig/libavcodec/Makefile mplayer-1.0rc2/libavcodec/Makefile

The preferred way to send patches is to attach then (uncompressed) 
instead of inlining it in the message.

> --- mplayer-1.0rc2.orig/libavcodec/Makefile	2007-10-07 15:49:37.000000000 -0400
> +++ mplayer-1.0rc2/libavcodec/Makefile	2008-05-15 09:28:17.000000000 -0400
> @@ -262,6 +262,7 @@
>  OBJS-$(CONFIG_ADPCM_CT_ENCODER)        += adpcm.o
>  OBJS-$(CONFIG_ADPCM_EA_DECODER)        += adpcm.o
>  OBJS-$(CONFIG_ADPCM_EA_ENCODER)        += adpcm.o
> +OBJS-$(CONFIG_ADPCM_G722_DECODER)      += g722.o
>  OBJS-$(CONFIG_ADPCM_G726_DECODER)      += g726.o
>  OBJS-$(CONFIG_ADPCM_G726_ENCODER)      += g726.o
>  OBJS-$(CONFIG_ADPCM_IMA_AMV_DECODER)   += adpcm.o
> diff -u mplayer-1.0rc2.orig/libavcodec/allcodecs.c mplayer-1.0rc2/libavcodec/allcodecs.c
> --- mplayer-1.0rc2.orig/libavcodec/allcodecs.c	2007-10-07 15:49:37.000000000 -0400
> +++ mplayer-1.0rc2/libavcodec/allcodecs.c	2008-05-15 09:30:17.000000000 -0400
> @@ -247,6 +247,7 @@
>      REGISTER_ENCDEC  (ADPCM_CT, adpcm_ct);
>      REGISTER_ENCDEC  (ADPCM_EA, adpcm_ea);
>      REGISTER_ENCDEC  (ADPCM_G726, adpcm_g726);
> +    REGISTER_DECODER (ADPCM_G722, adpcm_g722);

Alphabetic order is better

>      REGISTER_DECODER (ADPCM_IMA_AMV, adpcm_ima_amv);
>      REGISTER_ENCDEC  (ADPCM_IMA_DK3, adpcm_ima_dk3);
>      REGISTER_ENCDEC  (ADPCM_IMA_DK4, adpcm_ima_dk4);
> diff -u mplayer-1.0rc2.orig/libavcodec/avcodec.h mplayer-1.0rc2/libavcodec/avcodec.h
> --- mplayer-1.0rc2.orig/libavcodec/avcodec.h	2007-10-07 15:49:37.000000000 -0400
> +++ mplayer-1.0rc2/libavcodec/avcodec.h	2008-05-15 10:13:39.000000000 -0400
> @@ -273,6 +273,8 @@
>  
>      CODEC_ID_MPEG2TS= 0x20000, /* _FAKE_ codec to indicate a raw MPEG-2 TS
>                                  * stream (only used by libavformat) */
> +
> +    CODEC_ID_ADPCM_G722
>  };

I think the right place to put it is in the end of the relevant section, 
more precisely after CODEC_ID_ADPCM_EA_MAXIS_XA.

>  
>  #if LIBAVCODEC_VERSION_INT < ((52<<16)+(0<<8)+0)
> diff -u mplayer-1.0rc2.orig/libavcodec/g722.c mplayer-1.0rc2/libavcodec/g722.c
> --- mplayer-1.0rc2.orig/libavcodec/g722.c	2008-06-09 13:28:35.000000000 -0400
> +++ mplayer-1.0rc2/libavcodec/g722.c	2008-06-09 13:31:01.000000000 -0400
> @@ -0,0 +1,609 @@
> +/*
> + * SpanDSP - a series of DSP components for telephony
> + *
> + * g722.h - The ITU G.722 codec.
> + *
> + * Written by Steve Underwood <steveu at coppice.org>
> + *
> + * Copyright (C) 2005 Steve Underwood
> + *
> + *  Despite my general liking of the GPL, I place my own contributions 
> + *  to this code in the public domain for the benefit of all mankind -
> + *  even the slimy ones who might try to proprietize my work and use it
> + *  to my detriment.
> + *
> + * Based on a single channel G.722 codec which is:
> + *
> + *****    Copyright (c) CMU    1993      *****
> + * Computer Science, Speech Group
> + * Chengxiang Lu and Alex Hauptmann
> + *
> + * $Id$
> + */

It is really preferred (license consistency) if you license it instead 
in LGPL terms (which is compatible with public domain anyway). Ideally, 
you could put a FFmpeg general header with a note about SpanDSP authorship.

> +
> +
> +/*! \file */

Please see other files from FFmpeg to make your file consistent with it.

> +
> +#if !defined(_G722_H_)
> +#define _G722_H_

Same thing here.

> +
> +#include <inttypes.h>
> +
> +/*! \page g722_page G.722 encoding and decoding
> +\section g722_page_sec_1 What does it do?
> +The G.722 module is a bit exact implementation of the ITU G.722 specification for all three
> +specified bit rates - 64000bps, 56000bps and 48000bps. It passes the ITU tests.
> +
> +To allow fast and flexible interworking with narrow band telephony, the encoder and decoder
> +support an option for the linear audio to be an 8k samples/second stream. In this mode the
> +codec is considerably faster, and still fully compatible with wideband terminals using G.722.
> +
> +\section g722_page_sec_2 How does it work?
> +???.
> +*/
> +
> +enum
> +{
> +    G722_SAMPLE_RATE_8000 = 0x0001,
> +    G722_PACKED = 0x0002
> +};
> +
> +#ifndef INT16_MAX
> +#define INT16_MAX       32767
> +#endif
> +#ifndef INT16_MIN
> +#define INT16_MIN       (-32768)
> +#endif
> +
> +typedef struct
> +{
> +    /*! TRUE if the operating in the special ITU test mode, with the band split filters
> +             disabled. */
> +    int itu_test_mode;
> +    /*! TRUE if the G.722 data is packed */
> +    int packed;
> +    /*! TRUE if encode from 8k samples/second */
> +    int eight_k;
> +    /*! 6 for 48000kbps, 7 for 56000kbps, or 8 for 64000kbps. */
> +    int bits_per_sample;
> +
> +    /*! Signal history for the QMF */
> +    int x[24];
> +
> +    struct
> +    {
> +        int s;
> +        int sp;
> +        int sz;
> +        int r[3];
> +        int a[3];
> +        int ap[3];
> +        int p[3];
> +        int d[7];
> +        int b[7];
> +        int bp[7];
> +        int sg[7];
> +        int nb;
> +        int det;
> +    } band[2];

one-letter names are really not much helpful

> +    unsigned int in_buffer;
> +    int in_bits;
> +    unsigned int out_buffer;
> +    int out_bits;
> +} g722_encode_state_t;

Encode????

> +
> +typedef struct
> +{
> +    /*! TRUE if the operating in the special ITU test mode, with the band split filters
> +             disabled. */
> +    int itu_test_mode;
> +    /*! TRUE if the G.722 data is packed */
> +    int packed;
> +    /*! TRUE if decode to 8k samples/second */
> +    int eight_k;
> +    /*! 6 for 48000kbps, 7 for 56000kbps, or 8 for 64000kbps. */
> +    int bits_per_sample;
> +
> +    /*! Signal history for the QMF */
> +    int x[24];
> +
> +    struct
> +    {
> +        int s;
> +        int sp;
> +        int sz;
> +        int r[3];
> +        int a[3];
> +        int ap[3];
> +        int p[3];
> +        int d[7];
> +        int b[7];
> +        int bp[7];
> +        int sg[7];
> +        int nb;
> +        int det;
> +    } band[2];
> +    
> +    unsigned int in_buffer;
> +    int in_bits;
> +    unsigned int out_buffer;
> +    int out_bits;
> +} g722_decode_state_t;
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif

FFmpeg is a C library, and it is a internal header, so this shouldn't be 
here.

> +
> +g722_decode_state_t *g722_decode_init(g722_decode_state_t *s, int rate, int options);
> +int g722_decode_release(g722_decode_state_t *s);
> +int g722_decode(g722_decode_state_t *s, int16_t amp[], const uint8_t g722_data[], int len);

Why public functions? Also, why a header at all?

> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif
> +/*
> + * SpanDSP - a series of DSP components for telephony
> + *
> + * g722_decode.c - The ITU G.722 codec, decode part.
> + *
> + * Written by Steve Underwood <steveu at coppice.org>
> + *
> + * Copyright (C) 2005 Steve Underwood
> + *
> + *  Despite my general liking of the GPL, I place my own contributions 
> + *  to this code in the public domain for the benefit of all mankind -
> + *  even the slimy ones who might try to proprietize my work and use it
> + *  to my detriment.
> + *
> + * Based in part on a single channel G.722 codec which is:
> + *
> + * Copyright (c) CMU 1993
> + * Computer Science, Speech Group
> + * Chengxiang Lu and Alex Hauptmann
> + *
> + * $Id$
> + */
> +
> +/*! \file */
> +
> +#ifdef HAVE_CONFIG_H
> +#include <config.h>
> +#endif
> +
> +#include <stdio.h>
> +#include <inttypes.h>
> +#include <memory.h>
> +#include <stdlib.h>
> +
> +#include <limits.h>
> +#include "avcodec.h"
> +#include "bitstream.h"
> +
> +#if !defined(FALSE)
> +#define FALSE 0
> +#endif
> +#if !defined(TRUE)
> +#define TRUE (!FALSE)
> +#endif

Use just 0 and 1 directly.

> +
> +static int16_t saturate(int32_t amp)
> +{
> +    int16_t amp16;
> +
> +    /* Hopefully this is optimised for the common case - not clipping */
> +    amp16 = (int16_t) amp;
> +    if (amp == amp16)
> +        return amp16;
> +    if (amp > INT16_MAX)
> +        return  INT16_MAX;
> +    return  INT16_MIN;

See av_clip_int16().

> +}
> +/*- End of function --------------------------------------------------------*/

Consistency: remove such comments.

> +
> +static void block4(g722_decode_state_t *s, int band, int d)
> +{
> +    int wd1;
> +    int wd2;
> +    int wd3;
> +    int i;
> +
> +    /* Block 4, RECONS */
> +    s->band[band].d[0] = d;
> +    s->band[band].r[0] = saturate(s->band[band].s + d);
> +
> +    /* Block 4, PARREC */
> +    s->band[band].p[0] = saturate(s->band[band].sz + d);
> +
> +    /* Block 4, UPPOL2 */
> +    for (i = 0;  i < 3;  i++)
> +        s->band[band].sg[i] = s->band[band].p[i] >> 15;
> +    wd1 = saturate(s->band[band].a[1] << 2);
> +
> +    wd2 = (s->band[band].sg[0] == s->band[band].sg[1])  ?  -wd1  :  wd1;
> +    if (wd2 > 32767)
> +        wd2 = 32767;
> +    wd3 = (s->band[band].sg[0] == s->band[band].sg[2])  ?  128  :  -128;
> +    wd3 += (wd2 >> 7);
> +    wd3 += (s->band[band].a[2]*32512) >> 15;
> +    if (wd3 > 12288)
> +        wd3 = 12288;
> +    else if (wd3 < -12288)
> +        wd3 = -12288;

See av_clip().

> +    s->band[band].ap[2] = wd3;
> +
> +    /* Block 4, UPPOL1 */
> +    s->band[band].sg[0] = s->band[band].p[0] >> 15;
> +    s->band[band].sg[1] = s->band[band].p[1] >> 15;
> +    wd1 = (s->band[band].sg[0] == s->band[band].sg[1])  ?  192  :  -192;
> +    wd2 = (s->band[band].a[1]*32640) >> 15;
> +
> +    s->band[band].ap[1] = saturate(wd1 + wd2);
> +    wd3 = saturate(15360 - s->band[band].ap[2]);
> +    if (s->band[band].ap[1] > wd3)
> +        s->band[band].ap[1] = wd3;
> +    else if (s->band[band].ap[1] < -wd3)
> +        s->band[band].ap[1] = -wd3;

av_clip() here and in many other places...

> +
> +    /* Block 4, UPZERO */
> +    wd1 = (d == 0)  ?  0  :  128;
> +    s->band[band].sg[0] = d >> 15;
> +    for (i = 1;  i < 7;  i++)
> +    {
> +        s->band[band].sg[i] = s->band[band].d[i] >> 15;
> +        wd2 = (s->band[band].sg[i] == s->band[band].sg[0])  ?  wd1  :  -wd1;
> +        wd3 = (s->band[band].b[i]*32640) >> 15;
> +        s->band[band].bp[i] = saturate(wd2 + wd3);
> +    }
> +
> +    /* Block 4, DELAYA */
> +    for (i = 6;  i > 0;  i--)
> +    {
> +        s->band[band].d[i] = s->band[band].d[i - 1];
> +        s->band[band].b[i] = s->band[band].bp[i];
> +    }
> +    
> +    for (i = 2;  i > 0;  i--)
> +    {
> +        s->band[band].r[i] = s->band[band].r[i - 1];
> +        s->band[band].p[i] = s->band[band].p[i - 1];
> +        s->band[band].a[i] = s->band[band].ap[i];
> +    }
> +
> +    /* Block 4, FILTEP */
> +    wd1 = saturate(s->band[band].r[1] + s->band[band].r[1]);
> +    wd1 = (s->band[band].a[1]*wd1) >> 15;
> +    wd2 = saturate(s->band[band].r[2] + s->band[band].r[2]);
> +    wd2 = (s->band[band].a[2]*wd2) >> 15;
> +    s->band[band].sp = saturate(wd1 + wd2);
> +
> +    /* Block 4, FILTEZ */
> +    s->band[band].sz = 0;
> +    for (i = 6;  i > 0;  i--)
> +    {
> +        wd1 = saturate(s->band[band].d[i] + s->band[band].d[i]);
> +        s->band[band].sz += (s->band[band].b[i]*wd1) >> 15;
> +    }
> +    s->band[band].sz = saturate(s->band[band].sz);
> +
> +    /* Block 4, PREDIC */
> +    s->band[band].s = saturate(s->band[band].sp + s->band[band].sz);
> +}
> +/*- End of function --------------------------------------------------------*/
> +
> +g722_decode_state_t *g722_decode_init(g722_decode_state_t *s, int rate, int options)

could be static and it think it should be moved instead to g722_init().

> +{
> +    if (s == NULL)
> +    {
> +        if ((s = (g722_decode_state_t *) av_malloc(sizeof(*s))) == NULL)
> +            return NULL;
> +    }
> +    memset(s, 0, sizeof(*s));
> +    if (rate == 48000)
> +        s->bits_per_sample = 6;
> +    else if (rate == 56000)
> +        s->bits_per_sample = 7;
> +    else
> +        s->bits_per_sample = 8;
> +    if ((options & G722_SAMPLE_RATE_8000))
> +        s->eight_k = TRUE;
> +    if ((options & G722_PACKED)  &&  s->bits_per_sample != 8)
> +        s->packed = TRUE;
> +    else
> +        s->packed = FALSE;
> +    s->band[0].det = 32;
> +    s->band[1].det = 8;
> +    return s;
> +}
> +/*- End of function --------------------------------------------------------*/
> +
> +int g722_decode_release(g722_decode_state_t *s)

What about g722_close()?

> +{
> +    av_free(s);
> +    return 0;
> +}
> +/*- End of function --------------------------------------------------------*/
> +
> +int g722_decode(g722_decode_state_t *s, int16_t amp[], const uint8_t g722_data[], int len)
> +{
> +    static const int wl[8] = {-60, -30, 58, 172, 334, 538, 1198, 3042 };

static const int16_t makes binary smaller

> +    static const int rl42[16] = {0, 7, 6, 5, 4, 3, 2, 1, 7, 6, 5, 4, 3,  2, 1, 0 };

uint8_t

> +    static const int ilb[32] =

uint16_t...

> +    {
> +        2048, 2093, 2139, 2186, 2233, 2282, 2332,
> +        2383, 2435, 2489, 2543, 2599, 2656, 2714,
> +        2774, 2834, 2896, 2960, 3025, 3091, 3158,
> +        3228, 3298, 3371, 3444, 3520, 3597, 3676,
> +        3756, 3838, 3922, 4008
> +    };
> +    static const int wh[3] = {0, -214, 798};
> +    static const int rh2[4] = {2, 1, 2, 1};
> +    static const int qm2[4] = {-7408, -1616,  7408,   1616};
> +    static const int qm4[16] = 
> +    {
> +              0, -20456, -12896,  -8968, 
> +          -6288,  -4240,  -2584,  -1200,
> +          20456,  12896,   8968,   6288,
> +           4240,   2584,   1200,      0
> +    };
> +    static const int qm5[32] =
> +    {
> +           -280,   -280, -23352, -17560,
> +         -14120, -11664,  -9752,  -8184,
> +          -6864,  -5712,  -4696,  -3784,
> +          -2960,  -2208,  -1520,   -880,
> +          23352,  17560,  14120,  11664,
> +           9752,   8184,   6864,   5712,
> +           4696,   3784,   2960,   2208,
> +           1520,    880,    280,   -280
> +    };
> +    static const int qm6[64] =
> +    {
> +           -136,   -136,   -136,   -136,
> +         -24808, -21904, -19008, -16704,
> +         -14984, -13512, -12280, -11192,
> +         -10232,  -9360,  -8576,  -7856,
> +          -7192,  -6576,  -6000,  -5456,
> +          -4944,  -4464,  -4008,  -3576,
> +          -3168,  -2776,  -2400,  -2032,
> +          -1688,  -1360,  -1040,   -728,
> +          24808,  21904,  19008,  16704,
> +          14984,  13512,  12280,  11192,
> +          10232,   9360,   8576,   7856,
> +           7192,   6576,   6000,   5456,
> +           4944,   4464,   4008,   3576,
> +           3168,   2776,   2400,   2032,
> +           1688,   1360,   1040,    728,
> +            432,    136,   -432,   -136
> +    };
> +    static const int qmf_coeffs[12] =
> +    {
> +           3,  -11,   12,   32, -210,  951, 3876, -805,  362, -156,   53,  -11,
> +    };
> +
> +    int dlowt;
> +    int rlow;
> +    int ihigh;
> +    int dhigh;
> +    int rhigh;
> +    int xout1;
> +    int xout2;
> +    int wd1;
> +    int wd2;
> +    int wd3;
> +    int code;
> +    int outlen;
> +    int i;
> +    int j;
> +
> +    outlen = 0;
> +    rhigh = 0;
> +    for (j = 0;  j < len;  )
> +    {
> +        if (s->packed)
> +        {
> +            /* Unpack the code bits */
> +            if (s->in_bits < s->bits_per_sample)
> +            {
> +                s->in_buffer |= (g722_data[j++] << s->in_bits);
> +                s->in_bits += 8;
> +            }
> +            code = s->in_buffer & ((1 << s->bits_per_sample) - 1);
> +            s->in_buffer >>= s->bits_per_sample;
> +            s->in_bits -= s->bits_per_sample;
> +        }
> +        else
> +        {
> +            code = g722_data[j++];
> +        }
> +
> +        switch (s->bits_per_sample)
> +        {
> +        default:
> +        case 8:
> +            wd1 = code & 0x3F;
> +            ihigh = (code >> 6) & 0x03;
> +            wd2 = qm6[wd1];
> +            wd1 >>= 2;
> +            break;
> +        case 7:
> +            wd1 = code & 0x1F;
> +            ihigh = (code >> 5) & 0x03;
> +            wd2 = qm5[wd1];
> +            wd1 >>= 1;
> +            break;
> +        case 6:
> +            wd1 = code & 0x0F;
> +            ihigh = (code >> 4) & 0x03;
> +            wd2 = qm4[wd1];
> +            break;
> +        }
> +        /* Block 5L, LOW BAND INVQBL */
> +        wd2 = (s->band[0].det*wd2) >> 15;
> +        /* Block 5L, RECONS */
> +        rlow = s->band[0].s + wd2;
> +        /* Block 6L, LIMIT */
> +        if (rlow > 16383)
> +            rlow = 16383;
> +        else if (rlow < -16384)
> +            rlow = -16384;
> +
> +        /* Block 2L, INVQAL */
> +        wd2 = qm4[wd1];
> +        dlowt = (s->band[0].det*wd2) >> 15;
> +
> +        /* Block 3L, LOGSCL */
> +        wd2 = rl42[wd1];
> +        wd1 = (s->band[0].nb*127) >> 7;
> +        wd1 += wl[wd2];
> +        if (wd1 < 0)
> +            wd1 = 0;
> +        else if (wd1 > 18432)
> +            wd1 = 18432;
> +        s->band[0].nb = wd1;
> +            
> +        /* Block 3L, SCALEL */
> +        wd1 = (s->band[0].nb >> 6) & 31;
> +        wd2 = 8 - (s->band[0].nb >> 11);
> +        wd3 = (wd2 < 0)  ?  (ilb[wd1] << -wd2)  :  (ilb[wd1] >> wd2);
> +        s->band[0].det = wd3 << 2;
> +
> +        block4(s, 0, dlowt);
> +        
> +        if (!s->eight_k)
> +        {
> +            /* Block 2H, INVQAH */
> +            wd2 = qm2[ihigh];
> +            dhigh = (s->band[1].det*wd2) >> 15;
> +            /* Block 5H, RECONS */
> +            rhigh = dhigh + s->band[1].s;
> +            /* Block 6H, LIMIT */
> +            if (rhigh > 16383)
> +                rhigh = 16383;
> +            else if (rhigh < -16384)
> +                rhigh = -16384;
> +
> +            /* Block 2H, INVQAH */
> +            wd2 = rh2[ihigh];
> +            wd1 = (s->band[1].nb*127) >> 7;
> +            wd1 += wh[wd2];
> +            if (wd1 < 0)
> +                wd1 = 0;
> +            else if (wd1 > 22528)
> +                wd1 = 22528;
> +            s->band[1].nb = wd1;
> +            
> +            /* Block 3H, SCALEH */
> +            wd1 = (s->band[1].nb >> 6) & 31;
> +            wd2 = 10 - (s->band[1].nb >> 11);
> +            wd3 = (wd2 < 0)  ?  (ilb[wd1] << -wd2)  :  (ilb[wd1] >> wd2);
> +            s->band[1].det = wd3 << 2;
> +
> +            block4(s, 1, dhigh);
> +        }
> +
> +        if (s->itu_test_mode)
> +        {
> +            amp[outlen++] = (int16_t) (rlow << 1);
> +            amp[outlen++] = (int16_t) (rhigh << 1);
> +        }
> +        else
> +        {
> +            if (s->eight_k)
> +            {
> +                amp[outlen++] = (int16_t) rlow;
> +            }
> +            else
> +            {
> +                /* Apply the receive QMF */
> +                for (i = 0;  i < 22;  i++)
> +                    s->x[i] = s->x[i + 2];
> +                s->x[22] = rlow + rhigh;
> +                s->x[23] = rlow - rhigh;
> +
> +                xout1 = 0;
> +                xout2 = 0;
> +                for (i = 0;  i < 12;  i++)
> +                {
> +                    xout2 += s->x[2*i]*qmf_coeffs[i];
> +                    xout1 += s->x[2*i + 1]*qmf_coeffs[11 - i];
> +                }
> +                amp[outlen++] = (int16_t) (xout1 >> 12);
> +                amp[outlen++] = (int16_t) (xout2 >> 12);
> +            }
> +        }
> +    }
> +    return outlen;
> +}
> +/*- End of function --------------------------------------------------------*/
> +

Why not just rename g722_decode_state_t to AVG722Context? Our policy is 
not to have "kind of unmodified" SpanDSP code. We either link to it in 
compile time as an external library or we modify it to conform with our 
coding standards and add it to our tree.

> +typedef struct AVG722Context {
> +    g722_decode_state_t *s;
> +} AVG722Context;
> +
> +static int g722_init(AVCodecContext * avctx)
> +{
> +    AVG722Context *c = (AVG722Context *) avctx->priv_data;
> +    int options = 0;
> +
> +    if (avctx->channels != 1 ||
> +        (avctx->bit_rate != 48000 && avctx->bit_rate != 56000 &&
> +                                     avctx->bit_rate != 64000)) {
> +        av_log(avctx, AV_LOG_ERROR, "G722: unsupported audio format\n");
> +        return -1;
> +    }
> +
> +    if (avctx->sample_rate != 8000 && avctx->sample_rate != 16000
> +	&& avctx->strict_std_compliance>FF_COMPLIANCE_INOFFICIAL) {
> +        av_log(avctx, AV_LOG_ERROR, "G722: unsupported audio format\n");
> +        return -1;
> +    }
> +    
> +    if (avctx->sample_rate == 8000)
> +	options |= G722_SAMPLE_RATE_8000;
> +    /* options |= G722_PACKED? */
> +	
> +    c->s = g722_decode_init(NULL, avctx->bit_rate, options);
> +
> +    avctx->coded_frame = avcodec_alloc_frame();
> +    if (!avctx->coded_frame)
> +        return AVERROR(ENOMEM);
> +    avctx->coded_frame->key_frame = 1;
> +
> +    return 0;
> +}
> +
> +static int g722_decode_frame(AVCodecContext *avctx,
> +                             void *data, int *data_size,
> +                             uint8_t *buf, int buf_size)
> +{
> +    AVG722Context *c = avctx->priv_data;
> +    int16_t *amp = data;
> +
> +    *data_size = g722_decode(c->s, amp, buf, buf_size) * sizeof(short);
> +    return buf_size;
> +}
> +
> +static int g722_close(AVCodecContext *avctx)
> +{
> +    AVG722Context* c = (AVG722Context *) avctx->priv_data;
> +
> +    g722_decode_release(c->s);
> +    av_freep(&avctx->coded_frame);
> +    return 0;
> +}
> +
> +AVCodec adpcm_g722_decoder = {
> +    "g722",
> +    CODEC_TYPE_AUDIO,
> +    CODEC_ID_ADPCM_G722,
> +    sizeof(AVG722Context),
> +    g722_init,
> +    NULL,
> +    g722_close,
> +    g722_decode_frame,
> +};
> +
> +
> --- mplayer-1.0rc2.orig/etc/codecs.conf	2007-10-07 15:49:33.000000000 -0400
> +++ mplayer-1.0rc2/etc/codecs.conf	2008-05-16 11:16:42.000000000 -0400
> @@ -3141,6 +3141,13 @@
>    driver ffmpeg
>    dll "g726"
>  
> +audiocodec g722
> +  info "G.722 Audio"
> +  status working
> +  format 0x41
> +  driver ffmpeg
> +  dll "g722"
> +
>  audiocodec g726
>    info "Sharp G.726 Audio"
>    status untested

You should post this to MPlayer-dev after your patch is applied to 
ffmpeg tree, not here.

-Vitor




More information about the ffmpeg-devel mailing list