mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +00:00
typefind: rewrite h.264 detection
Make detection simpler: check for NALs, check that they make sense, and report how certain we are that it's a raw H.264 stream. Fixes: #583376.
This commit is contained in:
parent
ad399c8069
commit
e432c8ebc2
1 changed files with 30 additions and 24 deletions
|
@ -1874,14 +1874,9 @@ h264_video_type_find (GstTypeFind * tf, gpointer unused)
|
||||||
/* Stream consists of: a series of sync codes (00 00 00 01) followed
|
/* Stream consists of: a series of sync codes (00 00 00 01) followed
|
||||||
* by NALs
|
* by NALs
|
||||||
*/
|
*/
|
||||||
int stat_slice = 0;
|
|
||||||
int stat_dpa = 0;
|
|
||||||
int stat_dpb = 0;
|
|
||||||
int stat_dpc = 0;
|
|
||||||
int stat_idr = 0;
|
|
||||||
int stat_sps = 0;
|
|
||||||
int stat_pps = 0;
|
|
||||||
int nut, ref;
|
int nut, ref;
|
||||||
|
int good = 0;
|
||||||
|
int bad = 0;
|
||||||
|
|
||||||
while (c.offset < H264_MAX_PROBE_LENGTH) {
|
while (c.offset < H264_MAX_PROBE_LENGTH) {
|
||||||
if (G_UNLIKELY (!data_scan_ctx_ensure_data (tf, &c, 4)))
|
if (G_UNLIKELY (!data_scan_ctx_ensure_data (tf, &c, 4)))
|
||||||
|
@ -1892,27 +1887,33 @@ h264_video_type_find (GstTypeFind * tf, gpointer unused)
|
||||||
ref = c.data[3] & 0x60; /* nal_ref_idc */
|
ref = c.data[3] & 0x60; /* nal_ref_idc */
|
||||||
|
|
||||||
/* if forbiden bit is different to 0 won't be h264 */
|
/* if forbiden bit is different to 0 won't be h264 */
|
||||||
if (nut > 0x1f)
|
if (nut > 0x1f) {
|
||||||
|
bad++;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* collect statistics about the NAL types */
|
/* collect statistics about the NAL types */
|
||||||
if (nut == 1)
|
if ((nut >= 1 && nut <= 13) || nut == 19) {
|
||||||
stat_slice++;
|
if ((nut == 5 && ref == 0) ||
|
||||||
else if (nut == 2)
|
((nut == 6 || (nut >= 9 && nut <= 12)) && ref != 0)) {
|
||||||
stat_dpa++;
|
bad++;
|
||||||
else if (nut == 3)
|
} else {
|
||||||
stat_dpb++;
|
good++;
|
||||||
else if (nut == 4)
|
}
|
||||||
stat_dpc++;
|
} else if (nut >= 14 && nut <= 33) {
|
||||||
else if ((nut == 5) && (ref != 0))
|
/* reserved */
|
||||||
stat_idr++;
|
/* Theoretically these are good, since if they exist in the
|
||||||
else if ((nut == 7) && (ref != 0))
|
stream it merely means that a newer backwards-compatible
|
||||||
stat_sps++;
|
h.264 stream. But we should be identifying that separately. */
|
||||||
else if ((nut == 8) && (ref != 0))
|
bad++;
|
||||||
stat_pps++;
|
} else {
|
||||||
|
/* unspecified, application specific */
|
||||||
|
/* don't consider these bad */
|
||||||
|
}
|
||||||
|
|
||||||
if ((stat_slice > 4 || (stat_dpa > 4 && stat_dpb > 4 && stat_dpc > 4)) &&
|
GST_DEBUG ("good %d bad %d", good, bad);
|
||||||
stat_idr >= 1 && stat_sps >= 1 && stat_pps >= 1) {
|
|
||||||
|
if (good >= 10 && bad < 4) {
|
||||||
gst_type_find_suggest (tf, GST_TYPE_FIND_LIKELY, H264_VIDEO_CAPS);
|
gst_type_find_suggest (tf, GST_TYPE_FIND_LIKELY, H264_VIDEO_CAPS);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1921,6 +1922,11 @@ h264_video_type_find (GstTypeFind * tf, gpointer unused)
|
||||||
}
|
}
|
||||||
data_scan_ctx_advance (tf, &c, 1);
|
data_scan_ctx_advance (tf, &c, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (good >= 2 && bad < 1) {
|
||||||
|
gst_type_find_suggest (tf, GST_TYPE_FIND_POSSIBLE, H264_VIDEO_CAPS);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** video/mpeg video stream ***/
|
/*** video/mpeg video stream ***/
|
||||||
|
|
Loading…
Reference in a new issue