pbutils: Add codec-utility funtions to support H265
authorSreerenj Balachandran <sreerenj.balachandran@intel.com>
Wed, 2 Oct 2013 09:26:59 +0000 (12:26 +0300)
committerSebastian Dröge <slomo@circular-chaos.org>
Wed, 2 Oct 2013 09:37:39 +0000 (11:37 +0200)
https://bugzilla.gnome.org/show_bug.cgi?id=708921

docs/libs/gst-plugins-base-libs-sections.txt
gst-libs/gst/pbutils/codec-utils.c
gst-libs/gst/pbutils/codec-utils.h
win32/common/libgstpbutils.def

index 35d9cb63042d0095316f9479fd20705c8e1a0e36..32ca50c1ac2f8e13de4972b61061e517d5337644 100644 (file)
@@ -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
index a34b3bc5e188353962335cb24232ecae34ddf4fc..517bbb2ab87b179c8668fbeb0cc49774501f2eab 100644 (file)
@@ -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.
index bbbe7aa656f3fcb7b0124c57fc3a6cdb6592bcd0..0ef5bbdf449313b46dc0ff8287eedeae6651a883 100644 (file)
@@ -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);
index 350ec45c3ef96ae05745cb534892ce34cb949f49..6d142051270ae54a7b501f28fcc05885ae7d880d 100644 (file)
@@ -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