/**
 * gst_vaapi_subpicture_new:
 * @image: a #GstVaapiImage
 * @flags: #GstVaapiSubpictureFlags, or zero
 *
 * Creates a new #GstVaapiSubpicture with @image as source pixels. The
 * newly created object holds a reference on @image.
 *
 * Return value: the newly allocated #GstVaapiSubpicture object
 */
     GstVaapiSubpicture *gst_vaapi_subpicture_new (GstVaapiImage * image,
    guint flags)
{
  GstVaapiSubpicture *subpicture;
  GstVaapiDisplay *display;
  GstVideoFormat format;
  guint va_flags;

  g_return_val_if_fail (image != NULL, NULL);

  GST_DEBUG ("create from image %" GST_VAAPI_ID_FORMAT,
      GST_VAAPI_ID_ARGS (GST_VAAPI_OBJECT_ID (image)));

  display = GST_VAAPI_OBJECT_DISPLAY (image);
  format = GST_VAAPI_IMAGE_FORMAT (image);
  if (!gst_vaapi_display_has_subpicture_format (display, format, &va_flags))
    return NULL;
  if (flags & ~va_flags)
    return NULL;

  subpicture = gst_vaapi_object_new (gst_vaapi_subpicture_class (), display);
  if (!subpicture)
    return NULL;

  subpicture->global_alpha = 1.0f;
  if (!gst_vaapi_subpicture_set_image (subpicture, image))
    goto error;
  return subpicture;

error:
  gst_vaapi_object_unref (subpicture);
  return NULL;
}
static inline void
allocator_configure_surface_info (GstVaapiDisplay * display,
    GstVaapiVideoAllocator * allocator)
{
  const GstVideoInfo *vinfo;
  GstVaapiSurface *surface = NULL;
  GstVaapiImage *image = NULL;
  gboolean updated;
  GstVideoFormat fmt;

  vinfo = &allocator->video_info;

  fmt = gst_vaapi_video_format_get_best_native (GST_VIDEO_INFO_FORMAT (vinfo));
  gst_video_info_set_format (&allocator->surface_info, fmt,
      GST_VIDEO_INFO_WIDTH (vinfo), GST_VIDEO_INFO_HEIGHT (vinfo));

  /* nothing to configure */
  if (USE_NATIVE_FORMATS ||
      GST_VIDEO_INFO_FORMAT (vinfo) == GST_VIDEO_FORMAT_ENCODED)
    return;

  surface = new_surface (display, vinfo);
  if (!surface)
    goto bail;
  image = gst_vaapi_surface_derive_image (surface);
  if (!image)
    goto bail;
  if (!gst_vaapi_image_map (image))
    goto bail;

  updated = gst_video_info_update_from_image (&allocator->surface_info, image);

  allocator->has_direct_rendering = !USE_NATIVE_FORMATS && updated &&
      (GST_VAAPI_IMAGE_FORMAT (image) == GST_VIDEO_INFO_FORMAT (vinfo));

  GST_INFO ("has direct-rendering for %s surfaces: %s",
      GST_VIDEO_INFO_FORMAT_STRING (&allocator->surface_info),
      allocator->has_direct_rendering ? "yes" : "no");

  gst_vaapi_image_unmap (image);

bail:
  if (surface)
    gst_vaapi_object_unref (surface);
  if (image)
    gst_vaapi_object_unref (image);
}
/**
 * gst_vaapi_surface_get_format:
 * @surface: a #GstVaapiSurface
 *
 * Returns the #GstVideoFormat the @surface was created with.
 *
 * Return value: the #GstVideoFormat, or %GST_VIDEO_FORMAT_ENCODED if
 *   the surface was not created with an explicit video format, or if
 *   the underlying video format could not be determined
 */
GstVideoFormat
gst_vaapi_surface_get_format (GstVaapiSurface * surface)
{
  g_return_val_if_fail (surface != NULL, 0);

  /* Try to determine the underlying VA surface format */
  if (surface->format == GST_VIDEO_FORMAT_UNKNOWN) {
    GstVaapiImage *const image = gst_vaapi_surface_derive_image (surface);
    if (image) {
      surface->format = GST_VAAPI_IMAGE_FORMAT (image);
      gst_vaapi_object_unref (image);
    }
    if (surface->format == GST_VIDEO_FORMAT_UNKNOWN)
      surface->format = GST_VIDEO_FORMAT_ENCODED;
  }
  return GST_VAAPI_SURFACE_FORMAT (surface);
}