Mercurial > libavformat.hg
annotate amr.c @ 1456:34d0d965a0d0 libavformat
Add support for block duration.
Patch by Steve Lhomme % slhomme A divxcorp P com %
Original thread:
Date: Mon, 06 Nov 2006 19:22:14 +0100
Subject: [Ffmpeg-devel] [PATCH] Matroska block duration support
author | aurel |
---|---|
date | Mon, 06 Nov 2006 23:52:10 +0000 |
parents | 6f00a1374023 |
children | 1a3c9056982a |
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 |
906 | 33 #ifdef CONFIG_MUXERS |
148 | 34 static int amr_write_header(AVFormatContext *s) |
35 { | |
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 { |
468 | 59 put_buffer(&s->pb, pkt->data, pkt->size); |
148 | 60 put_flush_packet(&s->pb); |
61 return 0; | |
62 } | |
63 | |
64 static int amr_write_trailer(AVFormatContext *s) | |
65 { | |
66 return 0; | |
67 } | |
906 | 68 #endif /* CONFIG_MUXERS */ |
148 | 69 |
70 static int amr_probe(AVProbeData *p) | |
71 { | |
885 | 72 //Only check for "#!AMR" which could be amr-wb, amr-nb. |
73 //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
|
74 //"#!AMR-WB_MC1.0\n" (not supported) |
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
75 |
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
76 if (p->buf_size < 5) |
148 | 77 return 0; |
258
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
78 if(memcmp(p->buf,AMR_header,5)==0) |
148 | 79 return AVPROBE_SCORE_MAX; |
80 else | |
81 return 0; | |
82 } | |
83 | |
84 /* amr input */ | |
85 static int amr_read_header(AVFormatContext *s, | |
86 AVFormatParameters *ap) | |
87 { | |
88 ByteIOContext *pb = &s->pb; | |
89 AVStream *st; | |
258
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
90 uint8_t header[9]; |
148 | 91 |
92 get_buffer(pb, header, 6); | |
93 | |
1369 | 94 st = av_new_stream(s, 0); |
95 if (!st) | |
96 { | |
97 return AVERROR_NOMEM; | |
98 } | |
148 | 99 if(memcmp(header,AMR_header,6)!=0) |
100 { | |
258
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
101 get_buffer(pb, header+6, 3); |
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
102 if(memcmp(header,AMRWB_header,9)!=0) |
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 return -1; |
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
105 } |
885 | 106 |
820
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_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
|
108 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
|
109 st->codec->sample_rate = 16000; |
258
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
110 } |
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
111 else |
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
112 { |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
113 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
|
114 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
|
115 st->codec->sample_rate = 8000; |
148 | 116 } |
1368 | 117 st->codec->channels = 1; |
118 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
|
119 av_set_pts_info(st, 64, 1, st->codec->sample_rate); |
148 | 120 |
121 return 0; | |
122 } | |
123 | |
124 static int amr_read_packet(AVFormatContext *s, | |
125 AVPacket *pkt) | |
126 { | |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
127 AVCodecContext *enc = s->streams[0]->codec; |
1366 | 128 int read, size, toc, mode; |
129 | |
130 if (url_feof(&s->pb)) | |
131 { | |
132 return AVERROR_IO; | |
133 } | |
134 | |
1369 | 135 //FIXME this is wrong, this should rather be in a AVParset |
1366 | 136 toc=get_byte(&s->pb); |
137 mode = (toc >> 3) & 0x0F; | |
148 | 138 |
258
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
139 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
|
140 { |
1242
996ce2a68147
Fix some "'static' is not at beginning of declaration" warnings.
diego
parents:
1169
diff
changeset
|
141 static const uint8_t packed_size[16] = {12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0}; |
885 | 142 |
1366 | 143 size=packed_size[mode]+1; |
258
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
144 } |
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
145 else if(enc->codec_id == CODEC_ID_AMR_WB) |
148 | 146 { |
258
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
147 static uint8_t packed_size[16] = {18, 24, 33, 37, 41, 47, 51, 59, 61, 6, 6, 0, 0, 0, 1, 1}; |
885 | 148 |
1366 | 149 size=packed_size[mode]; |
258
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
150 } |
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
151 else |
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
152 { |
1365 | 153 assert(0); |
148 | 154 } |
1366 | 155 |
156 if ( (size==0) || av_new_packet(pkt, size)) | |
157 { | |
158 return AVERROR_IO; | |
159 } | |
160 | |
161 pkt->stream_index = 0; | |
162 pkt->pos= url_ftell(&s->pb); | |
163 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
|
164 pkt->duration= enc->codec_id == CODEC_ID_AMR_NB ? 160 : 320; |
1366 | 165 read = get_buffer(&s->pb, pkt->data+1, size-1); |
166 | |
167 if (read != size-1) | |
168 { | |
169 av_free_packet(pkt); | |
170 return AVERROR_IO; | |
171 } | |
172 | |
1365 | 173 return 0; |
148 | 174 } |
175 | |
1169 | 176 #ifdef CONFIG_AMR_DEMUXER |
177 AVInputFormat amr_demuxer = { | |
148 | 178 "amr", |
179 "3gpp amr file format", | |
258
59c2e84817a1
AMR-WB support by (Johannes Carlsson <joca at rixmail dot se>)
michaelni
parents:
154
diff
changeset
|
180 0, /*priv_data_size*/ |
148 | 181 amr_probe, |
182 amr_read_header, | |
183 amr_read_packet, | |
1370 | 184 NULL, |
148 | 185 }; |
1169 | 186 #endif |
148 | 187 |
1169 | 188 #ifdef CONFIG_AMR_MUXER |
189 AVOutputFormat amr_muxer = { | |
148 | 190 "amr", |
191 "3gpp amr file format", | |
192 "audio/amr", | |
193 "amr", | |
194 0, | |
195 CODEC_ID_AMR_NB, | |
196 CODEC_ID_NONE, | |
197 amr_write_header, | |
198 amr_write_packet, | |
199 amr_write_trailer, | |
200 }; | |
906 | 201 #endif |