libs: encoder: get surfaces resolution the same time with formats.
authorHe Junyan <junyan.he@hotmail.com>
Mon, 30 Dec 2019 06:09:17 +0000 (14:09 +0800)
committerVíctor Manuel Jáquez Leal <vjaquez@igalia.com>
Thu, 2 Jan 2020 17:01:45 +0000 (18:01 +0100)
We can get all the information about the video format at one shot
when we create the test context for getting the supported formats.

The current way to get the width and height ranges are inefficient,
since it calls the function gst_vaapi_profile_caps_append_encoder()
and it creates another temporal context to detect the resolution
information.

Signed-off-by: Víctor Manuel Jáquez Leal <vjaquez@igalia.com>
gst-libs/gst/vaapi/gstvaapiencoder.c
gst-libs/gst/vaapi/gstvaapiencoder.h
gst/vaapi/gstvaapiencode.c

index a63cb8d..1befb56 100644 (file)
@@ -1476,12 +1476,7 @@ create_test_context_config (GstVaapiEncoder * encoder, GstVaapiProfile profile)
   GstVaapiContextInfo cip = { 0, };
   GstVaapiContext *ctxt;
 
-  if (encoder->context)
-    return gst_vaapi_context_ref (encoder->context);
-
-  /* if there is no profile, let's figure out one */
-  if (profile == GST_VAAPI_PROFILE_UNKNOWN)
-    profile = get_profile (encoder);
+  g_assert (profile != GST_VAAPI_PROFILE_UNKNOWN);
 
   cip.profile = profile;
   cip.entrypoint = gst_vaapi_encoder_get_entrypoint (encoder, profile);
@@ -1499,69 +1494,96 @@ create_test_context_config (GstVaapiEncoder * encoder, GstVaapiProfile profile)
   return ctxt;
 }
 
-static GArray *
-get_profile_surface_formats (GstVaapiEncoder * encoder, GstVaapiProfile profile)
+static gboolean
+get_profile_surface_attributes (GstVaapiEncoder * encoder,
+    GstVaapiProfile profile, GstVaapiConfigSurfaceAttributes * attribs)
 {
-  GstVaapiContext *ctxt;
-  GArray *formats;
+  GstVaapiContext *ctxt = NULL;
+  gboolean ret;
+
+  g_return_val_if_fail (attribs != NULL, FALSE);
+  g_return_val_if_fail (profile != GST_VAAPI_PROFILE_UNKNOWN, FALSE);
 
   ctxt = create_test_context_config (encoder, profile);
   if (!ctxt)
-    return NULL;
-  formats = gst_vaapi_context_get_surface_formats (ctxt);
+    return FALSE;
+
+  ret = gst_vaapi_context_get_surface_attributes (ctxt, attribs);
+  if (ret)
+    attribs->formats = gst_vaapi_context_get_surface_formats (ctxt);
+
   gst_vaapi_context_unref (ctxt);
-  return formats;
+  return ret;
 }
 
 static gboolean
-merge_profile_surface_formats (GstVaapiEncoder * encoder,
-    GstVaapiProfile profile, GArray * formats)
+merge_profile_surface_attributes (GstVaapiEncoder * encoder,
+    GstVaapiProfile profile, GstVaapiConfigSurfaceAttributes * attribs)
 {
-  GArray *surface_fmts;
+  GstVaapiConfigSurfaceAttributes attr = { 0, };
   guint i, j;
   GstVideoFormat fmt, sfmt;
 
   if (profile == GST_VAAPI_PROFILE_UNKNOWN)
     return FALSE;
 
-  surface_fmts = get_profile_surface_formats (encoder, profile);
-  if (!surface_fmts)
+  if (!get_profile_surface_attributes (encoder, profile, &attr))
     return FALSE;
 
-  for (i = 0; i < surface_fmts->len; i++) {
-    sfmt = g_array_index (surface_fmts, GstVideoFormat, i);
-    for (j = 0; j < formats->len; j++) {
-      fmt = g_array_index (formats, GstVideoFormat, j);
+  for (i = 0; i < attr.formats->len; i++) {
+    sfmt = g_array_index (attr.formats, GstVideoFormat, i);
+    for (j = 0; j < attribs->formats->len; j++) {
+      fmt = g_array_index (attribs->formats, GstVideoFormat, j);
       if (fmt == sfmt)
         break;
     }
-    if (j >= formats->len)
-      g_array_append_val (formats, sfmt);
+    if (j >= attribs->formats->len)
+      g_array_append_val (attribs->formats, sfmt);
   }
 
-  g_array_unref (surface_fmts);
+  g_array_unref (attr.formats);
+
+  attribs->min_width = MIN (attribs->min_width, attr.min_width);
+  attribs->min_height = MIN (attribs->min_height, attr.min_height);
+  attribs->max_width = MAX (attribs->max_width, attr.max_width);
+  attribs->max_height = MAX (attribs->max_height, attr.max_height);
+
   return TRUE;
 }
 
 /**
- * gst_vaapi_encoder_get_surface_formats:
+ * gst_vaapi_encoder_get_surface_attributres:
  * @encoder: a #GstVaapiEncoder instances
+ * @profile: a #GstVaapiProfile to test
+ * @min_width (out): the minimal surface width
+ * @min_height (out): the minimal surface height
+ * @max_width (out): the maximal surface width
+ * @max_height (out): the maximal surface height
  *
- * Fetches the valid surface formats for the current VAConfig
+ * Fetches the valid surface's attributes for @profile if it is valid,
+ * Otherwise, it collects surface's attributes for all profiles which
+ * belong to the current encoder's codec.
  *
- * Returns: a #GArray of valid formats for the current VAConfig
+ * Returns: a #GArray of valid formats we get or %NULL if failed.
  **/
 GArray *
-gst_vaapi_encoder_get_surface_formats (GstVaapiEncoder * encoder,
-    GstVaapiProfile profile)
+gst_vaapi_encoder_get_surface_attributes (GstVaapiEncoder * encoder,
+    GstVaapiProfile profile, gint * min_width, gint * min_height,
+    gint * max_width, gint * max_height)
 {
   const GstVaapiEncoderClassData *const cdata =
       GST_VAAPI_ENCODER_GET_CLASS (encoder)->class_data;
-  GArray *profiles, *formats;
+  GstVaapiConfigSurfaceAttributes attribs = {
+    G_MAXINT, G_MAXINT, 1, 1, 0, NULL
+  };
+  GArray *profiles;
   guint i;
 
-  if (profile || encoder->context)
-    return get_profile_surface_formats (encoder, profile);
+  if (profile != GST_VAAPI_PROFILE_UNKNOWN) {
+    if (get_profile_surface_attributes (encoder, profile, &attribs))
+      goto success;
+    return NULL;
+  }
 
   /* no specific context neither specific profile, let's iterate among
    * the codec's profiles */
@@ -1569,21 +1591,33 @@ gst_vaapi_encoder_get_surface_formats (GstVaapiEncoder * encoder,
   if (!profiles)
     return NULL;
 
-  formats = g_array_new (FALSE, FALSE, sizeof (GstVideoFormat));
+  attribs.formats = g_array_new (FALSE, FALSE, sizeof (GstVideoFormat));
   for (i = 0; i < profiles->len; i++) {
     profile = g_array_index (profiles, GstVaapiProfile, i);
     if (gst_vaapi_profile_get_codec (profile) == cdata->codec) {
-      if (!merge_profile_surface_formats (encoder, profile, formats)) {
-        g_array_unref (formats);
-        formats = NULL;
-        break;
+      if (!merge_profile_surface_attributes (encoder, profile, &attribs)) {
+        GST_INFO ("Can not get surface formats for profile %s",
+            gst_vaapi_profile_get_va_name (profile));
+        continue;
       }
     }
   }
 
   g_array_unref (profiles);
 
-  return formats;
+  if (!attribs.formats)
+    return NULL;
+
+success:
+  if (min_width)
+    *min_width = attribs.min_width;
+  if (min_height)
+    *min_height = attribs.min_height;
+  if (max_width)
+    *max_width = attribs.max_width;
+  if (max_height)
+    *max_height = attribs.max_height;
+  return attribs.formats;
 }
 
 /**
index 84ca4aa..1d81baf 100644 (file)
@@ -181,8 +181,9 @@ GstVaapiEncoderStatus
 gst_vaapi_encoder_flush (GstVaapiEncoder * encoder);
 
 GArray *
-gst_vaapi_encoder_get_surface_formats (GstVaapiEncoder * encoder,
-    GstVaapiProfile profile);
+gst_vaapi_encoder_get_surface_attributes (GstVaapiEncoder * encoder,
+    GstVaapiProfile profile, gint * min_width, gint * min_height,
+    gint * max_width, gint * max_height);
 
 GstVaapiProfile
 gst_vaapi_encoder_get_profile (GstVaapiEncoder * encoder);
index b573e18..f19f221 100644 (file)
@@ -366,19 +366,6 @@ get_profile (GstVaapiEncode * encode)
   return GST_VAAPI_PROFILE_UNKNOWN;
 }
 
-static GstVaapiEntrypoint
-get_entrypoint (GstVaapiEncode * encode, GstVaapiProfile profile)
-{
-  GstVaapiEncoderTune tune = GST_VAAPI_ENCODER_TUNE_NONE;
-
-  g_object_get (encode, "tune", &tune, NULL);
-  if (tune == GST_VAAPI_ENCODER_TUNE_LOW_POWER)
-    return GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP;
-  if (profile == GST_VAAPI_PROFILE_JPEG_BASELINE)
-    return GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE;
-  return GST_VAAPI_ENTRYPOINT_SLICE_ENCODE;
-}
-
 static gboolean
 ensure_allowed_sinkpad_caps (GstVaapiEncode * encode)
 {
@@ -390,6 +377,7 @@ ensure_allowed_sinkpad_caps (GstVaapiEncode * encode)
   GstVaapiProfile profile;
   guint i, size;
   GstStructure *structure;
+  gint min_width, min_height, max_width, max_height;
 
   if (encode->allowed_sinkpad_caps)
     return TRUE;
@@ -397,19 +385,28 @@ ensure_allowed_sinkpad_caps (GstVaapiEncode * encode)
     return TRUE;
 
   profile = get_profile (encode);
-  if (profile == GST_VAAPI_PROFILE_UNKNOWN)
-    return TRUE;
 
   /* First get all supported formats, all these formats should be recognized
      in video-format map. */
-  formats = gst_vaapi_encoder_get_surface_formats (encode->encoder, profile);
+  formats = gst_vaapi_encoder_get_surface_attributes (encode->encoder, profile,
+      &min_width, &min_height, &max_width, &max_height);
   if (!formats)
-    goto failed_get_formats;
+    goto failed_get_attributes;
 
   raw_caps = gst_vaapi_video_format_new_template_caps_from_list (formats);
   if (!raw_caps)
     goto failed_create_raw_caps;
 
+  /* Set the width/height info to caps */
+  size = gst_caps_get_size (raw_caps);
+  for (i = 0; i < size; i++) {
+    structure = gst_caps_get_structure (raw_caps, i);
+    if (!structure)
+      continue;
+    gst_structure_set (structure, "width", GST_TYPE_INT_RANGE, min_width,
+        max_width, "height", GST_TYPE_INT_RANGE, min_height, max_height, NULL);
+  }
+
   va_caps = gst_caps_copy (raw_caps);
   gst_caps_set_features_simple (va_caps,
       gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE));
@@ -424,16 +421,6 @@ ensure_allowed_sinkpad_caps (GstVaapiEncode * encode)
   gst_caps_append (out_caps, va_caps);
   gst_caps_append (out_caps, dma_caps);
 
-  /* Last, set the width/height info to caps */
-  size = gst_caps_get_size (out_caps);
-  for (i = 0; i < size; i++) {
-    structure = gst_caps_get_structure (out_caps, i);
-    if (!structure)
-      continue;
-    gst_vaapi_profile_caps_append_encoder (GST_VAAPI_PLUGIN_BASE_DISPLAY
-        (encode), profile, get_entrypoint (encode, profile), structure);
-  }
-
   gst_caps_replace (&encode->allowed_sinkpad_caps, out_caps);
   GST_INFO_OBJECT (encode, "Allowed sink caps %" GST_PTR_FORMAT,
       encode->allowed_sinkpad_caps);
@@ -452,9 +439,9 @@ bail:
     g_array_unref (formats);
   return ret;
 
-failed_get_formats:
+failed_get_attributes:
   {
-    GST_WARNING_OBJECT (encode, "failed to get allowed surface formats");
+    GST_WARNING_OBJECT (encode, "failed to get surface attributes");
     goto bail;
   }
 failed_create_raw_caps: