Remove disabled code cruft.
[libav.git] / libavformat / wav.c
CommitLineData
115329f1 1/*
7fbde343 2 * WAV muxer and demuxer
406792e7 3 * Copyright (c) 2001, 2002 Fabrice Bellard
de6d9b64 4 *
b78e7197
DB
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
19720f15
FB
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
b78e7197 10 * version 2.1 of the License, or (at your option) any later version.
de6d9b64 11 *
b78e7197 12 * FFmpeg is distributed in the hope that it will be useful,
de6d9b64 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19720f15
FB
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
de6d9b64 16 *
19720f15 17 * You should have received a copy of the GNU Lesser General Public
b78e7197 18 * License along with FFmpeg; if not, write to the Free Software
5509bffa 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
de6d9b64 20 */
de6d9b64 21#include "avformat.h"
7241a6bb 22#include "raw.h"
9d9f4119 23#include "riff.h"
46a3d068 24
de6d9b64 25typedef struct {
bc5c918e
DB
26 int64_t data;
27 int64_t data_end;
d794d388
MB
28 int64_t minpts;
29 int64_t maxpts;
30 int last_duration;
de6d9b64
FB
31} WAVContext;
32
b250f9c6 33#if CONFIG_WAV_MUXER
de6d9b64
FB
34static int wav_write_header(AVFormatContext *s)
35{
c9a65ca8 36 WAVContext *wav = s->priv_data;
899681cd 37 ByteIOContext *pb = s->pb;
bc5c918e 38 int64_t fmt, fact;
de6d9b64 39
de6d9b64
FB
40 put_tag(pb, "RIFF");
41 put_le32(pb, 0); /* file length */
42 put_tag(pb, "WAVE");
43
44 /* format header */
1a40491e
DV
45 fmt = ff_start_tag(pb, "fmt ");
46 if (ff_put_wav_header(pb, s->streams[0]->codec) < 0) {
5165651c 47 av_log(s, AV_LOG_ERROR, "%s codec not supported in WAVE format\n",
f2d65a6c 48 s->streams[0]->codec->codec ? s->streams[0]->codec->codec->name : "NONE");
1ea4f593 49 av_free(wav);
46a3d068
FB
50 return -1;
51 }
1a40491e 52 ff_end_tag(pb, fmt);
de6d9b64 53
d794d388 54 if(s->streams[0]->codec->codec_tag != 0x01 /* hence for all other than PCM */
899681cd 55 && !url_is_streamed(s->pb)) {
1a40491e 56 fact = ff_start_tag(pb, "fact");
d794d388 57 put_le32(pb, 0);
1a40491e 58 ff_end_tag(pb, fact);
d794d388
MB
59 }
60
01f4895c 61 av_set_pts_info(s->streams[0], 64, 1, s->streams[0]->codec->sample_rate);
d794d388
MB
62 wav->maxpts = wav->last_duration = 0;
63 wav->minpts = INT64_MAX;
a1e568bd 64
de6d9b64 65 /* data header */
1a40491e 66 wav->data = ff_start_tag(pb, "data");
115329f1 67
de6d9b64
FB
68 put_flush_packet(pb);
69
70 return 0;
71}
72
e928649b 73static int wav_write_packet(AVFormatContext *s, AVPacket *pkt)
de6d9b64 74{
899681cd 75 ByteIOContext *pb = s->pb;
d794d388 76 WAVContext *wav = s->priv_data;
e928649b 77 put_buffer(pb, pkt->data, pkt->size);
d794d388
MB
78 if(pkt->pts != AV_NOPTS_VALUE) {
79 wav->minpts = FFMIN(wav->minpts, pkt->pts);
80 wav->maxpts = FFMAX(wav->maxpts, pkt->pts);
81 wav->last_duration = pkt->duration;
82 } else
83 av_log(s, AV_LOG_ERROR, "wav_write_packet: NOPTS\n");
de6d9b64
FB
84 return 0;
85}
86
87static int wav_write_trailer(AVFormatContext *s)
88{
899681cd 89 ByteIOContext *pb = s->pb;
de6d9b64 90 WAVContext *wav = s->priv_data;
bc5c918e 91 int64_t file_size;
de6d9b64 92
899681cd 93 if (!url_is_streamed(s->pb)) {
1a40491e 94 ff_end_tag(pb, wav->data);
de6d9b64
FB
95
96 /* update file size */
97 file_size = url_ftell(pb);
98 url_fseek(pb, 4, SEEK_SET);
0c1a9eda 99 put_le32(pb, (uint32_t)(file_size - 8));
de6d9b64
FB
100 url_fseek(pb, file_size, SEEK_SET);
101
102 put_flush_packet(pb);
d794d388
MB
103
104 if(s->streams[0]->codec->codec_tag != 0x01) {
105 /* Update num_samps in fact chunk */
106 int number_of_samples;
107 number_of_samples = av_rescale(wav->maxpts - wav->minpts + wav->last_duration,
108 s->streams[0]->codec->sample_rate * (int64_t)s->streams[0]->time_base.num,
109 s->streams[0]->time_base.den);
110 url_fseek(pb, wav->data-12, SEEK_SET);
111 put_le32(pb, number_of_samples);
112 url_fseek(pb, file_size, SEEK_SET);
113 put_flush_packet(pb);
114 }
de6d9b64 115 }
de6d9b64
FB
116 return 0;
117}
8212568a 118#endif /* CONFIG_WAV_MUXER */
de6d9b64
FB
119
120/* return the size of the found tag */
502d6c0a 121static int64_t find_tag(ByteIOContext *pb, uint32_t tag1)
de6d9b64
FB
122{
123 unsigned int tag;
502d6c0a 124 int64_t size;
de6d9b64
FB
125
126 for(;;) {
127 if (url_feof(pb))
128 return -1;
129 tag = get_le32(pb);
130 size = get_le32(pb);
131 if (tag == tag1)
132 break;
133 url_fseek(pb, size, SEEK_CUR);
134 }
de6d9b64
FB
135 return size;
136}
137
c9a65ca8
FB
138static int wav_probe(AVProbeData *p)
139{
140 /* check file header */
141 if (p->buf_size <= 32)
142 return 0;
143 if (p->buf[0] == 'R' && p->buf[1] == 'I' &&
144 p->buf[2] == 'F' && p->buf[3] == 'F' &&
145 p->buf[8] == 'W' && p->buf[9] == 'A' &&
146 p->buf[10] == 'V' && p->buf[11] == 'E')
c6cd525a
VV
147 /*
148 Since ACT demuxer has standard WAV header at top of it's own,
149 returning score is decreased to avoid probe conflict
150 between ACT and WAV.
151 */
152 return AVPROBE_SCORE_MAX - 1;
c9a65ca8
FB
153 else
154 return 0;
155}
156
de6d9b64
FB
157/* wav input */
158static int wav_read_header(AVFormatContext *s,
159 AVFormatParameters *ap)
160{
502d6c0a 161 int64_t size;
de6d9b64 162 unsigned int tag;
899681cd 163 ByteIOContext *pb = s->pb;
de6d9b64 164 AVStream *st;
b582d7ba 165 WAVContext *wav = s->priv_data;
de6d9b64
FB
166
167 /* check RIFF header */
168 tag = get_le32(pb);
169
170 if (tag != MKTAG('R', 'I', 'F', 'F'))
171 return -1;
172 get_le32(pb); /* file size */
173 tag = get_le32(pb);
174 if (tag != MKTAG('W', 'A', 'V', 'E'))
175 return -1;
115329f1 176
de6d9b64
FB
177 /* parse fmt header */
178 size = find_tag(pb, MKTAG('f', 'm', 't', ' '));
179 if (size < 0)
180 return -1;
c9a65ca8 181 st = av_new_stream(s, 0);
de6d9b64 182 if (!st)
769e10f0 183 return AVERROR(ENOMEM);
de6d9b64 184
1a40491e 185 ff_get_wav_header(pb, st->codec, size);
57004ff1 186 st->need_parsing = AVSTREAM_PARSE_FULL;
595bf4ef 187
01f4895c 188 av_set_pts_info(st, 64, 1, st->codec->sample_rate);
595bf4ef 189
e095026a
FB
190 size = find_tag(pb, MKTAG('d', 'a', 't', 'a'));
191 if (size < 0)
192 return -1;
b582d7ba 193 wav->data_end= url_ftell(pb) + size;
de6d9b64
FB
194 return 0;
195}
196
197#define MAX_SIZE 4096
198
199static int wav_read_packet(AVFormatContext *s,
200 AVPacket *pkt)
201{
b582d7ba 202 int ret, size, left;
f9b5459e 203 AVStream *st;
b582d7ba 204 WAVContext *wav = s->priv_data;
de6d9b64 205
899681cd 206 if (url_feof(s->pb))
6f3e0b21 207 return AVERROR(EIO);
f9b5459e
FB
208 st = s->streams[0];
209
899681cd 210 left= wav->data_end - url_ftell(s->pb);
b582d7ba 211 if(left <= 0){
899681cd 212 left = find_tag(s->pb, MKTAG('d', 'a', 't', 'a'));
b582d7ba 213 if (left < 0) {
6f3e0b21 214 return AVERROR(EIO);
b582d7ba 215 }
899681cd 216 wav->data_end= url_ftell(s->pb) + left;
b582d7ba
MN
217 }
218
f9b5459e 219 size = MAX_SIZE;
01f4895c
MN
220 if (st->codec->block_align > 1) {
221 if (size < st->codec->block_align)
222 size = st->codec->block_align;
223 size = (size / st->codec->block_align) * st->codec->block_align;
f9b5459e 224 }
b582d7ba 225 size= FFMIN(size, left);
899681cd 226 ret= av_get_packet(s->pb, pkt, size);
e9b78eeb 227 if (ret <= 0)
6f3e0b21 228 return AVERROR(EIO);
de6d9b64
FB
229 pkt->stream_index = 0;
230
5ed8fafc
FB
231 /* note: we need to modify the packet size here to handle the last
232 packet */
233 pkt->size = ret;
de6d9b64
FB
234 return ret;
235}
236
115329f1 237static int wav_read_seek(AVFormatContext *s,
7b3c1382 238 int stream_index, int64_t timestamp, int flags)
f9b5459e
FB
239{
240 AVStream *st;
241
242 st = s->streams[0];
01f4895c 243 switch(st->codec->codec_id) {
f9b5459e
FB
244 case CODEC_ID_MP2:
245 case CODEC_ID_MP3:
246 case CODEC_ID_AC3:
23c99253 247 case CODEC_ID_DTS:
f9b5459e
FB
248 /* use generic seeking with dynamically generated indexes */
249 return -1;
250 default:
251 break;
252 }
7b3c1382 253 return pcm_read_seek(s, stream_index, timestamp, flags);
f9b5459e
FB
254}
255
b250f9c6 256#if CONFIG_WAV_DEMUXER
ff70e601 257AVInputFormat wav_demuxer = {
c9a65ca8 258 "wav",
bde15e74 259 NULL_IF_CONFIG_SMALL("WAV format"),
b582d7ba 260 sizeof(WAVContext),
c9a65ca8
FB
261 wav_probe,
262 wav_read_header,
263 wav_read_packet,
9b64a036 264 NULL,
f9b5459e 265 wav_read_seek,
e9b78eeb 266 .flags= AVFMT_GENERIC_INDEX,
1a40491e 267 .codec_tag= (const AVCodecTag* const []){ff_codec_wav_tags, 0},
c9a65ca8 268};
ff70e601 269#endif
b250f9c6 270#if CONFIG_WAV_MUXER
ff70e601 271AVOutputFormat wav_muxer = {
de6d9b64 272 "wav",
bde15e74 273 NULL_IF_CONFIG_SMALL("WAV format"),
de6d9b64
FB
274 "audio/x-wav",
275 "wav",
c9a65ca8 276 sizeof(WAVContext),
5ed8fafc 277 CODEC_ID_PCM_S16LE,
de6d9b64
FB
278 CODEC_ID_NONE,
279 wav_write_header,
280 wav_write_packet,
281 wav_write_trailer,
1a40491e 282 .codec_tag= (const AVCodecTag* const []){ff_codec_wav_tags, 0},
de6d9b64 283};
ff70e601 284#endif