FFmpeg
amr.c
Go to the documentation of this file.
1 /*
2  * amr file format
3  * Copyright (c) 2001 FFmpeg project
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg 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  * FFmpeg 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 FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 /*
23 Write and read amr data according to RFC3267, http://www.ietf.org/rfc/rfc3267.txt?number=3267
24 
25 Only mono files are supported.
26 
27 */
28 
30 #include "avformat.h"
31 #include "internal.h"
32 
33 typedef struct {
34  uint64_t cumulated_size;
35  uint64_t block_count;
36 } AMRContext;
37 
38 static const char AMR_header[] = "#!AMR\n";
39 static const char AMRWB_header[] = "#!AMR-WB\n";
40 
41 static const uint8_t amrnb_packed_size[16] = {
42  13, 14, 16, 18, 20, 21, 27, 32, 6, 1, 1, 1, 1, 1, 1, 1
43 };
44 static const uint8_t amrwb_packed_size[16] = {
45  18, 24, 33, 37, 41, 47, 51, 59, 61, 6, 1, 1, 1, 1, 1, 1
46 };
47 
48 #if CONFIG_AMR_MUXER
49 static int amr_write_header(AVFormatContext *s)
50 {
51  AVIOContext *pb = s->pb;
52  AVCodecParameters *par = s->streams[0]->codecpar;
53 
54  s->priv_data = NULL;
55 
56  if (par->codec_id == AV_CODEC_ID_AMR_NB) {
57  avio_write(pb, AMR_header, sizeof(AMR_header) - 1); /* magic number */
58  } else if (par->codec_id == AV_CODEC_ID_AMR_WB) {
59  avio_write(pb, AMRWB_header, sizeof(AMRWB_header) - 1); /* magic number */
60  } else {
61  return -1;
62  }
63  return 0;
64 }
65 
66 static int amr_write_packet(AVFormatContext *s, AVPacket *pkt)
67 {
68  avio_write(s->pb, pkt->data, pkt->size);
69  return 0;
70 }
71 #endif /* CONFIG_AMR_MUXER */
72 
73 static int amr_probe(const AVProbeData *p)
74 {
75  // Only check for "#!AMR" which could be amr-wb, amr-nb.
76  // This will also trigger multichannel files: "#!AMR_MC1.0\n" and
77  // "#!AMR-WB_MC1.0\n" (not supported)
78 
79  if (!memcmp(p->buf, AMR_header, 5))
80  return AVPROBE_SCORE_MAX;
81  else
82  return 0;
83 }
84 
85 /* amr input */
87 {
88  AVIOContext *pb = s->pb;
89  AVStream *st;
90  uint8_t header[9];
91 
92  if (avio_read(pb, header, 6) != 6)
93  return AVERROR_INVALIDDATA;
94 
95  st = avformat_new_stream(s, NULL);
96  if (!st)
97  return AVERROR(ENOMEM);
98  if (memcmp(header, AMR_header, 6)) {
99  if (avio_read(pb, header + 6, 3) != 3)
100  return AVERROR_INVALIDDATA;
101  if (memcmp(header, AMRWB_header, 9)) {
102  return -1;
103  }
104 
105  st->codecpar->codec_tag = MKTAG('s', 'a', 'w', 'b');
107  st->codecpar->sample_rate = 16000;
108  } else {
109  st->codecpar->codec_tag = MKTAG('s', 'a', 'm', 'r');
111  st->codecpar->sample_rate = 8000;
112  }
113  st->codecpar->channels = 1;
116  avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);
117 
118  return 0;
119 }
120 
122 {
123  AVCodecParameters *par = s->streams[0]->codecpar;
124  int read, size = 0, toc, mode;
125  int64_t pos = avio_tell(s->pb);
126  AMRContext *amr = s->priv_data;
127 
128  if (avio_feof(s->pb)) {
129  return AVERROR_EOF;
130  }
131 
132  // FIXME this is wrong, this should rather be in an AVParser
133  toc = avio_r8(s->pb);
134  mode = (toc >> 3) & 0x0F;
135 
136  if (par->codec_id == AV_CODEC_ID_AMR_NB) {
137  size = amrnb_packed_size[mode];
138  } else if (par->codec_id == AV_CODEC_ID_AMR_WB) {
139  size = amrwb_packed_size[mode];
140  }
141 
142  if (!size || av_new_packet(pkt, size))
143  return AVERROR(EIO);
144 
145  if (amr->cumulated_size < UINT64_MAX - size) {
146  amr->cumulated_size += size;
147  /* Both AMR formats have 50 frames per second */
148  s->streams[0]->codecpar->bit_rate = amr->cumulated_size / ++amr->block_count * 8 * 50;
149  }
150 
151  pkt->stream_index = 0;
152  pkt->pos = pos;
153  pkt->data[0] = toc;
154  pkt->duration = par->codec_id == AV_CODEC_ID_AMR_NB ? 160 : 320;
155  read = avio_read(s->pb, pkt->data + 1, size - 1);
156 
157  if (read != size - 1) {
158  if (read < 0)
159  return read;
160  return AVERROR(EIO);
161  }
162 
163  return 0;
164 }
165 
166 #if CONFIG_AMR_DEMUXER
168  .name = "amr",
169  .long_name = NULL_IF_CONFIG_SMALL("3GPP AMR"),
170  .priv_data_size = sizeof(AMRContext),
175 };
176 #endif
177 
178 #if CONFIG_AMRNB_DEMUXER
179 static int amrnb_probe(const AVProbeData *p)
180 {
181  int mode, i = 0, valid = 0, invalid = 0;
182  const uint8_t *b = p->buf;
183 
184  while (i < p->buf_size) {
185  mode = b[i] >> 3 & 0x0F;
186  if (mode < 9 && (b[i] & 0x4) == 0x4) {
187  int last = b[i];
188  int size = amrnb_packed_size[mode];
189  while (size--) {
190  if (b[++i] != last)
191  break;
192  }
193  if (size > 0) {
194  valid++;
195  i += size;
196  }
197  } else {
198  valid = 0;
199  invalid++;
200  i++;
201  }
202  }
203  if (valid > 100 && valid >> 4 > invalid)
204  return AVPROBE_SCORE_EXTENSION / 2 + 1;
205  return 0;
206 }
207 
208 static int amrnb_read_header(AVFormatContext *s)
209 {
211  if (!st)
212  return AVERROR(ENOMEM);
214  st->codecpar->sample_rate = 8000;
215  st->codecpar->channels = 1;
218  avpriv_set_pts_info(st, 64, 1, 8000);
219 
220  return 0;
221 }
222 
224  .name = "amrnb",
225  .long_name = NULL_IF_CONFIG_SMALL("raw AMR-NB"),
226  .priv_data_size = sizeof(AMRContext),
227  .read_probe = amrnb_probe,
228  .read_header = amrnb_read_header,
231 };
232 #endif
233 
234 #if CONFIG_AMRWB_DEMUXER
235 static int amrwb_probe(const AVProbeData *p)
236 {
237  int mode, i = 0, valid = 0, invalid = 0;
238  const uint8_t *b = p->buf;
239 
240  while (i < p->buf_size) {
241  mode = b[i] >> 3 & 0x0F;
242  if (mode < 10 && (b[i] & 0x4) == 0x4) {
243  int last = b[i];
244  int size = amrwb_packed_size[mode];
245  while (size--) {
246  if (b[++i] != last)
247  break;
248  }
249  if (size > 0) {
250  valid++;
251  i += size;
252  }
253  } else {
254  valid = 0;
255  invalid++;
256  i++;
257  }
258  }
259  if (valid > 100 && valid >> 4 > invalid)
260  return AVPROBE_SCORE_EXTENSION / 2 + 1;
261  return 0;
262 }
263 
264 static int amrwb_read_header(AVFormatContext *s)
265 {
267  if (!st)
268  return AVERROR(ENOMEM);
270  st->codecpar->sample_rate = 16000;
271  st->codecpar->channels = 1;
274  avpriv_set_pts_info(st, 64, 1, 16000);
275 
276  return 0;
277 }
278 
280  .name = "amrwb",
281  .long_name = NULL_IF_CONFIG_SMALL("raw AMR-WB"),
282  .priv_data_size = sizeof(AMRContext),
283  .read_probe = amrwb_probe,
284  .read_header = amrwb_read_header,
287 };
288 #endif
289 
290 #if CONFIG_AMR_MUXER
292  .name = "amr",
293  .long_name = NULL_IF_CONFIG_SMALL("3GPP AMR"),
294  .mime_type = "audio/amr",
295  .extensions = "amr",
296  .audio_codec = AV_CODEC_ID_AMR_NB,
297  .video_codec = AV_CODEC_ID_NONE,
298  .write_header = amr_write_header,
299  .write_packet = amr_write_packet,
300  .flags = AVFMT_NOTIMESTAMPS,
301 };
302 #endif
#define NULL
Definition: coverity.c:32
Bytestream IO Context.
Definition: avio.h:161
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
int64_t pos
byte position in stream, -1 if unknown
Definition: avcodec.h:1553
void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition: utils.c:4943
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: avcodec.h:4036
uint64_t cumulated_size
Definition: amr.c:34
static int amr_read_header(AVFormatContext *s)
Definition: amr.c:86
int size
Definition: avcodec.h:1534
static AVPacket pkt
static const char AMR_header[]
Definition: amr.c:38
This struct describes the properties of an encoded stream.
Definition: avcodec.h:4028
Format I/O context.
Definition: avformat.h:1353
uint8_t
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: avcodec.h:1551
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
Definition: utils.c:4524
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1421
uint8_t * data
Definition: avcodec.h:1533
static const char AMRWB_header[]
Definition: amr.c:39
#define AVERROR_EOF
End of file.
Definition: error.h:55
static const uint8_t amrnb_packed_size[16]
Definition: amr.c:41
ptrdiff_t size
Definition: opengl_enc.c:100
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:557
AVInputFormat ff_amrwb_demuxer
static const uint8_t header[24]
Definition: sdr2.c:67
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition: aviobuf.c:213
uint64_t channel_layout
Audio only.
Definition: avcodec.h:4138
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:645
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
Definition: avcodec.h:4065
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
Definition: avpacket.c:86
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
unsigned int pos
Definition: spdifenc.c:410
enum AVMediaType codec_type
General type of the encoded data.
Definition: avcodec.h:4032
AVOutputFormat ff_amr_muxer
int avio_r8(AVIOContext *s)
Definition: aviobuf.c:636
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
Definition: avformat.h:443
#define b
Definition: input.c:41
audio channel layout utility functions
const char * name
Definition: avformat.h:500
#define s(width, name)
Definition: cbs_vp9.c:257
static const uint8_t amrwb_packed_size[16]
Definition: amr.c:44
static int read_header(FFV1Context *f)
Definition: ffv1dec.c:527
Stream structure.
Definition: avformat.h:876
#define AVFMT_NOTIMESTAMPS
Format does not need / have any timestamps.
Definition: avformat.h:462
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
Definition: avio_reading.c:42
AVIOContext * pb
I/O context.
Definition: avformat.h:1395
#define AVFMT_GENERIC_INDEX
Use generic index building code.
Definition: avformat.h:463
AVInputFormat ff_amr_demuxer
#define AVPROBE_SCORE_EXTENSION
score for file extension
Definition: avformat.h:451
This structure contains the data a format has to probe a file.
Definition: avformat.h:441
#define flags(name, subs,...)
Definition: cbs_av1.c:564
static int amr_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: amr.c:121
static int read_probe(const AVProbeData *pd)
Definition: jvdec.c:55
AVInputFormat ff_amrnb_demuxer
uint64_t block_count
Definition: amr.c:35
int sample_rate
Audio only.
Definition: avcodec.h:4146
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:453
Main libavformat public API header.
static int amr_probe(const AVProbeData *p)
Definition: amr.c:73
void * priv_data
Format private data.
Definition: avformat.h:1381
int channels
Audio only.
Definition: avcodec.h:4142
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:650
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:1023
int avio_feof(AVIOContext *s)
Similar to feof() but also returns nonzero on read errors.
Definition: aviobuf.c:356
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: avcodec.h:4040
int stream_index
Definition: avcodec.h:1535
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Frame references ownership and permissions
#define AV_CH_LAYOUT_MONO
#define MKTAG(a, b, c, d)
Definition: common.h:366
This structure stores compressed data.
Definition: avcodec.h:1510
mode
Use these values in ebur128_init (or&#39;ed).
Definition: ebur128.h:83