typefind: Add typefind function for H265
https://bugzilla.gnome.org/show_bug.cgi?id=708680
This commit is contained in:
parent
f8d8a56d7b
commit
ebaa714c9f
@ -2685,6 +2685,99 @@ h264_video_type_find (GstTypeFind * tf, gpointer unused)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*** video/x-h265 H265 elementary video stream ***/
|
||||||
|
|
||||||
|
static GstStaticCaps h265_video_caps =
|
||||||
|
GST_STATIC_CAPS ("video/x-h265,stream-format=byte-stream");
|
||||||
|
|
||||||
|
#define H265_VIDEO_CAPS gst_static_caps_get(&h265_video_caps)
|
||||||
|
|
||||||
|
#define H265_MAX_PROBE_LENGTH (128 * 1024) /* 128kB for HD should be enough. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
h265_video_type_find (GstTypeFind * tf, gpointer unused)
|
||||||
|
{
|
||||||
|
DataScanCtx c = { 0, NULL, 0 };
|
||||||
|
|
||||||
|
/* Stream consists of: a series of sync codes (00 00 00 01) followed
|
||||||
|
* by NALs
|
||||||
|
*/
|
||||||
|
gboolean seen_irap = FALSE;
|
||||||
|
gboolean seen_vps = FALSE;
|
||||||
|
gboolean seen_sps = FALSE;
|
||||||
|
gboolean seen_pps = FALSE;
|
||||||
|
int nut;
|
||||||
|
int good = 0;
|
||||||
|
int bad = 0;
|
||||||
|
|
||||||
|
while (c.offset < H265_MAX_PROBE_LENGTH) {
|
||||||
|
if (G_UNLIKELY (!data_scan_ctx_ensure_data (tf, &c, 5)))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (IS_MPEG_HEADER (c.data)) {
|
||||||
|
/* forbiden_zero_bit | nal_unit_type */
|
||||||
|
nut = c.data[3] & 0xfe;
|
||||||
|
|
||||||
|
/* if forbidden bit is different to 0 won't be h265 */
|
||||||
|
if (nut > 0x7e) {
|
||||||
|
bad++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
nut = nut >> 1;
|
||||||
|
|
||||||
|
/* if nuh_layer_id is not zero or nuh_temporal_id_plus1 is zero then
|
||||||
|
* it won't be h265 */
|
||||||
|
if ((c.data[3] & 0x01) || (c.data[4] & 0xf8) || !(c.data[4] & 0x07)) {
|
||||||
|
bad++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* collect statistics about the NAL types */
|
||||||
|
if ((nut >= 0 && nut <= 9) || (nut >= 16 && nut <= 21) || (nut >= 32
|
||||||
|
&& nut <= 40)) {
|
||||||
|
if (nut == 32)
|
||||||
|
seen_vps = TRUE;
|
||||||
|
else if (nut == 33)
|
||||||
|
seen_sps = TRUE;
|
||||||
|
else if (nut == 34)
|
||||||
|
seen_pps = TRUE;
|
||||||
|
else if (nut >= 16 || nut <= 21) {
|
||||||
|
/* BLA, IDR and CRA pictures are belongs to be IRAP picture */
|
||||||
|
/* we are not counting the reserved IRAP pictures (22 and 23) to good */
|
||||||
|
seen_irap = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
good++;
|
||||||
|
} else if ((nut >= 10 && nut <= 15) || (nut >= 22 && nut <= 31)
|
||||||
|
|| (nut >= 41 && nut <= 47)) {
|
||||||
|
/* reserved values are counting as bad */
|
||||||
|
bad++;
|
||||||
|
} else {
|
||||||
|
/* unspecified (48..63), application specific */
|
||||||
|
/* don't consider these as bad */
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
gst_type_find_suggest (tf, GST_TYPE_FIND_LIKELY, H265_VIDEO_CAPS);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
data_scan_ctx_advance (tf, &c, 5);
|
||||||
|
}
|
||||||
|
data_scan_ctx_advance (tf, &c, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
gst_type_find_suggest (tf, GST_TYPE_FIND_POSSIBLE, H265_VIDEO_CAPS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*** video/mpeg video stream ***/
|
/*** video/mpeg video stream ***/
|
||||||
|
|
||||||
static GstStaticCaps mpeg_video_caps = GST_STATIC_CAPS ("video/mpeg, "
|
static GstStaticCaps mpeg_video_caps = GST_STATIC_CAPS ("video/mpeg, "
|
||||||
@ -5365,6 +5458,8 @@ plugin_init (GstPlugin * plugin)
|
|||||||
h263_video_type_find, "h263,263", H263_VIDEO_CAPS, NULL, NULL);
|
h263_video_type_find, "h263,263", H263_VIDEO_CAPS, NULL, NULL);
|
||||||
TYPE_FIND_REGISTER (plugin, "video/x-h264", GST_RANK_PRIMARY,
|
TYPE_FIND_REGISTER (plugin, "video/x-h264", GST_RANK_PRIMARY,
|
||||||
h264_video_type_find, "h264,x264,264", H264_VIDEO_CAPS, NULL, NULL);
|
h264_video_type_find, "h264,x264,264", H264_VIDEO_CAPS, NULL, NULL);
|
||||||
|
TYPE_FIND_REGISTER (plugin, "video/x-h265", GST_RANK_PRIMARY,
|
||||||
|
h265_video_type_find, "h265,x265,265", H265_VIDEO_CAPS, NULL, NULL);
|
||||||
TYPE_FIND_REGISTER (plugin, "video/x-nuv", GST_RANK_SECONDARY, nuv_type_find,
|
TYPE_FIND_REGISTER (plugin, "video/x-nuv", GST_RANK_SECONDARY, nuv_type_find,
|
||||||
"nuv", NUV_CAPS, NULL, NULL);
|
"nuv", NUV_CAPS, NULL, NULL);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user