va: allocator: use _update_image_info() to set allocator parameters.

Use this standalone function to update the allocator info and make
all ensure_image() and mem_alloc() API clean.
We also change the default way of using image. We now set the non
derive manner as the default manner, and if it fails, then fallback
to the derived image manner.
On a lot of platforms, the derived image does not have caches, so the
read and write operations have very low performance.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1698>
This commit is contained in:
He Junyan 2020-10-20 14:31:22 +08:00 committed by GStreamer Merge Bot
parent e577ca140f
commit 32133c85d3

View file

@ -959,11 +959,10 @@ _reset_mem (GstVaMemory * mem, GstAllocator * allocator, gsize size)
} }
static inline gboolean static inline gboolean
_ensure_image (GstVaDisplay * display, VASurfaceID surface, GstVideoInfo * info, _ensure_image (GstVaDisplay * display, VASurfaceID surface,
VAImage * image, gboolean * derived, gboolean update_info) GstVideoInfo * info, VAImage * image, gboolean derived)
{ {
gint i; gboolean ret = TRUE;
gboolean try_derived;
if (image->image_id != VA_INVALID_ID) if (image->image_id != VA_INVALID_ID)
return TRUE; return TRUE;
@ -971,28 +970,14 @@ _ensure_image (GstVaDisplay * display, VASurfaceID surface, GstVideoInfo * info,
if (!_sync_surface (display, surface)) if (!_sync_surface (display, surface))
return FALSE; return FALSE;
try_derived = (derived) ? *derived : FALSE; if (derived) {
ret = _get_derive_image (display, surface, image);
if (try_derived && _get_derive_image (display, surface, image)) } else {
goto bail; ret = _create_image (display, GST_VIDEO_INFO_FORMAT (info),
if (!_create_image (display, GST_VIDEO_INFO_FORMAT (info), GST_VIDEO_INFO_WIDTH (info), GST_VIDEO_INFO_HEIGHT (info), image);
GST_VIDEO_INFO_WIDTH (info), GST_VIDEO_INFO_HEIGHT (info), image))
return FALSE;
if (derived)
*derived = FALSE;
bail:
if (G_UNLIKELY (update_info)) {
for (i = 0; i < image->num_planes; i++) {
GST_VIDEO_INFO_PLANE_OFFSET (info, i) = image->offsets[i];
GST_VIDEO_INFO_PLANE_STRIDE (info, i) = image->pitches[i];
}
GST_VIDEO_INFO_SIZE (info) = image->data_size;
} }
return TRUE; return ret;
} }
static inline gboolean static inline gboolean
@ -1070,11 +1055,8 @@ _va_map_unlocked (GstVaMemory * mem, GstMapFlags flags)
if (flags & GST_MAP_WRITE) { if (flags & GST_MAP_WRITE) {
mem->is_dirty = TRUE; mem->is_dirty = TRUE;
mem->is_derived = FALSE;
} else { /* GST_MAP_READ only */ } else { /* GST_MAP_READ only */
mem->is_dirty = FALSE; mem->is_dirty = FALSE;
mem->is_derived = va_allocator->use_derived &&
(GST_VIDEO_INFO_FORMAT (&va_allocator->info) == mem->surface_format);
} }
if (flags & GST_MAP_VA) { if (flags & GST_MAP_VA) {
@ -1083,10 +1065,10 @@ _va_map_unlocked (GstVaMemory * mem, GstMapFlags flags)
} }
if (!_ensure_image (display, mem->surface, &va_allocator->info, &mem->image, if (!_ensure_image (display, mem->surface, &va_allocator->info, &mem->image,
&mem->is_derived, FALSE)) va_allocator->use_derived))
return NULL; return NULL;
va_allocator->use_derived = mem->is_derived; mem->is_derived = va_allocator->use_derived;
if (!mem->is_derived) { if (!mem->is_derived) {
if (!_get_image (display, mem->surface, &mem->image)) if (!_get_image (display, mem->surface, &mem->image))
@ -1238,12 +1220,8 @@ gst_va_memory_release (GstMiniObject * mini_object)
return FALSE; return FALSE;
} }
/* If @info is not NULL, a dummy (non-pooled) memory and its VAImage GstMemory *
* are created, to update offsets and strides. The memory has to be gst_va_allocator_alloc (GstAllocator * allocator)
* unrefed immediately.
*/
static GstMemory *
gst_va_allocator_alloc_full (GstAllocator * allocator, GstVideoInfo * info)
{ {
GstVaAllocator *self; GstVaAllocator *self;
GstVaMemory *mem; GstVaMemory *mem;
@ -1253,20 +1231,14 @@ gst_va_allocator_alloc_full (GstAllocator * allocator, GstVideoInfo * info)
self = GST_VA_ALLOCATOR (allocator); self = GST_VA_ALLOCATOR (allocator);
g_return_val_if_fail (self->rt_format != 0, NULL);
if (!_create_surfaces (self->display, self->rt_format, self->fourcc, if (!_create_surfaces (self->display, self->rt_format, self->fourcc,
GST_VIDEO_INFO_WIDTH (&self->info), GST_VIDEO_INFO_WIDTH (&self->info),
GST_VIDEO_INFO_HEIGHT (&self->info), self->usage_hint, NULL, GST_VIDEO_INFO_HEIGHT (&self->info), self->usage_hint, NULL,
&surface, 1)) &surface, 1))
return NULL; return NULL;
if (G_UNLIKELY (info)) {
VAImage image = {.image_id = VA_INVALID_ID, };
if (!_ensure_image (self->display, surface, info, &image, NULL, TRUE))
return NULL;
_destroy_image (self->display, image.image_id);
}
mem = g_slice_new (GstVaMemory); mem = g_slice_new (GstVaMemory);
mem->surface = surface; mem->surface = surface;
@ -1274,10 +1246,8 @@ gst_va_allocator_alloc_full (GstAllocator * allocator, GstVideoInfo * info)
_reset_mem (mem, allocator, GST_VIDEO_INFO_SIZE (&self->info)); _reset_mem (mem, allocator, GST_VIDEO_INFO_SIZE (&self->info));
if (G_LIKELY (!info)) { GST_MINI_OBJECT (mem)->dispose = gst_va_memory_release;
GST_MINI_OBJECT (mem)->dispose = gst_va_memory_release; g_atomic_int_inc (&self->surface_count);
g_atomic_int_inc (&self->surface_count);
}
GST_LOG_OBJECT (self, "Created surface %#x [%dx%d]", mem->surface, GST_LOG_OBJECT (self, "Created surface %#x [%dx%d]", mem->surface,
GST_VIDEO_INFO_WIDTH (&self->info), GST_VIDEO_INFO_HEIGHT (&self->info)); GST_VIDEO_INFO_WIDTH (&self->info), GST_VIDEO_INFO_HEIGHT (&self->info));
@ -1285,12 +1255,6 @@ gst_va_allocator_alloc_full (GstAllocator * allocator, GstVideoInfo * info)
return GST_MEMORY_CAST (mem); return GST_MEMORY_CAST (mem);
} }
GstMemory *
gst_va_allocator_alloc (GstAllocator * allocator)
{
return gst_va_allocator_alloc_full (allocator, NULL);
}
GstAllocator * GstAllocator *
gst_va_allocator_new (GstVaDisplay * display, GArray * surface_formats) gst_va_allocator_new (GstVaDisplay * display, GArray * surface_formats)
{ {
@ -1344,9 +1308,7 @@ gst_va_allocator_flush (GstAllocator * allocator)
static gboolean static gboolean
gst_va_allocator_try (GstAllocator * allocator) gst_va_allocator_try (GstAllocator * allocator)
{ {
GstMemory *mem;
GstVaAllocator *self = GST_VA_ALLOCATOR (allocator); GstVaAllocator *self = GST_VA_ALLOCATOR (allocator);
GstVideoInfo info = self->info;
self->fourcc = 0; self->fourcc = 0;
self->rt_format = 0; self->rt_format = 0;
@ -1371,12 +1333,10 @@ gst_va_allocator_try (GstAllocator * allocator)
return FALSE; return FALSE;
} }
mem = gst_va_allocator_alloc_full (allocator, &info); if (!_update_image_info (self)) {
if (!mem) GST_ERROR_OBJECT (allocator, "Failed to update allocator info");
return FALSE; return FALSE;
gst_memory_unref (mem); }
self->info = info;
GST_INFO_OBJECT (self, GST_INFO_OBJECT (self,
"va allocator info, surface format: %s, image format: %s, " "va allocator info, surface format: %s, image format: %s, "