Mercurial > libavformat.hg
annotate amr.c @ 154:7f3e6d83abd3 libavformat
amr typefix patch by (Johannes Carlsson <joca at rixmail dot se>)
| author | michaelni |
|---|---|
| date | Wed, 18 Jun 2003 22:24:51 +0000 |
| parents | 31d7c9a8678c |
| 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 } |
