h265parser: decouple GstH265Profile and GstH265ProfileIDC

We used to have the same enum to represent H265 profiles and idc values.
Those are no longer the same with extension profiles defined from
version 2 of the spec.
Split those enums so the semantic of each is clearer and we'll be able
to add extension profiles to GstH265Profile.

Also add gst_h265_profile_tier_level_get_profile() to retrieve the
GstH265Profile from the GstH265ProfileTierLevel. It will be used to
implement the detection of extension profiles.

https://bugzilla.gnome.org/show_bug.cgi?id=793876
diff --git a/gst-libs/gst/codecparsers/gsth265parser.c b/gst-libs/gst/codecparsers/gsth265parser.c
index e7d56be..0b2d68c 100644
--- a/gst-libs/gst/codecparsers/gsth265parser.c
+++ b/gst-libs/gst/codecparsers/gsth265parser.c
@@ -2630,3 +2630,27 @@
   for (i = 0; i < 64; i++)
     out_quant[uprightdiagonal_8x8[i]] = quant[i];
 }
+
+GstH265Profile
+gst_h265_profile_tier_level_get_profile (GstH265ProfileTierLevel * ptl)
+{
+  if (ptl->profile_idc == GST_H265_PROFILE_IDC_MAIN
+      || ptl->profile_compatibility_flag[1])
+    return GST_H265_PROFILE_MAIN;
+
+  if (ptl->profile_idc == GST_H265_PROFILE_IDC_MAIN_10
+      || ptl->profile_compatibility_flag[2])
+    return GST_H265_PROFILE_MAIN_10;
+
+  if (ptl->profile_idc == GST_H265_PROFILE_IDC_MAIN_STILL_PICTURE
+      || ptl->profile_compatibility_flag[3])
+    return GST_H265_PROFILE_MAIN_STILL_PICTURE;
+
+  /* TODO:
+   * - GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION
+   * - GST_H265_PROFILE_IDC_HIGH_THROUGHPUT
+   * - GST_H265_PROFILE_IDC_SCREEN_CONTENT_CODING
+   */
+
+  return GST_H265_PROFILE_INVALID;
+}
diff --git a/gst-libs/gst/codecparsers/gsth265parser.h b/gst-libs/gst/codecparsers/gsth265parser.h
index 21d6551..8fa807a 100644
--- a/gst-libs/gst/codecparsers/gsth265parser.h
+++ b/gst-libs/gst/codecparsers/gsth265parser.h
@@ -51,12 +51,36 @@
  *
  */
 typedef enum {
+  GST_H265_PROFILE_INVALID              = -1,
   GST_H265_PROFILE_MAIN                 = 1,
   GST_H265_PROFILE_MAIN_10              = 2,
   GST_H265_PROFILE_MAIN_STILL_PICTURE   = 3
 } GstH265Profile;
 
 /**
+ * GstH265ProfileIDC:
+ * @GST_H265_PROFILE_IDC_MAIN: Main profile (A.3.2)
+ * @GST_H265_PROFILE_IDC_MAIN_10: Main 10 profile (A.3.3)
+ * @GST_H265_PROFILE_IDC_MAIN_STILL_PICTURE: Main Still Picture profile (A.3.4)
+ * @GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION: Format range extensions profile (A.3.5)
+ * @GST_H265_PROFILE_IDC_HIGH_THROUGHPUT: High throughput profiles (A.3.6)
+ * @GST_H265_PROFILE_IDC_SCREEN_CONTENT_CODING: Screen content coding extensions profiles (A.3.7)
+ *
+ * Valid values for the profile_idc field. This is different from
+ * #GstH265Profile as an extension idc can be used to encode a whole variety of
+ * profiles.
+ *
+ */
+typedef enum {
+  GST_H265_PROFILE_IDC_MAIN                   = 1,
+  GST_H265_PROFILE_IDC_MAIN_10                = 2,
+  GST_H265_PROFILE_IDC_MAIN_STILL_PICTURE     = 3,
+  GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION = 4,
+  GST_H265_PROFILE_IDC_HIGH_THROUGHPUT        = 5,
+  GST_H265_PROFILE_IDC_SCREEN_CONTENT_CODING  = 9,
+} GstH265ProfileIDC;
+
+/**
  * GstH265NalUnitType:
  * @GST_H265_NAL_SLICE_TRAIL_N: Slice nal of a non-TSA, non-STSA trailing picture
  * @GST_H265_NAL_SLICE_TRAIL_R: Slice nal of a non-TSA, non-STSA trailing picture
@@ -1134,5 +1158,8 @@
 #define gst_h265_quant_matrix_32x32_get_raster_from_uprightdiagonal\
         gst_h265_quant_matrix_8x8_get_raster_from_uprightdiagonal
 
+GST_EXPORT
+GstH265Profile gst_h265_profile_tier_level_get_profile (GstH265ProfileTierLevel * ptl);
+
 G_END_DECLS
 #endif
diff --git a/gst/videoparsers/gsth265parse.c b/gst/videoparsers/gsth265parse.c
index 63da2b4..9722d7e 100644
--- a/gst/videoparsers/gsth265parse.c
+++ b/gst/videoparsers/gsth265parse.c
@@ -1225,18 +1225,20 @@
 }
 
 static const gchar *
-get_profile_string (guint8 profile_idc)
+get_profile_string (GstH265Profile profile)
 {
-  const gchar *profile = NULL;
+  switch (profile) {
+    case GST_H265_PROFILE_MAIN:
+      return "main";
+    case GST_H265_PROFILE_MAIN_10:
+      return "main-10";
+    case GST_H265_PROFILE_MAIN_STILL_PICTURE:
+      return "main-still-picture";
+    default:
+      break;
+  }
 
-  if (profile_idc == 1)
-    profile = "main";
-  else if (profile_idc == 2)
-    profile = "main-10";
-  else if (profile_idc == 3)
-    profile = "main-still-picture";
-
-  return profile;
+  return NULL;
 }
 
 static const gchar *
@@ -1298,7 +1300,7 @@
   g_value_init (&compat_profiles, GST_TYPE_LIST);
 
   switch (sps->profile_tier_level.profile_idc) {
-    case GST_H265_PROFILE_MAIN_10:
+    case GST_H265_PROFILE_IDC_MAIN_10:
       if (sps->profile_tier_level.profile_compatibility_flag[1]) {
         if (sps->profile_tier_level.profile_compatibility_flag[3]) {
           static const gchar *profile_array[] =
@@ -1310,7 +1312,7 @@
         }
       }
       break;
-    case GST_H265_PROFILE_MAIN:
+    case GST_H265_PROFILE_IDC_MAIN:
       if (sps->profile_tier_level.profile_compatibility_flag[3]) {
         static const gchar *profile_array[] =
             { "main-still-picture", "main-10", NULL
@@ -1321,7 +1323,7 @@
         profiles = profile_array;
       }
       break;
-    case GST_H265_PROFILE_MAIN_STILL_PICTURE:
+    case GST_H265_PROFILE_IDC_MAIN_STILL_PICTURE:
     {
       static const gchar *profile_array[] = { "main", "main-10", NULL
       };
@@ -1587,8 +1589,10 @@
     /* set profile and level in caps */
     if (sps) {
       const gchar *profile, *tier, *level;
+      GstH265Profile p;
 
-      profile = get_profile_string (sps->profile_tier_level.profile_idc);
+      p = gst_h265_profile_tier_level_get_profile (&sps->profile_tier_level);
+      profile = get_profile_string (p);
       if (profile != NULL)
         gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, NULL);
 
