libs: encoder: set entrypoint based on tune automatically
authorHe Junyan <junyan.he@hotmail.com>
Mon, 16 Dec 2019 15:19:46 +0000 (23:19 +0800)
committerVíctor Manuel Jáquez Leal <vjaquez@igalia.com>
Sun, 29 Dec 2019 16:58:36 +0000 (17:58 +0100)
Some profile, such as H265_MAIN_444 on new Intel platform, may only
support ENTRYPOINT_SLICE_ENCODE_LP entrypoint. This leads two
problems:

1. We need to specify the tune mode like `vaapih265enc tune=low-power`
   every time when we need to use this kind of profile. Or we can not
   create the encoder context successfully.

2. More seriously, we set the entrypoint to a fixed value in
   init_context_info() and so the create_test_context_config() can not
   create the test context for these profile and can not get the
   supported video formats, either.

We now change the entrypoint setting based on the tune option of the
encoder. If no tune property provided, we just choose the first
available entrypoint.

gst-libs/gst/vaapi/gstvaapiencoder.c
gst-libs/gst/vaapi/gstvaapiencoder.h
gst-libs/gst/vaapi/gstvaapiencoder_h264.c
gst-libs/gst/vaapi/gstvaapiencoder_h265.c
gst-libs/gst/vaapi/gstvaapiencoder_vp9.c

index ccd804d..a63cb8d 100644 (file)
@@ -1473,8 +1473,6 @@ gst_vaapi_encoder_class_init (GstVaapiEncoderClass * klass)
 static GstVaapiContext *
 create_test_context_config (GstVaapiEncoder * encoder, GstVaapiProfile profile)
 {
-  const GstVaapiEncoderClassData *const cdata =
-     GST_VAAPI_ENCODER_GET_CLASS (encoder)->class_data;
   GstVaapiContextInfo cip = { 0, };
   GstVaapiContext *ctxt;
 
@@ -1486,8 +1484,15 @@ create_test_context_config (GstVaapiEncoder * encoder, GstVaapiProfile profile)
     profile = get_profile (encoder);
 
   cip.profile = profile;
-  cip.entrypoint = (cdata->codec == GST_VAAPI_CODEC_JPEG) ?
-    GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE : GST_VAAPI_ENTRYPOINT_SLICE_ENCODE;
+  cip.entrypoint = gst_vaapi_encoder_get_entrypoint (encoder, profile);
+  if (cip.entrypoint == GST_VAAPI_ENTRYPOINT_INVALID) {
+    GST_INFO ("can not find %s entrypoint for profile %s to create"
+        " text context. Ignore this profile",
+        GST_VAAPI_ENCODER_TUNE (encoder) == GST_VAAPI_ENCODER_TUNE_LOW_POWER ?
+        "the low-power" : "an available",
+        gst_vaapi_profile_get_va_name (profile));
+    return NULL;
+  }
 
   init_context_info (encoder, &cip);
   ctxt = gst_vaapi_context_new (encoder->display, &cip);
@@ -1681,6 +1686,50 @@ gst_vaapi_encoder_get_profile (GstVaapiEncoder * encoder)
   return encoder->profile;
 }
 
+/* Get the entrypoint based on the tune option. */
+/**
+ * gst_vaapi_encoder_get_entrypoint:
+ * @encoder: a #GstVaapiEncoder
+ * @profile: a #GstVaapiProfile
+ *
+ * This function will return the valid entrypoint of the @encoder for
+ * @profile. If the low-power mode(tune option) is set, only LP
+ * entrypoints will be considered. If not, the first available entry
+ * point will be return.
+ *
+ * Returns: The #GstVaapiEntrypoint.
+ **/
+GstVaapiEntrypoint
+gst_vaapi_encoder_get_entrypoint (GstVaapiEncoder * encoder,
+    GstVaapiProfile profile)
+{
+  /* XXX: The profile may not be the same with encoder->profile */
+
+  g_return_val_if_fail (encoder, GST_VAAPI_ENTRYPOINT_INVALID);
+  g_return_val_if_fail (profile != GST_VAAPI_PROFILE_UNKNOWN,
+      GST_VAAPI_ENTRYPOINT_INVALID);
+
+  if (profile == GST_VAAPI_PROFILE_JPEG_BASELINE)
+    return GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE;
+
+  if (GST_VAAPI_ENCODER_TUNE (encoder) == GST_VAAPI_ENCODER_TUNE_LOW_POWER) {
+    if (gst_vaapi_display_has_encoder (GST_VAAPI_ENCODER_DISPLAY (encoder),
+            profile, GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP))
+      return GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP;
+  } else {
+    /* If not set, choose the available one */
+    if (gst_vaapi_display_has_encoder (GST_VAAPI_ENCODER_DISPLAY (encoder),
+            profile, GST_VAAPI_ENTRYPOINT_SLICE_ENCODE))
+      return GST_VAAPI_ENTRYPOINT_SLICE_ENCODE;
+
+    if (gst_vaapi_display_has_encoder (GST_VAAPI_ENCODER_DISPLAY (encoder),
+            profile, GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP))
+      return GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP;
+  }
+
+  return GST_VAAPI_ENTRYPOINT_INVALID;
+}
+
 /** Returns a GType for the #GstVaapiEncoderTune set */
 GType
 gst_vaapi_encoder_tune_get_type (void)
