Mercurial > libavformat.hg
annotate wav.c @ 6124:778065ad3ac5 libavformat
matroskadec: simplify parsing of the first cluster
Now that we save the currently parsed ebml element ID after an interruption,
we don't need to special case the parsing of the first cluster.
author | aurel |
---|---|
date | Fri, 11 Jun 2010 16:36:51 +0000 |
parents | f3c5f3b0eb0d |
children | 67c36f475c54 |
rev | line source |
---|---|
885 | 1 /* |
1415
3b00fb8ef8e4
replace coder/decoder file description in libavformat by muxer/demuxer
aurel
parents:
1358
diff
changeset
|
2 * WAV muxer and demuxer |
4251
77e0c7511d41
cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents:
4206
diff
changeset
|
3 * Copyright (c) 2001, 2002 Fabrice Bellard |
0 | 4 * |
5126 | 5 * Sony Wave64 demuxer |
5267 | 6 * RF64 demuxer |
5126 | 7 * Copyright (c) 2009 Daniel Verkamp |
8 * | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1172
diff
changeset
|
9 * This file is part of FFmpeg. |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1172
diff
changeset
|
10 * |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1172
diff
changeset
|
11 * FFmpeg is free software; you can redistribute it and/or |
0 | 12 * modify it under the terms of the GNU Lesser General Public |
13 * 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
|
14 * version 2.1 of the License, or (at your option) any later version. |
0 | 15 * |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1172
diff
changeset
|
16 * FFmpeg is distributed in the hope that it will be useful, |
0 | 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
19 * Lesser General Public License for more details. | |
20 * | |
21 * 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
|
22 * License along with FFmpeg; if not, write to the Free Software |
896
edbe5c3717f9
Update licensing information: The FSF changed postal address.
diego
parents:
893
diff
changeset
|
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
0 | 24 */ |
25 #include "avformat.h" | |
2545
213268d7594e
move unrelated functions declarations out of allformats.h
aurel
parents:
2274
diff
changeset
|
26 #include "raw.h" |
1172
6a5e58d2114b
move common stuff from avienc.c and wav.c to new file riff.c
mru
parents:
1169
diff
changeset
|
27 #include "riff.h" |
0 | 28 |
29 typedef struct { | |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3934
diff
changeset
|
30 int64_t data; |
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3934
diff
changeset
|
31 int64_t data_end; |
1781 | 32 int64_t minpts; |
33 int64_t maxpts; | |
34 int last_duration; | |
5126 | 35 int w64; |
0 | 36 } WAVContext; |
37 | |
4206 | 38 #if CONFIG_WAV_MUXER |
0 | 39 static int wav_write_header(AVFormatContext *s) |
40 { | |
41 WAVContext *wav = s->priv_data; | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2545
diff
changeset
|
42 ByteIOContext *pb = s->pb; |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3934
diff
changeset
|
43 int64_t fmt, fact; |
0 | 44 |
45 put_tag(pb, "RIFF"); | |
46 put_le32(pb, 0); /* file length */ | |
47 put_tag(pb, "WAVE"); | |
48 | |
49 /* format header */ | |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
5001
diff
changeset
|
50 fmt = ff_start_tag(pb, "fmt "); |
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
5001
diff
changeset
|
51 if (ff_put_wav_header(pb, s->streams[0]->codec) < 0) { |
3925 | 52 av_log(s, AV_LOG_ERROR, "%s codec not supported in WAVE format\n", |
3934 | 53 s->streams[0]->codec->codec ? s->streams[0]->codec->codec->name : "NONE"); |
0 | 54 av_free(wav); |
55 return -1; | |
56 } | |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
5001
diff
changeset
|
57 ff_end_tag(pb, fmt); |
0 | 58 |
5127
e73c5f33463b
cosmetics: whitespace, prettyprinting, coding style fixes
diego
parents:
5126
diff
changeset
|
59 if (s->streams[0]->codec->codec_tag != 0x01 /* hence for all other than PCM */ |
e73c5f33463b
cosmetics: whitespace, prettyprinting, coding style fixes
diego
parents:
5126
diff
changeset
|
60 && !url_is_streamed(s->pb)) { |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
5001
diff
changeset
|
61 fact = ff_start_tag(pb, "fact"); |
1781 | 62 put_le32(pb, 0); |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
5001
diff
changeset
|
63 ff_end_tag(pb, fact); |
1781 | 64 } |
65 | |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
817
diff
changeset
|
66 av_set_pts_info(s->streams[0], 64, 1, s->streams[0]->codec->sample_rate); |
1781 | 67 wav->maxpts = wav->last_duration = 0; |
68 wav->minpts = INT64_MAX; | |
645
9fc2d2cc4608
wav timestamp truncation fix by (Wolfram Gloger <wmglo dent.med.uni-muenchen de>)
michael
parents:
587
diff
changeset
|
69 |
0 | 70 /* data header */ |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
5001
diff
changeset
|
71 wav->data = ff_start_tag(pb, "data"); |
885 | 72 |
0 | 73 put_flush_packet(pb); |
74 | |
75 return 0; | |
76 } | |
77 | |
468 | 78 static int wav_write_packet(AVFormatContext *s, AVPacket *pkt) |
0 | 79 { |
5127
e73c5f33463b
cosmetics: whitespace, prettyprinting, coding style fixes
diego
parents:
5126
diff
changeset
|
80 ByteIOContext *pb = s->pb; |
e73c5f33463b
cosmetics: whitespace, prettyprinting, coding style fixes
diego
parents:
5126
diff
changeset
|
81 WAVContext *wav = s->priv_data; |
468 | 82 put_buffer(pb, pkt->data, pkt->size); |
1781 | 83 if(pkt->pts != AV_NOPTS_VALUE) { |
5127
e73c5f33463b
cosmetics: whitespace, prettyprinting, coding style fixes
diego
parents:
5126
diff
changeset
|
84 wav->minpts = FFMIN(wav->minpts, pkt->pts); |
e73c5f33463b
cosmetics: whitespace, prettyprinting, coding style fixes
diego
parents:
5126
diff
changeset
|
85 wav->maxpts = FFMAX(wav->maxpts, pkt->pts); |
1781 | 86 wav->last_duration = pkt->duration; |
87 } else | |
88 av_log(s, AV_LOG_ERROR, "wav_write_packet: NOPTS\n"); | |
0 | 89 return 0; |
90 } | |
91 | |
92 static int wav_write_trailer(AVFormatContext *s) | |
93 { | |
5127
e73c5f33463b
cosmetics: whitespace, prettyprinting, coding style fixes
diego
parents:
5126
diff
changeset
|
94 ByteIOContext *pb = s->pb; |
e73c5f33463b
cosmetics: whitespace, prettyprinting, coding style fixes
diego
parents:
5126
diff
changeset
|
95 WAVContext *wav = s->priv_data; |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3934
diff
changeset
|
96 int64_t file_size; |
0 | 97 |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2545
diff
changeset
|
98 if (!url_is_streamed(s->pb)) { |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
5001
diff
changeset
|
99 ff_end_tag(pb, wav->data); |
0 | 100 |
101 /* update file size */ | |
102 file_size = url_ftell(pb); | |
103 url_fseek(pb, 4, SEEK_SET); | |
65 | 104 put_le32(pb, (uint32_t)(file_size - 8)); |
0 | 105 url_fseek(pb, file_size, SEEK_SET); |
106 | |
107 put_flush_packet(pb); | |
1781 | 108 |
109 if(s->streams[0]->codec->codec_tag != 0x01) { | |
110 /* Update num_samps in fact chunk */ | |
111 int number_of_samples; | |
112 number_of_samples = av_rescale(wav->maxpts - wav->minpts + wav->last_duration, | |
113 s->streams[0]->codec->sample_rate * (int64_t)s->streams[0]->time_base.num, | |
114 s->streams[0]->time_base.den); | |
115 url_fseek(pb, wav->data-12, SEEK_SET); | |
116 put_le32(pb, number_of_samples); | |
117 url_fseek(pb, file_size, SEEK_SET); | |
118 put_flush_packet(pb); | |
119 } | |
0 | 120 } |
121 return 0; | |
122 } | |
5225
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
123 |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
124 AVOutputFormat wav_muxer = { |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
125 "wav", |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
126 NULL_IF_CONFIG_SMALL("WAV format"), |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
127 "audio/x-wav", |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
128 "wav", |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
129 sizeof(WAVContext), |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
130 CODEC_ID_PCM_S16LE, |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
131 CODEC_ID_NONE, |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
132 wav_write_header, |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
133 wav_write_packet, |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
134 wav_write_trailer, |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
135 .codec_tag= (const AVCodecTag* const []){ff_codec_wav_tags, 0}, |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
136 }; |
3871
e6aeb2733e34
Replace generic CONFIG_MUXERS preprocessor conditionals by more specific
diego
parents:
3766
diff
changeset
|
137 #endif /* CONFIG_WAV_MUXER */ |
0 | 138 |
5225
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
139 |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
140 #if CONFIG_WAV_DEMUXER |
0 | 141 /* return the size of the found tag */ |
5001
4da68099d180
Change find_tag return type to int64_t, fix a bug
bcoudurier
parents:
4251
diff
changeset
|
142 static int64_t find_tag(ByteIOContext *pb, uint32_t tag1) |
0 | 143 { |
144 unsigned int tag; | |
5001
4da68099d180
Change find_tag return type to int64_t, fix a bug
bcoudurier
parents:
4251
diff
changeset
|
145 int64_t size; |
0 | 146 |
5127
e73c5f33463b
cosmetics: whitespace, prettyprinting, coding style fixes
diego
parents:
5126
diff
changeset
|
147 for (;;) { |
0 | 148 if (url_feof(pb)) |
149 return -1; | |
5127
e73c5f33463b
cosmetics: whitespace, prettyprinting, coding style fixes
diego
parents:
5126
diff
changeset
|
150 tag = get_le32(pb); |
0 | 151 size = get_le32(pb); |
152 if (tag == tag1) | |
153 break; | |
154 url_fseek(pb, size, SEEK_CUR); | |
155 } | |
156 return size; | |
157 } | |
158 | |
159 static int wav_probe(AVProbeData *p) | |
160 { | |
161 /* check file header */ | |
162 if (p->buf_size <= 32) | |
163 return 0; | |
5267 | 164 if (!memcmp(p->buf + 8, "WAVE", 4)) { |
165 if (!memcmp(p->buf, "RIFF", 4)) | |
5268 | 166 /* |
167 Since ACT demuxer has standard WAV header at top of it's own, | |
168 returning score is decreased to avoid probe conflict | |
169 between ACT and WAV. | |
170 */ | |
171 return AVPROBE_SCORE_MAX - 1; | |
5267 | 172 else if (!memcmp(p->buf, "RF64", 4) && |
173 !memcmp(p->buf + 12, "ds64", 4)) | |
174 return AVPROBE_SCORE_MAX; | |
175 } | |
5268 | 176 return 0; |
0 | 177 } |
178 | |
179 /* wav input */ | |
180 static int wav_read_header(AVFormatContext *s, | |
181 AVFormatParameters *ap) | |
182 { | |
5267 | 183 int64_t size, av_uninit(data_size); |
184 int rf64; | |
0 | 185 unsigned int tag; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2545
diff
changeset
|
186 ByteIOContext *pb = s->pb; |
0 | 187 AVStream *st; |
1136
d65cd7c3573e
dont read over the end of a data chunk and at the end search for the next
michael
parents:
1122
diff
changeset
|
188 WAVContext *wav = s->priv_data; |
0 | 189 |
190 /* check RIFF header */ | |
191 tag = get_le32(pb); | |
192 | |
5267 | 193 rf64 = tag == MKTAG('R', 'F', '6', '4'); |
194 if (!rf64 && tag != MKTAG('R', 'I', 'F', 'F')) | |
0 | 195 return -1; |
196 get_le32(pb); /* file size */ | |
197 tag = get_le32(pb); | |
198 if (tag != MKTAG('W', 'A', 'V', 'E')) | |
199 return -1; | |
885 | 200 |
5267 | 201 if (rf64) { |
202 if (get_le32(pb) != MKTAG('d', 's', '6', '4')) | |
203 return -1; | |
204 size = get_le32(pb); | |
205 if (size < 16) | |
206 return -1; | |
207 get_le64(pb); /* RIFF size */ | |
208 data_size = get_le64(pb); | |
209 url_fskip(pb, size - 16); /* skip rest of ds64 chunk */ | |
210 } | |
211 | |
0 | 212 /* parse fmt header */ |
213 size = find_tag(pb, MKTAG('f', 'm', 't', ' ')); | |
214 if (size < 0) | |
215 return -1; | |
216 st = av_new_stream(s, 0); | |
217 if (!st) | |
2273
7eb456c4ed8a
Replace all occurrences of AVERROR_NOMEM with AVERROR(ENOMEM).
takis
parents:
2023
diff
changeset
|
218 return AVERROR(ENOMEM); |
0 | 219 |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
5001
diff
changeset
|
220 ff_get_wav_header(pb, st->codec, size); |
2023 | 221 st->need_parsing = AVSTREAM_PARSE_FULL; |
567 | 222 |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
817
diff
changeset
|
223 av_set_pts_info(st, 64, 1, st->codec->sample_rate); |
567 | 224 |
0 | 225 size = find_tag(pb, MKTAG('d', 'a', 't', 'a')); |
5267 | 226 if (rf64) |
227 size = data_size; | |
0 | 228 if (size < 0) |
229 return -1; | |
5648 | 230 if (!size) { |
231 wav->data_end = INT64_MAX; | |
232 } else | |
5649 | 233 wav->data_end= url_ftell(pb) + size; |
0 | 234 return 0; |
235 } | |
236 | |
5126 | 237 /** Find chunk with w64 GUID by skipping over other chunks |
238 * @return the size of the found chunk | |
239 */ | |
240 static int64_t find_guid(ByteIOContext *pb, const uint8_t guid1[16]) | |
241 { | |
242 uint8_t guid[16]; | |
243 int64_t size; | |
244 | |
245 while (!url_feof(pb)) { | |
246 get_buffer(pb, guid, 16); | |
247 size = get_le64(pb); | |
248 if (size <= 24) | |
249 return -1; | |
250 if (!memcmp(guid, guid1, 16)) | |
251 return size; | |
252 url_fskip(pb, FFALIGN(size, INT64_C(8)) - 24); | |
253 } | |
254 return -1; | |
255 } | |
256 | |
5224
c2881eee05b7
Move find_guid function and guid_data array to a globally available place.
diego
parents:
5127
diff
changeset
|
257 static const uint8_t guid_data[16] = { 'd', 'a', 't', 'a', |
c2881eee05b7
Move find_guid function and guid_data array to a globally available place.
diego
parents:
5127
diff
changeset
|
258 0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A }; |
c2881eee05b7
Move find_guid function and guid_data array to a globally available place.
diego
parents:
5127
diff
changeset
|
259 |
5225
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
260 #define MAX_SIZE 4096 |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
261 |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
262 static int wav_read_packet(AVFormatContext *s, |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
263 AVPacket *pkt) |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
264 { |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
265 int ret, size; |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
266 int64_t left; |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
267 AVStream *st; |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
268 WAVContext *wav = s->priv_data; |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
269 |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
270 st = s->streams[0]; |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
271 |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
272 left = wav->data_end - url_ftell(s->pb); |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
273 if (left <= 0){ |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
274 if (CONFIG_W64_DEMUXER && wav->w64) |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
275 left = find_guid(s->pb, guid_data) - 24; |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
276 else |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
277 left = find_tag(s->pb, MKTAG('d', 'a', 't', 'a')); |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
278 if (left < 0) |
5259
1c4c83a0fd96
wav demuxer: return AVERROR_EOF instead of AVERROR(EIO) when the end of
reimar
parents:
5258
diff
changeset
|
279 return AVERROR_EOF; |
5225
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
280 wav->data_end= url_ftell(s->pb) + left; |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
281 } |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
282 |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
283 size = MAX_SIZE; |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
284 if (st->codec->block_align > 1) { |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
285 if (size < st->codec->block_align) |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
286 size = st->codec->block_align; |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
287 size = (size / st->codec->block_align) * st->codec->block_align; |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
288 } |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
289 size = FFMIN(size, left); |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
290 ret = av_get_packet(s->pb, pkt, size); |
5258 | 291 if (ret < 0) |
292 return ret; | |
5225
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
293 pkt->stream_index = 0; |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
294 |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
295 return ret; |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
296 } |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
297 |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
298 static int wav_read_seek(AVFormatContext *s, |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
299 int stream_index, int64_t timestamp, int flags) |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
300 { |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
301 AVStream *st; |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
302 |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
303 st = s->streams[0]; |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
304 switch (st->codec->codec_id) { |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
305 case CODEC_ID_MP2: |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
306 case CODEC_ID_MP3: |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
307 case CODEC_ID_AC3: |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
308 case CODEC_ID_DTS: |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
309 /* use generic seeking with dynamically generated indexes */ |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
310 return -1; |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
311 default: |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
312 break; |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
313 } |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
314 return pcm_read_seek(s, stream_index, timestamp, flags); |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
315 } |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
316 |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
317 AVInputFormat wav_demuxer = { |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
318 "wav", |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
319 NULL_IF_CONFIG_SMALL("WAV format"), |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
320 sizeof(WAVContext), |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
321 wav_probe, |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
322 wav_read_header, |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
323 wav_read_packet, |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
324 NULL, |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
325 wav_read_seek, |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
326 .flags= AVFMT_GENERIC_INDEX, |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
327 .codec_tag= (const AVCodecTag* const []){ff_codec_wav_tags, 0}, |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
328 }; |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
329 #endif /* CONFIG_WAV_DEMUXER */ |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
330 |
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
331 |
5224
c2881eee05b7
Move find_guid function and guid_data array to a globally available place.
diego
parents:
5127
diff
changeset
|
332 #if CONFIG_W64_DEMUXER |
c2881eee05b7
Move find_guid function and guid_data array to a globally available place.
diego
parents:
5127
diff
changeset
|
333 static const uint8_t guid_riff[16] = { 'r', 'i', 'f', 'f', |
c2881eee05b7
Move find_guid function and guid_data array to a globally available place.
diego
parents:
5127
diff
changeset
|
334 0x2E, 0x91, 0xCF, 0x11, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 }; |
c2881eee05b7
Move find_guid function and guid_data array to a globally available place.
diego
parents:
5127
diff
changeset
|
335 |
c2881eee05b7
Move find_guid function and guid_data array to a globally available place.
diego
parents:
5127
diff
changeset
|
336 static const uint8_t guid_wave[16] = { 'w', 'a', 'v', 'e', |
c2881eee05b7
Move find_guid function and guid_data array to a globally available place.
diego
parents:
5127
diff
changeset
|
337 0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A }; |
c2881eee05b7
Move find_guid function and guid_data array to a globally available place.
diego
parents:
5127
diff
changeset
|
338 |
c2881eee05b7
Move find_guid function and guid_data array to a globally available place.
diego
parents:
5127
diff
changeset
|
339 static const uint8_t guid_fmt [16] = { 'f', 'm', 't', ' ', |
c2881eee05b7
Move find_guid function and guid_data array to a globally available place.
diego
parents:
5127
diff
changeset
|
340 0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A }; |
c2881eee05b7
Move find_guid function and guid_data array to a globally available place.
diego
parents:
5127
diff
changeset
|
341 |
c2881eee05b7
Move find_guid function and guid_data array to a globally available place.
diego
parents:
5127
diff
changeset
|
342 static int w64_probe(AVProbeData *p) |
c2881eee05b7
Move find_guid function and guid_data array to a globally available place.
diego
parents:
5127
diff
changeset
|
343 { |
c2881eee05b7
Move find_guid function and guid_data array to a globally available place.
diego
parents:
5127
diff
changeset
|
344 if (p->buf_size <= 40) |
c2881eee05b7
Move find_guid function and guid_data array to a globally available place.
diego
parents:
5127
diff
changeset
|
345 return 0; |
c2881eee05b7
Move find_guid function and guid_data array to a globally available place.
diego
parents:
5127
diff
changeset
|
346 if (!memcmp(p->buf, guid_riff, 16) && |
c2881eee05b7
Move find_guid function and guid_data array to a globally available place.
diego
parents:
5127
diff
changeset
|
347 !memcmp(p->buf + 24, guid_wave, 16)) |
c2881eee05b7
Move find_guid function and guid_data array to a globally available place.
diego
parents:
5127
diff
changeset
|
348 return AVPROBE_SCORE_MAX; |
c2881eee05b7
Move find_guid function and guid_data array to a globally available place.
diego
parents:
5127
diff
changeset
|
349 else |
c2881eee05b7
Move find_guid function and guid_data array to a globally available place.
diego
parents:
5127
diff
changeset
|
350 return 0; |
c2881eee05b7
Move find_guid function and guid_data array to a globally available place.
diego
parents:
5127
diff
changeset
|
351 } |
c2881eee05b7
Move find_guid function and guid_data array to a globally available place.
diego
parents:
5127
diff
changeset
|
352 |
5126 | 353 static int w64_read_header(AVFormatContext *s, AVFormatParameters *ap) |
354 { | |
355 int64_t size; | |
5127
e73c5f33463b
cosmetics: whitespace, prettyprinting, coding style fixes
diego
parents:
5126
diff
changeset
|
356 ByteIOContext *pb = s->pb; |
e73c5f33463b
cosmetics: whitespace, prettyprinting, coding style fixes
diego
parents:
5126
diff
changeset
|
357 WAVContext *wav = s->priv_data; |
5126 | 358 AVStream *st; |
359 uint8_t guid[16]; | |
360 | |
361 get_buffer(pb, guid, 16); | |
362 if (memcmp(guid, guid_riff, 16)) | |
363 return -1; | |
364 | |
365 if (get_le64(pb) < 16 + 8 + 16 + 8 + 16 + 8) /* riff + wave + fmt + sizes */ | |
366 return -1; | |
367 | |
368 get_buffer(pb, guid, 16); | |
369 if (memcmp(guid, guid_wave, 16)) { | |
370 av_log(s, AV_LOG_ERROR, "could not find wave guid\n"); | |
371 return -1; | |
372 } | |
373 | |
374 size = find_guid(pb, guid_fmt); | |
375 if (size < 0) { | |
376 av_log(s, AV_LOG_ERROR, "could not find fmt guid\n"); | |
377 return -1; | |
378 } | |
379 | |
380 st = av_new_stream(s, 0); | |
381 if (!st) | |
382 return AVERROR(ENOMEM); | |
383 | |
384 /* subtract chunk header size - normal wav file doesn't count it */ | |
385 ff_get_wav_header(pb, st->codec, size - 24); | |
386 url_fskip(pb, FFALIGN(size, INT64_C(8)) - size); | |
387 | |
388 st->need_parsing = AVSTREAM_PARSE_FULL; | |
389 | |
390 av_set_pts_info(st, 64, 1, st->codec->sample_rate); | |
391 | |
392 size = find_guid(pb, guid_data); | |
393 if (size < 0) { | |
394 av_log(s, AV_LOG_ERROR, "could not find data guid\n"); | |
395 return -1; | |
396 } | |
397 wav->data_end = url_ftell(pb) + size - 24; | |
5127
e73c5f33463b
cosmetics: whitespace, prettyprinting, coding style fixes
diego
parents:
5126
diff
changeset
|
398 wav->w64 = 1; |
5126 | 399 |
400 return 0; | |
401 } | |
402 | |
403 AVInputFormat w64_demuxer = { | |
404 "w64", | |
405 NULL_IF_CONFIG_SMALL("Sony Wave64 format"), | |
406 sizeof(WAVContext), | |
407 w64_probe, | |
408 w64_read_header, | |
409 wav_read_packet, | |
410 NULL, | |
411 wav_read_seek, | |
412 .flags = AVFMT_GENERIC_INDEX, | |
413 .codec_tag = (const AVCodecTag* const []){ff_codec_wav_tags, 0}, | |
414 }; | |
5225
117ab940d1b9
Rearrange wav_muxer and {wav|w64}_demuxer blocks to be under proper #ifdefs.
diego
parents:
5224
diff
changeset
|
415 #endif /* CONFIG_W64_DEMUXER */ |