⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 libamr.c

📁 ffmpeg的完整源代码和作者自己写的文档。不但有在Linux的工程哦
💻 C
📖 第 1 页 / 共 2 页
字号:
typedef struct AMRContext {
    int frameCount;
    void * decState;
    int *enstate;
    int enc_bitrate;
} AMRContext;

static int amr_nb_decode_init(AVCodecContext * avctx)
{
    AMRContext *s = avctx->priv_data;

    s->frameCount=0;
    s->decState=Decoder_Interface_init();
    if(!s->decState)
    {
        av_log(avctx, AV_LOG_ERROR, "Decoder_Interface_init error\r\n");
        return -1;
    }

    amr_decode_fix_avctx(avctx);

    if(avctx->channels > 1)
    {
        av_log(avctx, AV_LOG_ERROR, "amr_nb: multichannel decoding not supported\n");
        return -1;
    }

    return 0;
}

static int amr_nb_encode_init(AVCodecContext * avctx)
{
    AMRContext *s = avctx->priv_data;

    s->frameCount=0;

    if(avctx->sample_rate!=8000)
    {
        av_log(avctx, AV_LOG_ERROR, "Only 8000Hz sample rate supported\n");
        return -1;
    }

    if(avctx->channels!=1)
    {
        av_log(avctx, AV_LOG_ERROR, "Only mono supported\n");
        return -1;
    }

    avctx->frame_size=160;
    avctx->coded_frame= avcodec_alloc_frame();

    s->enstate=Encoder_Interface_init(0);
    if(!s->enstate)
    {
        av_log(avctx, AV_LOG_ERROR, "Encoder_Interface_init error\n");
        return -1;
    }

    if((s->enc_bitrate=getBitrateMode(avctx->bit_rate))<0)
    {
        av_log(avctx, AV_LOG_ERROR, nb_bitrate_unsupported);
        return -1;
    }

    return 0;
}

static int amr_nb_decode_close(AVCodecContext * avctx)
{
    AMRContext *s = avctx->priv_data;

    Decoder_Interface_exit(s->decState);
    return 0;
}

static int amr_nb_encode_close(AVCodecContext * avctx)
{
    AMRContext *s = avctx->priv_data;

    Encoder_Interface_exit(s->enstate);
    av_freep(&avctx->coded_frame);
    return 0;
}

static int amr_nb_decode_frame(AVCodecContext * avctx,
            void *data, int *data_size,
            uint8_t * buf, int buf_size)
{
    AMRContext *s = avctx->priv_data;
    uint8_t*amrData=buf;
    static short block_size[16]={ 12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0 };
    enum Mode dec_mode;
    int packet_size;

    /* av_log(NULL,AV_LOG_DEBUG,"amr_decode_frame buf=%p buf_size=%d frameCount=%d!!\n",buf,buf_size,s->frameCount); */

    dec_mode = (buf[0] >> 3) & 0x000F;
    packet_size = block_size[dec_mode]+1;

    if(packet_size > buf_size) {
        av_log(avctx, AV_LOG_ERROR, "amr frame too short (%u, should be %u)\n", buf_size, packet_size);
        return -1;
    }

    s->frameCount++;
    /* av_log(NULL,AV_LOG_DEBUG,"packet_size=%d amrData= 0x%X %X %X %X\n",packet_size,amrData[0],amrData[1],amrData[2],amrData[3]); */
    /* call decoder */
    Decoder_Interface_Decode(s->decState, amrData, data, 0);
    *data_size=160*2;

    return packet_size;
}

static int amr_nb_encode_frame(AVCodecContext *avctx,
                            unsigned char *frame/*out*/, int buf_size, void *data/*in*/)
{
    AMRContext *s = avctx->priv_data;
    int written;

    if((s->enc_bitrate=getBitrateMode(avctx->bit_rate))<0)
    {
        av_log(avctx, AV_LOG_ERROR, nb_bitrate_unsupported);
        return -1;
    }

    written = Encoder_Interface_Encode(s->enstate,
        s->enc_bitrate,
        data,
        frame,
        0);
    /* av_log(NULL,AV_LOG_DEBUG,"amr_nb_encode_frame encoded %u bytes, bitrate %u, first byte was %#02x\n",written, s->enc_bitrate, frame[0] ); */

    return written;
}

#endif

#if defined(CONFIG_LIBAMR_NB) || defined(CONFIG_LIBAMR_NB_FIXED)

AVCodec libamr_nb_decoder =
{
    "libamr_nb",
    CODEC_TYPE_AUDIO,
    CODEC_ID_AMR_NB,
    sizeof(AMRContext),
    amr_nb_decode_init,
    NULL,
    amr_nb_decode_close,
    amr_nb_decode_frame,
};

AVCodec libamr_nb_encoder =
{
    "libamr_nb",
    CODEC_TYPE_AUDIO,
    CODEC_ID_AMR_NB,
    sizeof(AMRContext),
    amr_nb_encode_init,
    amr_nb_encode_frame,
    amr_nb_encode_close,
    NULL,
};

