From: Haihao Xiang Date: Tue, 9 Jun 2020 02:10:12 +0000 (+0800) Subject: h265parse: recognize more HEVC extension streams X-Git-Tag: 1.19.3~507^2~1396 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4a93f6e651e8af3c23325d1745534a73ac4a8bcb;p=platform%2Fupstream%2Fgstreamer.git h265parse: recognize more HEVC extension streams There are streams which have the right general_profile_idc and general_profile_compatibility_flag, but don't have the right extension flags. We may try to use chroma_format_idc and bit_depth to recognize these streams. e.g. https://www.itu.int/wftp3/av-arch/jctvc-site/bitstream_exchange/draft_conformance/SCC/IBF_Disabled_A_MediaTek_2.zip Part-of: --- diff --git a/gst-libs/gst/codecparsers/gsth265parser.c b/gst-libs/gst/codecparsers/gsth265parser.c index 69166ca..121f844 100644 --- a/gst-libs/gst/codecparsers/gsth265parser.c +++ b/gst-libs/gst/codecparsers/gsth265parser.c @@ -4289,3 +4289,91 @@ gst_h265_parser_insert_sei_hevc (GstH265Parser * parser, guint8 nal_length_size, return gst_h265_parser_insert_sei_internal (parser, nal_length_size, TRUE, au, sei); } + +/** + * gst_h265_get_profile_from_sps: + * @sps: a #GstH265SPS + * + * Return the H265 profile from @sps. + * + * Returns: a #GstH265Profile + * Since: 1.20 + */ +GstH265Profile +gst_h265_get_profile_from_sps (GstH265SPS * sps) +{ + GstH265Profile p; + + p = gst_h265_profile_tier_level_get_profile (&sps->profile_tier_level); + + if (p == GST_H265_PROFILE_INVALID) { + GstH265ProfileTierLevel tmp_ptl = sps->profile_tier_level; + guint chroma_format_idc = sps->chroma_format_idc; + guint bit_depth_luma = sps->bit_depth_luma_minus8 + 8; + guint bit_depth_chroma = sps->bit_depth_chroma_minus8 + 8; + + /* Set the conformance indicators based on chroma_format_idc / bit_depth */ + switch (chroma_format_idc) { + case 0: + tmp_ptl.max_monochrome_constraint_flag = 1; + tmp_ptl.max_420chroma_constraint_flag = 1; + tmp_ptl.max_422chroma_constraint_flag = 1; + break; + + case 1: + tmp_ptl.max_monochrome_constraint_flag = 0; + tmp_ptl.max_420chroma_constraint_flag = 1; + tmp_ptl.max_422chroma_constraint_flag = 1; + break; + + case 2: + tmp_ptl.max_monochrome_constraint_flag = 0; + tmp_ptl.max_420chroma_constraint_flag = 0; + tmp_ptl.max_422chroma_constraint_flag = 1; + break; + + case 3: + tmp_ptl.max_monochrome_constraint_flag = 0; + tmp_ptl.max_420chroma_constraint_flag = 0; + tmp_ptl.max_422chroma_constraint_flag = 0; + break; + + default: + g_assert_not_reached (); + break; + } + + tmp_ptl.max_8bit_constraint_flag = 1; + tmp_ptl.max_10bit_constraint_flag = 1; + tmp_ptl.max_12bit_constraint_flag = 1; + tmp_ptl.max_14bit_constraint_flag = 1; + + if (bit_depth_luma > 8 || bit_depth_chroma > 8) + tmp_ptl.max_8bit_constraint_flag = 0; + + if (bit_depth_luma > 10 || bit_depth_chroma > 10) + tmp_ptl.max_10bit_constraint_flag = 0; + + if (bit_depth_luma > 12 || bit_depth_chroma > 12) + tmp_ptl.max_12bit_constraint_flag = 0; + + if (tmp_ptl.profile_idc == GST_H265_PROFILE_IDC_HIGH_THROUGHPUT + || tmp_ptl.profile_idc == GST_H265_PROFILE_IDC_SCREEN_CONTENT_CODING + || tmp_ptl.profile_idc == + GST_H265_PROFILE_IDC_SCALABLE_FORMAT_RANGE_EXTENSION + || tmp_ptl.profile_idc == + GST_H265_PROFILE_IDC_HIGH_THROUGHPUT_SCREEN_CONTENT_CODING_EXTENSION + || tmp_ptl.profile_compatibility_flag[5] + || tmp_ptl.profile_compatibility_flag[9] + || tmp_ptl.profile_compatibility_flag[10] + || tmp_ptl.profile_compatibility_flag[11]) { + if (bit_depth_luma > 14 || bit_depth_chroma > 14) + tmp_ptl.max_14bit_constraint_flag = 0; + } else + tmp_ptl.max_14bit_constraint_flag = 0; + + p = gst_h265_profile_tier_level_get_profile (&tmp_ptl); + } + + return p; +} diff --git a/gst-libs/gst/codecparsers/gsth265parser.h b/gst-libs/gst/codecparsers/gsth265parser.h index 073123d..8234761 100644 --- a/gst-libs/gst/codecparsers/gsth265parser.h +++ b/gst-libs/gst/codecparsers/gsth265parser.h @@ -1808,5 +1808,8 @@ GstBuffer * gst_h265_parser_insert_sei_hevc (GstH265Parser * parser, GstBuffer * au, GstMemory * sei); +GST_CODEC_PARSERS_API +GstH265Profile gst_h265_get_profile_from_sps (GstH265SPS * sps); + G_END_DECLS #endif diff --git a/gst/videoparsers/gsth265parse.c b/gst/videoparsers/gsth265parse.c index 58d3d24..9b9a899 100644 --- a/gst/videoparsers/gsth265parse.c +++ b/gst/videoparsers/gsth265parse.c @@ -2194,7 +2194,8 @@ gst_h265_parse_update_src_caps (GstH265Parse * h265parse, GstCaps * caps) const gchar *profile, *tier, *level; GstH265Profile p; - p = gst_h265_profile_tier_level_get_profile (&sps->profile_tier_level); + p = gst_h265_get_profile_from_sps (sps); + profile = gst_h265_profile_to_string (p); if (profile != NULL) gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, NULL); diff --git a/tests/check/libs/h265parser.c b/tests/check/libs/h265parser.c index 5676aea..449fe2f 100644 --- a/tests/check/libs/h265parser.c +++ b/tests/check/libs/h265parser.c @@ -331,6 +331,15 @@ set_format_range_fields (GstH265ProfileTierLevel * ptl, ptl->lower_bit_rate_constraint_flag = lower_bit_rate_constraint_flag; } +static void +set_chroma_idc_and_depth (GstH265SPS * sps, guint8 chroma_idc, + guint8 depth_luma, guint8 depth_chroma) +{ + sps->chroma_format_idc = chroma_idc; + sps->bit_depth_luma_minus8 = depth_luma - 8; + sps->bit_depth_chroma_minus8 = depth_chroma - 8; +} + GST_START_TEST (test_h265_format_range_profiles_exact_match) { /* Test all the combinations from Table A.2 */ @@ -508,72 +517,81 @@ GST_END_TEST; GST_START_TEST (test_h265_format_range_profiles_partial_match) { /* Test matching compatible profiles from non-standard bitstream */ - GstH265ProfileTierLevel ptl; + GstH265SPS sps; + GstH265ProfileTierLevel *ptl = &sps.profile_tier_level; - memset (&ptl, 0, sizeof (ptl)); - ptl.profile_idc = 4; - set_format_range_fields (&ptl, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1); - g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==, + memset (&sps, 0, sizeof (sps)); + ptl->profile_idc = 4; + set_format_range_fields (ptl, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1); + g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (ptl), ==, GST_H265_PROFILE_MAIN_444); - ptl.profile_idc = 5; + ptl->profile_idc = 5; /* wrong max_monochrome_constraint_flag, should still be compatible with GST_H265_PROFILE_HIGH_THROUGHPUT_444_10 */ - set_format_range_fields (&ptl, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1); - g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==, + set_format_range_fields (ptl, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1); + g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (ptl), ==, GST_H265_PROFILE_HIGH_THROUGHPUT_444_10); /* wrong max_12bit_constraint_flag, should still be compatible with GST_H265_PROFILE_HIGH_THROUGHPUT_444_14 */ - set_format_range_fields (&ptl, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1); - g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==, + set_format_range_fields (ptl, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1); + g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (ptl), ==, GST_H265_PROFILE_HIGH_THROUGHPUT_444_14); /* wrong intra_constraint_flag, GST_H265_PROFILE_HIGH_THROUGHPUT_444_14 and GST_H265_PROFILE_HIGH_THROUGHPUT_444_16_INTRA are both compatible, but GST_H265_PROFILE_HIGH_THROUGHPUT_444_16_INTRA should be chosen because of the higher priority. */ - set_format_range_fields (&ptl, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0); - g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==, + set_format_range_fields (ptl, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0); + g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (ptl), ==, GST_H265_PROFILE_HIGH_THROUGHPUT_444_16_INTRA); - ptl.profile_idc = 6; + ptl->profile_idc = 6; /* wrong max_12bit_constraint_flag, should not be compatible with any */ - set_format_range_fields (&ptl, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1); - g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==, + set_format_range_fields (ptl, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1); + g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (ptl), ==, GST_H265_PROFILE_INVALID); - ptl.profile_idc = 7; + ptl->profile_idc = 7; /* wrong max_monochrome_constraint_flag, and intra_constraint_flag, still compatible with GST_H265_PROFILE_SCALABLE_MAIN_10 */ - set_format_range_fields (&ptl, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1); - g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==, + set_format_range_fields (ptl, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1); + g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (ptl), ==, GST_H265_PROFILE_SCALABLE_MAIN_10); - ptl.profile_idc = 8; + ptl->profile_idc = 8; /* wrong one_picture_only_constraint_flag, still compatible with GST_H265_PROFILE_3D_MAIN */ - set_format_range_fields (&ptl, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1); - g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==, + set_format_range_fields (ptl, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1); + g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (ptl), ==, GST_H265_PROFILE_3D_MAIN); - ptl.profile_idc = 9; + ptl->profile_idc = 9; /* wrong one_picture_only_constraint_flag, still compatible with GST_H265_PROFILE_SCREEN_EXTENDED_MAIN */ - set_format_range_fields (&ptl, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1); - g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==, + set_format_range_fields (ptl, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1); + g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (ptl), ==, GST_H265_PROFILE_SCREEN_EXTENDED_MAIN); + /* wrong indications but have right chroma_format_idc and bit_depth in SPS, + should be recognized as GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_444 */ + set_format_range_fields (ptl, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1); + g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (ptl), ==, + GST_H265_PROFILE_INVALID); + set_chroma_idc_and_depth (&sps, 3, 8, 8); + g_assert_cmpuint (gst_h265_get_profile_from_sps (&sps), ==, + GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_444); - ptl.profile_idc = 10; + ptl->profile_idc = 10; /* wrong max_10bit_constraint_flag, still compatible with GST_H265_PROFILE_SCALABLE_MONOCHROME_16 */ - set_format_range_fields (&ptl, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1); - g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==, + set_format_range_fields (ptl, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1); + g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (ptl), ==, GST_H265_PROFILE_SCALABLE_MONOCHROME_16); - ptl.profile_idc = 11; + ptl->profile_idc = 11; /* wrong max_12bit_constraint_flag and max_422chroma_constraint_flag, should be recognized as GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444_14 */ - set_format_range_fields (&ptl, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1); - g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==, + set_format_range_fields (ptl, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1); + g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (ptl), ==, GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444_14); }