diff --git a/tests/check/Makefile.am b/tests/check/Makefile.am
index dc2cac9..e23a05f 100644
--- a/tests/check/Makefile.am
+++ b/tests/check/Makefile.am
@@ -276,6 +276,7 @@
 	libs/mpegvideoparser \
 	libs/mpegts \
 	libs/h264parser \
+	libs/h265parser \
 	libs/vp8parser \
 	$(check_uvch264) \
 	libs/vc1parser \
@@ -361,6 +362,15 @@
 	$(top_builddir)/gst-libs/gst/codecparsers/libgstcodecparsers-@GST_API_VERSION@.la \
 	$(GST_BASE_LIBS) $(GST_LIBS) $(LDADD)
 
+libs_h265parser_CFLAGS = \
+	$(GST_PLUGINS_BAD_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) \
+	-DGST_USE_UNSTABLE_API \
+	$(GST_BASE_CFLAGS) $(GST_CFLAGS) $(AM_CFLAGS)
+
+libs_h265parser_LDADD = \
+	$(top_builddir)/gst-libs/gst/codecparsers/libgstcodecparsers-@GST_API_VERSION@.la \
+	$(GST_BASE_LIBS) $(GST_LIBS) $(LDADD)
+
 libs_vc1parser_CFLAGS = \
 	$(GST_PLUGINS_BAD_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) \
 	-DGST_USE_UNSTABLE_API \
