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: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1328>
This commit is contained in:
parent
626af12498
commit
4a93f6e651
@ -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,
|
return gst_h265_parser_insert_sei_internal (parser, nal_length_size, TRUE,
|
||||||
au, sei);
|
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;
|
||||||
|
}
|
||||||
|
@ -1808,5 +1808,8 @@ GstBuffer * gst_h265_parser_insert_sei_hevc (GstH265Parser * parser,
|
|||||||
GstBuffer * au,
|
GstBuffer * au,
|
||||||
GstMemory * sei);
|
GstMemory * sei);
|
||||||
|
|
||||||
|
GST_CODEC_PARSERS_API
|
||||||
|
GstH265Profile gst_h265_get_profile_from_sps (GstH265SPS * sps);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
#endif
|
#endif
|
||||||
|
@ -2194,7 +2194,8 @@ gst_h265_parse_update_src_caps (GstH265Parse * h265parse, GstCaps * caps)
|
|||||||
const gchar *profile, *tier, *level;
|
const gchar *profile, *tier, *level;
|
||||||
GstH265Profile p;
|
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);
|
profile = gst_h265_profile_to_string (p);
|
||||||
if (profile != NULL)
|
if (profile != NULL)
|
||||||
gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, NULL);
|
gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, NULL);
|
||||||
|
@ -331,6 +331,15 @@ set_format_range_fields (GstH265ProfileTierLevel * ptl,
|
|||||||
ptl->lower_bit_rate_constraint_flag = lower_bit_rate_constraint_flag;
|
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)
|
GST_START_TEST (test_h265_format_range_profiles_exact_match)
|
||||||
{
|
{
|
||||||
/* Test all the combinations from Table A.2 */
|
/* 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)
|
GST_START_TEST (test_h265_format_range_profiles_partial_match)
|
||||||
{
|
{
|
||||||
/* Test matching compatible profiles from non-standard bitstream */
|
/* Test matching compatible profiles from non-standard bitstream */
|
||||||
GstH265ProfileTierLevel ptl;
|
GstH265SPS sps;
|
||||||
|
GstH265ProfileTierLevel *ptl = &sps.profile_tier_level;
|
||||||
|
|
||||||
memset (&ptl, 0, sizeof (ptl));
|
memset (&sps, 0, sizeof (sps));
|
||||||
ptl.profile_idc = 4;
|
ptl->profile_idc = 4;
|
||||||
set_format_range_fields (&ptl, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1);
|
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), ==,
|
g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (ptl), ==,
|
||||||
GST_H265_PROFILE_MAIN_444);
|
GST_H265_PROFILE_MAIN_444);
|
||||||
|
|
||||||
ptl.profile_idc = 5;
|
ptl->profile_idc = 5;
|
||||||
/* wrong max_monochrome_constraint_flag, should still be compatible
|
/* wrong max_monochrome_constraint_flag, should still be compatible
|
||||||
with GST_H265_PROFILE_HIGH_THROUGHPUT_444_10 */
|
with GST_H265_PROFILE_HIGH_THROUGHPUT_444_10 */
|
||||||
set_format_range_fields (&ptl, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1);
|
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), ==,
|
g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (ptl), ==,
|
||||||
GST_H265_PROFILE_HIGH_THROUGHPUT_444_10);
|
GST_H265_PROFILE_HIGH_THROUGHPUT_444_10);
|
||||||
/* wrong max_12bit_constraint_flag, should still be compatible
|
/* wrong max_12bit_constraint_flag, should still be compatible
|
||||||
with GST_H265_PROFILE_HIGH_THROUGHPUT_444_14 */
|
with GST_H265_PROFILE_HIGH_THROUGHPUT_444_14 */
|
||||||
set_format_range_fields (&ptl, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1);
|
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), ==,
|
g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (ptl), ==,
|
||||||
GST_H265_PROFILE_HIGH_THROUGHPUT_444_14);
|
GST_H265_PROFILE_HIGH_THROUGHPUT_444_14);
|
||||||
/* wrong intra_constraint_flag, 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,
|
and GST_H265_PROFILE_HIGH_THROUGHPUT_444_16_INTRA are both compatible,
|
||||||
but GST_H265_PROFILE_HIGH_THROUGHPUT_444_16_INTRA should be chosen
|
but GST_H265_PROFILE_HIGH_THROUGHPUT_444_16_INTRA should be chosen
|
||||||
because of the higher priority. */
|
because of the higher priority. */
|
||||||
set_format_range_fields (&ptl, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0);
|
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), ==,
|
g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (ptl), ==,
|
||||||
GST_H265_PROFILE_HIGH_THROUGHPUT_444_16_INTRA);
|
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 */
|
/* 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);
|
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), ==,
|
g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (ptl), ==,
|
||||||
GST_H265_PROFILE_INVALID);
|
GST_H265_PROFILE_INVALID);
|
||||||
|
|
||||||
ptl.profile_idc = 7;
|
ptl->profile_idc = 7;
|
||||||
/* wrong max_monochrome_constraint_flag, and intra_constraint_flag,
|
/* wrong max_monochrome_constraint_flag, and intra_constraint_flag,
|
||||||
still compatible with GST_H265_PROFILE_SCALABLE_MAIN_10 */
|
still compatible with GST_H265_PROFILE_SCALABLE_MAIN_10 */
|
||||||
set_format_range_fields (&ptl, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1);
|
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), ==,
|
g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (ptl), ==,
|
||||||
GST_H265_PROFILE_SCALABLE_MAIN_10);
|
GST_H265_PROFILE_SCALABLE_MAIN_10);
|
||||||
|
|
||||||
ptl.profile_idc = 8;
|
ptl->profile_idc = 8;
|
||||||
/* wrong one_picture_only_constraint_flag, still compatible
|
/* wrong one_picture_only_constraint_flag, still compatible
|
||||||
with GST_H265_PROFILE_3D_MAIN */
|
with GST_H265_PROFILE_3D_MAIN */
|
||||||
set_format_range_fields (&ptl, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1);
|
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), ==,
|
g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (ptl), ==,
|
||||||
GST_H265_PROFILE_3D_MAIN);
|
GST_H265_PROFILE_3D_MAIN);
|
||||||
|
|
||||||
ptl.profile_idc = 9;
|
ptl->profile_idc = 9;
|
||||||
/* wrong one_picture_only_constraint_flag, still compatible
|
/* wrong one_picture_only_constraint_flag, still compatible
|
||||||
with GST_H265_PROFILE_SCREEN_EXTENDED_MAIN */
|
with GST_H265_PROFILE_SCREEN_EXTENDED_MAIN */
|
||||||
set_format_range_fields (&ptl, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1);
|
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), ==,
|
g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (ptl), ==,
|
||||||
GST_H265_PROFILE_SCREEN_EXTENDED_MAIN);
|
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
|
/* wrong max_10bit_constraint_flag, still compatible
|
||||||
with GST_H265_PROFILE_SCALABLE_MONOCHROME_16 */
|
with GST_H265_PROFILE_SCALABLE_MONOCHROME_16 */
|
||||||
set_format_range_fields (&ptl, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1);
|
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), ==,
|
g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (ptl), ==,
|
||||||
GST_H265_PROFILE_SCALABLE_MONOCHROME_16);
|
GST_H265_PROFILE_SCALABLE_MONOCHROME_16);
|
||||||
|
|
||||||
ptl.profile_idc = 11;
|
ptl->profile_idc = 11;
|
||||||
/* wrong max_12bit_constraint_flag and max_422chroma_constraint_flag,
|
/* wrong max_12bit_constraint_flag and max_422chroma_constraint_flag,
|
||||||
should be recognized as GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444_14 */
|
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);
|
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), ==,
|
g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (ptl), ==,
|
||||||
GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444_14);
|
GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444_14);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user