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; }
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); }
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; }
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; }
static void gst_vaapi_video_allocator_free (GstAllocator * allocator, GstMemory * mem) { gst_vaapi_video_memory_free (GST_VAAPI_VIDEO_MEMORY_CAST (mem)); }
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; } }