• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • Examples
  • File List
  • Globals

libavcodec/libopencore-amr.c

Go to the documentation of this file.
00001 /*
00002  * AMR Audio decoder stub
00003  * Copyright (c) 2003 the ffmpeg project
00004  *
00005  * This file is part of FFmpeg.
00006  *
00007  * FFmpeg is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * FFmpeg is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with FFmpeg; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020  */
00021 
00022 #include "avcodec.h"
00023 #include "libavutil/avstring.h"
00024 #include "libavutil/opt.h"
00025 
00026 static void amr_decode_fix_avctx(AVCodecContext *avctx)
00027 {
00028     const int is_amr_wb = 1 + (avctx->codec_id == CODEC_ID_AMR_WB);
00029 
00030     if (!avctx->sample_rate)
00031         avctx->sample_rate = 8000 * is_amr_wb;
00032 
00033     if (!avctx->channels)
00034         avctx->channels = 1;
00035 
00036     avctx->frame_size = 160 * is_amr_wb;
00037     avctx->sample_fmt = AV_SAMPLE_FMT_S16;
00038 }
00039 
00040 #if CONFIG_LIBOPENCORE_AMRNB
00041 
00042 #include <opencore-amrnb/interf_dec.h>
00043 #include <opencore-amrnb/interf_enc.h>
00044 
00045 /* Common code for fixed and float version*/
00046 typedef struct AMR_bitrates {
00047     int       rate;
00048     enum Mode mode;
00049 } AMR_bitrates;
00050 
00051 /* Match desired bitrate */
00052 static int get_bitrate_mode(int bitrate, void *log_ctx)
00053 {
00054     /* make the correspondance between bitrate and mode */
00055     static const AMR_bitrates rates[] = {
00056         { 4750, MR475 }, { 5150, MR515 }, {  5900, MR59  }, {  6700, MR67  },
00057         { 7400, MR74 },  { 7950, MR795 }, { 10200, MR102 }, { 12200, MR122 }
00058     };
00059     int i, best = -1, min_diff = 0;
00060     char log_buf[200];
00061 
00062     for (i = 0; i < 8; i++) {
00063         if (rates[i].rate == bitrate)
00064             return rates[i].mode;
00065         if (best < 0 || abs(rates[i].rate - bitrate) < min_diff) {
00066             best     = i;
00067             min_diff = abs(rates[i].rate - bitrate);
00068         }
00069     }
00070     /* no bitrate matching exactly, log a warning */
00071     snprintf(log_buf, sizeof(log_buf), "bitrate not supported: use one of ");
00072     for (i = 0; i < 8; i++)
00073         av_strlcatf(log_buf, sizeof(log_buf), "%.2fk, ", rates[i].rate    / 1000.f);
00074     av_strlcatf(log_buf, sizeof(log_buf), "using %.2fk", rates[best].rate / 1000.f);
00075     av_log(log_ctx, AV_LOG_WARNING, "%s\n", log_buf);
00076 
00077     return best;
00078 }
00079 
00080 typedef struct AMRContext {
00081     AVClass *av_class;
00082     int   frame_count;
00083     void *dec_state;
00084     void *enc_state;
00085     int   enc_bitrate;
00086     int   enc_mode;
00087     int   enc_dtx;
00088 } AMRContext;
00089 
00090 static const AVOption options[] = {
00091     { "dtx", "Allow DTX (generate comfort noise)", offsetof(AMRContext, enc_dtx), FF_OPT_TYPE_INT, 0, 0, 1, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM },
00092     { NULL }
00093 };
00094 
00095 static const AVClass class = {
00096     "libopencore_amrnb", av_default_item_name, options, LIBAVUTIL_VERSION_INT
00097 };
00098 
00099 static av_cold int amr_nb_decode_init(AVCodecContext *avctx)
00100 {
00101     AMRContext *s  = avctx->priv_data;
00102 
00103     s->frame_count = 0;
00104     s->dec_state   = Decoder_Interface_init();
00105     if (!s->dec_state) {
00106         av_log(avctx, AV_LOG_ERROR, "Decoder_Interface_init error\n");
00107         return -1;
00108     }
00109 
00110     amr_decode_fix_avctx(avctx);
00111 
00112     if (avctx->channels > 1) {
00113         av_log(avctx, AV_LOG_ERROR, "amr_nb: multichannel decoding not supported\n");
00114         return AVERROR(ENOSYS);
00115     }
00116 
00117     return 0;
00118 }
00119 
00120 static av_cold int amr_nb_decode_close(AVCodecContext *avctx)
00121 {
00122     AMRContext *s = avctx->priv_data;
00123 
00124     Decoder_Interface_exit(s->dec_state);
00125     return 0;
00126 }
00127 
00128 static int amr_nb_decode_frame(AVCodecContext *avctx, void *data,
00129                                int *data_size, AVPacket *avpkt)
00130 {
00131     const uint8_t *buf = avpkt->data;
00132     int buf_size       = avpkt->size;
00133     AMRContext *s      = avctx->priv_data;
00134     static const uint8_t block_size[16] = { 12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0 };
00135     enum Mode dec_mode;
00136     int packet_size;
00137 
00138     av_dlog(avctx, "amr_decode_frame buf=%p buf_size=%d frame_count=%d!!\n",
00139             buf, buf_size, s->frame_count);
00140 
00141     dec_mode    = (buf[0] >> 3) & 0x000F;
00142     packet_size = block_size[dec_mode] + 1;
00143 
00144     if (packet_size > buf_size) {
00145         av_log(avctx, AV_LOG_ERROR, "amr frame too short (%u, should be %u)\n",
00146                buf_size, packet_size);
00147         return AVERROR_INVALIDDATA;
00148     }
00149 
00150     s->frame_count++;
00151     av_dlog(avctx, "packet_size=%d buf= 0x%X %X %X %X\n",
00152               packet_size, buf[0], buf[1], buf[2], buf[3]);
00153     /* call decoder */
00154     Decoder_Interface_Decode(s->dec_state, buf, data, 0);
00155     *data_size = 160 * 2;
00156 
00157     return packet_size;
00158 }
00159 
00160 AVCodec ff_libopencore_amrnb_decoder = {
00161     "libopencore_amrnb",
00162     AVMEDIA_TYPE_AUDIO,
00163     CODEC_ID_AMR_NB,
00164     sizeof(AMRContext),
00165     amr_nb_decode_init,
00166     NULL,
00167     amr_nb_decode_close,
00168     amr_nb_decode_frame,
00169     .long_name = NULL_IF_CONFIG_SMALL("OpenCORE Adaptive Multi-Rate (AMR) Narrow-Band"),
00170 };
00171 
00172 static av_cold int amr_nb_encode_init(AVCodecContext *avctx)
00173 {
00174     AMRContext *s = avctx->priv_data;
00175 
00176     s->frame_count = 0;
00177 
00178     if (avctx->sample_rate != 8000) {
00179         av_log(avctx, AV_LOG_ERROR, "Only 8000Hz sample rate supported\n");
00180         return AVERROR(ENOSYS);
00181     }
00182 
00183     if (avctx->channels != 1) {
00184         av_log(avctx, AV_LOG_ERROR, "Only mono supported\n");
00185         return AVERROR(ENOSYS);
00186     }
00187 
00188     avctx->frame_size  = 160;
00189     avctx->coded_frame = avcodec_alloc_frame();
00190 
00191     s->enc_state = Encoder_Interface_init(s->enc_dtx);
00192     if (!s->enc_state) {
00193         av_log(avctx, AV_LOG_ERROR, "Encoder_Interface_init error\n");
00194         return -1;
00195     }
00196 
00197     s->enc_mode    = get_bitrate_mode(avctx->bit_rate, avctx);
00198     s->enc_bitrate = avctx->bit_rate;
00199 
00200     return 0;
00201 }
00202 
00203 static av_cold int amr_nb_encode_close(AVCodecContext *avctx)
00204 {
00205     AMRContext *s = avctx->priv_data;
00206 
00207     Encoder_Interface_exit(s->enc_state);
00208     av_freep(&avctx->coded_frame);
00209     return 0;
00210 }
00211 
00212 static int amr_nb_encode_frame(AVCodecContext *avctx,
00213                                unsigned char *frame/*out*/,
00214                                int buf_size, void *data/*in*/)
00215 {
00216     AMRContext *s = avctx->priv_data;
00217     int written;
00218 
00219     if (s->enc_bitrate != avctx->bit_rate) {
00220         s->enc_mode    = get_bitrate_mode(avctx->bit_rate, avctx);
00221         s->enc_bitrate = avctx->bit_rate;
00222     }
00223 
00224     written = Encoder_Interface_Encode(s->enc_state, s->enc_mode, data,
00225                                        frame, 0);
00226     av_dlog(avctx, "amr_nb_encode_frame encoded %u bytes, bitrate %u, first byte was %#02x\n",
00227             written, s->enc_mode, frame[0]);
00228 
00229     return written;
00230 }
00231 
00232 AVCodec ff_libopencore_amrnb_encoder = {
00233     "libopencore_amrnb",
00234     AVMEDIA_TYPE_AUDIO,
00235     CODEC_ID_AMR_NB,
00236     sizeof(AMRContext),
00237     amr_nb_encode_init,
00238     amr_nb_encode_frame,
00239     amr_nb_encode_close,
00240     NULL,
00241     .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE},
00242     .long_name = NULL_IF_CONFIG_SMALL("OpenCORE Adaptive Multi-Rate (AMR) Narrow-Band"),
00243     .priv_class = &class,
00244 };
00245 
00246 #endif
00247 
00248 /* -----------AMR wideband ------------*/
00249 #if CONFIG_LIBOPENCORE_AMRWB
00250 
00251 #include <opencore-amrwb/dec_if.h>
00252 #include <opencore-amrwb/if_rom.h>
00253 
00254 typedef struct AMRWBContext {
00255     void  *state;
00256 } AMRWBContext;
00257 
00258 static av_cold int amr_wb_decode_init(AVCodecContext *avctx)
00259 {
00260     AMRWBContext *s = avctx->priv_data;
00261 
00262     s->state        = D_IF_init();
00263 
00264     amr_decode_fix_avctx(avctx);
00265 
00266     if (avctx->channels > 1) {
00267         av_log(avctx, AV_LOG_ERROR, "amr_wb: multichannel decoding not supported\n");
00268         return AVERROR(ENOSYS);
00269     }
00270 
00271     return 0;
00272 }
00273 
00274 static int amr_wb_decode_frame(AVCodecContext *avctx, void *data,
00275                                int *data_size, AVPacket *avpkt)
00276 {
00277     const uint8_t *buf = avpkt->data;
00278     int buf_size       = avpkt->size;
00279     AMRWBContext *s    = avctx->priv_data;
00280     int mode;
00281     int packet_size;
00282     static const uint8_t block_size[16] = {18, 24, 33, 37, 41, 47, 51, 59, 61, 6, 6, 0, 0, 0, 1, 1};
00283 
00284     if (!buf_size)
00285         /* nothing to do */
00286         return 0;
00287 
00288     mode        = (buf[0] >> 3) & 0x000F;
00289     packet_size = block_size[mode];
00290 
00291     if (packet_size > buf_size) {
00292         av_log(avctx, AV_LOG_ERROR, "amr frame too short (%u, should be %u)\n",
00293                buf_size, packet_size + 1);
00294         return AVERROR_INVALIDDATA;
00295     }
00296 
00297     D_IF_decode(s->state, buf, data, _good_frame);
00298     *data_size = 320 * 2;
00299     return packet_size;
00300 }
00301 
00302 static int amr_wb_decode_close(AVCodecContext *avctx)
00303 {
00304     AMRWBContext *s = avctx->priv_data;
00305 
00306     D_IF_exit(s->state);
00307     return 0;
00308 }
00309 
00310 AVCodec ff_libopencore_amrwb_decoder = {
00311     "libopencore_amrwb",
00312     AVMEDIA_TYPE_AUDIO,
00313     CODEC_ID_AMR_WB,
00314     sizeof(AMRWBContext),
00315     amr_wb_decode_init,
00316     NULL,
00317     amr_wb_decode_close,
00318     amr_wb_decode_frame,
00319     .long_name = NULL_IF_CONFIG_SMALL("OpenCORE Adaptive Multi-Rate (AMR) Wide-Band"),
00320 };
00321 
00322 #endif /* CONFIG_LIBOPENCORE_AMRWB */

Generated on Fri Feb 22 2013 07:24:27 for FFmpeg by  doxygen 1.7.1