Libav
|
00001 /* 00002 * WAV muxer and demuxer 00003 * Copyright (c) 2001, 2002 Fabrice Bellard 00004 * 00005 * Sony Wave64 demuxer 00006 * RF64 demuxer 00007 * Copyright (c) 2009 Daniel Verkamp 00008 * 00009 * This file is part of FFmpeg. 00010 * 00011 * FFmpeg is free software; you can redistribute it and/or 00012 * modify it under the terms of the GNU Lesser General Public 00013 * License as published by the Free Software Foundation; either 00014 * version 2.1 of the License, or (at your option) any later version. 00015 * 00016 * FFmpeg is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00019 * Lesser General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU Lesser General Public 00022 * License along with FFmpeg; if not, write to the Free Software 00023 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00024 */ 00025 #include "avformat.h" 00026 #include "raw.h" 00027 #include "riff.h" 00028 00029 typedef struct { 00030 int64_t data; 00031 int64_t data_end; 00032 int64_t minpts; 00033 int64_t maxpts; 00034 int last_duration; 00035 int w64; 00036 } WAVContext; 00037 00038 #if CONFIG_WAV_MUXER 00039 static int wav_write_header(AVFormatContext *s) 00040 { 00041 WAVContext *wav = s->priv_data; 00042 ByteIOContext *pb = s->pb; 00043 int64_t fmt, fact; 00044 00045 put_tag(pb, "RIFF"); 00046 put_le32(pb, 0); /* file length */ 00047 put_tag(pb, "WAVE"); 00048 00049 /* format header */ 00050 fmt = ff_start_tag(pb, "fmt "); 00051 if (ff_put_wav_header(pb, s->streams[0]->codec) < 0) { 00052 av_log(s, AV_LOG_ERROR, "%s codec not supported in WAVE format\n", 00053 s->streams[0]->codec->codec ? s->streams[0]->codec->codec->name : "NONE"); 00054 av_free(wav); 00055 return -1; 00056 } 00057 ff_end_tag(pb, fmt); 00058 00059 if (s->streams[0]->codec->codec_tag != 0x01 /* hence for all other than PCM */ 00060 && !url_is_streamed(s->pb)) { 00061 fact = ff_start_tag(pb, "fact"); 00062 put_le32(pb, 0); 00063 ff_end_tag(pb, fact); 00064 } 00065 00066 av_set_pts_info(s->streams[0], 64, 1, s->streams[0]->codec->sample_rate); 00067 wav->maxpts = wav->last_duration = 0; 00068 wav->minpts = INT64_MAX; 00069 00070 /* data header */ 00071 wav->data = ff_start_tag(pb, "data"); 00072 00073 put_flush_packet(pb); 00074 00075 return 0; 00076 } 00077 00078 static int wav_write_packet(AVFormatContext *s, AVPacket *pkt) 00079 { 00080 ByteIOContext *pb = s->pb; 00081 WAVContext *wav = s->priv_data; 00082 put_buffer(pb, pkt->data, pkt->size); 00083 if(pkt->pts != AV_NOPTS_VALUE) { 00084 wav->minpts = FFMIN(wav->minpts, pkt->pts); 00085 wav->maxpts = FFMAX(wav->maxpts, pkt->pts); 00086 wav->last_duration = pkt->duration; 00087 } else 00088 av_log(s, AV_LOG_ERROR, "wav_write_packet: NOPTS\n"); 00089 return 0; 00090 } 00091 00092 static int wav_write_trailer(AVFormatContext *s) 00093 { 00094 ByteIOContext *pb = s->pb; 00095 WAVContext *wav = s->priv_data; 00096 int64_t file_size; 00097 00098 if (!url_is_streamed(s->pb)) { 00099 ff_end_tag(pb, wav->data); 00100 00101 /* update file size */ 00102 file_size = url_ftell(pb); 00103 url_fseek(pb, 4, SEEK_SET); 00104 put_le32(pb, (uint32_t)(file_size - 8)); 00105 url_fseek(pb, file_size, SEEK_SET); 00106 00107 put_flush_packet(pb); 00108 00109 if(s->streams[0]->codec->codec_tag != 0x01) { 00110 /* Update num_samps in fact chunk */ 00111 int number_of_samples; 00112 number_of_samples = av_rescale(wav->maxpts - wav->minpts + wav->last_duration, 00113 s->streams[0]->codec->sample_rate * (int64_t)s->streams[0]->time_base.num, 00114 s->streams[0]->time_base.den); 00115 url_fseek(pb, wav->data-12, SEEK_SET); 00116 put_le32(pb, number_of_samples); 00117 url_fseek(pb, file_size, SEEK_SET); 00118 put_flush_packet(pb); 00119 } 00120 } 00121 return 0; 00122 } 00123 00124 AVOutputFormat wav_muxer = { 00125 "wav", 00126 NULL_IF_CONFIG_SMALL("WAV format"), 00127 "audio/x-wav", 00128 "wav", 00129 sizeof(WAVContext), 00130 CODEC_ID_PCM_S16LE, 00131 CODEC_ID_NONE, 00132 wav_write_header, 00133 wav_write_packet, 00134 wav_write_trailer, 00135 .codec_tag= (const AVCodecTag* const []){ff_codec_wav_tags, 0}, 00136 }; 00137 #endif /* CONFIG_WAV_MUXER */ 00138 00139 00140 #if CONFIG_WAV_DEMUXER 00141 /* return the size of the found tag */ 00142 static int64_t find_tag(ByteIOContext *pb, uint32_t tag1) 00143 { 00144 unsigned int tag; 00145 int64_t size; 00146 00147 for (;;) { 00148 if (url_feof(pb)) 00149 return -1; 00150 tag = get_le32(pb); 00151 size = get_le32(pb); 00152 if (tag == tag1) 00153 break; 00154 url_fseek(pb, size, SEEK_CUR); 00155 } 00156 return size; 00157 } 00158 00159 static int wav_probe(AVProbeData *p) 00160 { 00161 /* check file header */ 00162 if (p->buf_size <= 32) 00163 return 0; 00164 if (!memcmp(p->buf + 8, "WAVE", 4)) { 00165 if (!memcmp(p->buf, "RIFF", 4)) 00166 /* 00167 Since ACT demuxer has standard WAV header at top of it's own, 00168 returning score is decreased to avoid probe conflict 00169 between ACT and WAV. 00170 */ 00171 return AVPROBE_SCORE_MAX - 1; 00172 else if (!memcmp(p->buf, "RF64", 4) && 00173 !memcmp(p->buf + 12, "ds64", 4)) 00174 return AVPROBE_SCORE_MAX; 00175 } 00176 return 0; 00177 } 00178 00179 /* wav input */ 00180 static int wav_read_header(AVFormatContext *s, 00181 AVFormatParameters *ap) 00182 { 00183 int64_t size, av_uninit(data_size); 00184 int rf64; 00185 unsigned int tag; 00186 ByteIOContext *pb = s->pb; 00187 AVStream *st; 00188 WAVContext *wav = s->priv_data; 00189 00190 /* check RIFF header */ 00191 tag = get_le32(pb); 00192 00193 rf64 = tag == MKTAG('R', 'F', '6', '4'); 00194 if (!rf64 && tag != MKTAG('R', 'I', 'F', 'F')) 00195 return -1; 00196 get_le32(pb); /* file size */ 00197 tag = get_le32(pb); 00198 if (tag != MKTAG('W', 'A', 'V', 'E')) 00199 return -1; 00200 00201 if (rf64) { 00202 if (get_le32(pb) != MKTAG('d', 's', '6', '4')) 00203 return -1; 00204 size = get_le32(pb); 00205 if (size < 16) 00206 return -1; 00207 get_le64(pb); /* RIFF size */ 00208 data_size = get_le64(pb); 00209 url_fskip(pb, size - 16); /* skip rest of ds64 chunk */ 00210 } 00211 00212 /* parse fmt header */ 00213 size = find_tag(pb, MKTAG('f', 'm', 't', ' ')); 00214 if (size < 0) 00215 return -1; 00216 st = av_new_stream(s, 0); 00217 if (!st) 00218 return AVERROR(ENOMEM); 00219 00220 ff_get_wav_header(pb, st->codec, size); 00221 st->need_parsing = AVSTREAM_PARSE_FULL; 00222 00223 av_set_pts_info(st, 64, 1, st->codec->sample_rate); 00224 00225 size = find_tag(pb, MKTAG('d', 'a', 't', 'a')); 00226 if (rf64) 00227 size = data_size; 00228 if (size < 0) 00229 return -1; 00230 if (!size) { 00231 wav->data_end = INT64_MAX; 00232 } else 00233 wav->data_end= url_ftell(pb) + size; 00234 return 0; 00235 } 00236 00240 static int64_t find_guid(ByteIOContext *pb, const uint8_t guid1[16]) 00241 { 00242 uint8_t guid[16]; 00243 int64_t size; 00244 00245 while (!url_feof(pb)) { 00246 get_buffer(pb, guid, 16); 00247 size = get_le64(pb); 00248 if (size <= 24) 00249 return -1; 00250 if (!memcmp(guid, guid1, 16)) 00251 return size; 00252 url_fskip(pb, FFALIGN(size, INT64_C(8)) - 24); 00253 } 00254 return -1; 00255 } 00256 00257 static const uint8_t guid_data[16] = { 'd', 'a', 't', 'a', 00258 0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A }; 00259 00260 #define MAX_SIZE 4096 00261 00262 static int wav_read_packet(AVFormatContext *s, 00263 AVPacket *pkt) 00264 { 00265 int ret, size; 00266 int64_t left; 00267 AVStream *st; 00268 WAVContext *wav = s->priv_data; 00269 00270 st = s->streams[0]; 00271 00272 left = wav->data_end - url_ftell(s->pb); 00273 if (left <= 0){ 00274 if (CONFIG_W64_DEMUXER && wav->w64) 00275 left = find_guid(s->pb, guid_data) - 24; 00276 else 00277 left = find_tag(s->pb, MKTAG('d', 'a', 't', 'a')); 00278 if (left < 0) 00279 return AVERROR_EOF; 00280 wav->data_end= url_ftell(s->pb) + left; 00281 } 00282 00283 size = MAX_SIZE; 00284 if (st->codec->block_align > 1) { 00285 if (size < st->codec->block_align) 00286 size = st->codec->block_align; 00287 size = (size / st->codec->block_align) * st->codec->block_align; 00288 } 00289 size = FFMIN(size, left); 00290 ret = av_get_packet(s->pb, pkt, size); 00291 if (ret < 0) 00292 return ret; 00293 pkt->stream_index = 0; 00294 00295 return ret; 00296 } 00297 00298 static int wav_read_seek(AVFormatContext *s, 00299 int stream_index, int64_t timestamp, int flags) 00300 { 00301 AVStream *st; 00302 00303 st = s->streams[0]; 00304 switch (st->codec->codec_id) { 00305 case CODEC_ID_MP2: 00306 case CODEC_ID_MP3: 00307 case CODEC_ID_AC3: 00308 case CODEC_ID_DTS: 00309 /* use generic seeking with dynamically generated indexes */ 00310 return -1; 00311 default: 00312 break; 00313 } 00314 return pcm_read_seek(s, stream_index, timestamp, flags); 00315 } 00316 00317 AVInputFormat wav_demuxer = { 00318 "wav", 00319 NULL_IF_CONFIG_SMALL("WAV format"), 00320 sizeof(WAVContext), 00321 wav_probe, 00322 wav_read_header, 00323 wav_read_packet, 00324 NULL, 00325 wav_read_seek, 00326 .flags= AVFMT_GENERIC_INDEX, 00327 .codec_tag= (const AVCodecTag* const []){ff_codec_wav_tags, 0}, 00328 }; 00329 #endif /* CONFIG_WAV_DEMUXER */ 00330 00331 00332 #if CONFIG_W64_DEMUXER 00333 static const uint8_t guid_riff[16] = { 'r', 'i', 'f', 'f', 00334 0x2E, 0x91, 0xCF, 0x11, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 }; 00335 00336 static const uint8_t guid_wave[16] = { 'w', 'a', 'v', 'e', 00337 0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A }; 00338 00339 static const uint8_t guid_fmt [16] = { 'f', 'm', 't', ' ', 00340 0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A }; 00341 00342 static int w64_probe(AVProbeData *p) 00343 { 00344 if (p->buf_size <= 40) 00345 return 0; 00346 if (!memcmp(p->buf, guid_riff, 16) && 00347 !memcmp(p->buf + 24, guid_wave, 16)) 00348 return AVPROBE_SCORE_MAX; 00349 else 00350 return 0; 00351 } 00352 00353 static int w64_read_header(AVFormatContext *s, AVFormatParameters *ap) 00354 { 00355 int64_t size; 00356 ByteIOContext *pb = s->pb; 00357 WAVContext *wav = s->priv_data; 00358 AVStream *st; 00359 uint8_t guid[16]; 00360 00361 get_buffer(pb, guid, 16); 00362 if (memcmp(guid, guid_riff, 16)) 00363 return -1; 00364 00365 if (get_le64(pb) < 16 + 8 + 16 + 8 + 16 + 8) /* riff + wave + fmt + sizes */ 00366 return -1; 00367 00368 get_buffer(pb, guid, 16); 00369 if (memcmp(guid, guid_wave, 16)) { 00370 av_log(s, AV_LOG_ERROR, "could not find wave guid\n"); 00371 return -1; 00372 } 00373 00374 size = find_guid(pb, guid_fmt); 00375 if (size < 0) { 00376 av_log(s, AV_LOG_ERROR, "could not find fmt guid\n"); 00377 return -1; 00378 } 00379 00380 st = av_new_stream(s, 0); 00381 if (!st) 00382 return AVERROR(ENOMEM); 00383 00384 /* subtract chunk header size - normal wav file doesn't count it */ 00385 ff_get_wav_header(pb, st->codec, size - 24); 00386 url_fskip(pb, FFALIGN(size, INT64_C(8)) - size); 00387 00388 st->need_parsing = AVSTREAM_PARSE_FULL; 00389 00390 av_set_pts_info(st, 64, 1, st->codec->sample_rate); 00391 00392 size = find_guid(pb, guid_data); 00393 if (size < 0) { 00394 av_log(s, AV_LOG_ERROR, "could not find data guid\n"); 00395 return -1; 00396 } 00397 wav->data_end = url_ftell(pb) + size - 24; 00398 wav->w64 = 1; 00399 00400 return 0; 00401 } 00402 00403 AVInputFormat w64_demuxer = { 00404 "w64", 00405 NULL_IF_CONFIG_SMALL("Sony Wave64 format"), 00406 sizeof(WAVContext), 00407 w64_probe, 00408 w64_read_header, 00409 wav_read_packet, 00410 NULL, 00411 wav_read_seek, 00412 .flags = AVFMT_GENERIC_INDEX, 00413 .codec_tag = (const AVCodecTag* const []){ff_codec_wav_tags, 0}, 00414 }; 00415 #endif /* CONFIG_W64_DEMUXER */