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  avio_read(pb, header, 6);
93 
94  st = avformat_new_stream(s, NULL);
95  if (!st)
96  return AVERROR(ENOMEM);
97  if (memcmp(header, AMR_header, 6)) {
98  avio_read(pb, header + 6, 3);
99  if (memcmp(header, AMRWB_header, 9)) {
100  return -1;
101  }
102 
103  st->codecpar->codec_tag = MKTAG('s', 'a', 'w', 'b');
105  st->codecpar->sample_rate = 16000;
106  } else {
107  st->codecpar->codec_tag = MKTAG('s', 'a', 'm', 'r');
109  st->codecpar->sample_rate = 8000;
110  }
111  st->codecpar->channels = 1;
114  avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);
115 
116  return 0;
117 }
118 
120 {
121  AVCodecParameters *par = s->streams[0]->codecpar;
122  int read, size = 0, toc, mode;
123  int64_t pos = avio_tell(s->pb);
124  AMRContext *amr = s->priv_data;
125 
126  if (avio_feof(s->pb)) {
127  return AVERROR_EOF;
128  }
129 
130  // FIXME this is wrong, this should rather be in an AVParser
131  toc = avio_r8(s->pb);
132  mode = (toc >> 3) & 0x0F;
133 
134  if (par->codec_id == AV_CODEC_ID_AMR_NB) {
135  size = amrnb_packed_size[mode];
136  } else if (par->codec_id == AV_CODEC_ID_AMR_WB) {
137  size = amrwb_packed_size[mode];
138  }
139 
140  if (!size || av_new_packet(pkt, size))
141  return AVERROR(EIO);
142 
143  if (amr->cumulated_size < UINT64_MAX - size) {
144  amr->cumulated_size += size;
145  /* Both AMR formats have 50 frames per second */
146  s->streams[0]->codecpar->bit_rate = amr->cumulated_size / ++amr->block_count * 8 * 50;
147  }
148 
149  pkt->stream_index = 0;
150  pkt->pos = pos;
151  pkt->data[0] = toc;
152  pkt->duration = par->codec_id == AV_CODEC_ID_AMR_NB ? 160 : 320;
153  read = avio_read(s->pb, pkt->data + 1, size - 1);
154 
155  if (read != size - 1) {
156  av_packet_unref(pkt);
157  if (read < 0)
158  return read;
159  return AVERROR(EIO);
160  }
161 
162  return 0;
163 }
164 
165 #if CONFIG_AMR_DEMUXER
167  .name = "amr",
168  .long_name = NULL_IF_CONFIG_SMALL("3GPP AMR"),
169  .priv_data_size = sizeof(AMRContext),
174 };
175 #endif
176 
177 #if CONFIG_AMRNB_DEMUXER
178 static int amrnb_probe(const AVProbeData *p)
179 {
180  int mode, i = 0, valid = 0, invalid = 0;
181  const uint8_t *b = p->buf;
182 
183  while (i < p->buf_size) {
184  mode = b[i] >> 3 & 0x0F;
185  if (mode < 9 && (b[i] & 0x4) == 0x4) {
186  int last = b[i];
187  int size = amrnb_packed_size[mode];
188  while (size--) {
189  if (b[++i] != last)
190  break;
191  }
192  if (size > 0) {
193  valid++;
194  i += size;
195  }
196  } else {
197  valid = 0;
198  invalid++;
199  i++;
200  }
201  }
202  if (valid > 100 && valid >> 4 > invalid)
203  return AVPROBE_SCORE_EXTENSION / 2 + 1;
204  return 0;
205 }
206 
207 static int amrnb_read_header(AVFormatContext *s)
208 {
210  if (!st)
211  return AVERROR(ENOMEM);
213  st->codecpar->sample_rate = 8000;
214  st->codecpar->channels = 1;
217  avpriv_set_pts_info(st, 64, 1, 8000);
218 
219  return 0;
220 }
221 
223  .name = "amrnb",
224  .long_name = NULL_IF_CONFIG_SMALL("raw AMR-NB"),
225  .priv_data_size = sizeof(AMRContext),
226  .read_probe = amrnb_probe,
227  .read_header = amrnb_read_header,
230 };
231 #endif
232 
233 #if CONFIG_AMRWB_DEMUXER
234 static int amrwb_probe(const AVProbeData *p)
235 {
236  int mode, i = 0, valid = 0, invalid = 0;
237  const uint8_t *b = p->buf;
238 
239  while (i < p->buf_size) {
240  mode = b[i] >> 3 & 0x0F;
241  if (mode < 10 && (b[i] & 0x4) == 0x4) {
242  int last = b[i];
243  int size = amrwb_packed_size[mode];
244  while (size--) {
245  if (b[++i] != last)
246  break;
247  }
248  if (size > 0) {
249  valid++;
250  i += size;
251  }
252  } else {
253  valid = 0;
254  invalid++;
255  i++;
256  }
257  }
258  if (valid > 100 && valid >> 4 > invalid)
259  return AVPROBE_SCORE_EXTENSION / 2 + 1;
260  return 0;
261 }
262 
263 static int amrwb_read_header(AVFormatContext *s)
264 {
266  if (!st)
267  return AVERROR(ENOMEM);
269  st->codecpar->sample_rate = 16000;
270  st->codecpar->channels = 1;
273  avpriv_set_pts_info(st, 64, 1, 16000);
274 
275  return 0;
276 }
277 
279  .name = "amrwb",
280  .long_name = NULL_IF_CONFIG_SMALL("raw AMR-WB"),
281  .priv_data_size = sizeof(AMRContext),
282  .read_probe = amrwb_probe,
283  .read_header = amrwb_read_header,
286 };
287 #endif
288 
289 #if CONFIG_AMR_MUXER
291  .name = "amr",
292  .long_name = NULL_IF_CONFIG_SMALL("3GPP AMR"),
293  .mime_type = "audio/amr",
294  .extensions = "amr",
295  .audio_codec = AV_CODEC_ID_AMR_NB,
296  .video_codec = AV_CODEC_ID_NONE,
297  .write_header = amr_write_header,
298  .write_packet = amr_write_packet,
299  .flags = AVFMT_NOTIMESTAMPS,
300 };
301 #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:1514
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:4931
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: avcodec.h:3987
uint64_t cumulated_size
Definition: amr.c:34
static int amr_read_header(AVFormatContext *s)
Definition: amr.c:86
int size
Definition: avcodec.h:1495
static AVPacket pkt
static const char AMR_header[]
Definition: amr.c:38
This struct describes the properties of an encoded stream.
Definition: avcodec.h:3979
Format I/O context.
Definition: avformat.h:1357
uint8_t
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: avcodec.h:1512
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
Definition: utils.c:4504
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1425
uint8_t * data
Definition: avcodec.h:1494
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:4089
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:4016
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:3983
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:880
#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:1399
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
#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:564
static int amr_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: amr.c:119
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:4097
#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:73
void * priv_data
Format private data.
Definition: avformat.h:1385
int channels
Audio only.
Definition: avcodec.h:4093
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:1027
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:3991
int stream_index
Definition: avcodec.h:1496
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:1471
mode
Use these values in ebur128_init (or&#39;ed).
Definition: ebur128.h:83