summaryrefslogtreecommitdiffstats
path: root/demux
diff options
context:
space:
mode:
Diffstat (limited to 'demux')
-rw-r--r--demux/demux_lavf.c43
-rw-r--r--demux/demux_mf.c6
-rw-r--r--demux/demux_mkv.c1
-rw-r--r--demux/demux_timeline.c1
-rw-r--r--demux/stheader.h1
5 files changed, 42 insertions, 10 deletions
diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c
index 71fb9fc289..c3eab80c4d 100644
--- a/demux/demux_lavf.c
+++ b/demux/demux_lavf.c
@@ -138,7 +138,6 @@ struct format_hack {
bool use_stream_ids : 1; // has a meaningful native stream IDs (export it)
bool fully_read : 1; // set demuxer.fully_read flag
bool detect_charset : 1; // format is a small text file, possibly not UTF8
- bool image_format : 1; // expected to contain exactly 1 frame
// Do not confuse player's position estimation (position is into external
// segment, with e.g. HLS, player knows about the playlist main file only).
bool clear_filepos : 1;
@@ -205,8 +204,6 @@ static const struct format_hack format_hacks[] = {
BLACKLIST("bin"),
// Useless, does not work with custom streams.
BLACKLIST("image2"),
- // Image demuxers ("<name>_pipe" is detected explicitly)
- {"image2pipe", .image_format = true},
{0}
};
@@ -528,11 +525,6 @@ static int lavf_check_file(demuxer_t *demuxer, enum demux_check check)
return -1;
}
- if (bstr_endswith0(bstr0(priv->avif->name), "_pipe")) {
- MP_VERBOSE(demuxer, "Assuming this is an image format.\n");
- priv->format_hack.image_format = true;
- }
-
if (lavfdopts->hacks)
priv->avif_flags = priv->avif->flags | priv->format_hack.if_flags;
@@ -655,6 +647,35 @@ static int dict_get_decimal(AVDictionary *dict, const char *entry, int def)
return def;
}
+// Detect if a stream is an image from the number of frames and duration.
+// Unlike checking only the codec, this doesn't detect videos with codecs
+// commonly used for images (e.g. mjpeg) as images, and can detect images in
+// codecs commonly used for videos. But for some video codecs and containers,
+// libavformat always returns 0/1 numbers of frames and 0 duration, so they
+// have to be hardcoded to never be considered images.
+static const int blacklisted_video_codecs[] =
+ {AV_CODEC_ID_AMV, AV_CODEC_ID_FLIC, AV_CODEC_ID_VMDVIDEO, 0};
+
+static const char *const blacklisted_formats[] = {"lavfi", "m4v", "vc1", NULL};
+
+static bool is_image(AVStream *st, int codec_id, const char *avifname)
+{
+ if (st->nb_frames > 1 || st->codec_info_nb_frames != 1 || st->duration > 10)
+ return false;
+
+ for (int i = 0; blacklisted_video_codecs[i]; i++) {
+ if (codec_id == blacklisted_video_codecs[i])
+ return false;
+ }
+
+ for (int i = 0; blacklisted_formats[i]; i++) {
+ if (strcmp(avifname, blacklisted_formats[i]) == 0)
+ return false;
+ }
+
+ return true;
+}
+
static void handle_new_stream(demuxer_t *demuxer, int i)
{
lavf_priv_t *priv = demuxer->priv;
@@ -714,8 +735,12 @@ static void handle_new_stream(demuxer_t *demuxer, int i)
sh->codec->disp_h = codec->height;
if (st->avg_frame_rate.num)
sh->codec->fps = av_q2d(st->avg_frame_rate);
- if (priv->format_hack.image_format)
+ if (sh->attached_picture ||
+ is_image(st, codec->codec_id, priv->avif->name)) {
+ MP_VERBOSE(demuxer, "Assuming this is an image format.\n");
+ sh->image = true;
sh->codec->fps = priv->mf_fps;
+ }
sh->codec->par_w = st->sample_aspect_ratio.num;
sh->codec->par_h = st->sample_aspect_ratio.den;
diff --git a/demux/demux_mf.c b/demux/demux_mf.c
index 40f94f4e4e..69fa0fa91c 100644
--- a/demux/demux_mf.c
+++ b/demux/demux_mf.c
@@ -381,8 +381,12 @@ static int demux_open_mf(demuxer_t *demuxer, enum demux_check check)
// create a new video stream header
struct sh_stream *sh = demux_alloc_sh_stream(STREAM_VIDEO);
- struct mp_codec_params *c = sh->codec;
+ if (mf->nr_of_files == 1) {
+ MP_VERBOSE(demuxer, "Assuming this is an image format.\n");
+ sh->image = true;
+ }
+ struct mp_codec_params *c = sh->codec;
c->codec = codec;
c->disp_w = 0;
c->disp_h = 0;
diff --git a/demux/demux_mkv.c b/demux/demux_mkv.c
index d07f8fe1e0..b0117f0b6d 100644
--- a/demux/demux_mkv.c
+++ b/demux/demux_mkv.c
@@ -1300,6 +1300,7 @@ static void add_coverart(struct demuxer *demuxer)
sh->attached_picture->pts = 0;
talloc_steal(sh, sh->attached_picture);
sh->attached_picture->keyframe = true;
+ sh->image = true;
}
sh->title = att->name;
demux_add_sh_stream(demuxer, sh);
diff --git a/demux/demux_timeline.c b/demux/demux_timeline.c
index 9b4a049aee..5572fb53bf 100644
--- a/demux/demux_timeline.c
+++ b/demux/demux_timeline.c
@@ -525,6 +525,7 @@ static void apply_meta(struct sh_stream *dst, struct sh_stream *src)
dst->missing_timestamps = src->missing_timestamps;
if (src->attached_picture)
dst->attached_picture = src->attached_picture;
+ dst->image = src->image;
}
// This is mostly for EDL user-defined metadata.
diff --git a/demux/stheader.h b/demux/stheader.h
index 6be3b16463..8d2129e05b 100644
--- a/demux/stheader.h
+++ b/demux/stheader.h
@@ -48,6 +48,7 @@ struct sh_stream {
bool dependent_track; // container dependent track flag
bool visual_impaired_track; // container flag
bool hearing_impaired_track;// container flag
+ bool image; // video stream is an image
bool still_image; // video stream contains still images
int hls_bitrate;