diff options
author | Dudemanguy <random342@airmail.cc> | 2024-01-31 14:06:56 -0600 |
---|---|---|
committer | Dudemanguy <random342@airmail.cc> | 2024-02-01 22:12:22 +0000 |
commit | 26a51464b68ce2571bdbe538da9c0a1c255b879f (patch) | |
tree | ea9effd23582fe80acd4b57c803a0017e1e57c84 /demux | |
parent | 289b3a432e010a155efbe255575abf16db3d1b71 (diff) | |
download | mpv-26a51464b68ce2571bdbe538da9c0a1c255b879f.tar.bz2 mpv-26a51464b68ce2571bdbe538da9c0a1c255b879f.tar.xz |
demux_mkv: detect images by reading blocks and timecodes
4709a94aec5b16534b1d6b0d6738caeaf692e9c9 along with some related commits
added a way to detect image codecs embedded into mkv streams that
weren't tagged with attached picture (arguably a broken file anyways,
but maybe not the worst thing to workaround). Unfortunately, this has
some false positives particularly with mjpeg playback. So, as usual,
revert and rewrite. Instead, we can probe the file and count blocks in
the stream. If the video stream has only 1 block and 1 timecode, then
assume it's a still image.
Diffstat (limited to 'demux')
-rw-r--r-- | demux/demux_mkv.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/demux/demux_mkv.c b/demux/demux_mkv.c index 40b9a1b0ad..98be0cf6d6 100644 --- a/demux/demux_mkv.c +++ b/demux/demux_mkv.c @@ -2002,6 +2002,41 @@ static int demux_mkv_open_sub(demuxer_t *demuxer, mkv_track_t *track) return 0; } +// Workaround for broken files that don't set attached_picture +static void probe_if_image(demuxer_t *demuxer) +{ + mkv_demuxer_t *mkv_d = demuxer->priv; + + for (int n = 0; n < mkv_d->num_tracks; n++) { + int video_blocks = 0; + mkv_track_t *track = mkv_d->tracks[n]; + struct sh_stream *sh = track->stream; + + if (!sh || sh->type != STREAM_VIDEO) + continue; + + int64_t timecode = -1; + // Arbitrary restriction on packet reading. + for (int i = 0; i < 100; i++) { + int ret = read_next_block_into_queue(demuxer); + if (ret == 1 && mkv_d->blocks[i].track == track) { + if (timecode != mkv_d->blocks[i].timecode) + ++video_blocks; + timecode = mkv_d->blocks[i].timecode; + } + // No need to read more + if (video_blocks > 1) + break; + } + + // Assume still image + if (video_blocks == 1) { + sh->still_image = true; + sh->image = true; + } + } +} + static void probe_x264_garbage(demuxer_t *demuxer) { mkv_demuxer_t *mkv_d = demuxer->priv; @@ -2254,6 +2289,7 @@ static int demux_mkv_open(demuxer_t *demuxer, enum demux_check check) if (mkv_d->opts->probe_duration) probe_last_timestamp(demuxer, start_pos); probe_x264_garbage(demuxer); + probe_if_image(demuxer); return 0; } |