ffmpeg / libavformat / au.c @ 9dd94f83
History | View | Annotate | Download (5.27 KB)
1 | 115329f1 | Diego Biurrun | /*
|
---|---|---|---|
2 | 7fbde343 | Aurelien Jacobs | * AU muxer and demuxer
|
3 | 406792e7 | Diego Biurrun | * Copyright (c) 2001 Fabrice Bellard
|
4 | 6cea494e | Zdenek Kabelac | *
|
5 | 2912e87a | Mans Rullgard | * This file is part of Libav.
|
6 | b78e7197 | Diego Biurrun | *
|
7 | 2912e87a | Mans Rullgard | * Libav is free software; you can redistribute it and/or
|
8 | 19720f15 | Fabrice Bellard | * modify it under the terms of the GNU Lesser General Public
|
9 | * License as published by the Free Software Foundation; either
|
||
10 | b78e7197 | Diego Biurrun | * version 2.1 of the License, or (at your option) any later version.
|
11 | 6cea494e | Zdenek Kabelac | *
|
12 | 2912e87a | Mans Rullgard | * Libav is distributed in the hope that it will be useful,
|
13 | 6cea494e | Zdenek Kabelac | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 | 19720f15 | Fabrice Bellard | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
15 | * Lesser General Public License for more details.
|
||
16 | 6cea494e | Zdenek Kabelac | *
|
17 | 19720f15 | Fabrice Bellard | * You should have received a copy of the GNU Lesser General Public
|
18 | 2912e87a | Mans Rullgard | * License along with Libav; if not, write to the Free Software
|
19 | 5509bffa | Diego Biurrun | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
20 | 6cea494e | Zdenek Kabelac | */
|
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" |
||
31 | 0abdb293 | Anton Khirnov | #include "avio_internal.h" |
32 | e94204df | Aurelien Jacobs | #include "pcm.h" |
33 | 9d9f4119 | Måns Rullgård | #include "riff.h" |
34 | 6cea494e | Zdenek Kabelac | |
35 | /* if we don't know the size in advance */
|
||
36 | 9ff85412 | Diego Biurrun | #define AU_UNKNOWN_SIZE ((uint32_t)(~0)) |
37 | 6cea494e | Zdenek Kabelac | |
38 | /* The ffmpeg codecs we support, and the IDs they have in the file */
|
||
39 | 7caf0cc6 | Michael Niedermayer | static const AVCodecTag codec_au_tags[] = { |
40 | 6cea494e | Zdenek Kabelac | { CODEC_ID_PCM_MULAW, 1 },
|
41 | c5adfd64 | Roberto Togni | { CODEC_ID_PCM_S8, 2 },
|
42 | 6cea494e | Zdenek Kabelac | { CODEC_ID_PCM_S16BE, 3 },
|
43 | 7b21690a | Peter Ross | { CODEC_ID_PCM_S24BE, 4 },
|
44 | { CODEC_ID_PCM_S32BE, 5 },
|
||
45 | 249f3243 | Peter Ross | { CODEC_ID_PCM_F32BE, 6 },
|
46 | 7b21690a | Peter Ross | { CODEC_ID_PCM_F64BE, 7 },
|
47 | 6cea494e | Zdenek Kabelac | { CODEC_ID_PCM_ALAW, 27 },
|
48 | bc2d2a07 | Carl Eugen Hoyos | { CODEC_ID_NONE, 0 },
|
49 | 6cea494e | Zdenek Kabelac | }; |
50 | |||
51 | b250f9c6 | Aurelien Jacobs | #if CONFIG_AU_MUXER
|
52 | 6cea494e | Zdenek Kabelac | /* AUDIO_FILE header */
|
53 | ae628ec1 | Anton Khirnov | static int put_au_header(AVIOContext *pb, AVCodecContext *enc) |
54 | 6cea494e | Zdenek Kabelac | { |
55 | bd5a6020 | Michael Niedermayer | if(!enc->codec_tag)
|
56 | 6cea494e | Zdenek Kabelac | return -1; |
57 | 0abdb293 | Anton Khirnov | ffio_wfourcc(pb, ".snd"); /* magic number */ |
58 | 77eb5504 | Anton Khirnov | avio_wb32(pb, 24); /* header size */ |
59 | avio_wb32(pb, AU_UNKNOWN_SIZE); /* data size */
|
||
60 | avio_wb32(pb, (uint32_t)enc->codec_tag); /* codec ID */
|
||
61 | avio_wb32(pb, enc->sample_rate); |
||
62 | avio_wb32(pb, (uint32_t)enc->channels); |
||
63 | 6cea494e | Zdenek Kabelac | return 0; |
64 | } |
||
65 | |||
66 | static int au_write_header(AVFormatContext *s) |
||
67 | { |
||
68 | ae628ec1 | Anton Khirnov | AVIOContext *pb = s->pb; |
69 | 6cea494e | Zdenek Kabelac | |
70 | s->priv_data = NULL;
|
||
71 | |||
72 | /* format header */
|
||
73 | 01f4895c | Michael Niedermayer | if (put_au_header(pb, s->streams[0]->codec) < 0) { |
74 | 6cea494e | Zdenek Kabelac | return -1; |
75 | } |
||
76 | |||
77 | b7f2fdde | Anton Khirnov | avio_flush(pb); |
78 | 6cea494e | Zdenek Kabelac | |
79 | return 0; |
||
80 | } |
||
81 | |||
82 | e928649b | Michael Niedermayer | static int au_write_packet(AVFormatContext *s, AVPacket *pkt) |
83 | 6cea494e | Zdenek Kabelac | { |
84 | ae628ec1 | Anton Khirnov | AVIOContext *pb = s->pb; |
85 | 77eb5504 | Anton Khirnov | avio_write(pb, pkt->data, pkt->size); |
86 | 6cea494e | Zdenek Kabelac | return 0; |
87 | } |
||
88 | |||
89 | static int au_write_trailer(AVFormatContext *s) |
||
90 | { |
||
91 | ae628ec1 | Anton Khirnov | AVIOContext *pb = s->pb; |
92 | bc5c918e | Diego Biurrun | int64_t file_size; |
93 | 6cea494e | Zdenek Kabelac | |
94 | 899681cd | Björn Axelsson | if (!url_is_streamed(s->pb)) {
|
95 | 6cea494e | Zdenek Kabelac | |
96 | /* update file size */
|
||
97 | a2704c97 | Anton Khirnov | file_size = avio_tell(pb); |
98 | 6b4aa5da | Anton Khirnov | avio_seek(pb, 8, SEEK_SET);
|
99 | 77eb5504 | Anton Khirnov | avio_wb32(pb, (uint32_t)(file_size - 24));
|
100 | 6b4aa5da | Anton Khirnov | avio_seek(pb, file_size, SEEK_SET); |
101 | 6cea494e | Zdenek Kabelac | |
102 | b7f2fdde | Anton Khirnov | avio_flush(pb); |
103 | 6cea494e | Zdenek Kabelac | } |
104 | |||
105 | return 0; |
||
106 | } |
||
107 | 8212568a | Diego Biurrun | #endif /* CONFIG_AU_MUXER */ |
108 | 6cea494e | Zdenek Kabelac | |
109 | c9a65ca8 | Fabrice Bellard | static int au_probe(AVProbeData *p) |
110 | { |
||
111 | /* check file header */
|
||
112 | if (p->buf[0] == '.' && p->buf[1] == 's' && |
||
113 | p->buf[2] == 'n' && p->buf[3] == 'd') |
||
114 | return AVPROBE_SCORE_MAX;
|
||
115 | else
|
||
116 | return 0; |
||
117 | } |
||
118 | |||
119 | 6cea494e | Zdenek Kabelac | /* au input */
|
120 | static int au_read_header(AVFormatContext *s, |
||
121 | 4986a429 | Fabrice Bellard | AVFormatParameters *ap) |
122 | 6cea494e | Zdenek Kabelac | { |
123 | int size;
|
||
124 | unsigned int tag; |
||
125 | ae628ec1 | Anton Khirnov | AVIOContext *pb = s->pb; |
126 | fb65d2ca | Diego Pettenò | unsigned int id, channels, rate; |
127 | enum CodecID codec;
|
||
128 | 6cea494e | Zdenek Kabelac | AVStream *st; |
129 | |||
130 | /* check ".snd" header */
|
||
131 | b7effd4e | Anton Khirnov | tag = avio_rl32(pb); |
132 | 6cea494e | Zdenek Kabelac | if (tag != MKTAG('.', 's', 'n', 'd')) |
133 | return -1; |
||
134 | b7effd4e | Anton Khirnov | size = avio_rb32(pb); /* header size */
|
135 | avio_rb32(pb); /* data size */
|
||
136 | 115329f1 | Diego Biurrun | |
137 | b7effd4e | Anton Khirnov | id = avio_rb32(pb); |
138 | rate = avio_rb32(pb); |
||
139 | channels = avio_rb32(pb); |
||
140 | 115329f1 | Diego Biurrun | |
141 | 1a40491e | Daniel Verkamp | codec = ff_codec_get_id(codec_au_tags, id); |
142 | 6cea494e | Zdenek Kabelac | |
143 | 0a624147 | Peter Ross | if (!av_get_bits_per_sample(codec)) {
|
144 | av_log_ask_for_sample(s, "could not determine bits per sample\n");
|
||
145 | return AVERROR_INVALIDDATA;
|
||
146 | } |
||
147 | |||
148 | 6cea494e | Zdenek Kabelac | if (size >= 24) { |
149 | /* skip unused data */
|
||
150 | 45a8a02a | Anton Khirnov | avio_skip(pb, size - 24);
|
151 | 6cea494e | Zdenek Kabelac | } |
152 | |||
153 | /* now we are ready: build format streams */
|
||
154 | fa26a29d | Fabrice Bellard | st = av_new_stream(s, 0);
|
155 | 6cea494e | Zdenek Kabelac | if (!st)
|
156 | return -1; |
||
157 | 72415b2a | Stefano Sabatini | st->codec->codec_type = AVMEDIA_TYPE_AUDIO; |
158 | 01f4895c | Michael Niedermayer | st->codec->codec_tag = id; |
159 | st->codec->codec_id = codec; |
||
160 | st->codec->channels = channels; |
||
161 | st->codec->sample_rate = rate; |
||
162 | 595bf4ef | Michael Niedermayer | av_set_pts_info(st, 64, 1, rate); |
163 | 6cea494e | Zdenek Kabelac | return 0; |
164 | } |
||
165 | |||
166 | 4da715cb | Jai Menon | #define BLOCK_SIZE 1024 |
167 | 6cea494e | Zdenek Kabelac | |
168 | static int au_read_packet(AVFormatContext *s, |
||
169 | 94ef6864 | Fabrice Bellard | AVPacket *pkt) |
170 | 6cea494e | Zdenek Kabelac | { |
171 | 94ef6864 | Fabrice Bellard | int ret;
|
172 | 6cea494e | Zdenek Kabelac | |
173 | 4da715cb | Jai Menon | ret= av_get_packet(s->pb, pkt, BLOCK_SIZE * |
174 | s->streams[0]->codec->channels *
|
||
175 | av_get_bits_per_sample(s->streams[0]->codec->codec_id) >> 3); |
||
176 | 2692067a | Michael Niedermayer | if (ret < 0) |
177 | b46c98bf | Reimar Döffinger | return ret;
|
178 | 6cea494e | Zdenek Kabelac | pkt->stream_index = 0;
|
179 | |||
180 | /* note: we need to modify the packet size here to handle the last
|
||
181 | packet */
|
||
182 | pkt->size = ret; |
||
183 | 94ef6864 | Fabrice Bellard | return 0; |
184 | 6cea494e | Zdenek Kabelac | } |
185 | |||
186 | b250f9c6 | Aurelien Jacobs | #if CONFIG_AU_DEMUXER
|
187 | c6610a21 | Diego Elio Pettenò | AVInputFormat ff_au_demuxer = { |
188 | c9a65ca8 | Fabrice Bellard | "au",
|
189 | bde15e74 | Stefano Sabatini | NULL_IF_CONFIG_SMALL("SUN AU format"),
|
190 | c9a65ca8 | Fabrice Bellard | 0,
|
191 | au_probe, |
||
192 | au_read_header, |
||
193 | au_read_packet, |
||
194 | 9b64a036 | Baptiste Coudurier | NULL,
|
195 | 4986a429 | Fabrice Bellard | pcm_read_seek, |
196 | c1854592 | Reimar Döffinger | .codec_tag= (const AVCodecTag* const []){codec_au_tags, 0}, |
197 | c9a65ca8 | Fabrice Bellard | }; |
198 | ff70e601 | Måns Rullgård | #endif
|
199 | c9a65ca8 | Fabrice Bellard | |
200 | b250f9c6 | Aurelien Jacobs | #if CONFIG_AU_MUXER
|
201 | c6610a21 | Diego Elio Pettenò | AVOutputFormat ff_au_muxer = { |
202 | 6cea494e | Zdenek Kabelac | "au",
|
203 | bde15e74 | Stefano Sabatini | NULL_IF_CONFIG_SMALL("SUN AU format"),
|
204 | 6cea494e | Zdenek Kabelac | "audio/basic",
|
205 | "au",
|
||
206 | c9a65ca8 | Fabrice Bellard | 0,
|
207 | 6cea494e | Zdenek Kabelac | CODEC_ID_PCM_S16BE, |
208 | CODEC_ID_NONE, |
||
209 | au_write_header, |
||
210 | au_write_packet, |
||
211 | au_write_trailer, |
||
212 | c1854592 | Reimar Döffinger | .codec_tag= (const AVCodecTag* const []){codec_au_tags, 0}, |
213 | 6cea494e | Zdenek Kabelac | }; |
214 | ff70e601 | Måns Rullgård | #endif //CONFIG_AU_MUXER |