libvo-amrwbenc: Don't explicitly store bitrate modes in the bitrate table
[ffmpeg.git] / libavcodec / libvo-amrwbenc.c
1 /*
2  * AMR Audio encoder stub
3  * Copyright (c) 2003 the ffmpeg project
4  *
5  * This file is part of Libav.
6  *
7  * Libav is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * Libav is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with Libav; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21
22 #include <vo-amrwbenc/enc_if.h>
23
24 #include "avcodec.h"
25
26 static const char wb_bitrate_unsupported[] =
27     "bitrate not supported: use one of 6.6k, 8.85k, 12.65k, 14.25k, 15.85k, "
28     "18.25k, 19.85k, 23.05k, or 23.85k\n";
29
30 typedef struct AMRWBContext {
31     void  *state;
32     int    mode;
33     int    allow_dtx;
34 } AMRWBContext;
35
36 static int getWBBitrateMode(int bitrate)
37 {
38     /* make the correspondance between bitrate and mode */
39     static const int rates[] = {  6600,  8850, 12650, 14250, 15850, 18250,
40                                  19850, 23050, 23850 };
41     int i;
42
43     for (i = 0; i < 9; i++)
44         if (rates[i] == bitrate)
45             return i;
46     /* no bitrate matching, return an error */
47     return -1;
48 }
49
50 static av_cold int amr_wb_encode_init(AVCodecContext *avctx)
51 {
52     AMRWBContext *s = avctx->priv_data;
53
54     if (avctx->sample_rate != 16000) {
55         av_log(avctx, AV_LOG_ERROR, "Only 16000Hz sample rate supported\n");
56         return AVERROR(ENOSYS);
57     }
58
59     if (avctx->channels != 1) {
60         av_log(avctx, AV_LOG_ERROR, "Only mono supported\n");
61         return AVERROR(ENOSYS);
62     }
63
64     if ((s->mode = getWBBitrateMode(avctx->bit_rate)) < 0) {
65         av_log(avctx, AV_LOG_ERROR, wb_bitrate_unsupported);
66         return AVERROR(ENOSYS);
67     }
68
69     avctx->frame_size  = 320;
70     avctx->coded_frame = avcodec_alloc_frame();
71
72     s->state     = E_IF_init();
73     s->allow_dtx = 0;
74
75     return 0;
76 }
77
78 static int amr_wb_encode_close(AVCodecContext *avctx)
79 {
80     AMRWBContext *s = avctx->priv_data;
81
82     E_IF_exit(s->state);
83     av_freep(&avctx->coded_frame);
84     return 0;
85 }
86
87 static int amr_wb_encode_frame(AVCodecContext *avctx,
88                                unsigned char *frame/*out*/,
89                                int buf_size, void *data/*in*/)
90 {
91     AMRWBContext *s = avctx->priv_data;
92     int size;
93
94     if ((s->mode = getWBBitrateMode(avctx->bit_rate)) < 0) {
95         av_log(avctx, AV_LOG_ERROR, wb_bitrate_unsupported);
96         return AVERROR(ENOSYS);
97     }
98     size = E_IF_encode(s->state, s->mode, data, frame, s->allow_dtx);
99     return size;
100 }
101
102 AVCodec ff_libvo_amrwbenc_encoder = {
103     "libvo_amrwbenc",
104     CODEC_TYPE_AUDIO,
105     CODEC_ID_AMR_WB,
106     sizeof(AMRWBContext),
107     amr_wb_encode_init,
108     amr_wb_encode_frame,
109     amr_wb_encode_close,
110     NULL,
111     .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE},
112     .long_name = NULL_IF_CONFIG_SMALL("libvo-amrwbenc Adaptive Multi-Rate "
113                                       "(AMR) Wide-Band"),
114 };
115