mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 03:35:21 +00:00
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
4 changed files with 141 additions and 31 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue