3 * Copyright (c) 2001 ffmpeg project
5 * This file is part of FFmpeg.
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.
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.
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
23 Write and read amr data according to RFC3267, http://www.ietf.org/rfc/rfc3267.txt?number=3267
25 Only mono files are supported.
30 static const char AMR_header
[] = "#!AMR\n";
31 static const char AMRWB_header
[] = "#!AMR-WB\n";
34 static int amr_write_header(AVFormatContext
*s
)
36 ByteIOContext
*pb
= s
->pb
;
37 AVCodecContext
*enc
= s
->streams
[0]->codec
;
41 if (enc
->codec_id
== CODEC_ID_AMR_NB
)
43 put_tag(pb
, AMR_header
); /* magic number */
45 else if(enc
->codec_id
== CODEC_ID_AMR_WB
)
47 put_tag(pb
, AMRWB_header
); /* magic number */
57 static int amr_write_packet(AVFormatContext
*s
, AVPacket
*pkt
)
59 put_buffer(s
->pb
, pkt
->data
, pkt
->size
);
60 put_flush_packet(s
->pb
);
63 #endif /* CONFIG_AMR_MUXER */
65 static int amr_probe(AVProbeData
*p
)
67 //Only check for "#!AMR" which could be amr-wb, amr-nb.
68 //This will also trigger multichannel files: "#!AMR_MC1.0\n" and
69 //"#!AMR-WB_MC1.0\n" (not supported)
71 if(memcmp(p
->buf
,AMR_header
,5)==0)
72 return AVPROBE_SCORE_MAX
;
78 static int amr_read_header(AVFormatContext
*s
,
79 AVFormatParameters
*ap
)
81 ByteIOContext
*pb
= s
->pb
;
85 get_buffer(pb
, header
, 6);
87 st
= av_new_stream(s
, 0);
90 return AVERROR(ENOMEM
);
92 if(memcmp(header
,AMR_header
,6)!=0)
94 get_buffer(pb
, header
+6, 3);
95 if(memcmp(header
,AMRWB_header
,9)!=0)
100 st
->codec
->codec_tag
= MKTAG('s', 'a', 'w', 'b');
101 st
->codec
->codec_id
= CODEC_ID_AMR_WB
;
102 st
->codec
->sample_rate
= 16000;
106 st
->codec
->codec_tag
= MKTAG('s', 'a', 'm', 'r');
107 st
->codec
->codec_id
= CODEC_ID_AMR_NB
;
108 st
->codec
->sample_rate
= 8000;
110 st
->codec
->channels
= 1;
111 st
->codec
->codec_type
= CODEC_TYPE_AUDIO
;
112 av_set_pts_info(st
, 64, 1, st
->codec
->sample_rate
);
117 static int amr_read_packet(AVFormatContext
*s
,
120 AVCodecContext
*enc
= s
->streams
[0]->codec
;
121 int read
, size
= 0, toc
, mode
;
128 //FIXME this is wrong, this should rather be in a AVParset
130 mode
= (toc
>> 3) & 0x0F;
132 if (enc
->codec_id
== CODEC_ID_AMR_NB
)
134 static const uint8_t packed_size
[16] = {12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0};
136 size
=packed_size
[mode
]+1;
138 else if(enc
->codec_id
== CODEC_ID_AMR_WB
)
140 static uint8_t packed_size
[16] = {18, 24, 33, 37, 41, 47, 51, 59, 61, 6, 6, 0, 0, 0, 1, 1};
142 size
=packed_size
[mode
];
149 if ( (size
==0) || av_new_packet(pkt
, size
))
154 pkt
->stream_index
= 0;
155 pkt
->pos
= url_ftell(s
->pb
);
157 pkt
->duration
= enc
->codec_id
== CODEC_ID_AMR_NB
? 160 : 320;
158 read
= get_buffer(s
->pb
, pkt
->data
+1, size
-1);
169 #if CONFIG_AMR_DEMUXER
170 AVInputFormat amr_demuxer
= {
172 NULL_IF_CONFIG_SMALL("3GPP AMR file format"),
173 0, /*priv_data_size*/
182 AVOutputFormat amr_muxer
= {
184 NULL_IF_CONFIG_SMALL("3GPP AMR file format"),