2 * Ogg bitstream support
3 * Luca Barbato <lu_zero@gentoo.org>
4 * Based on tcvp implementation
8 Copyright (C) 2005 Michael Ahlberg, Måns Rullgård
10 Permission is hereby granted, free of charge, to any person
11 obtaining a copy of this software and associated documentation
12 files (the "Software"), to deal in the Software without
13 restriction, including without limitation the rights to use, copy,
14 modify, merge, publish, distribute, sublicense, and/or sell copies
15 of the Software, and to permit persons to whom the Software is
16 furnished to do so, subject to the following conditions:
18 The above copyright notice and this permission notice shall be
19 included in all copies or substantial portions of the Software.
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28 DEALINGS IN THE SOFTWARE.
32 #include "libavutil/avassert.h"
33 #include "libavutil/intreadwrite.h"
34 #include "avio_internal.h"
38 #include "vorbiscomment.h"
40 #define MAX_PAGE_SIZE 65307
41 #define DECODER_BUFFER_SIZE MAX_PAGE_SIZE
43 static const struct ogg_codec * const ogg_codecs[] = {
63 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts);
64 static int ogg_new_stream(AVFormatContext *s, uint32_t serial);
65 static int ogg_restore(AVFormatContext *s);
67 static void free_stream(AVFormatContext *s, int i)
69 struct ogg *ogg = s->priv_data;
70 struct ogg_stream *stream = &ogg->streams[i];
72 av_freep(&stream->buf);
74 stream->codec->cleanup) {
75 stream->codec->cleanup(s, i);
78 av_freep(&stream->private);
79 av_freep(&stream->new_metadata);
82 //FIXME We could avoid some structure duplication
83 static int ogg_save(AVFormatContext *s)
85 struct ogg *ogg = s->priv_data;
86 struct ogg_state *ost =
87 av_malloc(sizeof(*ost) + (ogg->nstreams - 1) * sizeof(*ogg->streams));
92 return AVERROR(ENOMEM);
94 ost->pos = avio_tell(s->pb);
95 ost->curidx = ogg->curidx;
96 ost->next = ogg->state;
97 ost->nstreams = ogg->nstreams;
98 memcpy(ost->streams, ogg->streams, ogg->nstreams * sizeof(*ogg->streams));
100 for (i = 0; i < ogg->nstreams; i++) {
101 struct ogg_stream *os = ogg->streams + i;
102 os->buf = av_mallocz(os->bufsize + AV_INPUT_BUFFER_PADDING_SIZE);
104 memcpy(os->buf, ost->streams[i].buf, os->bufpos);
106 ret = AVERROR(ENOMEM);
107 os->new_metadata = NULL;
108 os->new_metadata_size = 0;
119 static int ogg_restore(AVFormatContext *s)
121 struct ogg *ogg = s->priv_data;
122 AVIOContext *bc = s->pb;
123 struct ogg_state *ost = ogg->state;
129 ogg->state = ost->next;
131 for (i = 0; i < ogg->nstreams; i++) {
132 struct ogg_stream *stream = &ogg->streams[i];
133 av_freep(&stream->buf);
134 av_freep(&stream->new_metadata);
136 if (i >= ost->nstreams || !ost->streams[i].private) {
141 avio_seek(bc, ost->pos, SEEK_SET);
143 ogg->curidx = ost->curidx;
144 ogg->nstreams = ost->nstreams;
145 if ((err = av_reallocp_array(&ogg->streams, ogg->nstreams,
146 sizeof(*ogg->streams))) < 0) {
150 memcpy(ogg->streams, ost->streams,
151 ost->nstreams * sizeof(*ogg->streams));
158 static int ogg_reset(AVFormatContext *s)
160 struct ogg *ogg = s->priv_data;
162 int64_t start_pos = avio_tell(s->pb);
164 for (i = 0; i < ogg->nstreams; i++) {
165 struct ogg_stream *os = ogg->streams + i;
170 os->lastpts = AV_NOPTS_VALUE;
171 os->lastdts = AV_NOPTS_VALUE;
178 if (start_pos <= s->internal->data_offset) {
181 os->end_trimming = 0;
182 av_freep(&os->new_metadata);
183 os->new_metadata_size = 0;
192 static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
196 for (i = 0; ogg_codecs[i]; i++)
197 if (size >= ogg_codecs[i]->magicsize &&
198 !memcmp(buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
199 return ogg_codecs[i];
205 * Replace the current stream with a new one. This is a typical webradio
206 * situation where a new audio stream spawn (identified with a new serial) and
207 * must replace the previous one (track switch).
209 static int ogg_replace_stream(AVFormatContext *s, uint32_t serial, int size)
211 struct ogg *ogg = s->priv_data;
212 struct ogg_stream *os;
213 const struct ogg_codec *codec;
216 if (s->pb->seekable & AVIO_SEEKABLE_NORMAL) {
218 avio_seek(s->pb, -size, SEEK_CUR);
219 if (avio_read(s->pb, magic, sizeof(magic)) != sizeof(magic))
220 return AVERROR_INVALIDDATA;
221 avio_seek(s->pb, size - sizeof(magic), SEEK_CUR);
222 codec = ogg_find_codec(magic, sizeof(magic));
224 av_log(s, AV_LOG_ERROR, "Cannot identify new stream\n");
225 return AVERROR_INVALIDDATA;
227 for (i = 0; i < ogg->nstreams; i++) {
228 if (ogg->streams[i].codec == codec)
231 if (i >= ogg->nstreams)
232 return ogg_new_stream(s, serial);
233 } else if (ogg->nstreams != 1) {
234 avpriv_report_missing_feature(s, "Changing stream parameters in multistream ogg");
235 return AVERROR_PATCHWELCOME;
238 os = &ogg->streams[i];
245 bufsize = os->bufsize;
248 if (!ogg->state || ogg->state->streams[i].private != os->private)
249 av_freep(&ogg->streams[i].private);
251 /* Set Ogg stream settings similar to what is done in ogg_new_stream(). We
252 * also re-use the ogg_stream allocated buffer */
253 memset(os, 0, sizeof(*os));
255 os->bufsize = bufsize;
264 static int ogg_new_stream(AVFormatContext *s, uint32_t serial)
266 struct ogg *ogg = s->priv_data;
267 int idx = ogg->nstreams;
269 struct ogg_stream *os;
273 av_log(s, AV_LOG_ERROR, "New streams are not supposed to be added "
274 "in between Ogg context save/restore operations.\n");
278 /* Allocate and init a new Ogg Stream */
279 if (av_size_mult(ogg->nstreams + 1, sizeof(*ogg->streams), &size) < 0 ||
280 !(os = av_realloc(ogg->streams, size)))
281 return AVERROR(ENOMEM);
283 os = ogg->streams + idx;
284 memset(os, 0, sizeof(*os));
286 os->bufsize = DECODER_BUFFER_SIZE;
287 os->buf = av_malloc(os->bufsize + AV_INPUT_BUFFER_PADDING_SIZE);
289 os->start_granule = OGG_NOGRANULE_VALUE;
291 return AVERROR(ENOMEM);
293 /* Create the associated AVStream */
294 st = avformat_new_stream(s, NULL);
297 return AVERROR(ENOMEM);
300 avpriv_set_pts_info(st, 64, 1, 1000000);
306 static int data_packets_seen(const struct ogg *ogg)
310 for (i = 0; i < ogg->nstreams; i++)
311 if (ogg->streams[i].got_data)
316 static int ogg_read_page(AVFormatContext *s, int *sid)
318 AVIOContext *bc = s->pb;
319 struct ogg *ogg = s->priv_data;
320 struct ogg_stream *os;
325 uint32_t crc, crc_tmp;
327 int64_t version, page_pos;
329 uint8_t segments[255];
330 uint8_t *readout_buf;
333 ret = avio_read(bc, sync, 4);
335 return ret < 0 ? ret : AVERROR_EOF;
340 if (sync[sp & 3] == 'O' &&
341 sync[(sp + 1) & 3] == 'g' &&
342 sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
345 if(!i && (bc->seekable & AVIO_SEEKABLE_NORMAL) && ogg->page_pos > 0) {
347 avio_seek(bc, ogg->page_pos+4, SEEK_SET);
357 } while (i++ < MAX_PAGE_SIZE);
359 if (i >= MAX_PAGE_SIZE) {
360 av_log(s, AV_LOG_INFO, "cannot find sync word\n");
361 return AVERROR_INVALIDDATA;
364 /* 0x4fa9b05f = av_crc(AV_CRC_32_IEEE, 0x0, "OggS", 4) */
365 ffio_init_checksum(bc, ff_crc04C11DB7_update, 0x4fa9b05f);
367 version = avio_r8(bc);
370 serial = avio_rl32(bc);
371 avio_skip(bc, 4); /* seq */
373 crc_tmp = ffio_get_checksum(bc);
375 crc_tmp = ff_crc04C11DB7_update(crc_tmp, (uint8_t[4]){0}, 4);
376 ffio_init_checksum(bc, ff_crc04C11DB7_update, crc_tmp);
379 page_pos = avio_tell(bc) - 27;
381 ret = avio_read(bc, segments, nsegs);
383 return ret < 0 ? ret : AVERROR_EOF;
385 for (i = 0; i < nsegs; i++)
388 idx = ogg_find_stream(ogg, serial);
390 os = ogg->streams + idx;
392 /* Even if invalid guarantee there's enough memory to read the page */
393 if (os->bufsize - os->bufpos < size) {
394 uint8_t *nb = av_realloc(os->buf, 2*os->bufsize + AV_INPUT_BUFFER_PADDING_SIZE);
396 return AVERROR(ENOMEM);
401 readout_buf = os->buf + os->bufpos;
403 readout_buf = av_malloc(size);
406 ret = avio_read(bc, readout_buf, size);
409 av_free(readout_buf);
410 return ret < 0 ? ret : AVERROR_EOF;
413 if (crc ^ ffio_get_checksum(bc)) {
414 av_log(s, AV_LOG_ERROR, "CRC mismatch!\n");
416 av_free(readout_buf);
417 avio_seek(bc, -size, SEEK_CUR);
421 /* Since we're almost sure its a valid packet, checking the version after
422 * the checksum lets the demuxer be more tolerant */
424 av_log(s, AV_LOG_ERROR, "Invalid Ogg vers!\n");
426 av_free(readout_buf);
427 avio_seek(bc, -size, SEEK_CUR);
431 /* CRC is correct so we can be 99% sure there's an actual change here */
433 if (data_packets_seen(ogg))
434 idx = ogg_replace_stream(s, serial, size);
436 idx = ogg_new_stream(s, serial);
439 av_log(s, AV_LOG_ERROR, "failed to create or replace stream\n");
440 av_free(readout_buf);
444 os = ogg->streams + idx;
446 memcpy(os->buf + os->bufpos, readout_buf, size);
447 av_free(readout_buf);
450 ogg->page_pos = page_pos;
451 os->page_pos = page_pos;
454 os->got_data = !(flags & OGG_FLAG_BOS);
458 memcpy(os->segments, segments, nsegs);
459 memset(os->buf + os->bufpos, 0, AV_INPUT_BUFFER_PADDING_SIZE);
461 if (flags & OGG_FLAG_CONT || os->incomplete) {
463 // If this is the very first segment we started
464 // playback in the middle of a continuation packet.
465 // Discard it since we missed the start of it.
466 while (os->segp < os->nsegs) {
467 int seg = os->segments[os->segp++];
472 os->sync_pos = os->page_pos;
476 os->sync_pos = os->page_pos;
479 /* This function is always called with sid != NULL */
486 * @brief find the next Ogg packet
487 * @param *sid is set to the stream for the packet or -1 if there is
488 * no matching stream, in that case assume all other return
489 * values to be uninitialized.
490 * @return negative value on error or EOF.
492 static int ogg_packet(AVFormatContext *s, int *sid, int *dstart, int *dsize,
495 struct ogg *ogg = s->priv_data;
497 struct ogg_stream *os;
499 int segp = 0, psize = 0;
501 av_log(s, AV_LOG_TRACE, "ogg_packet: curidx=%i\n", ogg->curidx);
509 ret = ogg_read_page(s, &idx);
514 os = ogg->streams + idx;
516 av_log(s, AV_LOG_TRACE, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
517 idx, os->pstart, os->psize, os->segp, os->nsegs);
520 if (os->header < 0) {
521 os->codec = ogg_find_codec(os->buf, os->bufpos);
523 av_log(s, AV_LOG_WARNING, "Codec not found\n");
535 while (os->segp < os->nsegs) {
536 int ss = os->segments[os->segp++];
544 if (!complete && os->segp == os->nsegs) {
546 // Do not set incomplete for empty packets.
547 // Together with the code in ogg_read_page
548 // that discards all continuation of empty packets
549 // we would get an infinite loop.
550 os->incomplete = !!os->psize;
555 if (os->granule == -1)
556 av_log(s, AV_LOG_WARNING,
557 "Page at %"PRId64" is missing granule\n",
564 if ((ret = os->codec->header(s, idx)) < 0) {
565 av_log(s, AV_LOG_ERROR, "Header processing failed: %s\n", av_err2str(ret));
573 // We have reached the first non-header packet in this stream.
574 // Unfortunately more header packets may still follow for others,
575 // but if we continue with header parsing we may lose data packets.
578 // Update the header state for all streams and
579 // compute the data_offset.
580 if (!s->internal->data_offset)
581 s->internal->data_offset = os->sync_pos;
583 for (i = 0; i < ogg->nstreams; i++) {
584 struct ogg_stream *cur_os = ogg->streams + i;
586 // if we have a partial non-header packet, its start is
587 // obviously at or after the data start
588 if (cur_os->incomplete)
589 s->internal->data_offset = FFMIN(s->internal->data_offset, cur_os->sync_pos);
593 os->pstart += os->psize;
599 if (os->codec && os->codec->packet) {
600 if ((ret = os->codec->packet(s, idx)) < 0) {
601 av_log(s, AV_LOG_ERROR, "Packet processing failed: %s\n", av_err2str(ret));
608 *dstart = os->pstart;
612 *fpos = os->sync_pos;
613 os->pstart += os->psize;
615 if(os->pstart == os->bufpos)
616 os->bufpos = os->pstart = 0;
617 os->sync_pos = os->page_pos;
620 // determine whether there are more complete packets in this page
621 // if not, the page's granule will apply to this packet
623 for (i = os->segp; i < os->nsegs; i++)
624 if (os->segments[i] < 255) {
629 if (os->segp == os->nsegs)
635 static int ogg_get_length(AVFormatContext *s)
637 struct ogg *ogg = s->priv_data;
642 if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL))
646 if (s->duration != AV_NOPTS_VALUE)
649 size = avio_size(s->pb);
652 end = size > MAX_PAGE_SIZE ? size - MAX_PAGE_SIZE : 0;
657 avio_seek(s->pb, end, SEEK_SET);
660 while (!ogg_read_page(s, &i)) {
661 if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
662 ogg->streams[i].codec) {
663 s->streams[i]->duration =
664 ogg_gptopts(s, i, ogg->streams[i].granule, NULL);
665 if (s->streams[i]->start_time != AV_NOPTS_VALUE) {
666 s->streams[i]->duration -= s->streams[i]->start_time;
667 streams_left-= (ogg->streams[i].got_start==-1);
668 ogg->streams[i].got_start= 1;
669 } else if(!ogg->streams[i].got_start) {
670 ogg->streams[i].got_start= -1;
682 avio_seek (s->pb, s->internal->data_offset, SEEK_SET);
684 while (streams_left > 0 && !ogg_packet(s, &i, NULL, NULL, NULL)) {
687 pts = ogg_calc_pts(s, i, NULL);
688 if (s->streams[i]->duration == AV_NOPTS_VALUE)
690 if (pts != AV_NOPTS_VALUE && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
691 s->streams[i]->duration -= pts;
692 ogg->streams[i].got_start= 1;
694 }else if(s->streams[i]->start_time != AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
695 ogg->streams[i].got_start= 1;
704 static int ogg_read_close(AVFormatContext *s)
706 struct ogg *ogg = s->priv_data;
709 for (i = 0; i < ogg->nstreams; i++) {
715 av_freep(&ogg->streams);
719 static int ogg_read_header(AVFormatContext *s)
721 struct ogg *ogg = s->priv_data;
726 //linear headers seek from start
728 ret = ogg_packet(s, NULL, NULL, NULL, NULL);
733 } while (!ogg->headers);
734 av_log(s, AV_LOG_TRACE, "found headers\n");
736 for (i = 0; i < ogg->nstreams; i++) {
737 struct ogg_stream *os = ogg->streams + i;
739 if (ogg->streams[i].header < 0) {
740 av_log(s, AV_LOG_ERROR, "Header parsing failed for stream %d\n", i);
741 ogg->streams[i].codec = NULL;
742 av_freep(&ogg->streams[i].private);
743 } else if (os->codec && os->nb_header < os->codec->nb_header) {
744 av_log(s, AV_LOG_WARNING,
745 "Headers mismatch for stream %d: "
746 "expected %d received %d.\n",
747 i, os->codec->nb_header, os->nb_header);
748 if (s->error_recognition & AV_EF_EXPLODE) {
750 return AVERROR_INVALIDDATA;
753 if (os->start_granule != OGG_NOGRANULE_VALUE)
754 os->lastpts = s->streams[i]->start_time =
755 ogg_gptopts(s, i, os->start_granule, NULL);
758 //linear granulepos seek from end
759 ret = ogg_get_length(s);
768 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
770 struct ogg *ogg = s->priv_data;
771 struct ogg_stream *os = ogg->streams + idx;
772 int64_t pts = AV_NOPTS_VALUE;
775 *dts = AV_NOPTS_VALUE;
777 if (os->lastpts != AV_NOPTS_VALUE) {
779 os->lastpts = AV_NOPTS_VALUE;
781 if (os->lastdts != AV_NOPTS_VALUE) {
784 os->lastdts = AV_NOPTS_VALUE;
787 if (os->granule != -1LL) {
788 if (os->codec && os->codec->granule_is_start)
789 pts = ogg_gptopts(s, idx, os->granule, dts);
791 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
798 static void ogg_validate_keyframe(AVFormatContext *s, int idx, int pstart, int psize)
800 struct ogg *ogg = s->priv_data;
801 struct ogg_stream *os = ogg->streams + idx;
804 switch (s->streams[idx]->codecpar->codec_id) {
805 case AV_CODEC_ID_THEORA:
806 invalid = !!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 0x40);
808 case AV_CODEC_ID_VP8:
809 invalid = !!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 1);
812 os->pflags ^= AV_PKT_FLAG_KEY;
813 av_log(s, AV_LOG_WARNING, "Broken file, %skeyframe not correctly marked.\n",
814 (os->pflags & AV_PKT_FLAG_KEY) ? "" : "non-");
819 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
822 struct ogg_stream *os;
825 int64_t fpos, pts, dts;
827 if (s->io_repositioned) {
829 s->io_repositioned = 0;
835 ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
838 } while (idx < 0 || !s->streams[idx]);
841 os = ogg->streams + idx;
843 // pflags might not be set until after this
844 pts = ogg_calc_pts(s, idx, &dts);
845 ogg_validate_keyframe(s, idx, pstart, psize);
847 if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
849 os->keyframe_seek = 0;
852 ret = av_new_packet(pkt, psize);
855 pkt->stream_index = idx;
856 memcpy(pkt->data, os->buf + pstart, psize);
860 pkt->flags = os->pflags;
861 pkt->duration = os->pduration;
864 if (os->end_trimming) {
865 uint8_t *side_data = av_packet_new_side_data(pkt,
866 AV_PKT_DATA_SKIP_SAMPLES,
869 return AVERROR(ENOMEM);
870 AV_WL32(side_data + 4, os->end_trimming);
871 os->end_trimming = 0;
874 if (os->new_metadata) {
875 uint8_t *side_data = av_packet_new_side_data(pkt,
876 AV_PKT_DATA_METADATA_UPDATE,
877 os->new_metadata_size);
879 return AVERROR(ENOMEM);
881 memcpy(side_data, os->new_metadata, os->new_metadata_size);
882 av_freep(&os->new_metadata);
883 os->new_metadata_size = 0;
889 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
890 int64_t *pos_arg, int64_t pos_limit)
892 struct ogg *ogg = s->priv_data;
893 AVIOContext *bc = s->pb;
894 int64_t pts = AV_NOPTS_VALUE;
898 avio_seek(bc, *pos_arg, SEEK_SET);
901 while ( avio_tell(bc) <= pos_limit
902 && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) {
903 if (i == stream_index) {
904 struct ogg_stream *os = ogg->streams + stream_index;
905 // Do not trust the last timestamps of an ogm video
906 if ( (os->flags & OGG_FLAG_EOS)
907 && !(os->flags & OGG_FLAG_BOS)
908 && os->codec == &ff_ogm_video_codec)
910 pts = ogg_calc_pts(s, i, NULL);
911 ogg_validate_keyframe(s, i, pstart, psize);
912 if (os->pflags & AV_PKT_FLAG_KEY) {
914 } else if (os->keyframe_seek) {
915 // if we had a previous keyframe but no pts for it,
916 // return that keyframe with this pts value.
920 pts = AV_NOPTS_VALUE;
923 if (pts != AV_NOPTS_VALUE)
930 static int ogg_read_seek(AVFormatContext *s, int stream_index,
931 int64_t timestamp, int flags)
933 struct ogg *ogg = s->priv_data;
934 struct ogg_stream *os = ogg->streams + stream_index;
937 av_assert0(stream_index < ogg->nstreams);
938 // Ensure everything is reset even when seeking via
939 // the generated index.
942 // Try seeking to a keyframe first. If this fails (very possible),
943 // av_seek_frame will fall back to ignoring keyframes
944 if (s->streams[stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO
945 && !(flags & AVSEEK_FLAG_ANY))
946 os->keyframe_seek = 1;
948 ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
950 os = ogg->streams + stream_index;
952 os->keyframe_seek = 0;
956 static int ogg_probe(const AVProbeData *p)
958 if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
959 return AVPROBE_SCORE_MAX;
963 AVInputFormat ff_ogg_demuxer = {
965 .long_name = NULL_IF_CONFIG_SMALL("Ogg"),
966 .priv_data_size = sizeof(struct ogg),
967 .read_probe = ogg_probe,
968 .read_header = ogg_read_header,
969 .read_packet = ogg_read_packet,
970 .read_close = ogg_read_close,
971 .read_seek = ogg_read_seek,
972 .read_timestamp = ogg_read_timestamp,
974 .flags = AVFMT_GENERIC_INDEX | AVFMT_TS_DISCONT | AVFMT_NOBINSEARCH,