00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "libavutil/avassert.h"
00027 #include "libavutil/dict.h"
00028 #include "libavutil/log.h"
00029 #include "libavutil/mathematics.h"
00030 #include "libavutil/opt.h"
00031 #include "avformat.h"
00032 #include "internal.h"
00033 #include "avio_internal.h"
00034 #include "pcm.h"
00035 #include "riff.h"
00036 #include "avio.h"
00037 #include "metadata.h"
00038
00039 typedef struct {
00040 const AVClass *class;
00041 int64_t data;
00042 int64_t data_end;
00043 int64_t minpts;
00044 int64_t maxpts;
00045 int last_duration;
00046 int w64;
00047 int write_bext;
00048 int64_t smv_data_ofs;
00049 int smv_block_size;
00050 int smv_frames_per_jpeg;
00051 int smv_block;
00052 int smv_last_stream;
00053 int smv_eof;
00054 int audio_eof;
00055 int ignore_length;
00056 } WAVContext;
00057
00058 #if CONFIG_WAV_MUXER
00059 static inline void bwf_write_bext_string(AVFormatContext *s, const char *key, int maxlen)
00060 {
00061 AVDictionaryEntry *tag;
00062 int len = 0;
00063
00064 if (tag = av_dict_get(s->metadata, key, NULL, 0)) {
00065 len = strlen(tag->value);
00066 len = FFMIN(len, maxlen);
00067 avio_write(s->pb, tag->value, len);
00068 }
00069
00070 ffio_fill(s->pb, 0, maxlen - len);
00071 }
00072
00073 static void bwf_write_bext_chunk(AVFormatContext *s)
00074 {
00075 AVDictionaryEntry *tmp_tag;
00076 uint64_t time_reference = 0;
00077 int64_t bext = ff_start_tag(s->pb, "bext");
00078
00079 bwf_write_bext_string(s, "description", 256);
00080 bwf_write_bext_string(s, "originator", 32);
00081 bwf_write_bext_string(s, "originator_reference", 32);
00082 bwf_write_bext_string(s, "origination_date", 10);
00083 bwf_write_bext_string(s, "origination_time", 8);
00084
00085 if (tmp_tag = av_dict_get(s->metadata, "time_reference", NULL, 0))
00086 time_reference = strtoll(tmp_tag->value, NULL, 10);
00087 avio_wl64(s->pb, time_reference);
00088 avio_wl16(s->pb, 1);
00089
00090 if (tmp_tag = av_dict_get(s->metadata, "umid", NULL, 0)) {
00091 unsigned char umidpart_str[17] = {0};
00092 int i;
00093 uint64_t umidpart;
00094 int len = strlen(tmp_tag->value+2);
00095
00096 for (i = 0; i < len/16; i++) {
00097 memcpy(umidpart_str, tmp_tag->value + 2 + (i*16), 16);
00098 umidpart = strtoll(umidpart_str, NULL, 16);
00099 avio_wb64(s->pb, umidpart);
00100 }
00101 ffio_fill(s->pb, 0, 64 - i*8);
00102 } else
00103 ffio_fill(s->pb, 0, 64);
00104
00105 ffio_fill(s->pb, 0, 190);
00106
00107 if (tmp_tag = av_dict_get(s->metadata, "coding_history", NULL, 0))
00108 avio_put_str(s->pb, tmp_tag->value);
00109
00110 ff_end_tag(s->pb, bext);
00111 }
00112
00113 static int wav_write_header(AVFormatContext *s)
00114 {
00115 WAVContext *wav = s->priv_data;
00116 AVIOContext *pb = s->pb;
00117 int64_t fmt, fact;
00118
00119 ffio_wfourcc(pb, "RIFF");
00120 avio_wl32(pb, 0);
00121 ffio_wfourcc(pb, "WAVE");
00122
00123
00124 fmt = ff_start_tag(pb, "fmt ");
00125 if (ff_put_wav_header(pb, s->streams[0]->codec) < 0) {
00126 av_log(s, AV_LOG_ERROR, "%s codec not supported in WAVE format\n",
00127 s->streams[0]->codec->codec ? s->streams[0]->codec->codec->name : "NONE");
00128 return -1;
00129 }
00130 ff_end_tag(pb, fmt);
00131
00132 if (s->streams[0]->codec->codec_tag != 0x01
00133 && s->pb->seekable) {
00134 fact = ff_start_tag(pb, "fact");
00135 avio_wl32(pb, 0);
00136 ff_end_tag(pb, fact);
00137 }
00138
00139 if (wav->write_bext)
00140 bwf_write_bext_chunk(s);
00141
00142 avpriv_set_pts_info(s->streams[0], 64, 1, s->streams[0]->codec->sample_rate);
00143 wav->maxpts = wav->last_duration = 0;
00144 wav->minpts = INT64_MAX;
00145
00146
00147 wav->data = ff_start_tag(pb, "data");
00148
00149 avio_flush(pb);
00150
00151 return 0;
00152 }
00153
00154 static int wav_write_packet(AVFormatContext *s, AVPacket *pkt)
00155 {
00156 AVIOContext *pb = s->pb;
00157 WAVContext *wav = s->priv_data;
00158 avio_write(pb, pkt->data, pkt->size);
00159 if(pkt->pts != AV_NOPTS_VALUE) {
00160 wav->minpts = FFMIN(wav->minpts, pkt->pts);
00161 wav->maxpts = FFMAX(wav->maxpts, pkt->pts);
00162 wav->last_duration = pkt->duration;
00163 } else
00164 av_log(s, AV_LOG_ERROR, "wav_write_packet: NOPTS\n");
00165 return 0;
00166 }
00167
00168 static int wav_write_trailer(AVFormatContext *s)
00169 {
00170 AVIOContext *pb = s->pb;
00171 WAVContext *wav = s->priv_data;
00172 int64_t file_size;
00173
00174 avio_flush(pb);
00175
00176 if (s->pb->seekable) {
00177 ff_end_tag(pb, wav->data);
00178
00179
00180 file_size = avio_tell(pb);
00181 avio_seek(pb, 4, SEEK_SET);
00182 avio_wl32(pb, (uint32_t)(file_size - 8));
00183 avio_seek(pb, file_size, SEEK_SET);
00184
00185 avio_flush(pb);
00186
00187 if(s->streams[0]->codec->codec_tag != 0x01) {
00188
00189 int number_of_samples;
00190 number_of_samples = av_rescale(wav->maxpts - wav->minpts + wav->last_duration,
00191 s->streams[0]->codec->sample_rate * (int64_t)s->streams[0]->time_base.num,
00192 s->streams[0]->time_base.den);
00193 avio_seek(pb, wav->data-12, SEEK_SET);
00194 avio_wl32(pb, number_of_samples);
00195 avio_seek(pb, file_size, SEEK_SET);
00196 avio_flush(pb);
00197 }
00198 }
00199 return 0;
00200 }
00201
00202 #define OFFSET(x) offsetof(WAVContext, x)
00203 #define ENC AV_OPT_FLAG_ENCODING_PARAM
00204 static const AVOption options[] = {
00205 { "write_bext", "Write BEXT chunk.", OFFSET(write_bext), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, ENC },
00206 { NULL },
00207 };
00208
00209 static const AVClass wav_muxer_class = {
00210 .class_name = "WAV muxer",
00211 .item_name = av_default_item_name,
00212 .option = options,
00213 .version = LIBAVUTIL_VERSION_INT,
00214 };
00215
00216 AVOutputFormat ff_wav_muxer = {
00217 .name = "wav",
00218 .long_name = NULL_IF_CONFIG_SMALL("WAV / WAVE (Waveform Audio)"),
00219 .mime_type = "audio/x-wav",
00220 .extensions = "wav",
00221 .priv_data_size = sizeof(WAVContext),
00222 .audio_codec = AV_CODEC_ID_PCM_S16LE,
00223 .video_codec = AV_CODEC_ID_NONE,
00224 .write_header = wav_write_header,
00225 .write_packet = wav_write_packet,
00226 .write_trailer = wav_write_trailer,
00227 .flags = AVFMT_TS_NONSTRICT,
00228 .codec_tag = (const AVCodecTag* const []){ ff_codec_wav_tags, 0 },
00229 .priv_class = &wav_muxer_class,
00230 };
00231 #endif
00232
00233
00234 #if CONFIG_WAV_DEMUXER
00235
00236 static int64_t next_tag(AVIOContext *pb, uint32_t *tag)
00237 {
00238 *tag = avio_rl32(pb);
00239 return avio_rl32(pb);
00240 }
00241
00242
00243 static int64_t find_tag(AVIOContext *pb, uint32_t tag1)
00244 {
00245 unsigned int tag;
00246 int64_t size;
00247
00248 for (;;) {
00249 if (url_feof(pb))
00250 return -1;
00251 size = next_tag(pb, &tag);
00252 if (tag == tag1)
00253 break;
00254 avio_skip(pb, size);
00255 }
00256 return size;
00257 }
00258
00259 static int wav_probe(AVProbeData *p)
00260 {
00261
00262 if (p->buf_size <= 32)
00263 return 0;
00264 if (!memcmp(p->buf + 8, "WAVE", 4)) {
00265 if (!memcmp(p->buf, "RIFF", 4))
00266
00267
00268
00269
00270
00271 return AVPROBE_SCORE_MAX - 1;
00272 else if (!memcmp(p->buf, "RF64", 4) &&
00273 !memcmp(p->buf + 12, "ds64", 4))
00274 return AVPROBE_SCORE_MAX;
00275 }
00276 return 0;
00277 }
00278
00279 static void handle_stream_probing(AVStream *st)
00280 {
00281 if (st->codec->codec_id == AV_CODEC_ID_PCM_S16LE) {
00282 st->request_probe = AVPROBE_SCORE_MAX/2;
00283 st->probe_packets = FFMIN(st->probe_packets, 4);
00284 }
00285 }
00286
00287 static int wav_parse_fmt_tag(AVFormatContext *s, int64_t size, AVStream **st)
00288 {
00289 AVIOContext *pb = s->pb;
00290 int ret;
00291
00292
00293 *st = avformat_new_stream(s, NULL);
00294 if (!*st)
00295 return AVERROR(ENOMEM);
00296
00297 ret = ff_get_wav_header(pb, (*st)->codec, size);
00298 if (ret < 0)
00299 return ret;
00300 handle_stream_probing(*st);
00301
00302 (*st)->need_parsing = AVSTREAM_PARSE_FULL_RAW;
00303
00304 avpriv_set_pts_info(*st, 64, 1, (*st)->codec->sample_rate);
00305
00306 return 0;
00307 }
00308
00309 static inline int wav_parse_bext_string(AVFormatContext *s, const char *key,
00310 int length)
00311 {
00312 char temp[257];
00313 int ret;
00314
00315 av_assert0(length <= sizeof(temp));
00316 if ((ret = avio_read(s->pb, temp, length)) < 0)
00317 return ret;
00318
00319 temp[length] = 0;
00320
00321 if (strlen(temp))
00322 return av_dict_set(&s->metadata, key, temp, 0);
00323
00324 return 0;
00325 }
00326
00327 static int wav_parse_bext_tag(AVFormatContext *s, int64_t size)
00328 {
00329 char temp[131], *coding_history;
00330 int ret, x;
00331 uint64_t time_reference;
00332 int64_t umid_parts[8], umid_mask = 0;
00333
00334 if ((ret = wav_parse_bext_string(s, "description", 256)) < 0 ||
00335 (ret = wav_parse_bext_string(s, "originator", 32)) < 0 ||
00336 (ret = wav_parse_bext_string(s, "originator_reference", 32)) < 0 ||
00337 (ret = wav_parse_bext_string(s, "origination_date", 10)) < 0 ||
00338 (ret = wav_parse_bext_string(s, "origination_time", 8)) < 0)
00339 return ret;
00340
00341 time_reference = avio_rl64(s->pb);
00342 snprintf(temp, sizeof(temp), "%"PRIu64, time_reference);
00343 if ((ret = av_dict_set(&s->metadata, "time_reference", temp, 0)) < 0)
00344 return ret;
00345
00346
00347 if (avio_rl16(s->pb) >= 1) {
00348 for (x = 0; x < 8; x++)
00349 umid_mask |= umid_parts[x] = avio_rb64(s->pb);
00350
00351 if (umid_mask) {
00352
00353 if (umid_parts[4] == 0 && umid_parts[5] == 0 && umid_parts[6] == 0 && umid_parts[7] == 0) {
00354
00355 snprintf(temp, sizeof(temp), "0x%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64,
00356 umid_parts[0], umid_parts[1], umid_parts[2], umid_parts[3]);
00357 } else {
00358
00359 snprintf(temp, sizeof(temp), "0x%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64
00360 "%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64,
00361 umid_parts[0], umid_parts[1], umid_parts[2], umid_parts[3],
00362 umid_parts[4], umid_parts[5], umid_parts[6], umid_parts[7]);
00363 }
00364
00365 if ((ret = av_dict_set(&s->metadata, "umid", temp, 0)) < 0)
00366 return ret;
00367 }
00368
00369 avio_skip(s->pb, 190);
00370 } else
00371 avio_skip(s->pb, 254);
00372
00373 if (size > 602) {
00374
00375 size -= 602;
00376
00377 if (!(coding_history = av_malloc(size+1)))
00378 return AVERROR(ENOMEM);
00379
00380 if ((ret = avio_read(s->pb, coding_history, size)) < 0)
00381 return ret;
00382
00383 coding_history[size] = 0;
00384 if ((ret = av_dict_set(&s->metadata, "coding_history", coding_history,
00385 AV_DICT_DONT_STRDUP_VAL)) < 0)
00386 return ret;
00387 }
00388
00389 return 0;
00390 }
00391
00392 static const AVMetadataConv wav_metadata_conv[] = {
00393 {"description", "comment" },
00394 {"originator", "encoded_by" },
00395 {"origination_date", "date" },
00396 {"origination_time", "creation_time"},
00397 {0},
00398 };
00399
00400
00401 static int wav_read_header(AVFormatContext *s)
00402 {
00403 int64_t size, av_uninit(data_size);
00404 int64_t sample_count=0;
00405 int rf64;
00406 uint32_t tag, list_type;
00407 AVIOContext *pb = s->pb;
00408 AVStream *st = NULL;
00409 WAVContext *wav = s->priv_data;
00410 int ret, got_fmt = 0;
00411 int64_t next_tag_ofs, data_ofs = -1;
00412
00413 wav->smv_data_ofs = -1;
00414
00415
00416 tag = avio_rl32(pb);
00417
00418 rf64 = tag == MKTAG('R', 'F', '6', '4');
00419 if (!rf64 && tag != MKTAG('R', 'I', 'F', 'F'))
00420 return -1;
00421 avio_rl32(pb);
00422 tag = avio_rl32(pb);
00423 if (tag != MKTAG('W', 'A', 'V', 'E'))
00424 return -1;
00425
00426 if (rf64) {
00427 if (avio_rl32(pb) != MKTAG('d', 's', '6', '4'))
00428 return -1;
00429 size = avio_rl32(pb);
00430 if (size < 24)
00431 return -1;
00432 avio_rl64(pb);
00433 data_size = avio_rl64(pb);
00434 sample_count = avio_rl64(pb);
00435 if (data_size < 0 || sample_count < 0) {
00436 av_log(s, AV_LOG_ERROR, "negative data_size and/or sample_count in "
00437 "ds64: data_size = %"PRId64", sample_count = %"PRId64"\n",
00438 data_size, sample_count);
00439 return AVERROR_INVALIDDATA;
00440 }
00441 avio_skip(pb, size - 24);
00442
00443 }
00444
00445 for (;;) {
00446 AVStream *vst;
00447 size = next_tag(pb, &tag);
00448 next_tag_ofs = avio_tell(pb) + size;
00449
00450 if (url_feof(pb))
00451 break;
00452
00453 switch (tag) {
00454 case MKTAG('f', 'm', 't', ' '):
00455
00456 if (!got_fmt && (ret = wav_parse_fmt_tag(s, size, &st)) < 0) {
00457 return ret;
00458 } else if (got_fmt)
00459 av_log(s, AV_LOG_WARNING, "found more than one 'fmt ' tag\n");
00460
00461 got_fmt = 1;
00462 break;
00463 case MKTAG('d', 'a', 't', 'a'):
00464 if (!got_fmt) {
00465 av_log(s, AV_LOG_ERROR, "found no 'fmt ' tag before the 'data' tag\n");
00466 return AVERROR_INVALIDDATA;
00467 }
00468
00469 if (rf64) {
00470 next_tag_ofs = wav->data_end = avio_tell(pb) + data_size;
00471 } else {
00472 data_size = size;
00473 next_tag_ofs = wav->data_end = size ? next_tag_ofs : INT64_MAX;
00474 }
00475
00476 data_ofs = avio_tell(pb);
00477
00478
00479
00480
00481 if (!pb->seekable || (!rf64 && !size))
00482 goto break_loop;
00483 break;
00484 case MKTAG('f','a','c','t'):
00485 if (!sample_count)
00486 sample_count = avio_rl32(pb);
00487 break;
00488 case MKTAG('b','e','x','t'):
00489 if ((ret = wav_parse_bext_tag(s, size)) < 0)
00490 return ret;
00491 break;
00492 case MKTAG('S','M','V','0'):
00493 if (!got_fmt) {
00494 av_log(s, AV_LOG_ERROR, "found no 'fmt ' tag before the 'SMV0' tag\n");
00495 return AVERROR_INVALIDDATA;
00496 }
00497
00498 if (size != MKTAG('0','2','0','0')) {
00499 av_log(s, AV_LOG_ERROR, "Unknown SMV version found\n");
00500 goto break_loop;
00501 }
00502 av_log(s, AV_LOG_DEBUG, "Found SMV data\n");
00503 vst = avformat_new_stream(s, NULL);
00504 if (!vst)
00505 return AVERROR(ENOMEM);
00506 avio_r8(pb);
00507 vst->id = 1;
00508 vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
00509 vst->codec->codec_id = AV_CODEC_ID_MJPEG;
00510 vst->codec->width = avio_rl24(pb);
00511 vst->codec->height = avio_rl24(pb);
00512 size = avio_rl24(pb);
00513 wav->smv_data_ofs = avio_tell(pb) + (size - 5) * 3;
00514 avio_rl24(pb);
00515 wav->smv_block_size = avio_rl24(pb);
00516 avpriv_set_pts_info(vst, 32, 1, avio_rl24(pb));
00517 vst->duration = avio_rl24(pb);
00518 avio_rl24(pb);
00519 avio_rl24(pb);
00520 wav->smv_frames_per_jpeg = avio_rl24(pb);
00521 goto break_loop;
00522 case MKTAG('L', 'I', 'S', 'T'):
00523 list_type = avio_rl32(pb);
00524 if (size < 4) {
00525 av_log(s, AV_LOG_ERROR, "too short LIST tag\n");
00526 return AVERROR_INVALIDDATA;
00527 }
00528 switch (list_type) {
00529 case MKTAG('I', 'N', 'F', 'O'):
00530 if ((ret = ff_read_riff_info(s, size - 4)) < 0)
00531 return ret;
00532 }
00533 break;
00534 }
00535
00536
00537 if ((avio_size(pb) > 0 && next_tag_ofs >= avio_size(pb)) ||
00538 avio_seek(pb, next_tag_ofs, SEEK_SET) < 0) {
00539 break;
00540 }
00541 }
00542 break_loop:
00543 if (data_ofs < 0) {
00544 av_log(s, AV_LOG_ERROR, "no 'data' tag found\n");
00545 return AVERROR_INVALIDDATA;
00546 }
00547
00548 avio_seek(pb, data_ofs, SEEK_SET);
00549
00550 if (!sample_count && st->codec->channels && av_get_bits_per_sample(st->codec->codec_id))
00551 sample_count = (data_size<<3) / (st->codec->channels * (uint64_t)av_get_bits_per_sample(st->codec->codec_id));
00552 if (sample_count)
00553 st->duration = sample_count;
00554
00555 ff_metadata_conv_ctx(s, NULL, wav_metadata_conv);
00556 ff_metadata_conv_ctx(s, NULL, ff_riff_info_conv);
00557
00558 return 0;
00559 }
00560
00564 static int64_t find_guid(AVIOContext *pb, const uint8_t guid1[16])
00565 {
00566 uint8_t guid[16];
00567 int64_t size;
00568
00569 while (!url_feof(pb)) {
00570 avio_read(pb, guid, 16);
00571 size = avio_rl64(pb);
00572 if (size <= 24)
00573 return -1;
00574 if (!memcmp(guid, guid1, 16))
00575 return size;
00576 avio_skip(pb, FFALIGN(size, INT64_C(8)) - 24);
00577 }
00578 return -1;
00579 }
00580
00581 static const uint8_t guid_data[16] = { 'd', 'a', 't', 'a',
00582 0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A };
00583
00584 #define MAX_SIZE 4096
00585
00586 static int wav_read_packet(AVFormatContext *s,
00587 AVPacket *pkt)
00588 {
00589 int ret, size;
00590 int64_t left;
00591 AVStream *st;
00592 WAVContext *wav = s->priv_data;
00593
00594 if (wav->smv_data_ofs > 0) {
00595 int64_t audio_dts, video_dts;
00596 smv_retry:
00597 audio_dts = s->streams[0]->cur_dts;
00598 video_dts = s->streams[1]->cur_dts;
00599 if (audio_dts != AV_NOPTS_VALUE && video_dts != AV_NOPTS_VALUE) {
00600 audio_dts = av_rescale_q(audio_dts, s->streams[0]->time_base, AV_TIME_BASE_Q);
00601 video_dts = av_rescale_q(video_dts, s->streams[1]->time_base, AV_TIME_BASE_Q);
00602 wav->smv_last_stream = video_dts >= audio_dts;
00603 }
00604 wav->smv_last_stream = !wav->smv_last_stream;
00605 wav->smv_last_stream |= wav->audio_eof;
00606 wav->smv_last_stream &= !wav->smv_eof;
00607 if (wav->smv_last_stream) {
00608 uint64_t old_pos = avio_tell(s->pb);
00609 uint64_t new_pos = wav->smv_data_ofs +
00610 wav->smv_block * wav->smv_block_size;
00611 if (avio_seek(s->pb, new_pos, SEEK_SET) < 0) {
00612 ret = AVERROR_EOF;
00613 goto smv_out;
00614 }
00615 size = avio_rl24(s->pb);
00616 ret = av_get_packet(s->pb, pkt, size);
00617 if (ret < 0)
00618 goto smv_out;
00619 pkt->pos -= 3;
00620 pkt->pts = wav->smv_block * wav->smv_frames_per_jpeg;
00621 wav->smv_block++;
00622 pkt->stream_index = 1;
00623 smv_out:
00624 avio_seek(s->pb, old_pos, SEEK_SET);
00625 if (ret == AVERROR_EOF) {
00626 wav->smv_eof = 1;
00627 goto smv_retry;
00628 }
00629 return ret;
00630 }
00631 }
00632
00633 st = s->streams[0];
00634
00635 left = wav->data_end - avio_tell(s->pb);
00636 if (wav->ignore_length)
00637 left= INT_MAX;
00638 if (left <= 0){
00639 if (CONFIG_W64_DEMUXER && wav->w64)
00640 left = find_guid(s->pb, guid_data) - 24;
00641 else
00642 left = find_tag(s->pb, MKTAG('d', 'a', 't', 'a'));
00643 if (left < 0) {
00644 wav->audio_eof = 1;
00645 if (wav->smv_data_ofs > 0 && !wav->smv_eof)
00646 goto smv_retry;
00647 return AVERROR_EOF;
00648 }
00649 wav->data_end= avio_tell(s->pb) + left;
00650 }
00651
00652 size = MAX_SIZE;
00653 if (st->codec->block_align > 1) {
00654 if (size < st->codec->block_align)
00655 size = st->codec->block_align;
00656 size = (size / st->codec->block_align) * st->codec->block_align;
00657 }
00658 size = FFMIN(size, left);
00659 ret = av_get_packet(s->pb, pkt, size);
00660 if (ret < 0)
00661 return ret;
00662 pkt->stream_index = 0;
00663
00664 return ret;
00665 }
00666
00667 static int wav_read_seek(AVFormatContext *s,
00668 int stream_index, int64_t timestamp, int flags)
00669 {
00670 WAVContext *wav = s->priv_data;
00671 AVStream *st;
00672 wav->smv_eof = 0;
00673 wav->audio_eof = 0;
00674 if (wav->smv_data_ofs > 0) {
00675 int64_t smv_timestamp = timestamp;
00676 if (stream_index == 0)
00677 smv_timestamp = av_rescale_q(timestamp, s->streams[0]->time_base, s->streams[1]->time_base);
00678 else
00679 timestamp = av_rescale_q(smv_timestamp, s->streams[1]->time_base, s->streams[0]->time_base);
00680 wav->smv_block = smv_timestamp / wav->smv_frames_per_jpeg;
00681 }
00682
00683 st = s->streams[0];
00684 switch (st->codec->codec_id) {
00685 case AV_CODEC_ID_MP2:
00686 case AV_CODEC_ID_MP3:
00687 case AV_CODEC_ID_AC3:
00688 case AV_CODEC_ID_DTS:
00689
00690 return -1;
00691 default:
00692 break;
00693 }
00694 return ff_pcm_read_seek(s, stream_index, timestamp, flags);
00695 }
00696
00697 #define OFFSET(x) offsetof(WAVContext, x)
00698 #define DEC AV_OPT_FLAG_DECODING_PARAM
00699 static const AVOption demux_options[] = {
00700 { "ignore_length", "Ignore length", OFFSET(ignore_length), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, DEC },
00701 { NULL },
00702 };
00703
00704 static const AVClass wav_demuxer_class = {
00705 .class_name = "WAV demuxer",
00706 .item_name = av_default_item_name,
00707 .option = demux_options,
00708 .version = LIBAVUTIL_VERSION_INT,
00709 };
00710 AVInputFormat ff_wav_demuxer = {
00711 .name = "wav",
00712 .long_name = NULL_IF_CONFIG_SMALL("WAV / WAVE (Waveform Audio)"),
00713 .priv_data_size = sizeof(WAVContext),
00714 .read_probe = wav_probe,
00715 .read_header = wav_read_header,
00716 .read_packet = wav_read_packet,
00717 .read_seek = wav_read_seek,
00718 .flags = AVFMT_GENERIC_INDEX,
00719 .codec_tag = (const AVCodecTag* const []){ ff_codec_wav_tags, 0 },
00720 .priv_class = &wav_demuxer_class,
00721 };
00722 #endif
00723
00724
00725 #if CONFIG_W64_DEMUXER
00726 static const uint8_t guid_riff[16] = { 'r', 'i', 'f', 'f',
00727 0x2E, 0x91, 0xCF, 0x11, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 };
00728
00729 static const uint8_t guid_wave[16] = { 'w', 'a', 'v', 'e',
00730 0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A };
00731
00732 static const uint8_t guid_fmt [16] = { 'f', 'm', 't', ' ',
00733 0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A };
00734
00735 static int w64_probe(AVProbeData *p)
00736 {
00737 if (p->buf_size <= 40)
00738 return 0;
00739 if (!memcmp(p->buf, guid_riff, 16) &&
00740 !memcmp(p->buf + 24, guid_wave, 16))
00741 return AVPROBE_SCORE_MAX;
00742 else
00743 return 0;
00744 }
00745
00746 static int w64_read_header(AVFormatContext *s)
00747 {
00748 int64_t size;
00749 AVIOContext *pb = s->pb;
00750 WAVContext *wav = s->priv_data;
00751 AVStream *st;
00752 uint8_t guid[16];
00753 int ret;
00754
00755 avio_read(pb, guid, 16);
00756 if (memcmp(guid, guid_riff, 16))
00757 return -1;
00758
00759 if (avio_rl64(pb) < 16 + 8 + 16 + 8 + 16 + 8)
00760 return -1;
00761
00762 avio_read(pb, guid, 16);
00763 if (memcmp(guid, guid_wave, 16)) {
00764 av_log(s, AV_LOG_ERROR, "could not find wave guid\n");
00765 return -1;
00766 }
00767
00768 size = find_guid(pb, guid_fmt);
00769 if (size < 0) {
00770 av_log(s, AV_LOG_ERROR, "could not find fmt guid\n");
00771 return -1;
00772 }
00773
00774 st = avformat_new_stream(s, NULL);
00775 if (!st)
00776 return AVERROR(ENOMEM);
00777
00778
00779 ret = ff_get_wav_header(pb, st->codec, size - 24);
00780 if (ret < 0)
00781 return ret;
00782 avio_skip(pb, FFALIGN(size, INT64_C(8)) - size);
00783
00784 handle_stream_probing(st);
00785 st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
00786
00787 avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
00788
00789 size = find_guid(pb, guid_data);
00790 if (size < 0) {
00791 av_log(s, AV_LOG_ERROR, "could not find data guid\n");
00792 return -1;
00793 }
00794 wav->data_end = avio_tell(pb) + size - 24;
00795 wav->w64 = 1;
00796
00797 return 0;
00798 }
00799
00800 AVInputFormat ff_w64_demuxer = {
00801 .name = "w64",
00802 .long_name = NULL_IF_CONFIG_SMALL("Sony Wave64"),
00803 .priv_data_size = sizeof(WAVContext),
00804 .read_probe = w64_probe,
00805 .read_header = w64_read_header,
00806 .read_packet = wav_read_packet,
00807 .read_seek = wav_read_seek,
00808 .flags = AVFMT_GENERIC_INDEX,
00809 .codec_tag = (const AVCodecTag* const []){ ff_codec_wav_tags, 0 },
00810 };
00811 #endif