/**
 * 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;
}
/*
 * gst_vaapi_coded_buffer_new:
 * @context: the parent #GstVaapiContext object
 * @buf_size: the buffer size in bytes
 *
 * Creates a new VA coded buffer bound to the supplied @context.
 *
 * Return value: the newly allocated #GstVaapiCodedBuffer object, or
 *   %NULL if an error occurred
 */
GstVaapiCodedBuffer *
gst_vaapi_coded_buffer_new (GstVaapiContext * context, guint buf_size)
{
  GstVaapiCodedBuffer *buf;
  GstVaapiDisplay *display;

  g_return_val_if_fail (context != NULL, NULL);
  g_return_val_if_fail (buf_size > 0, NULL);

  display = GST_VAAPI_OBJECT_DISPLAY (context);
  g_return_val_if_fail (display != NULL, NULL);

  buf = gst_vaapi_object_new (gst_vaapi_coded_buffer_class (), display);
  if (!buf)
    return NULL;

  if (!coded_buffer_create (buf, buf_size, context))
    goto error;
  return buf;

  /* ERRORS */
error:
  {
    gst_vaapi_object_unref (buf);
    return NULL;
  }
}
static inline GstVaapiPixmap *
gst_vaapi_pixmap_new_internal (const GstVaapiPixmapClass * pixmap_class,
                               GstVaapiDisplay * display)
{
    g_assert (pixmap_class->create != NULL);
    g_assert (pixmap_class->render != NULL);

    return gst_vaapi_object_new (GST_VAAPI_OBJECT_CLASS (pixmap_class), display);
}
/**
 * gst_vaapi_surface_new:
 * @display: a #GstVaapiDisplay
 * @chroma_type: the surface chroma format
 * @width: the requested surface width
 * @height: the requested surface height
 *
 * Creates a new #GstVaapiSurface with the specified chroma format and
 * dimensions.
 *
 * Return value: the newly allocated #GstVaapiSurface object
 */
GstVaapiSurface *
gst_vaapi_surface_new (GstVaapiDisplay * display,
    GstVaapiChromaType chroma_type, guint width, guint height)
{
  GstVaapiSurface *surface;

  GST_DEBUG ("size %ux%u, chroma type 0x%x", width, height, chroma_type);

  surface = gst_vaapi_object_new (gst_vaapi_surface_class (), display);
  if (!surface)
    return NULL;

  if (!gst_vaapi_surface_create (surface, chroma_type, width, height))
    goto error;
  return surface;

error:
  gst_vaapi_object_unref (surface);
  return NULL;
}
/**
 * gst_vaapi_surface_new_from_buffer_proxy:
 * @display: a #GstVaapiDisplay
 * @proxy: a #GstVaapiBufferProxy
 * @info: the #GstVideoInfo structure defining the layout of the buffer
 *
 * Creates a new #GstVaapiSurface with the supplied VA buffer proxy
 * abstraction. The underlying VA buffer memory type could be anything
 * that is supported by the VA driver.
 *
 * The resulting #GstVaapiSurface object owns an extra reference to
 * the buffer @proxy, so the caller can safely release that handle as
 * early as on return of this call.
 *
 * Return value: the newly allocated #GstVaapiSurface object, or %NULL
 *   if creation of VA surface failed or is not supported
 */
GstVaapiSurface *
gst_vaapi_surface_new_from_buffer_proxy (GstVaapiDisplay * display,
    GstVaapiBufferProxy * proxy, const GstVideoInfo * info)
{
  GstVaapiSurface *surface;

  g_return_val_if_fail (proxy != NULL, NULL);
  g_return_val_if_fail (info != NULL, NULL);

  surface = gst_vaapi_object_new (gst_vaapi_surface_class (), display);
  if (!surface)
    return NULL;

  if (!gst_vaapi_surface_create_from_buffer_proxy (surface, proxy, info))
    goto error;
  return surface;

error:
  gst_vaapi_object_unref (surface);
  return NULL;
}
/**
 * gst_vaapi_surface_new_full:
 * @display: a #GstVaapiDisplay
 * @vip: the pointer to a #GstVideoInfo
 * @flags: (optional) allocation flags
 *
 * Creates a new #GstVaapiSurface with the specified video information
 * and optional #GstVaapiSurfaceAllocFlags
 *
 * Return value: the newly allocated #GstVaapiSurface object, or %NULL
 *   if creation of VA surface with explicit pixel format is not
 *   supported or failed.
 */
GstVaapiSurface *
gst_vaapi_surface_new_full (GstVaapiDisplay * display,
    const GstVideoInfo * vip, guint flags)
{
  GstVaapiSurface *surface;

  GST_DEBUG ("size %ux%u, format %s, flags 0x%08x", GST_VIDEO_INFO_WIDTH (vip),
      GST_VIDEO_INFO_HEIGHT (vip),
      gst_vaapi_video_format_to_string (GST_VIDEO_INFO_FORMAT (vip)), flags);

  surface = gst_vaapi_object_new (gst_vaapi_surface_class (), display);
  if (!surface)
    return NULL;

  if (!gst_vaapi_surface_create_full (surface, vip, flags))
    goto error;
  return surface;

error:
  gst_vaapi_object_unref (surface);
  return NULL;
}