mirror of
https://github.com/mpv-player/mpv
synced 2025-01-11 09:29:29 +00:00
demux_lavf: workaround reading gif from unseekable streams
FFmpeg, being the pile of trash as usual, recently broke this. Add our own trash hack to trashily workaround this shit. Fixes: #7893
This commit is contained in:
parent
adbd28b1db
commit
06033df715
@ -148,6 +148,7 @@ struct format_hack {
|
||||
bool no_seek : 1;
|
||||
bool no_pcm_seek : 1;
|
||||
bool no_seek_on_no_duration : 1;
|
||||
bool readall_on_no_streamseek : 1;
|
||||
};
|
||||
|
||||
#define BLACKLIST(fmt) {fmt, .ignore = true}
|
||||
@ -186,6 +187,10 @@ static const struct format_hack format_hacks[] = {
|
||||
// reset timestamps, which causes all sorts of problems.
|
||||
{"ogg", .linearize_audio_ts = true, .use_stream_ids = true},
|
||||
|
||||
// At some point, FFmpeg lost the ability to read gif from unseekable
|
||||
// streams.
|
||||
{"gif", .readall_on_no_streamseek = true},
|
||||
|
||||
TEXTSUB("aqtitle"), TEXTSUB("jacosub"), TEXTSUB("microdvd"),
|
||||
TEXTSUB("mpl2"), TEXTSUB("mpsub"), TEXTSUB("pjs"), TEXTSUB("realtext"),
|
||||
TEXTSUB("sami"), TEXTSUB("srt"), TEXTSUB("stl"), TEXTSUB("subviewer"),
|
||||
@ -1020,6 +1025,20 @@ static int demux_open_lavf(demuxer_t *demuxer, enum demux_check check)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (priv->format_hack.readall_on_no_streamseek && priv->pb &&
|
||||
!priv->pb->seekable)
|
||||
{
|
||||
MP_VERBOSE(demuxer, "Non-seekable demuxer pre-read hack...\n");
|
||||
// Read incremental to avoid unnecessary large buffer sizes.
|
||||
int r = 0;
|
||||
for (int n = 16; n < 29; n++) {
|
||||
r = stream_peek(priv->stream, 1 << n);
|
||||
if (r < (1 << n))
|
||||
break;
|
||||
}
|
||||
MP_VERBOSE(demuxer, "...did read %d bytes.\n", r);
|
||||
}
|
||||
|
||||
if (avformat_open_input(&avfc, priv->filename, priv->avif, &dopts) < 0) {
|
||||
MP_ERR(demuxer, "avformat_open_input() failed\n");
|
||||
av_dict_free(&dopts);
|
||||
|
@ -611,11 +611,19 @@ int stream_read(stream_t *s, void *mem, int total)
|
||||
return total;
|
||||
}
|
||||
|
||||
// Read ahead so that at least forward_size bytes are readable ahead. Returns
|
||||
// the actual forward amount available (restricted by EOF or buffer limits).
|
||||
int stream_peek(stream_t *s, int forward_size)
|
||||
{
|
||||
while (stream_read_more(s, forward_size)) {}
|
||||
return s->buf_end - s->buf_cur;
|
||||
}
|
||||
|
||||
// Like stream_read(), but do not advance the current position. This may resize
|
||||
// the buffer to satisfy the read request.
|
||||
int stream_read_peek(stream_t *s, void *buf, int buf_size)
|
||||
{
|
||||
while (stream_read_more(s, buf_size)) {}
|
||||
stream_peek(s, buf_size);
|
||||
return ring_copy(s, buf, buf_size, s->buf_cur);
|
||||
}
|
||||
|
||||
|
@ -212,6 +212,7 @@ bool stream_seek_skip(stream_t *s, int64_t pos);
|
||||
bool stream_seek(stream_t *s, int64_t pos);
|
||||
int stream_read(stream_t *s, void *mem, int total);
|
||||
int stream_read_partial(stream_t *s, void *buf, int buf_size);
|
||||
int stream_peek(stream_t *s, int forward_size);
|
||||
int stream_read_peek(stream_t *s, void *buf, int buf_size);
|
||||
void stream_drop_buffers(stream_t *s);
|
||||
int64_t stream_get_size(stream_t *s);
|
||||
|
Loading…
Reference in New Issue
Block a user