FFmpeg
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
Examples
File List
Globals
•
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
libavformat
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
29
#include "
libavutil/avassert.h
"
30
#include "
libavutil/channel_layout.h
"
31
#include "
avformat.h
"
32
#include "
internal.h
"
33
34
static
const
char
AMR_header
[] =
"#!AMR\n"
;
35
static
const
char
AMRWB_header
[] =
"#!AMR-WB\n"
;
36
37
#if CONFIG_AMR_MUXER
38
static
int
amr_write_header(
AVFormatContext
*
s
)
39
{
40
AVIOContext
*pb = s->
pb
;
41
AVCodecContext
*enc = s->
streams
[0]->
codec
;
42
43
s->
priv_data
= NULL;
44
45
if
(enc->
codec_id
==
AV_CODEC_ID_AMR_NB
) {
46
avio_write
(pb,
AMR_header
,
sizeof
(
AMR_header
) - 1);
/* magic number */
47
}
else
if
(enc->
codec_id
==
AV_CODEC_ID_AMR_WB
) {
48
avio_write
(pb,
AMRWB_header
,
sizeof
(
AMRWB_header
) - 1);
/* magic number */
49
}
else
{
50
return
-1;
51
}
52
avio_flush
(pb);
53
return
0;
54
}
55
56
static
int
amr_write_packet(
AVFormatContext
*
s
,
AVPacket
*
pkt
)
57
{
58
avio_write
(s->
pb
, pkt->
data
, pkt->
size
);
59
return
0;
60
}
61
#endif
/* CONFIG_AMR_MUXER */
62
63
static
int
amr_probe
(
AVProbeData
*p)
64
{
65
// Only check for "#!AMR" which could be amr-wb, amr-nb.
66
// This will also trigger multichannel files: "#!AMR_MC1.0\n" and
67
// "#!AMR-WB_MC1.0\n" (not supported)
68
69
if
(!memcmp(p->
buf
,
AMR_header
, 5))
70
return
AVPROBE_SCORE_MAX
;
71
else
72
return
0;
73
}
74
75
/* amr input */
76
static
int
amr_read_header
(
AVFormatContext
*
s
)
77
{
78
AVIOContext
*pb = s->
pb
;
79
AVStream
*st;
80
uint8_t
header
[9];
81
82
avio_read
(pb, header, 6);
83
84
st =
avformat_new_stream
(s, NULL);
85
if
(!st)
86
return
AVERROR
(ENOMEM);
87
if
(memcmp(header,
AMR_header
, 6)) {
88
avio_read
(pb, header + 6, 3);
89
if
(memcmp(header,
AMRWB_header
, 9)) {
90
return
-1;
91
}
92
93
st->
codec
->
codec_tag
=
MKTAG
(
's'
,
'a'
,
'w'
,
'b'
);
94
st->
codec
->
codec_id
=
AV_CODEC_ID_AMR_WB
;
95
st->
codec
->
sample_rate
= 16000;
96
}
else
{
97
st->
codec
->
codec_tag
=
MKTAG
(
's'
,
'a'
,
'm'
,
'r'
);
98
st->
codec
->
codec_id
=
AV_CODEC_ID_AMR_NB
;
99
st->
codec
->
sample_rate
= 8000;
100
}
101
st->
codec
->
channels
= 1;
102
st->
codec
->
channel_layout
=
AV_CH_LAYOUT_MONO
;
103
st->
codec
->
codec_type
=
AVMEDIA_TYPE_AUDIO
;
104
avpriv_set_pts_info
(st, 64, 1, st->
codec
->
sample_rate
);
105
106
return
0;
107
}
108
109
static
int
amr_read_packet
(
AVFormatContext
*
s
,
AVPacket
*
pkt
)
110
{
111
AVCodecContext
*enc = s->
streams
[0]->
codec
;
112
int
read,
size
= 0, toc,
mode
;
113
int64_t pos =
avio_tell
(s->
pb
);
114
115
if
(
url_feof
(s->
pb
)) {
116
return
AVERROR
(EIO);
117
}
118
119
// FIXME this is wrong, this should rather be in a AVParset
120
toc =
avio_r8
(s->
pb
);
121
mode = (toc >> 3) & 0x0F;
122
123
if
(enc->
codec_id
==
AV_CODEC_ID_AMR_NB
) {
124
static
const
uint8_t
packed_size[16] = {
125
12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0
126
};
127
128
size = packed_size[
mode
] + 1;
129
}
else
if
(enc->
codec_id
==
AV_CODEC_ID_AMR_WB
) {
130
static
const
uint8_t
packed_size[16] = {
131
18, 24, 33, 37, 41, 47, 51, 59, 61, 6, 6, 0, 0, 0, 1, 1
132
};
133
134
size = packed_size[
mode
];
135
}
136
137
if
(!size ||
av_new_packet
(pkt, size))
138
return
AVERROR
(EIO);
139
140
/* Both AMR formats have 50 frames per second */
141
s->
streams
[0]->
codec
->
bit_rate
= size*8*50;
142
143
pkt->
stream_index
= 0;
144
pkt->
pos
= pos;
145
pkt->
data
[0] = toc;
146
pkt->
duration
= enc->
codec_id
==
AV_CODEC_ID_AMR_NB
? 160 : 320;
147
read =
avio_read
(s->
pb
, pkt->
data
+ 1, size - 1);
148
149
if
(read != size - 1) {
150
av_free_packet
(pkt);
151
return
AVERROR
(EIO);
152
}
153
154
return
0;
155
}
156
157
#if CONFIG_AMR_DEMUXER
158
AVInputFormat
ff_amr_demuxer = {
159
.
name
=
"amr"
,
160
.long_name =
NULL_IF_CONFIG_SMALL
(
"3GPP AMR"
),
161
.read_probe =
amr_probe
,
162
.read_header =
amr_read_header
,
163
.read_packet =
amr_read_packet
,
164
.flags =
AVFMT_GENERIC_INDEX
,
165
};
166
#endif
167
168
#if CONFIG_AMR_MUXER
169
AVOutputFormat
ff_amr_muxer = {
170
.
name
=
"amr"
,
171
.long_name =
NULL_IF_CONFIG_SMALL
(
"3GPP AMR"
),
172
.mime_type =
"audio/amr"
,
173
.extensions =
"amr"
,
174
.audio_codec =
AV_CODEC_ID_AMR_NB
,
175
.video_codec =
AV_CODEC_ID_NONE
,
176
.write_header = amr_write_header,
177
.write_packet = amr_write_packet,
178
};
179
#endif
Generated on Sun Mar 23 2014 23:50:10 for FFmpeg by
1.8.2