mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 20:21:24 +00:00
typefind: Hold off making suggestions too early for MPEG based formats
By suggesting possible detection too early, it's possible that the wrong format is detected. Hold off making suggestions until one of the following conditions is met: * Probability > GST_TYPE_FIND_LIKELY * At least MPEG_MIN_PROBE_LENGTH bytes have been examined * EOS, in which case the best guess wins Fixes #628
This commit is contained in:
parent
8f125fb4d9
commit
36319169d0
1 changed files with 36 additions and 8 deletions
|
@ -2159,12 +2159,27 @@ static GstStaticCaps mpeg_sys_caps = GST_STATIC_CAPS ("video/mpeg, "
|
|||
#define IS_MPEG_PES_HEADER(data) (IS_MPEG_HEADER (data) && \
|
||||
IS_MPEG_PES_CODE (((guint8 *)(data))[3]))
|
||||
|
||||
#define MPEG_MIN_PROBE_LENGTH (4 * 1024) /* Examine at least 4kB of data to
|
||||
* give the various MPEG formats enough
|
||||
* data to avoid mis-detections. */
|
||||
|
||||
#define MPEG2_MAX_PROBE_LENGTH (128 * 1024) /* 128kB should be 64 packs of the
|
||||
* most common 2kB pack size. */
|
||||
|
||||
#define MPEG2_MIN_SYS_HEADERS 2
|
||||
#define MPEG2_MAX_SYS_HEADERS 5
|
||||
|
||||
static gboolean
|
||||
mpeg_should_suggest (GstTypeFind * tf, GstTypeFindProbability prob, guint size)
|
||||
{
|
||||
/* only suggest if we probed at least a certain amount of data, if
|
||||
* we have a high confindence, or when we reached eos. This gives
|
||||
* various MPEG based formats a better chance of correctly identifying
|
||||
* the data. */
|
||||
return prob > GST_TYPE_FIND_LIKELY || size >= MPEG_MIN_PROBE_LENGTH ||
|
||||
gst_type_find_is_eos (tf);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
mpeg_sys_is_valid_pack (GstTypeFind * tf, const guint8 * data, guint len,
|
||||
guint * pack_size)
|
||||
|
@ -2407,6 +2422,9 @@ suggest:
|
|||
if (data0 != first_sync && prob >= 10)
|
||||
prob -= 10;
|
||||
|
||||
if (!mpeg_should_suggest (tf, prob, end - data0))
|
||||
return;
|
||||
|
||||
GST_LOG ("Suggesting MPEG %d system stream, %d packs, %d pes, prob %u%%",
|
||||
mpegversion, pack_headers, pes_headers, prob);
|
||||
|
||||
|
@ -2505,6 +2523,9 @@ mpeg_ts_type_find (GstTypeFind * tf, gpointer unused)
|
|||
* found, 40% -> 100% */
|
||||
probability = MIN (10 * found, GST_TYPE_FIND_MAXIMUM);
|
||||
|
||||
if (!mpeg_should_suggest (tf, probability, size))
|
||||
return;
|
||||
|
||||
gst_type_find_suggest_simple (tf, probability, "video/mpegts",
|
||||
"systemstream", G_TYPE_BOOLEAN, TRUE,
|
||||
"packetsize", G_TYPE_INT, pack_sizes[p], NULL);
|
||||
|
@ -2664,7 +2685,8 @@ mpeg4_video_type_find (GstTypeFind * tf, gpointer unused)
|
|||
else if (seen_vos && seen_vol)
|
||||
probability = GST_TYPE_FIND_POSSIBLE - 20;
|
||||
|
||||
gst_type_find_suggest (tf, probability, MPEG4_VIDEO_CAPS);
|
||||
if (mpeg_should_suggest (tf, probability, c.size))
|
||||
gst_type_find_suggest (tf, probability, MPEG4_VIDEO_CAPS);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2807,7 +2829,8 @@ h264_video_type_find (GstTypeFind * tf, gpointer unused)
|
|||
GST_LOG ("good:%d, bad:%d, pps:%d, sps:%d, idr:%d ssps:%d", good, bad,
|
||||
seen_pps, seen_sps, seen_idr, seen_ssps);
|
||||
|
||||
if (seen_sps && seen_pps && seen_idr && good >= 10 && bad < 4) {
|
||||
if (seen_sps && seen_pps && seen_idr && good >= 10 && bad < 4
|
||||
&& mpeg_should_suggest (tf, GST_TYPE_FIND_LIKELY, c.size)) {
|
||||
gst_type_find_suggest (tf, GST_TYPE_FIND_LIKELY, H264_VIDEO_CAPS);
|
||||
return;
|
||||
}
|
||||
|
@ -2820,7 +2843,8 @@ h264_video_type_find (GstTypeFind * tf, gpointer unused)
|
|||
GST_LOG ("good:%d, bad:%d, pps:%d, sps:%d, idr:%d ssps=%d", good, bad,
|
||||
seen_pps, seen_sps, seen_idr, seen_ssps);
|
||||
|
||||
if (good >= 2 && bad == 0) {
|
||||
if (good >= 2 && bad == 0
|
||||
&& mpeg_should_suggest (tf, GST_TYPE_FIND_POSSIBLE, c.size)) {
|
||||
gst_type_find_suggest (tf, GST_TYPE_FIND_POSSIBLE, H264_VIDEO_CAPS);
|
||||
}
|
||||
}
|
||||
|
@ -2900,7 +2924,8 @@ h265_video_type_find (GstTypeFind * tf, gpointer unused)
|
|||
GST_LOG ("good:%d, bad:%d, pps:%d, sps:%d, vps:%d, irap:%d", good, bad,
|
||||
seen_pps, seen_sps, seen_vps, seen_irap);
|
||||
|
||||
if (seen_sps && seen_pps && seen_irap && good >= 10 && bad < 4) {
|
||||
if (seen_sps && seen_pps && seen_irap && good >= 10 && bad < 4
|
||||
&& mpeg_should_suggest (tf, GST_TYPE_FIND_LIKELY, c.size)) {
|
||||
gst_type_find_suggest (tf, GST_TYPE_FIND_LIKELY, H265_VIDEO_CAPS);
|
||||
return;
|
||||
}
|
||||
|
@ -2913,7 +2938,8 @@ h265_video_type_find (GstTypeFind * tf, gpointer unused)
|
|||
GST_LOG ("good:%d, bad:%d, pps:%d, sps:%d, vps:%d, irap:%d", good, bad,
|
||||
seen_pps, seen_sps, seen_vps, seen_irap);
|
||||
|
||||
if (good >= 2 && bad == 0) {
|
||||
if (good >= 2 && bad == 0
|
||||
&& mpeg_should_suggest (tf, GST_TYPE_FIND_POSSIBLE, c.size)) {
|
||||
gst_type_find_suggest (tf, GST_TYPE_FIND_POSSIBLE, H265_VIDEO_CAPS);
|
||||
}
|
||||
}
|
||||
|
@ -3020,9 +3046,11 @@ mpeg_video_stream_type_find (GstTypeFind * tf, gpointer unused)
|
|||
else if (seen_seq)
|
||||
probability = GST_TYPE_FIND_POSSIBLE - 20;
|
||||
|
||||
gst_type_find_suggest_simple (tf, probability, "video/mpeg",
|
||||
"systemstream", G_TYPE_BOOLEAN, FALSE,
|
||||
"mpegversion", G_TYPE_INT, 1, "parsed", G_TYPE_BOOLEAN, FALSE, NULL);
|
||||
if (mpeg_should_suggest (tf, probability, c.size)) {
|
||||
gst_type_find_suggest_simple (tf, probability, "video/mpeg",
|
||||
"systemstream", G_TYPE_BOOLEAN, FALSE,
|
||||
"mpegversion", G_TYPE_INT, 1, "parsed", G_TYPE_BOOLEAN, FALSE, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue