vaapiencode: h264: verify if requested profile is supported
authorVíctor Manuel Jáquez Leal <vjaquez@igalia.com>
Thu, 22 Jun 2017 07:56:49 +0000 (09:56 +0200)
committerVíctor Manuel Jáquez Leal <vjaquez@igalia.com>
Mon, 3 Jul 2017 13:33:20 +0000 (15:33 +0200)
Check if the requested profile in source caps, is supported by the
VA driver. If it is not, an info log message is send saying that
another (compatible?) profile will be used.

https://bugzilla.gnome.org/show_bug.cgi?id=757941

gst/vaapi/gstvaapiencode_h264.c
gst/vaapi/gstvaapiencode_h264.h

index 63b82fb..1b7572c 100644 (file)
@@ -170,6 +170,9 @@ gst_vaapiencode_h264_init (GstVaapiEncodeH264 * encode)
 static void
 gst_vaapiencode_h264_finalize (GObject * object)
 {
+  GstVaapiEncodeH264 *const encode = GST_VAAPIENCODE_H264_CAST (object);
+
+  gst_caps_replace (&encode->available_caps, NULL);
   G_OBJECT_CLASS (gst_vaapiencode_h264_parent_class)->finalize (object);
 }
 
@@ -278,6 +281,51 @@ find_best_profile (GstCaps * caps)
   return data.best_profile;
 }
 
+static GstCaps *
+get_available_caps (GstVaapiEncodeH264 * encode)
+{
+  GstCaps *out_caps;
+  GArray *profiles;
+  GstVaapiProfile profile;
+  const gchar *profile_str;
+  GValue profile_v = G_VALUE_INIT;
+  GValue profile_list = G_VALUE_INIT;
+  guint i;
+
+  if (encode->available_caps)
+    return encode->available_caps;
+
+  g_value_init (&profile_list, GST_TYPE_LIST);
+  g_value_init (&profile_v, G_TYPE_STRING);
+
+  profiles =
+      gst_vaapi_display_get_encode_profiles
+      (GST_VAAPI_PLUGIN_BASE_DISPLAY (encode));
+  if (!profiles)
+    return NULL;
+
+  for (i = 0; i < profiles->len; i++) {
+    profile = g_array_index (profiles, GstVaapiProfile, i);
+    if (gst_vaapi_profile_get_codec (profile) != GST_VAAPI_CODEC_H264)
+      continue;
+    profile_str = gst_vaapi_profile_get_name (profile);
+    if (!profile_str)
+      continue;
+    g_value_set_string (&profile_v, profile_str);
+    gst_value_list_append_value (&profile_list, &profile_v);
+  }
+  g_array_unref (profiles);
+
+  out_caps = gst_caps_from_string (GST_CODEC_CAPS);
+  gst_caps_set_value (out_caps, "profile", &profile_list);
+  g_value_unset (&profile_list);
+  g_value_unset (&profile_v);
+
+  encode->available_caps = out_caps;
+
+  return encode->available_caps;
+}
+
 static gboolean
 gst_vaapiencode_h264_set_config (GstVaapiEncode * base_encode)
 {
@@ -310,6 +358,18 @@ gst_vaapiencode_h264_set_config (GstVaapiEncode * base_encode)
     GstStructure *structure;
     guint i, num_structures;
     GstVaapiProfile profile;
+    GstCaps *available_caps;
+
+    available_caps = get_available_caps (encode);
+    if (!available_caps) {
+      gst_caps_unref (template_caps);
+      gst_caps_unref (allowed_caps);
+      return FALSE;
+    }
+    if (!gst_caps_can_intersect (allowed_caps, available_caps)) {
+      GST_INFO_OBJECT (encode, "downstream requested an unsupported profile, "
+          "but encoder will output a compatible one");
+    }
 
     /* Check whether "stream-format" is avcC mode */
     num_structures = gst_caps_get_size (allowed_caps);
index cab73d7..46a0e81 100644 (file)
@@ -56,6 +56,7 @@ struct _GstVaapiEncodeH264
   GstVaapiEncode parent_instance;
 
   guint is_avc:1; /* [FALSE]=byte-stream (default); [TRUE]=avcC */
+  GstCaps *available_caps;
 };
 
 struct _GstVaapiEncodeH264Class