diff --git a/gst/typefind/gsttypefindfunctions.c b/gst/typefind/gsttypefindfunctions.c index 93ddb63204..c7b46dc50f 100644 --- a/gst/typefind/gsttypefindfunctions.c +++ b/gst/typefind/gsttypefindfunctions.c @@ -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 * 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 good = 0; + int bad = 0; while (c.offset < H264_MAX_PROBE_LENGTH) { 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 */ /* if forbiden bit is different to 0 won't be h264 */ - if (nut > 0x1f) + if (nut > 0x1f) { + bad++; break; + } /* collect statistics about the NAL types */ - if (nut == 1) - stat_slice++; - else if (nut == 2) - stat_dpa++; - else if (nut == 3) - stat_dpb++; - else if (nut == 4) - stat_dpc++; - else if ((nut == 5) && (ref != 0)) - stat_idr++; - else if ((nut == 7) && (ref != 0)) - stat_sps++; - else if ((nut == 8) && (ref != 0)) - stat_pps++; + if ((nut >= 1 && nut <= 13) || nut == 19) { + if ((nut == 5 && ref == 0) || + ((nut == 6 || (nut >= 9 && nut <= 12)) && ref != 0)) { + bad++; + } else { + good++; + } + } else if (nut >= 14 && nut <= 33) { + /* reserved */ + /* Theoretically these are good, since if they exist in the + stream it merely means that a newer backwards-compatible + h.264 stream. But we should be identifying that separately. */ + bad++; + } else { + /* unspecified, application specific */ + /* don't consider these bad */ + } - if ((stat_slice > 4 || (stat_dpa > 4 && stat_dpb > 4 && stat_dpc > 4)) && - stat_idr >= 1 && stat_sps >= 1 && stat_pps >= 1) { + GST_DEBUG ("good %d bad %d", good, bad); + + if (good >= 10 && bad < 4) { gst_type_find_suggest (tf, GST_TYPE_FIND_LIKELY, H264_VIDEO_CAPS); return; } @@ -1921,6 +1922,11 @@ h264_video_type_find (GstTypeFind * tf, gpointer unused) } 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 ***/