Mercurial > libavformat.hg
annotate au.c @ 6085:72c7c3d5c4e9 libavformat
matroskaenc: Mux clusters better
Start them on keyframes when reasonable, and delay writing audio packets
to help ensure that there's audio samples available for the first frame in
clusters.
Patch by James Zern <jzern at google>
author | conrad |
---|---|
date | Fri, 04 Jun 2010 22:40:50 +0000 |
parents | 51ae348d4511 |
children | 4aaed59641ff |
rev | line source |
---|---|
885 | 1 /* |
1415
3b00fb8ef8e4
replace coder/decoder file description in libavformat by muxer/demuxer
aurel
parents:
1358
diff
changeset
|
2 * AU muxer and demuxer |
4251
77e0c7511d41
cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents:
4206
diff
changeset
|
3 * Copyright (c) 2001 Fabrice Bellard |
0 | 4 * |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1172
diff
changeset
|
5 * This file is part of FFmpeg. |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1172
diff
changeset
|
6 * |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1172
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
0 | 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:
1172
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
0 | 11 * |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1172
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
0 | 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:
1172
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 |
0 | 20 */ |
21 | |
22 /* | |
23 * First version by Francois Revol revol@free.fr | |
24 * | |
25 * Reference documents: | |
26 * http://www.opengroup.org/public/pubs/external/auformat.html | |
27 * http://www.goice.co.jp/member/mo/formats/au.html | |
28 */ | |
29 | |
30 #include "avformat.h" | |
2545
213268d7594e
move unrelated functions declarations out of allformats.h
aurel
parents:
2274
diff
changeset
|
31 #include "raw.h" |
1172
6a5e58d2114b
move common stuff from avienc.c and wav.c to new file riff.c
mru
parents:
1169
diff
changeset
|
32 #include "riff.h" |
0 | 33 |
34 /* if we don't know the size in advance */ | |
1885 | 35 #define AU_UNKNOWN_SIZE ((uint32_t)(~0)) |
0 | 36 |
37 /* The ffmpeg codecs we support, and the IDs they have in the file */ | |
1677
2a85c82b8538
add codec_id <-> codec_tag tables to AVIn/OutputFormat
michael
parents:
1415
diff
changeset
|
38 static const AVCodecTag codec_au_tags[] = { |
0 | 39 { CODEC_ID_PCM_MULAW, 1 }, |
2933 | 40 { CODEC_ID_PCM_S8, 2 }, |
0 | 41 { CODEC_ID_PCM_S16BE, 3 }, |
3736
441e758e1a5e
Make AU demuxer handle S24BE, S32BE and F64BE PCM audio.
pross
parents:
3599
diff
changeset
|
42 { CODEC_ID_PCM_S24BE, 4 }, |
441e758e1a5e
Make AU demuxer handle S24BE, S32BE and F64BE PCM audio.
pross
parents:
3599
diff
changeset
|
43 { CODEC_ID_PCM_S32BE, 5 }, |
3599
d99961d92b99
Support 32-bit floating point audio samples in Sun AU demuxer
pross
parents:
3484
diff
changeset
|
44 { CODEC_ID_PCM_F32BE, 6 }, |
3736
441e758e1a5e
Make AU demuxer handle S24BE, S32BE and F64BE PCM audio.
pross
parents:
3599
diff
changeset
|
45 { CODEC_ID_PCM_F64BE, 7 }, |
0 | 46 { CODEC_ID_PCM_ALAW, 27 }, |
5290
0d5653941bf9
Make AVCodecTag.id enum CodecID and use CODEC_ID_NONE instead of 0.
cehoyos
parents:
5255
diff
changeset
|
47 { CODEC_ID_NONE, 0 }, |
0 | 48 }; |
49 | |
4206 | 50 #if CONFIG_AU_MUXER |
0 | 51 /* AUDIO_FILE header */ |
52 static int put_au_header(ByteIOContext *pb, AVCodecContext *enc) | |
53 { | |
196 | 54 if(!enc->codec_tag) |
0 | 55 return -1; |
56 put_tag(pb, ".snd"); /* magic number */ | |
57 put_be32(pb, 24); /* header size */ | |
1885 | 58 put_be32(pb, AU_UNKNOWN_SIZE); /* data size */ |
196 | 59 put_be32(pb, (uint32_t)enc->codec_tag); /* codec ID */ |
0 | 60 put_be32(pb, enc->sample_rate); |
65 | 61 put_be32(pb, (uint32_t)enc->channels); |
0 | 62 return 0; |
63 } | |
64 | |
65 static int au_write_header(AVFormatContext *s) | |
66 { | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2545
diff
changeset
|
67 ByteIOContext *pb = s->pb; |
0 | 68 |
69 s->priv_data = NULL; | |
70 | |
71 /* format header */ | |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
72 if (put_au_header(pb, s->streams[0]->codec) < 0) { |
0 | 73 return -1; |
74 } | |
75 | |
76 put_flush_packet(pb); | |
77 | |
78 return 0; | |
79 } | |
80 | |
468 | 81 static int au_write_packet(AVFormatContext *s, AVPacket *pkt) |
0 | 82 { |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2545
diff
changeset
|
83 ByteIOContext *pb = s->pb; |
468 | 84 put_buffer(pb, pkt->data, pkt->size); |
0 | 85 return 0; |
86 } | |
87 | |
88 static int au_write_trailer(AVFormatContext *s) | |
89 { | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2545
diff
changeset
|
90 ByteIOContext *pb = s->pb; |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3967
diff
changeset
|
91 int64_t file_size; |
0 | 92 |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2545
diff
changeset
|
93 if (!url_is_streamed(s->pb)) { |
0 | 94 |
95 /* update file size */ | |
96 file_size = url_ftell(pb); | |
97 url_fseek(pb, 8, SEEK_SET); | |
65 | 98 put_be32(pb, (uint32_t)(file_size - 24)); |
0 | 99 url_fseek(pb, file_size, SEEK_SET); |
100 | |
101 put_flush_packet(pb); | |
102 } | |
103 | |
104 return 0; | |
105 } | |
3871
e6aeb2733e34
Replace generic CONFIG_MUXERS preprocessor conditionals by more specific
diego
parents:
3766
diff
changeset
|
106 #endif /* CONFIG_AU_MUXER */ |
0 | 107 |
108 static int au_probe(AVProbeData *p) | |
109 { | |
110 /* check file header */ | |
111 if (p->buf[0] == '.' && p->buf[1] == 's' && | |
112 p->buf[2] == 'n' && p->buf[3] == 'd') | |
113 return AVPROBE_SCORE_MAX; | |
114 else | |
115 return 0; | |
116 } | |
117 | |
118 /* au input */ | |
119 static int au_read_header(AVFormatContext *s, | |
306 | 120 AVFormatParameters *ap) |
0 | 121 { |
122 int size; | |
123 unsigned int tag; | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2545
diff
changeset
|
124 ByteIOContext *pb = s->pb; |
3967 | 125 unsigned int id, channels, rate; |
126 enum CodecID codec; | |
0 | 127 AVStream *st; |
128 | |
129 /* check ".snd" header */ | |
130 tag = get_le32(pb); | |
131 if (tag != MKTAG('.', 's', 'n', 'd')) | |
132 return -1; | |
133 size = get_be32(pb); /* header size */ | |
134 get_be32(pb); /* data size */ | |
885 | 135 |
0 | 136 id = get_be32(pb); |
137 rate = get_be32(pb); | |
138 channels = get_be32(pb); | |
885 | 139 |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
4251
diff
changeset
|
140 codec = ff_codec_get_id(codec_au_tags, id); |
0 | 141 |
6067
51ae348d4511
Prevent au_read_packet() looping endlessly when .au file contains unsupported codec type.
pross
parents:
5910
diff
changeset
|
142 if (!av_get_bits_per_sample(codec)) { |
51ae348d4511
Prevent au_read_packet() looping endlessly when .au file contains unsupported codec type.
pross
parents:
5910
diff
changeset
|
143 av_log_ask_for_sample(s, "could not determine bits per sample\n"); |
51ae348d4511
Prevent au_read_packet() looping endlessly when .au file contains unsupported codec type.
pross
parents:
5910
diff
changeset
|
144 return AVERROR_INVALIDDATA; |
51ae348d4511
Prevent au_read_packet() looping endlessly when .au file contains unsupported codec type.
pross
parents:
5910
diff
changeset
|
145 } |
51ae348d4511
Prevent au_read_packet() looping endlessly when .au file contains unsupported codec type.
pross
parents:
5910
diff
changeset
|
146 |
0 | 147 if (size >= 24) { |
148 /* skip unused data */ | |
149 url_fseek(pb, size - 24, SEEK_CUR); | |
150 } | |
151 | |
152 /* now we are ready: build format streams */ | |
187 | 153 st = av_new_stream(s, 0); |
0 | 154 if (!st) |
155 return -1; | |
5910
536e5527c1e0
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
5421
diff
changeset
|
156 st->codec->codec_type = AVMEDIA_TYPE_AUDIO; |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
157 st->codec->codec_tag = id; |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
158 st->codec->codec_id = codec; |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
159 st->codec->channels = channels; |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
160 st->codec->sample_rate = rate; |
567 | 161 av_set_pts_info(st, 64, 1, rate); |
0 | 162 return 0; |
163 } | |
164 | |
5421
26a5d390beb0
AU : demuxed packet size should be sample size aligned.
jai_menon
parents:
5290
diff
changeset
|
165 #define BLOCK_SIZE 1024 |
0 | 166 |
167 static int au_read_packet(AVFormatContext *s, | |
168 AVPacket *pkt) | |
169 { | |
170 int ret; | |
171 | |
5421
26a5d390beb0
AU : demuxed packet size should be sample size aligned.
jai_menon
parents:
5290
diff
changeset
|
172 ret= av_get_packet(s->pb, pkt, BLOCK_SIZE * |
26a5d390beb0
AU : demuxed packet size should be sample size aligned.
jai_menon
parents:
5290
diff
changeset
|
173 s->streams[0]->codec->channels * |
26a5d390beb0
AU : demuxed packet size should be sample size aligned.
jai_menon
parents:
5290
diff
changeset
|
174 av_get_bits_per_sample(s->streams[0]->codec->codec_id) >> 3); |
775 | 175 if (ret < 0) |
5246
dc7045701f0e
au demuxer: pass av_get_packet error on unchanged instead of converting to
reimar
parents:
5058
diff
changeset
|
176 return ret; |
0 | 177 pkt->stream_index = 0; |
178 | |
179 /* note: we need to modify the packet size here to handle the last | |
180 packet */ | |
181 pkt->size = ret; | |
182 return 0; | |
183 } | |
184 | |
4206 | 185 #if CONFIG_AU_DEMUXER |
1169 | 186 AVInputFormat au_demuxer = { |
0 | 187 "au", |
3424
7a0230981402
Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents:
2933
diff
changeset
|
188 NULL_IF_CONFIG_SMALL("SUN AU format"), |
0 | 189 0, |
190 au_probe, | |
191 au_read_header, | |
192 au_read_packet, | |
3484 | 193 NULL, |
306 | 194 pcm_read_seek, |
3766
f062deeedb8d
Change codec_tag type from const struct AVCodecTag ** to const struct AVCodecTag * const *
reimar
parents:
3736
diff
changeset
|
195 .codec_tag= (const AVCodecTag* const []){codec_au_tags, 0}, |
0 | 196 }; |
1169 | 197 #endif |
0 | 198 |
4206 | 199 #if CONFIG_AU_MUXER |
1169 | 200 AVOutputFormat au_muxer = { |
0 | 201 "au", |
3424
7a0230981402
Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents:
2933
diff
changeset
|
202 NULL_IF_CONFIG_SMALL("SUN AU format"), |
0 | 203 "audio/basic", |
204 "au", | |
205 0, | |
206 CODEC_ID_PCM_S16BE, | |
207 CODEC_ID_NONE, | |
208 au_write_header, | |
209 au_write_packet, | |
210 au_write_trailer, | |
3766
f062deeedb8d
Change codec_tag type from const struct AVCodecTag ** to const struct AVCodecTag * const *
reimar
parents:
3736
diff
changeset
|
211 .codec_tag= (const AVCodecTag* const []){codec_au_tags, 0}, |
0 | 212 }; |
1169 | 213 #endif //CONFIG_AU_MUXER |