diff options
Diffstat (limited to 'contrib/ffmpeg/libavcodec/amr.c')
-rw-r--r-- | contrib/ffmpeg/libavcodec/amr.c | 266 |
1 files changed, 133 insertions, 133 deletions
diff --git a/contrib/ffmpeg/libavcodec/amr.c b/contrib/ffmpeg/libavcodec/amr.c index 2d1877b22..6a8193f0b 100644 --- a/contrib/ffmpeg/libavcodec/amr.c +++ b/contrib/ffmpeg/libavcodec/amr.c @@ -18,41 +18,53 @@ * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - /* - This code implements amr-nb and amr-wb audio encoder/decoder through external reference - code from www.3gpp.org. The licence of the code from 3gpp is unclear so you - have to download the code separately. Two versions exists: One fixed-point - and one with floats. For some reason the float-encoder is significant faster - atleast on a P4 1.5GHz (0.9s instead of 9.9s on a 30s audio clip at MR102). - Both float and fixed point is supported for amr-nb, but only float for - amr-wb. - - --AMR-NB-- - The fixed-point (TS26.073) can be downloaded from: - http://www.3gpp.org/ftp/Specs/archive/26_series/26.073/26073-510.zip - Extract the soure into ffmpeg/libavcodec/amr - To use the fixed version run "./configure" with "--enable-amr_nb-fixed" - - The float version (default) can be downloaded from: - http://www.3gpp.org/ftp/Specs/archive/26_series/26.104/26104-510.zip - Extract the soure into ffmpeg/libavcodec/amr_float - - The specification for amr-nb can be found in TS 26.071 - (http://www.3gpp.org/ftp/Specs/html-info/26071.htm) and some other - info at http://www.3gpp.org/ftp/Specs/html-info/26-series.htm - - --AMR-WB-- - The reference code can be downloaded from: - http://www.3gpp.org/ftp/Specs/archive/26_series/26.204/26204-510.zip - It should be extracted to "libavcodec/amrwb_float". Enable it with - "--enable-amr_wb". - - The specification for amr-wb can be downloaded from: - http://www.3gpp.org/ftp/Specs/archive/26_series/26.171/26171-500.zip - - If someone want to use the fixed point version it can be downloaded - from: http://www.3gpp.org/ftp/Specs/archive/26_series/26.173/26173-571.zip + /** @file + * Adaptive Multi-Rate (AMR) Audio decoder stub. + * + * This code implements both an AMR-NarrowBand (AMR-NB) and an AMR-WideBand + * (AMR-WB) audio encoder/decoder through external reference code from + * http://www.3gpp.org/. The license of the code from 3gpp is unclear so you + * have to download the code separately. Two versions exists: One fixed-point + * and one with floats. For some reason the float-encoder is significant faster + * at least on a P4 1.5GHz (0.9s instead of 9.9s on a 30s audio clip at MR102). + * Both float and fixed point are supported for AMR-NB, but only float for + * AMR-WB. + * + * \section AMR-NB + * + * \subsection Float + * The float version (default) can be downloaded from: + * http://www.3gpp.org/ftp/Specs/archive/26_series/26.104/26104-610.zip + * Extract the source into \c "ffmpeg/libavcodec/amr_float". + * + * \subsection Fixed-point + * The fixed-point (TS26.073) can be downloaded from: + * http://www.3gpp.org/ftp/Specs/archive/26_series/26.073/26073-510.zip. + * Extract the source into \c "ffmpeg/libavcodec/amr". + * To use the fixed version run \c "./configure" with \c "--enable-amr_nb-fixed". + * + * \subsection Specification + * The specification for AMR-NB can be found in TS 26.071 + * (http://www.3gpp.org/ftp/Specs/html-info/26071.htm) and some other + * info at http://www.3gpp.org/ftp/Specs/html-info/26-series.htm. + * + * \section AMR-WB + * \subsection Float + * The reference code can be downloaded from: + * http://www.3gpp.org/ftp/Specs/archive/26_series/26.204/26204-600.zip + * It should be extracted to \c "ffmpeg/libavcodec/amrwb_float". Enable it with + * \c "--enable-amr_wb". + * + * \subsection Fixed-point + * If someone wants to use the fixed point version it can be downloaded from: + * http://www.3gpp.org/ftp/Specs/archive/26_series/26.173/26173-571.zip. + * + * \subsection Specification + * The specification for AMR-WB can be found in TS 26.171 + * (http://www.3gpp.org/ftp/Specs/html-info/26171.htm) and some other + * info at http://www.3gpp.org/ftp/Specs/html-info/26-series.htm. + * */ #include "avcodec.h" @@ -76,37 +88,34 @@ /* Common code for fixed and float version*/ typedef struct AMR_bitrates { - int startrate; - int stoprate; + int rate; enum Mode mode; - } AMR_bitrates; -/* Match desired bitrate with closest one*/ -static enum Mode getBitrateMode(int bitrate) +/* Match desired bitrate */ +static int getBitrateMode(int bitrate) { - /* Adjusted so that all bitrates can be used from commandline where - only a multiple of 1000 can be specified*/ - AMR_bitrates rates[]={ {0,4999,MR475}, //4 - {5000,5899,MR515},//5 - {5900,6699,MR59},//6 - {6700,7000,MR67},//7 - {7001,7949,MR74},//8 - {7950,9999,MR795},//9 - {10000,11999,MR102},//10 - {12000,64000,MR122},//12 - + /* make the correspondance between bitrate and mode */ + AMR_bitrates rates[]={ {4750,MR475}, + {5150,MR515}, + {5900,MR59}, + {6700,MR67}, + {7400,MR74}, + {7950,MR795}, + {10200,MR102}, + {12200,MR122}, }; int i; + for(i=0;i<8;i++) { - if(rates[i].startrate<=bitrate && rates[i].stoprate>=bitrate) + if(rates[i].rate==bitrate) { return(rates[i].mode); } } - /*Return highest possible*/ - return(MR122); + /* no bitrate matching, return an error */ + return -1; } static void amr_decode_fix_avctx(AVCodecContext * avctx) @@ -139,17 +148,16 @@ typedef struct AMRContext { Word16 reset_flag; Word16 reset_flag_old; - enum Mode enc_bitrate; + int enc_bitrate; Speech_Encode_FrameState *enstate; sid_syncState *sidstate; enum TXFrameType tx_frametype; - - } AMRContext; static int amr_nb_decode_init(AVCodecContext * avctx) { AMRContext *s = avctx->priv_data; + s->frameCount=0; s->speech_decoder_state=NULL; s->rx_type = (enum RXFrameType)0; @@ -177,6 +185,7 @@ static int amr_nb_decode_init(AVCodecContext * avctx) static int amr_nb_encode_init(AVCodecContext * avctx) { AMRContext *s = avctx->priv_data; + s->frameCount=0; s->speech_decoder_state=NULL; s->rx_type = (enum RXFrameType)0; @@ -186,19 +195,13 @@ static int amr_nb_encode_init(AVCodecContext * avctx) if(avctx->sample_rate!=8000) { - if(avctx->debug) - { - av_log(avctx, AV_LOG_DEBUG, "Only 8000Hz sample rate supported\n"); - } + av_log(avctx, AV_LOG_ERROR, "Only 8000Hz sample rate supported\n"); return -1; } if(avctx->channels!=1) { - if(avctx->debug) - { - av_log(avctx, AV_LOG_DEBUG, "Only mono supported\n"); - } + av_log(avctx, AV_LOG_ERROR, "Only mono supported\n"); return -1; } @@ -207,14 +210,15 @@ static int amr_nb_encode_init(AVCodecContext * avctx) if(Speech_Encode_Frame_init(&s->enstate, 0, "encoder") || sid_sync_init (&s->sidstate)) { - if(avctx->debug) - { - av_log(avctx, AV_LOG_DEBUG, "Speech_Encode_Frame_init error\n"); - } + av_log(avctx, AV_LOG_ERROR, "Speech_Encode_Frame_init error\n"); return -1; } - s->enc_bitrate=getBitrateMode(avctx->bit_rate); + if((s->enc_bitrate=getBitrateMode(avctx->bit_rate))<0) + { + av_log(avctx, AV_LOG_ERROR, "bitrate not supported\n"); + return -1; + } return 0; } @@ -222,6 +226,7 @@ static int amr_nb_encode_init(AVCodecContext * avctx) static int amr_nb_encode_close(AVCodecContext * avctx) { AMRContext *s = avctx->priv_data; + Speech_Encode_Frame_exit(&s->enstate); sid_sync_exit (&s->sidstate); av_freep(&avctx->coded_frame); @@ -231,6 +236,7 @@ static int amr_nb_encode_close(AVCodecContext * avctx) static int amr_nb_decode_close(AVCodecContext * avctx) { AMRContext *s = avctx->priv_data; + Speech_Decode_Frame_exit(&s->speech_decoder_state); return 0; } @@ -240,16 +246,12 @@ static int amr_nb_decode_frame(AVCodecContext * avctx, uint8_t * buf, int buf_size) { AMRContext *s = avctx->priv_data; - uint8_t*amrData=buf; int offset=0; - UWord8 toc, q, ft; - Word16 serial[SERIAL_FRAMESIZE]; /* coded bits */ Word16 *synth; UWord8 *packed_bits; - static Word16 packed_size[16] = {12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0}; int i; @@ -332,7 +334,6 @@ static int amr_nb_encode_frame(AVCodecContext *avctx, unsigned char *frame/*out*/, int buf_size, void *data/*in*/) { short serial_data[250] = {0}; - AMRContext *s = avctx->priv_data; int written; @@ -360,12 +361,13 @@ typedef struct AMRContext { int frameCount; void * decState; int *enstate; - enum Mode enc_bitrate; + 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) @@ -388,23 +390,18 @@ static int amr_nb_decode_init(AVCodecContext * avctx) static int amr_nb_encode_init(AVCodecContext * avctx) { AMRContext *s = avctx->priv_data; + s->frameCount=0; if(avctx->sample_rate!=8000) { - if(avctx->debug) - { - av_log(avctx, AV_LOG_DEBUG, "Only 8000Hz sample rate supported\n"); - } + av_log(avctx, AV_LOG_ERROR, "Only 8000Hz sample rate supported\n"); return -1; } if(avctx->channels!=1) { - if(avctx->debug) - { - av_log(avctx, AV_LOG_DEBUG, "Only mono supported\n"); - } + av_log(avctx, AV_LOG_ERROR, "Only mono supported\n"); return -1; } @@ -414,14 +411,15 @@ static int amr_nb_encode_init(AVCodecContext * avctx) s->enstate=Encoder_Interface_init(0); if(!s->enstate) { - if(avctx->debug) - { - av_log(avctx, AV_LOG_DEBUG, "Encoder_Interface_init error\n"); - } + av_log(avctx, AV_LOG_ERROR, "Encoder_Interface_init error\n"); return -1; } - s->enc_bitrate=getBitrateMode(avctx->bit_rate); + if((s->enc_bitrate=getBitrateMode(avctx->bit_rate))<0) + { + av_log(avctx, AV_LOG_ERROR, "bitrate not supported\n"); + return -1; + } return 0; } @@ -429,6 +427,7 @@ static int amr_nb_encode_init(AVCodecContext * avctx) static int amr_nb_decode_close(AVCodecContext * avctx) { AMRContext *s = avctx->priv_data; + Decoder_Interface_exit(s->decState); return 0; } @@ -436,6 +435,7 @@ static int amr_nb_decode_close(AVCodecContext * avctx) 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; @@ -445,8 +445,7 @@ static int amr_nb_decode_frame(AVCodecContext * avctx, void *data, int *data_size, uint8_t * buf, int buf_size) { - AMRContext *s = (AMRContext*)avctx->priv_data; - + 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; @@ -454,11 +453,6 @@ static int amr_nb_decode_frame(AVCodecContext * avctx, /* av_log(NULL,AV_LOG_DEBUG,"amr_decode_frame buf=%p buf_size=%d frameCount=%d!!\n",buf,buf_size,s->frameCount); */ - if(buf_size==0) { - /* nothing to do */ - return 0; - } - dec_mode = (buf[0] >> 3) & 0x000F; packet_size = block_size[dec_mode]+1; @@ -479,10 +473,14 @@ static int amr_nb_decode_frame(AVCodecContext * avctx, static int amr_nb_encode_frame(AVCodecContext *avctx, unsigned char *frame/*out*/, int buf_size, void *data/*in*/) { - AMRContext *s = (AMRContext*)avctx->priv_data; + AMRContext *s = avctx->priv_data; int written; - s->enc_bitrate=getBitrateMode(avctx->bit_rate); + if((s->enc_bitrate=getBitrateMode(avctx->bit_rate))<0) + { + av_log(avctx, AV_LOG_ERROR, "bitrate not supported\n"); + return -1; + } written = Encoder_Interface_Encode(s->enstate, s->enc_bitrate, @@ -538,38 +536,34 @@ AVCodec amr_nb_encoder = /* Common code for fixed and float version*/ typedef struct AMRWB_bitrates { - int startrate; - int stoprate; + int rate; int mode; - } AMRWB_bitrates; static int getWBBitrateMode(int bitrate) { - /* Adjusted so that all bitrates can be used from commandline where - only a multiple of 1000 can be specified*/ - AMRWB_bitrates rates[]={ {0,7999,0}, //6.6kHz - {8000,9999,1},//8.85 - {10000,13000,2},//12.65 - {13001,14999,3},//14.25 - {15000,17000,4},//15.85 - {17001,18000,5},//18.25 - {18001,22000,6},//19.85 - {22001,23000,7},//23.05 - {23001,24000,8},//23.85 - + /* 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].startrate<=bitrate && rates[i].stoprate>=bitrate) + if(rates[i].rate==bitrate) { return(rates[i].mode); } } - /*Return highest possible*/ - return(8); + /* no bitrate matching, return an error */ + return -1; } @@ -582,24 +576,25 @@ typedef struct AMRWBContext { static int amr_wb_encode_init(AVCodecContext * avctx) { - AMRWBContext *s = (AMRWBContext*)avctx->priv_data; + AMRWBContext *s = avctx->priv_data; + s->frameCount=0; if(avctx->sample_rate!=16000) { - if(avctx->debug) - { - av_log(avctx, AV_LOG_DEBUG, "Only 16000Hz sample rate supported\n"); - } + av_log(avctx, AV_LOG_ERROR, "Only 16000Hz sample rate supported\n"); return -1; } if(avctx->channels!=1) { - if(avctx->debug) - { - av_log(avctx, AV_LOG_DEBUG, "Only mono supported\n"); - } + 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, "bitrate not supported\n"); return -1; } @@ -607,7 +602,6 @@ static int amr_wb_encode_init(AVCodecContext * avctx) avctx->coded_frame= avcodec_alloc_frame(); s->state = E_IF_init(); - s->mode=getWBBitrateMode(avctx->bit_rate); s->allow_dtx=0; return 0; @@ -615,7 +609,8 @@ static int amr_wb_encode_init(AVCodecContext * avctx) static int amr_wb_encode_close(AVCodecContext * avctx) { - AMRWBContext *s = (AMRWBContext*) avctx->priv_data; + AMRWBContext *s = avctx->priv_data; + E_IF_exit(s->state); av_freep(&avctx->coded_frame); s->frameCount++; @@ -625,17 +620,22 @@ static int amr_wb_encode_close(AVCodecContext * avctx) static int amr_wb_encode_frame(AVCodecContext *avctx, unsigned char *frame/*out*/, int buf_size, void *data/*in*/) { - AMRWBContext *s; + AMRWBContext *s = avctx->priv_data; int size; - s = (AMRWBContext*) avctx->priv_data; - s->mode=getWBBitrateMode(avctx->bit_rate); + + if((s->mode=getWBBitrateMode(avctx->bit_rate))<0) + { + av_log(avctx, AV_LOG_ERROR, "bitrate not supported\n"); + 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 = (AMRWBContext *)avctx->priv_data; + AMRWBContext *s = avctx->priv_data; + s->frameCount=0; s->state = D_IF_init(); @@ -656,8 +656,7 @@ static int amr_wb_decode_frame(AVCodecContext * avctx, void *data, int *data_size, uint8_t * buf, int buf_size) { - AMRWBContext *s = (AMRWBContext*)avctx->priv_data; - + AMRWBContext *s = avctx->priv_data; uint8_t*amrData=buf; int mode; int packet_size; @@ -683,7 +682,8 @@ static int amr_wb_decode_frame(AVCodecContext * avctx, static int amr_wb_decode_close(AVCodecContext * avctx) { - AMRWBContext *s = (AMRWBContext *)avctx->priv_data; + AMRWBContext *s = avctx->priv_data; + D_IF_exit(s->state); return 0; } |