Mercurial > libavformat.hg
annotate amr.c @ 5149:4a53fcd622ea libavformat
Check for seek failures in avi_load_index, otherwise if the index offset
is invalid (e.g. truncated file) we might end up reading the whole file
since trying to seek beyond the end of file does not set EOF.
author | reimar |
---|---|
date | Wed, 26 Aug 2009 08:38:44 +0000 |
parents | c3102b189cb6 |
children | 536e5527c1e0 |
rev | line source |
---|---|
885 | 1 /* |
148 | 2 * amr file format |
3 * Copyright (c) 2001 ffmpeg project | |
4 * | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1332
diff
changeset
|
5 * This file is part of FFmpeg. |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1332
diff
changeset
|
6 * |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1332
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
148 | 8 * modify it under the terms of the GNU Lesser General Public |
9 * License as published by the Free Software Foundation; either | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1332
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
148 | 11 * |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1332
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
148 | 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 | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1332
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
896
edbe5c3717f9
Update licensing information: The FSF changed postal address.
diego
parents:
885
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
148 | 20 */ |
21 | |
22 /* | |
23 Write and read amr data according to RFC3267, http://www.ietf.org/rfc/rfc3267.txt?number=3267 | |
24 | |
258
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
25 Only mono files are supported. |
148 | 26 |
27 */ | |
28 #include "avformat.h" | |
29 | |
1332 | 30 static const char AMR_header [] = "#!AMR\n"; |
31 static const char AMRWB_header [] = "#!AMR-WB\n"; | |
148 | 32 |
4206 | 33 #if CONFIG_AMR_MUXER |
148 | 34 static int amr_write_header(AVFormatContext *s) |
35 { | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2274
diff
changeset
|
36 ByteIOContext *pb = s->pb; |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
37 AVCodecContext *enc = s->streams[0]->codec; |
148 | 38 |
39 s->priv_data = NULL; | |
40 | |
258
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
41 if (enc->codec_id == CODEC_ID_AMR_NB) |
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
42 { |
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
43 put_tag(pb, AMR_header); /* magic number */ |
148 | 44 } |
258
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
45 else if(enc->codec_id == CODEC_ID_AMR_WB) |
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
46 { |
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
47 put_tag(pb, AMRWB_header); /* magic number */ |
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
48 } |
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
49 else |
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
50 { |
1365 | 51 return -1; |
258
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
52 } |
148 | 53 put_flush_packet(pb); |
54 return 0; | |
55 } | |
56 | |
468 | 57 static int amr_write_packet(AVFormatContext *s, AVPacket *pkt) |
148 | 58 { |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2274
diff
changeset
|
59 put_buffer(s->pb, pkt->data, pkt->size); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2274
diff
changeset
|
60 put_flush_packet(s->pb); |
148 | 61 return 0; |
62 } | |
3871
e6aeb2733e34
Replace generic CONFIG_MUXERS preprocessor conditionals by more specific
diego
parents:
3424
diff
changeset
|
63 #endif /* CONFIG_AMR_MUXER */ |
148 | 64 |
65 static int amr_probe(AVProbeData *p) | |
66 { | |
885 | 67 //Only check for "#!AMR" which could be amr-wb, amr-nb. |
68 //This will also trigger multichannel files: "#!AMR_MC1.0\n" and | |
258
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
69 //"#!AMR-WB_MC1.0\n" (not supported) |
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
70 |
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
71 if(memcmp(p->buf,AMR_header,5)==0) |
148 | 72 return AVPROBE_SCORE_MAX; |
73 else | |
74 return 0; | |
75 } | |
76 | |
77 /* amr input */ | |
78 static int amr_read_header(AVFormatContext *s, | |
79 AVFormatParameters *ap) | |
80 { | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2274
diff
changeset
|
81 ByteIOContext *pb = s->pb; |
148 | 82 AVStream *st; |
258
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
83 uint8_t header[9]; |
148 | 84 |
85 get_buffer(pb, header, 6); | |
86 | |
1369 | 87 st = av_new_stream(s, 0); |
88 if (!st) | |
89 { | |
2273
7eb456c4ed8a
Replace all occurrences of AVERROR_NOMEM with AVERROR(ENOMEM).
takis
parents:
2225
diff
changeset
|
90 return AVERROR(ENOMEM); |
1369 | 91 } |
148 | 92 if(memcmp(header,AMR_header,6)!=0) |
93 { | |
258
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
94 get_buffer(pb, header+6, 3); |
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
95 if(memcmp(header,AMRWB_header,9)!=0) |
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
96 { |
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
97 return -1; |
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
98 } |
885 | 99 |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
100 st->codec->codec_tag = MKTAG('s', 'a', 'w', 'b'); |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
101 st->codec->codec_id = CODEC_ID_AMR_WB; |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
102 st->codec->sample_rate = 16000; |
258
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
103 } |
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
104 else |
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
105 { |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
106 st->codec->codec_tag = MKTAG('s', 'a', 'm', 'r'); |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
107 st->codec->codec_id = CODEC_ID_AMR_NB; |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
108 st->codec->sample_rate = 8000; |
148 | 109 } |
1368 | 110 st->codec->channels = 1; |
111 st->codec->codec_type = CODEC_TYPE_AUDIO; | |
1367
8e0ee2faf4d5
set duration and timebase (based on a patch by Simon Morlat simon.morlat linphone org)
michael
parents:
1366
diff
changeset
|
112 av_set_pts_info(st, 64, 1, st->codec->sample_rate); |
148 | 113 |
114 return 0; | |
115 } | |
116 | |
117 static int amr_read_packet(AVFormatContext *s, | |
118 AVPacket *pkt) | |
119 { | |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
120 AVCodecContext *enc = s->streams[0]->codec; |
2225
7e5e26f8052a
kill uninitialised variable warning in amr_read_packet()
mru
parents:
2210
diff
changeset
|
121 int read, size = 0, toc, mode; |
1366 | 122 |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2274
diff
changeset
|
123 if (url_feof(s->pb)) |
1366 | 124 { |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2273
diff
changeset
|
125 return AVERROR(EIO); |
1366 | 126 } |
127 | |
1369 | 128 //FIXME this is wrong, this should rather be in a AVParset |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2274
diff
changeset
|
129 toc=get_byte(s->pb); |
1366 | 130 mode = (toc >> 3) & 0x0F; |
148 | 131 |
258
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
132 if (enc->codec_id == CODEC_ID_AMR_NB) |
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
133 { |
1242
996ce2a68147
Fix some "'static' is not at beginning of declaration" warnings.
diego
parents:
1169
diff
changeset
|
134 static const uint8_t packed_size[16] = {12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0}; |
885 | 135 |
1366 | 136 size=packed_size[mode]+1; |
258
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
137 } |
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
138 else if(enc->codec_id == CODEC_ID_AMR_WB) |
148 | 139 { |
258
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
140 static uint8_t packed_size[16] = {18, 24, 33, 37, 41, 47, 51, 59, 61, 6, 6, 0, 0, 0, 1, 1}; |
885 | 141 |
1366 | 142 size=packed_size[mode]; |
258
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
143 } |
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
144 else |
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
145 { |
1365 | 146 assert(0); |
148 | 147 } |
1366 | 148 |
149 if ( (size==0) || av_new_packet(pkt, size)) | |
150 { | |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2273
diff
changeset
|
151 return AVERROR(EIO); |
1366 | 152 } |
153 | |
154 pkt->stream_index = 0; | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2274
diff
changeset
|
155 pkt->pos= url_ftell(s->pb); |
1366 | 156 pkt->data[0]=toc; |
1367
8e0ee2faf4d5
set duration and timebase (based on a patch by Simon Morlat simon.morlat linphone org)
michael
parents:
1366
diff
changeset
|
157 pkt->duration= enc->codec_id == CODEC_ID_AMR_NB ? 160 : 320; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2274
diff
changeset
|
158 read = get_buffer(s->pb, pkt->data+1, size-1); |
1366 | 159 |
160 if (read != size-1) | |
161 { | |
162 av_free_packet(pkt); | |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2273
diff
changeset
|
163 return AVERROR(EIO); |
1366 | 164 } |
165 | |
1365 | 166 return 0; |
148 | 167 } |
168 | |
4206 | 169 #if CONFIG_AMR_DEMUXER |
1169 | 170 AVInputFormat amr_demuxer = { |
148 | 171 "amr", |
3424
7a0230981402
Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents:
2771
diff
changeset
|
172 NULL_IF_CONFIG_SMALL("3GPP AMR file format"), |
258
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
173 0, /*priv_data_size*/ |
148 | 174 amr_probe, |
175 amr_read_header, | |
176 amr_read_packet, | |
1370 | 177 NULL, |
148 | 178 }; |
1169 | 179 #endif |
148 | 180 |
4206 | 181 #if CONFIG_AMR_MUXER |
1169 | 182 AVOutputFormat amr_muxer = { |
148 | 183 "amr", |
3424
7a0230981402
Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents:
2771
diff
changeset
|
184 NULL_IF_CONFIG_SMALL("3GPP AMR file format"), |
148 | 185 "audio/amr", |
186 "amr", | |
187 0, | |
188 CODEC_ID_AMR_NB, | |
189 CODEC_ID_NONE, | |
190 amr_write_header, | |
191 amr_write_packet, | |
192 }; | |
906 | 193 #endif |