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  avio_flush(pb);
64  return 0;
65 }
66 
67 static int amr_write_packet(AVFormatContext *s, AVPacket *pkt)
68 {
69  avio_write(s->pb, pkt->data, pkt->size);
70  return 0;
71 }
72 #endif /* CONFIG_AMR_MUXER */
73 
74 static int amr_probe(const AVProbeData *p)
75 {
76  // Only check for "#!AMR" which could be amr-wb, amr-nb.
77  // This will also trigger multichannel files: "#!AMR_MC1.0\n" and
78  // "#!AMR-WB_MC1.0\n" (not supported)
79 
80  if (!memcmp(p->buf, AMR_header, 5))
81  return AVPROBE_SCORE_MAX;
82  else
83  return 0;
84 }
85 
86 /* amr input */
88 {
89  AVIOContext *pb = s->pb;
90  AVStream *st;
91  uint8_t header[9];
92 
93  avio_read(pb, header, 6);
94 
95  st = avformat_new_stream(s, NULL);
96  if (!st)
97  return AVERROR(ENOMEM);
98  if (memcmp(header, AMR_header, 6)) {
99  avio_read(pb, header + 6, 3);
100  if (memcmp(header, AMRWB_header, 9)) {
101  return -1;
102  }
103 
104  st->codecpar->codec_tag = MKTAG('s', 'a', 'w', 'b');
106  st->codecpar->sample_rate = 16000;
107  } else {
108  st->codecpar->codec_tag = MKTAG('s', 'a', 'm', 'r');
110  st->codecpar->sample_rate = 8000;
111  }
112  st->codecpar->channels = 1;
115  avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);
116 
117  return 0;
118 }
119 
121 {
122  AVCodecParameters *par = s->streams[0]->codecpar;
123  int read, size = 0, toc, mode;
124  int64_t pos = avio_tell(s->pb);
125  AMRContext *amr = s->priv_data;
126 
127  if (avio_feof(s->pb)) {
128  return AVERROR_EOF;
129  }
130 
131  // FIXME this is wrong, this should rather be in an AVParser
132  toc = avio_r8(s->pb);
133  mode = (toc >> 3) & 0x0F;
134 
135  if (par->codec_id == AV_CODEC_ID_AMR_NB) {
136  size = amrnb_packed_size[mode];
137  } else if (par->codec_id == AV_CODEC_ID_AMR_WB) {
138  size = amrwb_packed_size[mode];
139  }
140 
141  if (!size || av_new_packet(pkt, size))
142  return AVERROR(EIO);
143 
144  if (amr->cumulated_size < UINT64_MAX - size) {
145  amr->cumulated_size += size;
146  /* Both AMR formats have 50 frames per second */
147  s->streams[0]->codecpar->bit_rate = amr->cumulated_size / ++amr->block_count * 8 * 50;
148  }
149 
150  pkt->stream_index = 0;
151  pkt->pos = pos;
152  pkt->data[0] = toc;
153  pkt->duration = par->codec_id == AV_CODEC_ID_AMR_NB ? 160 : 320;
154  read = avio_read(s->pb, pkt->data + 1, size - 1);
155 
156  if (read != size - 1) {
157  av_packet_unref(pkt);
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
int64_t pos
byte position in stream, -1 if unknown
Definition: avcodec.h:1497
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:4892
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: avcodec.h:3957
uint64_t cumulated_size
Definition: amr.c:34
static int amr_read_header(AVFormatContext *s)
Definition: amr.c:87
int size
Definition: avcodec.h:1478
static AVPacket pkt
static const char AMR_header[]
Definition: amr.c:38
This struct describes the properties of an encoded stream.
Definition: avcodec.h:3949
Format I/O context.
Definition: avformat.h:1358
uint8_t
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: avcodec.h:1495
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
Definition: utils.c:4465
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1426
uint8_t * data
Definition: avcodec.h:1477
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:218
uint64_t channel_layout
Audio only.
Definition: avcodec.h:4059
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:650
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
Definition: avcodec.h:3986
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
enum AVMediaType codec_type
General type of the encoded data.
Definition: avcodec.h:3953
AVOutputFormat ff_amr_muxer
int avio_r8(AVIOContext *s)
Definition: aviobuf.c:641
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
Definition: avformat.h:448
#define b
Definition: input.c:41
audio channel layout utility functions
const char * name
Definition: avformat.h:505
#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:530
Stream structure.
Definition: avformat.h:881
#define AVFMT_NOTIMESTAMPS
Format does not need / have any timestamps.
Definition: avformat.h:467
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:1400
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:599
#define AVFMT_GENERIC_INDEX
Use generic index building code.
Definition: avformat.h:468
AVInputFormat ff_amr_demuxer
void avio_flush(AVIOContext *s)
Force flushing of buffered data.
Definition: aviobuf.c:238
#define AVPROBE_SCORE_EXTENSION
score for file extension
Definition: avformat.h:456
This structure contains the data a format has to probe a file.
Definition: avformat.h:446
#define flags(name, subs,...)
Definition: cbs_av1.c:561
static int amr_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: amr.c:120
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:4067
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:458
Main libavformat public API header.
static int amr_probe(const AVProbeData *p)
Definition: amr.c:74
void * priv_data
Format private data.
Definition: avformat.h:1386
int channels
Audio only.
Definition: avcodec.h:4063
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:654
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:1028
int avio_feof(AVIOContext *s)
Similar to feof() but also returns nonzero on read errors.
Definition: aviobuf.c:361
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: avcodec.h:3961
int stream_index
Definition: avcodec.h:1479
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:1454
mode
Use these values in ebur128_init (or&#39;ed).
Definition: ebur128.h:83