ffmpeg / libavcodec / libopencore-amr.c @ 0e03f94d
History | View | Annotate | Download (8.35 KB)
1 |
/*
|
---|---|
2 |
* AMR Audio decoder 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 "avcodec.h" |
23 |
|
24 |
static void amr_decode_fix_avctx(AVCodecContext *avctx) |
25 |
{ |
26 |
const int is_amr_wb = 1 + (avctx->codec_id == CODEC_ID_AMR_WB); |
27 |
|
28 |
if (!avctx->sample_rate)
|
29 |
avctx->sample_rate = 8000 * is_amr_wb;
|
30 |
|
31 |
if (!avctx->channels)
|
32 |
avctx->channels = 1;
|
33 |
|
34 |
avctx->frame_size = 160 * is_amr_wb;
|
35 |
avctx->sample_fmt = AV_SAMPLE_FMT_S16; |
36 |
} |
37 |
|
38 |
#if CONFIG_LIBOPENCORE_AMRNB
|
39 |
|
40 |
#include <opencore-amrnb/interf_dec.h> |
41 |
#include <opencore-amrnb/interf_enc.h> |
42 |
|
43 |
static const char nb_bitrate_unsupported[] = |
44 |
"bitrate not supported: use one of 4.75k, 5.15k, 5.9k, 6.7k, 7.4k, 7.95k, 10.2k or 12.2k\n";
|
45 |
|
46 |
/* Common code for fixed and float version*/
|
47 |
typedef struct AMR_bitrates { |
48 |
int rate;
|
49 |
enum Mode mode;
|
50 |
} AMR_bitrates; |
51 |
|
52 |
/* Match desired bitrate */
|
53 |
static int getBitrateMode(int bitrate) |
54 |
{ |
55 |
/* make the correspondance between bitrate and mode */
|
56 |
static const AMR_bitrates rates[] = {{ 4750, MR475}, |
57 |
{ 5150, MR515},
|
58 |
{ 5900, MR59},
|
59 |
{ 6700, MR67},
|
60 |
{ 7400, MR74},
|
61 |
{ 7950, MR795},
|
62 |
{10200, MR102},
|
63 |
{12200, MR122}, };
|
64 |
int i;
|
65 |
|
66 |
for (i = 0; i < 8; i++) |
67 |
if (rates[i].rate == bitrate)
|
68 |
return rates[i].mode;
|
69 |
/* no bitrate matching, return an error */
|
70 |
return -1; |
71 |
} |
72 |
|
73 |
typedef struct AMRContext { |
74 |
int frameCount;
|
75 |
void *decState;
|
76 |
void *enstate;
|
77 |
int enc_bitrate;
|
78 |
} AMRContext; |
79 |
|
80 |
static av_cold int amr_nb_decode_init(AVCodecContext *avctx) |
81 |
{ |
82 |
AMRContext *s = avctx->priv_data; |
83 |
|
84 |
s->frameCount = 0;
|
85 |
s->decState = Decoder_Interface_init(); |
86 |
if (!s->decState) {
|
87 |
av_log(avctx, AV_LOG_ERROR, "Decoder_Interface_init error\n");
|
88 |
return -1; |
89 |
} |
90 |
|
91 |
amr_decode_fix_avctx(avctx); |
92 |
|
93 |
if (avctx->channels > 1) { |
94 |
av_log(avctx, AV_LOG_ERROR, "amr_nb: multichannel decoding not supported\n");
|
95 |
return AVERROR(ENOSYS);
|
96 |
} |
97 |
|
98 |
return 0; |
99 |
} |
100 |
|
101 |
static av_cold int amr_nb_decode_close(AVCodecContext *avctx) |
102 |
{ |
103 |
AMRContext *s = avctx->priv_data; |
104 |
|
105 |
Decoder_Interface_exit(s->decState); |
106 |
return 0; |
107 |
} |
108 |
|
109 |
static int amr_nb_decode_frame(AVCodecContext *avctx, void *data, |
110 |
int *data_size, AVPacket *avpkt)
|
111 |
{ |
112 |
const uint8_t *buf = avpkt->data;
|
113 |
int buf_size = avpkt->size;
|
114 |
AMRContext *s = avctx->priv_data; |
115 |
static const uint8_t block_size[16] = { 12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0 }; |
116 |
enum Mode dec_mode;
|
117 |
int packet_size;
|
118 |
|
119 |
/* av_log(NULL, AV_LOG_DEBUG, "amr_decode_frame buf=%p buf_size=%d frameCount=%d!!\n",
|
120 |
buf, buf_size, s->frameCount); */
|
121 |
|
122 |
dec_mode = (buf[0] >> 3) & 0x000F; |
123 |
packet_size = block_size[dec_mode] + 1;
|
124 |
|
125 |
if (packet_size > buf_size) {
|
126 |
av_log(avctx, AV_LOG_ERROR, "amr frame too short (%u, should be %u)\n",
|
127 |
buf_size, packet_size); |
128 |
return AVERROR_INVALIDDATA;
|
129 |
} |
130 |
|
131 |
s->frameCount++; |
132 |
/* av_log(NULL, AV_LOG_DEBUG, "packet_size=%d buf= 0x%X %X %X %X\n",
|
133 |
packet_size, buf[0], buf[1], buf[2], buf[3]); */
|
134 |
/* call decoder */
|
135 |
Decoder_Interface_Decode(s->decState, buf, data, 0);
|
136 |
*data_size = 160 * 2; |
137 |
|
138 |
return packet_size;
|
139 |
} |
140 |
|
141 |
AVCodec ff_libopencore_amrnb_decoder = { |
142 |
"libopencore_amrnb",
|
143 |
AVMEDIA_TYPE_AUDIO, |
144 |
CODEC_ID_AMR_NB, |
145 |
sizeof(AMRContext),
|
146 |
amr_nb_decode_init, |
147 |
NULL,
|
148 |
amr_nb_decode_close, |
149 |
amr_nb_decode_frame, |
150 |
.long_name = NULL_IF_CONFIG_SMALL("OpenCORE Adaptive Multi-Rate (AMR) Narrow-Band"),
|
151 |
}; |
152 |
|
153 |
static av_cold int amr_nb_encode_init(AVCodecContext *avctx) |
154 |
{ |
155 |
AMRContext *s = avctx->priv_data; |
156 |
|
157 |
s->frameCount = 0;
|
158 |
|
159 |
if (avctx->sample_rate != 8000) { |
160 |
av_log(avctx, AV_LOG_ERROR, "Only 8000Hz sample rate supported\n");
|
161 |
return AVERROR(ENOSYS);
|
162 |
} |
163 |
|
164 |
if (avctx->channels != 1) { |
165 |
av_log(avctx, AV_LOG_ERROR, "Only mono supported\n");
|
166 |
return AVERROR(ENOSYS);
|
167 |
} |
168 |
|
169 |
avctx->frame_size = 160;
|
170 |
avctx->coded_frame = avcodec_alloc_frame(); |
171 |
|
172 |
s->enstate=Encoder_Interface_init(0);
|
173 |
if (!s->enstate) {
|
174 |
av_log(avctx, AV_LOG_ERROR, "Encoder_Interface_init error\n");
|
175 |
return -1; |
176 |
} |
177 |
|
178 |
if ((s->enc_bitrate = getBitrateMode(avctx->bit_rate)) < 0) { |
179 |
av_log(avctx, AV_LOG_ERROR, nb_bitrate_unsupported); |
180 |
return AVERROR(ENOSYS);
|
181 |
} |
182 |
|
183 |
return 0; |
184 |
} |
185 |
|
186 |
static av_cold int amr_nb_encode_close(AVCodecContext *avctx) |
187 |
{ |
188 |
AMRContext *s = avctx->priv_data; |
189 |
|
190 |
Encoder_Interface_exit(s->enstate); |
191 |
av_freep(&avctx->coded_frame); |
192 |
return 0; |
193 |
} |
194 |
|
195 |
static int amr_nb_encode_frame(AVCodecContext *avctx, |
196 |
unsigned char *frame/*out*/, |
197 |
int buf_size, void *data/*in*/) |
198 |
{ |
199 |
AMRContext *s = avctx->priv_data; |
200 |
int written;
|
201 |
|
202 |
if ((s->enc_bitrate = getBitrateMode(avctx->bit_rate)) < 0) { |
203 |
av_log(avctx, AV_LOG_ERROR, nb_bitrate_unsupported); |
204 |
return AVERROR(ENOSYS);
|
205 |
} |
206 |
|
207 |
written = Encoder_Interface_Encode(s->enstate, s->enc_bitrate, data, |
208 |
frame, 0);
|
209 |
/* av_log(NULL, AV_LOG_DEBUG, "amr_nb_encode_frame encoded %u bytes, bitrate %u, first byte was %#02x\n",
|
210 |
written, s->enc_bitrate, frame[0] ); */
|
211 |
|
212 |
return written;
|
213 |
} |
214 |
|
215 |
AVCodec ff_libopencore_amrnb_encoder = { |
216 |
"libopencore_amrnb",
|
217 |
AVMEDIA_TYPE_AUDIO, |
218 |
CODEC_ID_AMR_NB, |
219 |
sizeof(AMRContext),
|
220 |
amr_nb_encode_init, |
221 |
amr_nb_encode_frame, |
222 |
amr_nb_encode_close, |
223 |
NULL,
|
224 |
.sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE}, |
225 |
.long_name = NULL_IF_CONFIG_SMALL("OpenCORE Adaptive Multi-Rate (AMR) Narrow-Band"),
|
226 |
}; |
227 |
|
228 |
#endif
|
229 |
|
230 |
/* -----------AMR wideband ------------*/
|
231 |
#if CONFIG_LIBOPENCORE_AMRWB
|
232 |
|
233 |
#include <opencore-amrwb/dec_if.h> |
234 |
#include <opencore-amrwb/if_rom.h> |
235 |
|
236 |
typedef struct AMRWBContext { |
237 |
int frameCount;
|
238 |
void *state;
|
239 |
} AMRWBContext; |
240 |
|
241 |
static av_cold int amr_wb_decode_init(AVCodecContext *avctx) |
242 |
{ |
243 |
AMRWBContext *s = avctx->priv_data; |
244 |
|
245 |
s->frameCount = 0;
|
246 |
s->state = D_IF_init(); |
247 |
|
248 |
amr_decode_fix_avctx(avctx); |
249 |
|
250 |
if (avctx->channels > 1) { |
251 |
av_log(avctx, AV_LOG_ERROR, "amr_wb: multichannel decoding not supported\n");
|
252 |
return AVERROR(ENOSYS);
|
253 |
} |
254 |
|
255 |
return 0; |
256 |
} |
257 |
|
258 |
static int amr_wb_decode_frame(AVCodecContext *avctx, void *data, |
259 |
int *data_size, AVPacket *avpkt)
|
260 |
{ |
261 |
const uint8_t *buf = avpkt->data;
|
262 |
int buf_size = avpkt->size;
|
263 |
AMRWBContext *s = avctx->priv_data; |
264 |
int mode;
|
265 |
int packet_size;
|
266 |
static const uint8_t block_size[16] = {18, 24, 33, 37, 41, 47, 51, 59, 61, 6, 6, 0, 0, 0, 1, 1}; |
267 |
|
268 |
if (!buf_size)
|
269 |
/* nothing to do */
|
270 |
return 0; |
271 |
|
272 |
mode = (buf[0] >> 3) & 0x000F; |
273 |
packet_size = block_size[mode]; |
274 |
|
275 |
if (packet_size > buf_size) {
|
276 |
av_log(avctx, AV_LOG_ERROR, "amr frame too short (%u, should be %u)\n",
|
277 |
buf_size, packet_size + 1);
|
278 |
return AVERROR_INVALIDDATA;
|
279 |
} |
280 |
|
281 |
s->frameCount++; |
282 |
D_IF_decode(s->state, buf, data, _good_frame); |
283 |
*data_size = 320 * 2; |
284 |
return packet_size;
|
285 |
} |
286 |
|
287 |
static int amr_wb_decode_close(AVCodecContext *avctx) |
288 |
{ |
289 |
AMRWBContext *s = avctx->priv_data; |
290 |
|
291 |
D_IF_exit(s->state); |
292 |
return 0; |
293 |
} |
294 |
|
295 |
AVCodec ff_libopencore_amrwb_decoder = { |
296 |
"libopencore_amrwb",
|
297 |
AVMEDIA_TYPE_AUDIO, |
298 |
CODEC_ID_AMR_WB, |
299 |
sizeof(AMRWBContext),
|
300 |
amr_wb_decode_init, |
301 |
NULL,
|
302 |
amr_wb_decode_close, |
303 |
amr_wb_decode_frame, |
304 |
.long_name = NULL_IF_CONFIG_SMALL("OpenCORE Adaptive Multi-Rate (AMR) Wide-Band"),
|
305 |
}; |
306 |
|
307 |
#endif /* CONFIG_LIBOPENCORE_AMRWB */ |