#endif

/* -----------AMR wideband ------------*/
#ifdef CONFIG_LIBAMR_WB

#ifdef _TYPEDEF_H
//To avoid duplicate typedefs from typdef in amr-nb
#define typedef_h
#endif

#include <amrwb/enc_if.h>
#include <amrwb/dec_if.h>
#include <amrwb/if_rom.h>

/* Common code for fixed and float version*/
typedef struct AMRWB_bitrates
{
    int rate;
    int mode;
} AMRWB_bitrates;

static int getWBBitrateMode(int bitrate)
{
    /* make the correspondance between bitrate and mode */
    AMRWB_bitrates rates[]={ {6600,0},
                           {8850,1},
                           {12650,2},
                           {14250,3},
                           {15850,4},
                           {18250,5},
                           {19850,6},
                           {23050,7},
                           {23850,8},
                         };
    int i;

    for(i=0;i<9;i++)
    {
        if(rates[i].rate==bitrate)
        {
            return(rates[i].mode);
        }
    }
    /* no bitrate matching, return an error */
    return -1;
}


typedef struct AMRWBContext {
    int frameCount;
    void *state;
    int mode;
    Word16 allow_dtx;
} AMRWBContext;

static int amr_wb_encode_init(AVCodecContext * avctx)
{
    AMRWBContext *s = avctx->priv_data;

    s->frameCount=0;

    if(avctx->sample_rate!=16000)
    {
        av_log(avctx, AV_LOG_ERROR, "Only 16000Hz sample rate supported\n");
        return -1;
    }

    if(avctx->channels!=1)
    {
        av_log(avctx, AV_LOG_ERROR, "Only mono supported\n");
        return -1;
    }

    if((s->mode=getWBBitrateMode(avctx->bit_rate))<0)
    {
        av_log(avctx, AV_LOG_ERROR, wb_bitrate_unsupported);
        return -1;
    }

    avctx->frame_size=320;
    avctx->coded_frame= avcodec_alloc_frame();

    s->state = E_IF_init();
    s->allow_dtx=0;

    return 0;
}

static int amr_wb_encode_close(AVCodecContext * avctx)
{
    AMRWBContext *s = avctx->priv_data;

    E_IF_exit(s->state);
    av_freep(&avctx->coded_frame);
    s->frameCount++;
    return 0;
}

static int amr_wb_encode_frame(AVCodecContext *avctx,
                            unsigned char *frame/*out*/, int buf_size, void *data/*in*/)
{
    AMRWBContext *s = avctx->priv_data;
    int size;

    if((s->mode=getWBBitrateMode(avctx->bit_rate))<0)
    {
        av_log(avctx, AV_LOG_ERROR, wb_bitrate_unsupported);
        return -1;
    }
    size = E_IF_encode(s->state, s->mode, data, frame, s->allow_dtx);
    return size;
}

static int amr_wb_decode_init(AVCodecContext * avctx)
{
    AMRWBContext *s = avctx->priv_data;

    s->frameCount=0;
    s->state = D_IF_init();

    amr_decode_fix_avctx(avctx);

    if(avctx->channels > 1)
    {
        av_log(avctx, AV_LOG_ERROR, "amr_wb: multichannel decoding not supported\n");
        return -1;
    }

    return 0;
}

static int amr_wb_decode_frame(AVCodecContext * avctx,
            void *data, int *data_size,
            uint8_t * buf, int buf_size)
{
    AMRWBContext *s = avctx->priv_data;
    uint8_t*amrData=buf;
    int mode;
    int packet_size;

    if(buf_size==0) {
        /* nothing to do */
        return 0;
    }

    mode = (amrData[0] >> 3) & 0x000F;
    packet_size = block_size[mode];

    if(packet_size > buf_size) {
        av_log(avctx, AV_LOG_ERROR, "amr frame too short (%u, should be %u)\n", buf_size, packet_size+1);
        return -1;
    }

    s->frameCount++;
    D_IF_decode( s->state, amrData, data, _good_frame);
    *data_size=320*2;
    return packet_size;
}

static int amr_wb_decode_close(AVCodecContext * avctx)
{
    AMRWBContext *s = avctx->priv_data;

    D_IF_exit(s->state);
    return 0;
}

AVCodec libamr_wb_decoder =
{
    "libamr_wb",
    CODEC_TYPE_AUDIO,
    CODEC_ID_AMR_WB,
    sizeof(AMRWBContext),
    amr_wb_decode_init,
    NULL,
    amr_wb_decode_close,
    amr_wb_decode_frame,
};

AVCodec libamr_wb_encoder =
{
    "libamr_wb",
    CODEC_TYPE_AUDIO,
    CODEC_ID_AMR_WB,
    sizeof(AMRWBContext),
    amr_wb_encode_init,
    amr_wb_encode_frame,
    amr_wb_encode_close,
    NULL,
};

#endif //CONFIG_LIBAMR_WB

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -