summaryrefslogtreecommitdiffstats
path: root/demux
diff options
context:
space:
mode:
authorDudemanguy <random342@airmail.cc>2024-01-31 14:06:56 -0600
committerDudemanguy <random342@airmail.cc>2024-02-01 22:12:22 +0000
commit26a51464b68ce2571bdbe538da9c0a1c255b879f (patch)
treeea9effd23582fe80acd4b57c803a0017e1e57c84 /demux
parent289b3a432e010a155efbe255575abf16db3d1b71 (diff)
downloadmpv-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.c36
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;
}