Mercurial > libavformat.hg
annotate amr.c @ 161:e01949598794 libavformat
undefined local_port fix by (Giancarlo Formicuccia <ilsensine at inwind dot it>)
author | michaelni |
---|---|
date | Fri, 04 Jul 2003 09:14:14 +0000 |
parents | 7f3e6d83abd3 |
children | 59c2e84817a1 |
rev | line source |
---|---|
148 | 1 /* |
2 * amr file format | |
3 * Copyright (c) 2001 ffmpeg project | |
4 * | |
5 * This library is free software; you can redistribute it and/or | |
6 * modify it under the terms of the GNU Lesser General Public | |
7 * License as published by the Free Software Foundation; either | |
8 * version 2 of the License, or (at your option) any later version. | |
9 * | |
10 * This library is distributed in the hope that it will be useful, | |
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 * Lesser General Public License for more details. | |
14 * | |
15 * You should have received a copy of the GNU Lesser General Public | |
16 * License along with this library; if not, write to the Free Software | |
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 */ | |
19 | |
20 /* | |
21 Write and read amr data according to RFC3267, http://www.ietf.org/rfc/rfc3267.txt?number=3267 | |
22 | |
23 Only amr narrowband (not amr-wb) is supported for now. | |
24 | |
25 */ | |
26 #include "avformat.h" | |
27 #include "avi.h" | |
28 | |
29 static const unsigned char AMR_header [] = "#!AMR\n"; | |
30 | |
31 /* AMR_FILE header */ | |
32 static int put_amr_header(ByteIOContext *pb, AVCodecContext *enc) | |
33 { | |
34 put_tag(pb, AMR_header); /* magic number */ | |
35 return 0; | |
36 } | |
37 | |
38 static int amr_write_header(AVFormatContext *s) | |
39 { | |
40 ByteIOContext *pb = &s->pb; | |
41 | |
42 s->priv_data = NULL; | |
43 | |
44 /* format header */ | |
45 if (put_amr_header(pb, &s->streams[0]->codec) < 0) { | |
46 return -1; | |
47 } | |
48 | |
49 put_flush_packet(pb); | |
50 | |
51 return 0; | |
52 } | |
53 | |
54 static int amr_write_packet(AVFormatContext *s, int stream_index_ptr, | |
55 uint8_t *buf, int size, int force_pts) | |
56 { | |
57 put_buffer(&s->pb, buf, size); | |
58 put_flush_packet(&s->pb); | |
59 return 0; | |
60 } | |
61 | |
62 static int amr_write_trailer(AVFormatContext *s) | |
63 { | |
64 return 0; | |
65 } | |
66 | |
67 static int amr_probe(AVProbeData *p) | |
68 { | |
69 /* check file header */ | |
70 if (p->buf_size < 6) | |
71 return 0; | |
72 if(memcmp(p->buf,AMR_header,6)==0) | |
73 return AVPROBE_SCORE_MAX; | |
74 else | |
75 return 0; | |
76 } | |
77 | |
78 /* amr input */ | |
79 static int amr_read_header(AVFormatContext *s, | |
80 AVFormatParameters *ap) | |
81 { | |
82 ByteIOContext *pb = &s->pb; | |
83 AVStream *st; | |
154
7f3e6d83abd3
amr typefix patch by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
148
diff
changeset
|
84 uint8_t header[6]; |
148 | 85 |
86 get_buffer(pb, header, 6); | |
87 | |
88 if(memcmp(header,AMR_header,6)!=0) | |
89 { | |
90 return -1; | |
91 } | |
92 | |
93 st = av_new_stream(s, 0); | |
94 if (!st) | |
95 return AVERROR_NOMEM; | |
96 | |
97 st->codec.codec_type = CODEC_TYPE_AUDIO; | |
98 st->codec.codec_tag = CODEC_ID_AMR_NB; | |
99 st->codec.codec_id = CODEC_ID_AMR_NB; | |
100 st->codec.channels = 1; | |
101 st->codec.sample_rate = 8000; | |
102 return 0; | |
103 } | |
104 | |
105 #define MAX_SIZE 32 | |
106 | |
107 static int amr_read_packet(AVFormatContext *s, | |
108 AVPacket *pkt) | |
109 { | |
154
7f3e6d83abd3
amr typefix patch by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
148
diff
changeset
|
110 static uint16_t packed_size[16] = {12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0}; |
7f3e6d83abd3
amr typefix patch by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
148
diff
changeset
|
111 uint8_t toc, q, ft; |
148 | 112 int read; |
113 int size; | |
114 | |
115 if (url_feof(&s->pb)) | |
116 return -EIO; | |
117 | |
118 toc=0; | |
119 | |
120 toc=get_byte(&s->pb); | |
121 | |
122 q = (toc >> 2) & 0x01; | |
123 ft = (toc >> 3) & 0x0F; | |
124 | |
125 size=packed_size[ft]; | |
126 //printf("amr_read_packet size=%d\n",size); | |
127 | |
128 if (av_new_packet(pkt, size+1)) | |
129 return -EIO; | |
130 pkt->stream_index = 0; | |
131 | |
132 pkt->data[0]=toc; | |
133 | |
134 read = get_buffer(&s->pb, pkt->data+1, size); | |
135 | |
136 if (read != size) | |
137 { | |
138 av_free_packet(pkt); | |
139 return -EIO; | |
140 } | |
141 | |
142 return 0; | |
143 } | |
144 | |
145 static int amr_read_close(AVFormatContext *s) | |
146 { | |
147 return 0; | |
148 } | |
149 | |
150 static AVInputFormat amr_iformat = { | |
151 "amr", | |
152 "3gpp amr file format", | |
153 0, | |
154 amr_probe, | |
155 amr_read_header, | |
156 amr_read_packet, | |
157 amr_read_close, | |
158 }; | |
159 | |
160 static AVOutputFormat amr_oformat = { | |
161 "amr", | |
162 "3gpp amr file format", | |
163 "audio/amr", | |
164 "amr", | |
165 0, | |
166 CODEC_ID_AMR_NB, | |
167 CODEC_ID_NONE, | |
168 amr_write_header, | |
169 amr_write_packet, | |
170 amr_write_trailer, | |
171 }; | |
172 | |
173 int amr_init(void) | |
174 { | |
175 av_register_input_format(&amr_iformat); | |
176 av_register_output_format(&amr_oformat); | |
177 return 0; | |
178 } |