demux_mkv: detect images by reading blocks and timecodes

4709a94aec 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.
This commit is contained in:
Dudemanguy 2024-01-31 14:06:56 -06:00
parent 289b3a432e
commit 26a51464b6
1 changed files with 36 additions and 0 deletions

View File

@ -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;
}