diff options
-rw-r--r-- | DOCS/man/en/options.rst | 12 | ||||
-rw-r--r-- | demux/demux_lavf.c | 95 |
2 files changed, 13 insertions, 94 deletions
diff --git a/DOCS/man/en/options.rst b/DOCS/man/en/options.rst index 386f0fdf76..02be5b86f4 100644 --- a/DOCS/man/en/options.rst +++ b/DOCS/man/en/options.rst @@ -627,15 +627,11 @@ OPTIONS ``--demuxer-lavf-format=<name>`` Force a specific libavformat demuxer. -``--demuxer-lavf-genpts-mode=<auto|lavf|builtin|no>`` +``--demuxer-lavf-genpts-mode=<no|lavf>`` Mode for deriving missing packet PTS values from packet DTS. ``lavf`` - enables libavformat's ``genpts`` option. ``builtin`` enables equivalent - code in mpv. ``auto`` will enable either lavf (normal playback) or builtin - (DVD playback) in correct-pts mode. The difference between them is that - the builtin code will not potentially read until EOF trying to derive the - PTS (which is very bad for DVD playback). On the other hand, builtin might - give up too early, which is why lavf is preferred normally. ``no`` disables - both. + enables libavformat's ``genpts`` option. ``no`` disables it. This used + to be enabled by default, but then it was deemed as not needed anymore. + Enabling this might help with timestamp problems, or make them worse. ``--demuxer-lavf-o=<key>=<value>[,<key>=<value>[,...]]`` Pass AVOptions to libavformat demuxer. diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c index 98efbc32f3..0e368cdf3d 100644 --- a/demux/demux_lavf.c +++ b/demux/demux_lavf.c @@ -65,7 +65,7 @@ const m_option_t lavfdopts_conf[] = { OPT_INTRANGE("probescore", lavfdopts.probescore, 0, 0, 100), OPT_STRING("cryptokey", lavfdopts.cryptokey, 0), OPT_CHOICE("genpts-mode", lavfdopts.genptsmode, 0, - ({"auto", 0}, {"lavf", 1}, {"builtin", 2}, {"no", 3})), + ({"lavf", 1}, {"no", 0})), OPT_STRING("o", lavfdopts.avopt, 0), {NULL, NULL, 0, 0, 0, 0, NULL} }; @@ -83,9 +83,6 @@ typedef struct lavf_priv { int num_streams; int cur_program; char *mime_type; - bool genpts_hack; - AVPacket *packets[MAX_PKT_QUEUE]; - int num_packets; } lavf_priv_t; struct format_hack { @@ -537,18 +534,8 @@ static int demux_open_lavf(demuxer_t *demuxer, enum demux_check check) if (lavfdopts->cryptokey) parse_cryptokey(avfc, lavfdopts->cryptokey); - if (matches_avinputformat_name(priv, "avi")) { - /* for avi libavformat returns the avi timestamps in .dts, - * some made-up stuff that's not really pts in .pts */ - } else { - int mode = lavfdopts->genptsmode; - if (mode == 0 && opts->correct_pts) - mode = demuxer->stream->uncached_type == STREAMTYPE_DVD ? 2 : 1; - if (mode == 1) - avfc->flags |= AVFMT_FLAG_GENPTS; - if (mode == 2) - priv->genpts_hack = true; - } + if (lavfdopts->genptsmode) + avfc->flags |= AVFMT_FLAG_GENPTS; if (opts->index_mode == 0) avfc->flags |= AVFMT_FLAG_IGNIDX; @@ -683,31 +670,21 @@ static int demux_open_lavf(demuxer_t *demuxer, enum demux_check check) return 0; } -static void seek_reset(demuxer_t *demux) -{ - lavf_priv_t *priv = demux->priv; - - for (int n = 0; n < priv->num_packets; n++) - talloc_free(priv->packets[n]); - priv->num_packets = 0; -} - static void destroy_avpacket(void *pkt) { av_free_packet(pkt); } -static int read_more_av_packets(demuxer_t *demux) +static int demux_lavf_fill_buffer(demuxer_t *demux) { lavf_priv_t *priv = demux->priv; - - if (priv->num_packets >= MAX_PKT_QUEUE) - return -1; + demux_packet_t *dp; + mp_msg(MSGT_DEMUX, MSGL_DBG2, "demux_lavf_fill_buffer()\n"); AVPacket *pkt = talloc(NULL, AVPacket); if (av_read_frame(priv->avfc, pkt) < 0) { talloc_free(pkt); - return -2; // eof + return 0; // eof } talloc_set_destructor(pkt, destroy_avpacket); @@ -715,10 +692,11 @@ static int read_more_av_packets(demuxer_t *demux) assert(pkt->stream_index >= 0 && pkt->stream_index < priv->num_streams); struct sh_stream *stream = priv->streams[pkt->stream_index]; + AVStream *st = priv->avfc->streams[pkt->stream_index]; if (!demuxer_stream_is_selected(demux, stream)) { talloc_free(pkt); - return 0; // skip + return 1; // don't signal EOF if skipping a packet } // If the packet has pointers to temporary fields that could be @@ -727,58 +705,6 @@ static int read_more_av_packets(demuxer_t *demux) if (av_dup_packet(pkt) < 0) abort(); - priv->packets[priv->num_packets++] = pkt; - talloc_steal(priv, pkt); - return 1; -} - -static int read_av_packet(demuxer_t *demux, AVPacket **pkt) -{ - lavf_priv_t *priv = demux->priv; - - if (priv->num_packets < 1) { - int r = read_more_av_packets(demux); - if (r <= 0) - return r; - } - - AVPacket *next = priv->packets[0]; - if (priv->genpts_hack && next->dts != AV_NOPTS_VALUE) { - int n = 1; - while (next->pts == AV_NOPTS_VALUE) { - while (n >= priv->num_packets) { - if (read_more_av_packets(demux) < 0) - goto end; // queue limit or EOF reached - just use as is - } - AVPacket *cur = priv->packets[n]; - if (cur->stream_index == next->stream_index) { - if (next->dts < cur->dts && cur->pts != cur->dts) - next->pts = cur->dts; - } - n++; - } - } - -end: - MP_TARRAY_REMOVE_AT(priv->packets, priv->num_packets, 0); - *pkt = next; - return 1; -} - -static int demux_lavf_fill_buffer(demuxer_t *demux) -{ - lavf_priv_t *priv = demux->priv; - demux_packet_t *dp; - mp_msg(MSGT_DEMUX, MSGL_DBG2, "demux_lavf_fill_buffer()\n"); - - AVPacket *pkt; - int r = read_av_packet(demux, &pkt); - if (r <= 0) - return r == 0; // don't signal EOF if skipping a packet - - AVStream *st = priv->avfc->streams[pkt->stream_index]; - struct sh_stream *stream = priv->streams[pkt->stream_index]; - dp = new_demux_packet_fromdata(pkt->data, pkt->size); dp->avpacket = talloc_steal(dp, pkt); @@ -813,8 +739,6 @@ static void demux_seek_lavf(demuxer_t *demuxer, float rel_seek_secs, int flags) mp_msg(MSGT_DEMUX, MSGL_DBG2, "demux_seek_lavf(%p, %f, %d)\n", demuxer, rel_seek_secs, flags); - seek_reset(demuxer); - if (flags & SEEK_ABSOLUTE) priv->last_pts = 0; else if (rel_seek_secs < 0) @@ -980,7 +904,6 @@ redo: avio_flush(priv->avfc->pb); av_seek_frame(priv->avfc, 0, stream_tell(demuxer->stream), AVSEEK_FLAG_BYTE); - seek_reset(demuxer); avio_flush(priv->avfc->pb); return DEMUXER_CTRL_OK; default: |