static gboolean
ensure_allowed_raw_caps (GstVaapiPluginBase * plugin)
{
  GArray *formats, *out_formats;
  GstVaapiSurface *surface;
  guint i;
  GstCaps *out_caps;
  gboolean ret = FALSE;

  if (plugin->allowed_raw_caps)
    return TRUE;

  out_formats = formats = NULL;
  surface = NULL;

  formats = gst_vaapi_display_get_image_formats (plugin->display);
  if (!formats)
    goto bail;

  out_formats =
      g_array_sized_new (FALSE, FALSE, sizeof (GstVideoFormat), formats->len);
  if (!out_formats)
    goto bail;

  surface =
      gst_vaapi_surface_new (plugin->display, GST_VAAPI_CHROMA_TYPE_YUV420, 64,
      64);
  if (!surface)
    goto bail;

  for (i = 0; i < formats->len; i++) {
    const GstVideoFormat format = g_array_index (formats, GstVideoFormat, i);
    GstVaapiImage *image;

    if (format == GST_VIDEO_FORMAT_UNKNOWN)
      continue;
    image = gst_vaapi_image_new (plugin->display, format, 64, 64);
    if (!image)
      continue;
    if (gst_vaapi_surface_put_image (surface, image))
      g_array_append_val (out_formats, format);
    gst_vaapi_object_unref (image);
  }

  out_caps = gst_vaapi_video_format_new_template_caps_from_list (out_formats);
  if (!out_caps)
    goto bail;

  gst_caps_replace (&plugin->allowed_raw_caps, out_caps);
  gst_caps_unref (out_caps);
  ret = TRUE;

bail:
  if (formats)
    g_array_unref (formats);
  if (out_formats)
    g_array_unref (out_formats);
  if (surface)
    gst_vaapi_object_unref (surface);

  return ret;
}
static gboolean
ensure_allowed_sinkpad_caps (GstVaapiEncode * encode)
{
  GstVaapiEncodeClass *klass = GST_VAAPIENCODE_GET_CLASS (encode);
  GstCaps *out_caps, *raw_caps = NULL;
  GArray *formats = NULL;
  gboolean ret = FALSE;
  GstVaapiProfile profile = GST_VAAPI_PROFILE_UNKNOWN;

  if (encode->allowed_sinkpad_caps)
    return TRUE;
  if (!encode->encoder)
    return TRUE;

  out_caps = gst_caps_from_string (GST_VAAPI_MAKE_SURFACE_CAPS);
  if (!out_caps)
    goto failed_create_va_caps;

  if (klass->get_profile) {
    GstCaps *allowed =
        gst_pad_get_allowed_caps (GST_VAAPI_PLUGIN_BASE_SRC_PAD (encode));
    if (allowed) {
      if (!gst_caps_is_empty (allowed) && !gst_caps_is_any (allowed))
        profile = klass->get_profile (allowed);
      gst_caps_unref (allowed);
    }
  }

  formats = gst_vaapi_encoder_get_surface_formats (encode->encoder, profile);
  if (!formats)
    goto failed_get_formats;

  raw_caps = gst_vaapi_video_format_new_template_caps_from_list (formats);
  if (!raw_caps)
    goto failed_create_raw_caps;

  out_caps = gst_caps_make_writable (out_caps);
  gst_caps_append (out_caps, gst_caps_copy (raw_caps));
  gst_caps_replace (&encode->allowed_sinkpad_caps, out_caps);
  GST_INFO_OBJECT (encode, "Allowed sink caps %" GST_PTR_FORMAT,
      encode->allowed_sinkpad_caps);

  ret = TRUE;

bail:
  if (out_caps)
    gst_caps_unref (out_caps);
  if (raw_caps)
    gst_caps_unref (raw_caps);
  if (formats)
    g_array_unref (formats);
  return ret;

failed_create_va_caps:
  {
    GST_WARNING_OBJECT (encode, "failed to create VA/GL sink caps");
    return FALSE;
  }
failed_get_formats:
  {
    GST_WARNING_OBJECT (encode, "failed to get allowed surface formats");
    goto bail;
  }
failed_create_raw_caps:
  {
    GST_WARNING_OBJECT (encode, "failed to create raw sink caps");
    goto bail;
  }
}