コード例 #1
0
gboolean
gst_video_meta_unmap_vaapi_memory (GstVideoMeta * meta, guint plane,
    GstMapInfo * info)
{
  GstVaapiVideoMemory *const mem =
      GST_VAAPI_VIDEO_MEMORY_CAST (gst_buffer_peek_memory (meta->buffer, 0));

  g_return_val_if_fail (mem, FALSE);
  g_return_val_if_fail (GST_VAAPI_IS_VIDEO_ALLOCATOR (mem->parent_instance.
          allocator), FALSE);
  g_return_val_if_fail (mem->meta, FALSE);
  g_return_val_if_fail (mem->surface, FALSE);
  g_return_val_if_fail (mem->image, FALSE);

  if (--mem->map_count == 0) {
    mem->map_type = 0;

    /* Unmap VA image used for read/writes */
    if (info->flags & GST_MAP_READWRITE) {
      gst_vaapi_image_unmap (mem->image);

      if (info->flags & GST_MAP_WRITE) {
        GST_VAAPI_VIDEO_MEMORY_FLAG_SET (mem,
            GST_VAAPI_VIDEO_MEMORY_FLAG_IMAGE_IS_CURRENT);
      }
    }
  }
  return TRUE;
}
コード例 #2
0
static void
gst_vaapi_video_buffer_pool_reset_buffer (GstBufferPool * pool,
    GstBuffer * buffer)
{
  GstMemory *const mem = gst_buffer_peek_memory (buffer, 0);

  /* Release the underlying surface proxy */
  if (GST_VAAPI_IS_VIDEO_MEMORY (mem))
    gst_vaapi_video_memory_reset_surface (GST_VAAPI_VIDEO_MEMORY_CAST (mem));

  GST_BUFFER_POOL_CLASS (gst_vaapi_video_buffer_pool_parent_class)->reset_buffer
      (pool, buffer);
}
コード例 #3
0
static gboolean
ensure_surface_proxy (GstVaapiVideoMeta * meta)
{
  if (!meta->proxy)
    return FALSE;

  if (meta->buffer) {
    GstMemory *const mem = gst_buffer_peek_memory (meta->buffer, 0);

    if (GST_VAAPI_IS_VIDEO_MEMORY (mem))
      return gst_vaapi_video_memory_sync (GST_VAAPI_VIDEO_MEMORY_CAST (mem));
  }
  return TRUE;
}
コード例 #4
0
static GstVaapiVideoMemory *
gst_vaapi_video_memory_copy (GstVaapiVideoMemory * mem,
    gssize offset, gssize size)
{
  GstVaapiVideoMeta *meta;
  GstMemory *out_mem;
  gsize maxsize;

  g_return_val_if_fail (mem, NULL);
  g_return_val_if_fail (mem->meta, NULL);

  /* XXX: this implements a soft-copy, i.e. underlying VA surfaces
     are not copied */
  (void) gst_memory_get_sizes (GST_MEMORY_CAST (mem), NULL, &maxsize);
  if (offset != 0 || (size != -1 && (gsize) size != maxsize))
    goto error_unsupported;

  if (!ensure_surface_is_current (mem))
    goto error_no_current_surface;

  meta = gst_vaapi_video_meta_copy (mem->meta);
  if (!meta)
    goto error_allocate_memory;

  out_mem = gst_vaapi_video_memory_new (GST_MEMORY_CAST (mem)->allocator, meta);
  gst_vaapi_video_meta_unref (meta);
  if (!out_mem)
    goto error_allocate_memory;
  return GST_VAAPI_VIDEO_MEMORY_CAST (out_mem);

  /* ERRORS */
error_no_current_surface:
  GST_ERROR ("failed to make surface current");
  return NULL;
error_unsupported:
  GST_ERROR ("failed to copy partial memory (unsupported operation)");
  return NULL;
error_allocate_memory:
  GST_ERROR ("failed to allocate GstVaapiVideoMemory copy");
  return NULL;
}
コード例 #5
0
static void
gst_vaapi_video_allocator_free (GstAllocator * allocator, GstMemory * mem)
{
  gst_vaapi_video_memory_free (GST_VAAPI_VIDEO_MEMORY_CAST (mem));
}
コード例 #6
0
gboolean
gst_video_meta_map_vaapi_memory (GstVideoMeta * meta, guint plane,
    GstMapInfo * info, gpointer * data, gint * stride, GstMapFlags flags)
{
  GstVaapiVideoMemory *const mem =
      GST_VAAPI_VIDEO_MEMORY_CAST (gst_buffer_peek_memory (meta->buffer, 0));

  g_return_val_if_fail (mem, FALSE);
  g_return_val_if_fail (GST_VAAPI_IS_VIDEO_ALLOCATOR (mem->parent_instance.
          allocator), FALSE);
  g_return_val_if_fail (mem->meta, FALSE);

  if (mem->map_type && mem->map_type != GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_PLANAR)
    goto error_incompatible_map;

  /* Map for writing */
  if (++mem->map_count == 1) {
    if (!ensure_surface (mem))
      goto error_ensure_surface;
    if (!ensure_image (mem))
      goto error_ensure_image;

    // Load VA image from surface
    if ((flags & GST_MAP_READ) && !ensure_image_is_current (mem))
      goto error_no_current_image;

    if (!gst_vaapi_image_map (mem->image))
      goto error_map_image;
    mem->map_type = GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_PLANAR;

    // Mark surface as dirty and expect updates from image
    if (flags & GST_MAP_WRITE)
      GST_VAAPI_VIDEO_MEMORY_FLAG_UNSET (mem,
          GST_VAAPI_VIDEO_MEMORY_FLAG_SURFACE_IS_CURRENT);
  }

  *data = gst_vaapi_image_get_plane (mem->image, plane);
  *stride = gst_vaapi_image_get_pitch (mem->image, plane);
  info->flags = flags;
  return TRUE;

  /* ERRORS */
error_incompatible_map:
  {
    GST_ERROR ("incompatible map type (%d)", mem->map_type);
    return FALSE;
  }
error_ensure_surface:
  {
    const GstVideoInfo *const vip = mem->surface_info;
    GST_ERROR ("failed to create %s surface of size %ux%u",
        GST_VIDEO_INFO_FORMAT_STRING (vip),
        GST_VIDEO_INFO_WIDTH (vip), GST_VIDEO_INFO_HEIGHT (vip));
    return FALSE;
  }
error_ensure_image:
  {
    const GstVideoInfo *const vip = mem->image_info;
    GST_ERROR ("failed to create %s image of size %ux%u",
        GST_VIDEO_INFO_FORMAT_STRING (vip),
        GST_VIDEO_INFO_WIDTH (vip), GST_VIDEO_INFO_HEIGHT (vip));
    return FALSE;
  }
error_map_image:
  {
    GST_ERROR ("failed to map image %" GST_VAAPI_ID_FORMAT,
        GST_VAAPI_ID_ARGS (gst_vaapi_image_get_id (mem->image)));
    return FALSE;
  }
error_no_current_image:
  {
    GST_ERROR ("failed to make image current");
    return FALSE;
  }
}