index ab4de26..84ca4aa 100644 (file)
@@ -187,6 +187,10 @@ gst_vaapi_encoder_get_surface_formats (GstVaapiEncoder * encoder,
 GstVaapiProfile
 gst_vaapi_encoder_get_profile (GstVaapiEncoder * encoder);
 
+GstVaapiEntrypoint
+gst_vaapi_encoder_get_entrypoint (GstVaapiEncoder * encoder,
+    GstVaapiProfile profile);
+
 G_END_DECLS
 
 #endif /* GST_VAAPI_ENCODER_H */
index abff56a..89a6cc1 100644 (file)
@@ -1301,14 +1301,6 @@ ensure_tuning (GstVaapiEncoderH264 * encoder)
     case GST_VAAPI_ENCODER_TUNE_HIGH_COMPRESSION:
       success = ensure_tuning_high_compression (encoder);
       break;
-    case GST_VAAPI_ENCODER_TUNE_LOW_POWER:
-      /* Set low-power encode entry point. If hardware doesn't have
-       * support, it will fail in ensure_hw_profile() in later stage.
-       * So not duplicating the profile/entrypont query mechanism
-       * here as a part of optimization */
-      encoder->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP;
-      success = TRUE;
-      break;
     default:
       success = TRUE;
       break;
@@ -2738,6 +2730,16 @@ ensure_profile_and_level (GstVaapiEncoderH264 * encoder)
   if (!ensure_profile (encoder) || !ensure_profile_limits (encoder))
     return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
 
+  /* If set low-power encode entry point and hardware doesn't have
+   * support, it will fail in ensure_hw_profile() in later stage. */
+  encoder->entrypoint =
+      gst_vaapi_encoder_get_entrypoint (GST_VAAPI_ENCODER_CAST (encoder),
+      encoder->profile);
+  if (encoder->entrypoint == GST_VAAPI_ENTRYPOINT_INVALID) {
+    GST_WARNING ("Cannot find valid entrypoint");
+    return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
+  }
+
   /* Check HW constraints */
   if (!ensure_hw_profile_limits (encoder))
     return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
index 0c14422..fcb7bb5 100644 (file)
@@ -1082,10 +1082,6 @@ ensure_tuning (GstVaapiEncoderH265 * encoder)
     case GST_VAAPI_ENCODER_TUNE_HIGH_COMPRESSION:
       success = ensure_tuning_high_compression (encoder);
       break;
-    case GST_VAAPI_ENCODER_TUNE_LOW_POWER:
-      encoder->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP;
-      success = TRUE;
-      break;
     default:
       success = TRUE;
       break;
@@ -2039,6 +2035,14 @@ ensure_profile_tier_level (GstVaapiEncoderH265 * encoder)
   if (!ensure_profile (encoder) || !ensure_profile_limits (encoder))
     return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
 
+  encoder->entrypoint =
+      gst_vaapi_encoder_get_entrypoint (GST_VAAPI_ENCODER_CAST (encoder),
+      encoder->profile);
+  if (encoder->entrypoint == GST_VAAPI_ENTRYPOINT_INVALID) {
+    GST_WARNING ("Cannot find valid entrypoint");
+    return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
+  }
+
   /* Check HW constraints */
   if (!ensure_hw_profile_limits (encoder))
     return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
index 9315e3d..ff679ce 100644 (file)
@@ -527,8 +527,13 @@ gst_vaapi_encoder_vp9_reconfigure (GstVaapiEncoder * base_encoder)
   if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS)
     return status;
 
-  if (GST_VAAPI_ENCODER_TUNE (encoder) == GST_VAAPI_ENCODER_TUNE_LOW_POWER)
-    encoder->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP;
+  encoder->entrypoint =
+      gst_vaapi_encoder_get_entrypoint (base_encoder, encoder->profile);
+  if (encoder->entrypoint == GST_VAAPI_ENTRYPOINT_INVALID) {
+    GST_WARNING ("Cannot find valid entrypoint");
+    return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
+  }
+
   ensure_control_rate_params (encoder);
   return set_context_info (base_encoder);
 }