diff options
author | David Schleef <ds@schleef.org> | 2010-01-19 13:33:06 -0800 |
---|---|---|
committer | David Schleef <ds@schleef.org> | 2010-01-19 13:37:12 -0800 |
commit | e432c8ebc21f7574203b46065a9ea2cea0412a74 (patch) | |
tree | c1ef2c9c37088e00c5f66a67602b6ddb7bbe3add | |
parent | ad399c806922a419713d50a97731ae3bc5fb8b6d (diff) |
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.
-rw-r--r-- | gst/typefind/gsttypefindfunctions.c | 56 |
1 files changed, 31 insertions, 25 deletions
diff --git a/gst/typefind/gsttypefindfunctions.c b/gst/typefind/gsttypefindfunctions.c index 93ddb632..c7b46dc5 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 ((stat_slice > 4 || (stat_dpa > 4 && stat_dpb > 4 && stat_dpc > 4)) && - stat_idr >= 1 && stat_sps >= 1 && stat_pps >= 1) { + 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 */ + } + + 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 ***/ |