diff --git a/tests/check/libs/h265parser.c b/tests/check/libs/h265parser.c
new file mode 100644
index 0000000..0a58e76
--- /dev/null
+++ b/tests/check/libs/h265parser.c
@@ -0,0 +1,87 @@
+/* Gstreamer
+ * Copyright (C) <2018> Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#include <gst/check/gstcheck.h>
+#include <gst/codecparsers/gsth265parser.h>
+
+GST_START_TEST (test_h265_base_profiles)
+{
+  GstH265ProfileTierLevel ptl;
+
+  memset (&ptl, 0, sizeof (ptl));
+
+  ptl.profile_idc = 1;
+  g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
+      GST_H265_PROFILE_MAIN);
+  ptl.profile_idc = 2;
+  g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
+      GST_H265_PROFILE_MAIN_10);
+  ptl.profile_idc = 3;
+  g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
+      GST_H265_PROFILE_MAIN_STILL_PICTURE);
+
+  ptl.profile_idc = 42;
+  g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
+      GST_H265_PROFILE_INVALID);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (test_h265_base_profiles_compat)
+{
+  GstH265ProfileTierLevel ptl;
+
+  memset (&ptl, 0, sizeof (ptl));
+
+  ptl.profile_compatibility_flag[1] = 1;
+  g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
+      GST_H265_PROFILE_MAIN);
+  ptl.profile_compatibility_flag[1] = 0;
+
+  ptl.profile_compatibility_flag[2] = 1;
+  g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
+      GST_H265_PROFILE_MAIN_10);
+  ptl.profile_compatibility_flag[2] = 0;
+
+  ptl.profile_compatibility_flag[3] = 1;
+  g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
+      GST_H265_PROFILE_MAIN_STILL_PICTURE);
+  ptl.profile_compatibility_flag[3] = 0;
+
+  ptl.profile_idc = 42;
+  g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
+      GST_H265_PROFILE_INVALID);
+}
+
+GST_END_TEST;
+
+static Suite *
+h265parser_suite (void)
+{
+  Suite *s = suite_create ("H265 Parser library");
+
+  TCase *tc_chain = tcase_create ("general");
+
+  suite_add_tcase (s, tc_chain);
+  tcase_add_test (tc_chain, test_h265_base_profiles);
+  tcase_add_test (tc_chain, test_h265_base_profiles_compat);
+
+  return s;
+}
+
+GST_CHECK_MAIN (h265parser);
diff --git a/tests/check/meson.build b/tests/check/meson.build
index 5b624c2..51da3e4 100644
--- a/tests/check/meson.build
+++ b/tests/check/meson.build
@@ -57,6 +57,7 @@
   [['elements/x265enc.c'], not x265_dep.found(), [x265_dep]],
   [['elements/zbar.c'], not zbar_dep.found(), [zbar_dep]],
   [['libs/h264parser.c'], false, [gstcodecparsers_dep]],
+  [['libs/h265parser.c'], false, [gstcodecparsers_dep]],
   [['libs/insertbin.c'], false, [gstinsertbin_dep]],
   [['libs/isoff.c'], not xml2_dep.found(), [gstisoff_dep, xml2_dep]],
   [['libs/mpegts.c'], false, [gstmpegts_dep]],