mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
pbutils: Add codec-utility funtions to support H265
https://bugzilla.gnome.org/show_bug.cgi?id=708921
This commit is contained in:
parent
82ade7b1ea
commit
9ffaaddcbe
4 changed files with 273 additions and 0 deletions
|
@ -2007,6 +2007,12 @@ gst_codec_utils_h264_get_level
|
|||
gst_codec_utils_h264_caps_set_level_and_profile
|
||||
gst_codec_utils_h264_get_level_idc
|
||||
<SUBSECTION>
|
||||
gst_codec_utils_h265_get_profile
|
||||
gst_codec_utils_h265_get_tier
|
||||
gst_codec_utils_h265_get_level
|
||||
gst_codec_utils_h265_get_level_idc
|
||||
gst_codec_utils_h265_caps_set_level_tier_and_profile
|
||||
<SUBSECTION>
|
||||
gst_codec_utils_mpeg4video_get_profile
|
||||
gst_codec_utils_mpeg4video_get_level
|
||||
gst_codec_utils_mpeg4video_caps_set_level_and_profile
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
/* GStreamer base utils library codec-specific utility functions
|
||||
* Copyright (C) 2010 Arun Raghavan <arun.raghavan@collabora.co.uk>
|
||||
* 2013 Sreerenj Balachandran <sreerenj.balachandran@intel.com>
|
||||
* 2010 Collabora Multimedia
|
||||
* 2010 Nokia Corporation
|
||||
* 2013 Intel Corporation
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
|
@ -633,6 +635,250 @@ gst_codec_utils_h264_caps_set_level_and_profile (GstCaps * caps,
|
|||
return (level != NULL && profile != NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_codec_utils_h265_get_profile:
|
||||
* @profile_tier_level: Pointer to the profile_tier_level
|
||||
* structure for the stream.
|
||||
* @len: Length of the data available in @profile_tier_level
|
||||
*
|
||||
* Converts the profile indication (general_profile_idc) in the stream's
|
||||
* profile_level_tier structure into a string. The profile_tier_level is
|
||||
* expected to have the following format, as defined in the H.265
|
||||
* specification. The profile_tier_level is viewed as a bitstream here,
|
||||
* with bit 0 being the most significant bit of the first byte.
|
||||
*
|
||||
* <itemizedlist>
|
||||
* <listitem><para>Bit 0:1 - general_profile_space</para></listitem>
|
||||
* <listitem><para>Bit 2 - general_tier_flag</para></listitem>
|
||||
* <listitem><para>Bit 3:7 - general_profile_idc</para></listitem>
|
||||
* <listitem><para>Bit 8:39 - gernal_profile_compatibility_flags</para></listitem>
|
||||
* <listitem><para>Bit 40 - general_progressive_source_flag</para></listitem>
|
||||
* <listitem><para>Bit 41 - general_interlaced_source_flag</para></listitem>
|
||||
* <listitem><para>Bit 42 - general_non_packed_constraint_flag</para></listitem>
|
||||
* <listitem><para>Bit 43 - general_frame_only_constraint_flag</para></listitem>
|
||||
* <listitem><para>Bit 44:87 - general_reserved_zero_44bits</para></listitem>
|
||||
* <listitem><para>Bit 88:95 - general_level_idc</para></listitem>
|
||||
* </itemizedlist>
|
||||
*
|
||||
* Returns: The profile as a const string, or %NULL if there is an error.
|
||||
*
|
||||
* Since 1.4
|
||||
*/
|
||||
const gchar *
|
||||
gst_codec_utils_h265_get_profile (const guint8 * profile_tier_level, guint len)
|
||||
{
|
||||
const gchar *profile = NULL;
|
||||
gint gpcf1 = 0, gpcf2 = 0, gpcf3 = 0;
|
||||
gint profile_idc;
|
||||
|
||||
g_return_val_if_fail (profile_tier_level != NULL, NULL);
|
||||
|
||||
if (len < 2)
|
||||
return NULL;
|
||||
|
||||
GST_MEMDUMP ("ProfileTierLevel", profile_tier_level, len);
|
||||
|
||||
profile_idc = (profile_tier_level[0] & 0x1f);
|
||||
|
||||
gpcf1 = (profile_tier_level[1] & 0x40) >> 6;
|
||||
gpcf2 = (profile_tier_level[1] & 0x20) >> 5;
|
||||
gpcf3 = (profile_tier_level[1] & 0x10) >> 4;
|
||||
|
||||
if (profile_idc == 1 || gpcf1)
|
||||
profile = "main";
|
||||
else if (profile_idc == 2 || gpcf2)
|
||||
profile = "main-10";
|
||||
else if (profile_idc == 3 || gpcf3)
|
||||
profile = "main-still-picture";
|
||||
else
|
||||
profile = NULL;
|
||||
|
||||
return profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_codec_utils_h265_get_tier:
|
||||
* @profile_tier_level: Pointer to the profile_tier_level structure
|
||||
* for the stream.
|
||||
* @len: Length of the data available in @profile_tier_level.
|
||||
*
|
||||
* Converts the tier indication (general_tier_flag) in the stream's
|
||||
* profile_tier_level structure into a string. The profile_tier_level
|
||||
* is expected to have the same format as for gst_codec_utils_h264_get_profile().
|
||||
*
|
||||
* Returns: The tier as a const string, or %NULL if there is an error.
|
||||
*
|
||||
* Since 1.4
|
||||
*/
|
||||
const gchar *
|
||||
gst_codec_utils_h265_get_tier (const guint8 * profile_tier_level, guint len)
|
||||
{
|
||||
const gchar *tier = NULL;
|
||||
gint tier_flag = 0;
|
||||
|
||||
g_return_val_if_fail (profile_tier_level != NULL, NULL);
|
||||
|
||||
if (len < 1)
|
||||
return NULL;
|
||||
|
||||
GST_MEMDUMP ("ProfileTierLevel", profile_tier_level, len);
|
||||
|
||||
tier_flag = (profile_tier_level[0] & 0x20) >> 5;
|
||||
|
||||
if (tier_flag)
|
||||
tier = "high";
|
||||
else
|
||||
tier = "main";
|
||||
|
||||
return tier;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_codec_utils_h265_get_level:
|
||||
* @profile_tier_level: Pointer to the profile_tier_level structure
|
||||
* for the stream
|
||||
* @len: Length of the data available in @profile_tier_level.
|
||||
*
|
||||
* Converts the level indication (general_level_idc) in the stream's
|
||||
* profile_tier_level structure into a string. The profiel_tier_level is
|
||||
* expected to have the same format as for gst_codec_utils_h264_get_profile().
|
||||
*
|
||||
* Returns: The level as a const string, or %NULL if there is an error.
|
||||
*
|
||||
* Since 1.4
|
||||
*/
|
||||
const gchar *
|
||||
gst_codec_utils_h265_get_level (const guint8 * profile_tier_level, guint len)
|
||||
{
|
||||
g_return_val_if_fail (profile_tier_level != NULL, NULL);
|
||||
|
||||
if (len < 12)
|
||||
return NULL;
|
||||
|
||||
GST_MEMDUMP ("ProfileTierLevel", profile_tier_level, len);
|
||||
|
||||
if (profile_tier_level[11] % 30 == 0)
|
||||
return digit_to_string (profile_tier_level[11] / 30);
|
||||
else {
|
||||
switch (profile_tier_level[11]) {
|
||||
case 63:
|
||||
return "2.1";
|
||||
break;
|
||||
case 93:
|
||||
return "3.1";
|
||||
break;
|
||||
case 123:
|
||||
return "4.1";
|
||||
break;
|
||||
case 153:
|
||||
return "5.1";
|
||||
break;
|
||||
case 156:
|
||||
return "5.2";
|
||||
break;
|
||||
case 183:
|
||||
return "6.1";
|
||||
break;
|
||||
case 186:
|
||||
return "6.2";
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_codec_utils_h265_get_level_idc:
|
||||
* @level: A level string from caps
|
||||
*
|
||||
* Transform a level string from the caps into the level_idc
|
||||
*
|
||||
* Returns: the level_idc or 0 if the level is unknown
|
||||
*
|
||||
* Since 1.4
|
||||
*/
|
||||
guint8
|
||||
gst_codec_utils_h265_get_level_idc (const gchar * level)
|
||||
{
|
||||
g_return_val_if_fail (level != NULL, 0);
|
||||
|
||||
if (!strcmp (level, "1"))
|
||||
return 30;
|
||||
else if (!strcmp (level, "2"))
|
||||
return 60;
|
||||
else if (!strcmp (level, "2.1"))
|
||||
return 63;
|
||||
else if (!strcmp (level, "3"))
|
||||
return 90;
|
||||
else if (!strcmp (level, "3.1"))
|
||||
return 93;
|
||||
else if (!strcmp (level, "4"))
|
||||
return 120;
|
||||
else if (!strcmp (level, "4.1"))
|
||||
return 123;
|
||||
else if (!strcmp (level, "5"))
|
||||
return 150;
|
||||
else if (!strcmp (level, "5.1"))
|
||||
return 153;
|
||||
else if (!strcmp (level, "5.2"))
|
||||
return 156;
|
||||
else if (!strcmp (level, "6"))
|
||||
return 180;
|
||||
else if (!strcmp (level, "6.1"))
|
||||
return 183;
|
||||
else if (!strcmp (level, "6.2"))
|
||||
return 186;
|
||||
|
||||
GST_WARNING ("Invalid level %s", level);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_codec_utils_h265_caps_set_level_tier_and_profile:
|
||||
* @caps: the #GstCaps to which the level, tier and profile are to be added
|
||||
* @profile_tier_level: Pointer to the profile_tier_level struct
|
||||
* @len: Length of the data available in @profile_tier_level.
|
||||
*
|
||||
* Sets the level, tier and profile in @caps if it can be determined from
|
||||
* @profile_tier_level. See gst_codec_utils_h265_get_level(),
|
||||
* gst_codec_utils_h265_get_tier() and gst_codec_utils_h265_get_profile()
|
||||
* for more details on the parameters.
|
||||
*
|
||||
* Returns: %TRUE if the level, tier, profile could be set, %FALSE otherwise.
|
||||
*
|
||||
* Since 1.4
|
||||
*/
|
||||
gboolean
|
||||
gst_codec_utils_h265_caps_set_level_tier_and_profile (GstCaps * caps,
|
||||
const guint8 * profile_tier_level, guint len)
|
||||
{
|
||||
const gchar *level, *tier, *profile;
|
||||
|
||||
g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
|
||||
g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), FALSE);
|
||||
g_return_val_if_fail (GST_SIMPLE_CAPS_HAS_NAME (caps, "video/x-h265"), FALSE);
|
||||
g_return_val_if_fail (profile_tier_level != NULL, FALSE);
|
||||
|
||||
level = gst_codec_utils_h265_get_level (profile_tier_level, len);
|
||||
if (level != NULL)
|
||||
gst_caps_set_simple (caps, "level", G_TYPE_STRING, level, NULL);
|
||||
|
||||
tier = gst_codec_utils_h265_get_tier (profile_tier_level, len);
|
||||
if (tier != NULL)
|
||||
gst_caps_set_simple (caps, "tier", G_TYPE_STRING, tier, NULL);
|
||||
|
||||
profile = gst_codec_utils_h265_get_profile (profile_tier_level, len);
|
||||
if (profile != NULL)
|
||||
gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, NULL);
|
||||
|
||||
GST_LOG ("profile : %s", (profile) ? profile : "---");
|
||||
GST_LOG ("tier : %s", (tier) ? tier : "---");
|
||||
GST_LOG ("level : %s", (level) ? level : "---");
|
||||
|
||||
return (level != NULL && tier != NULL && profile != NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_codec_utils_mpeg4video_get_profile:
|
||||
* @vis_obj_seq: Pointer to the visual object sequence for the stream.
|
||||
|
|
|
@ -51,6 +51,22 @@ gboolean gst_codec_utils_h264_caps_set_level_and_profile (GstCaps * ca
|
|||
const guint8 * sps,
|
||||
guint len);
|
||||
|
||||
/* H.265 */
|
||||
|
||||
const gchar * gst_codec_utils_h265_get_profile (const guint8 * profile_tier_level,
|
||||
guint len);
|
||||
|
||||
const gchar * gst_codec_utils_h265_get_tier (const guint8 * profile_tier_level,
|
||||
guint len);
|
||||
|
||||
const gchar * gst_codec_utils_h265_get_level (const guint8 * profile_tier_level,
|
||||
guint len);
|
||||
|
||||
guint8 gst_codec_utils_h265_get_level_idc (const gchar * level);
|
||||
|
||||
gboolean gst_codec_utils_h265_caps_set_level_tier_and_profile (GstCaps * caps,
|
||||
const guint8 * profile_tier_level,
|
||||
guint len);
|
||||
/* MPEG-4 part 2 */
|
||||
|
||||
const gchar * gst_codec_utils_mpeg4video_get_profile (const guint8 * vis_obj_seq, guint len);
|
||||
|
|
|
@ -8,6 +8,11 @@ EXPORTS
|
|||
gst_codec_utils_h264_get_level
|
||||
gst_codec_utils_h264_get_level_idc
|
||||
gst_codec_utils_h264_get_profile
|
||||
gst_codec_utils_h265_get_profile
|
||||
gst_codec_utils_h265_get_tier
|
||||
gst_codec_utils_h265_get_level
|
||||
gst_codec_utils_h265_get_level_idc
|
||||
gst_codec_utils_h265_caps_set_level_tier_and_profile
|
||||
gst_codec_utils_mpeg4video_caps_set_level_and_profile
|
||||
gst_codec_utils_mpeg4video_get_level
|
||||
gst_codec_utils_mpeg4video_get_profile
|
||||
|
|
Loading…
Reference in a new issue