diff options
author | Sreerenj Balachandran <sreerenj.balachandran@intel.com> | 2013-10-02 12:26:59 +0300 |
---|---|---|
committer | Sebastian Dröge <slomo@circular-chaos.org> | 2013-10-02 11:37:39 +0200 |
commit | 9ffaaddcbe71a38c37a14175942729664f4bf005 (patch) | |
tree | 7346b4b386f99670b772d600cf2ec5ac616f77d2 | |
parent | 82ade7b1ea5299e57f2da91fa7f244d65bd8ef7f (diff) |
pbutils: Add codec-utility funtions to support H265
https://bugzilla.gnome.org/show_bug.cgi?id=708921
-rw-r--r-- | docs/libs/gst-plugins-base-libs-sections.txt | 6 | ||||
-rw-r--r-- | gst-libs/gst/pbutils/codec-utils.c | 246 | ||||
-rw-r--r-- | gst-libs/gst/pbutils/codec-utils.h | 16 | ||||
-rw-r--r-- | win32/common/libgstpbutils.def | 5 |
4 files changed, 273 insertions, 0 deletions
diff --git a/docs/libs/gst-plugins-base-libs-sections.txt b/docs/libs/gst-plugins-base-libs-sections.txt index 35d9cb630..32ca50c1a 100644 --- a/docs/libs/gst-plugins-base-libs-sections.txt +++ b/docs/libs/gst-plugins-base-libs-sections.txt @@ -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 diff --git a/gst-libs/gst/pbutils/codec-utils.c b/gst-libs/gst/pbutils/codec-utils.c index a34b3bc5e..517bbb2ab 100644 --- a/gst-libs/gst/pbutils/codec-utils.c +++ b/gst-libs/gst/pbutils/codec-utils.c @@ -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 @@ -634,6 +636,250 @@ gst_codec_utils_h264_caps_set_level_and_profile (GstCaps * caps, } /** + * 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. * @len: Length of the data available in @sps. diff --git a/gst-libs/gst/pbutils/codec-utils.h b/gst-libs/gst/pbutils/codec-utils.h index bbbe7aa65..0ef5bbdf4 100644 --- a/gst-libs/gst/pbutils/codec-utils.h +++ b/gst-libs/gst/pbutils/codec-utils.h @@ -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); diff --git a/win32/common/libgstpbutils.def b/win32/common/libgstpbutils.def index 350ec45c3..6d1420512 100644 --- a/win32/common/libgstpbutils.def +++ b/win32/common/libgstpbutils.def @@ -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 |