va: Use a lock to protect the surface copy by using vpp.

If we use vpp to do the surface copy, its operation is not atomic.
 We need to maintain the filter's context unchanged during the whole
 copy progress.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1373>
This commit is contained in:
He Junyan 2021-11-23 16:35:16 +08:00 committed by GStreamer Marge Bot
parent 954f7cf88c
commit b5c07e11ca

View file

@ -34,6 +34,8 @@ struct _GstVaSurfaceCopy
GstVideoInfo info; GstVideoInfo info;
gboolean has_copy; gboolean has_copy;
GRecMutex lock;
GstVaFilter *filter; GstVaFilter *filter;
}; };
@ -77,6 +79,7 @@ gst_va_surface_copy_new (GstVaDisplay * display, GstVideoInfo * vinfo)
self->has_copy = _has_copy (display); self->has_copy = _has_copy (display);
self->info = *vinfo; self->info = *vinfo;
self->filter = NULL; self->filter = NULL;
g_rec_mutex_init (&self->lock);
if (gst_va_display_has_vpp (display)) { if (gst_va_display_has_vpp (display)) {
self->filter = gst_va_filter_new (display); self->filter = gst_va_filter_new (display);
@ -98,19 +101,29 @@ gst_va_surface_copy_free (GstVaSurfaceCopy * self)
gst_va_filter_close (self->filter); gst_va_filter_close (self->filter);
gst_clear_object (&self->filter); gst_clear_object (&self->filter);
} }
g_rec_mutex_clear (&self->lock);
g_slice_free (GstVaSurfaceCopy, self); g_slice_free (GstVaSurfaceCopy, self);
} }
static gboolean static gboolean
_vpp_copy_surface (GstVaFilter * filter, VASurfaceID dst, VASurfaceID src) _vpp_copy_surface (GstVaSurfaceCopy * self, VASurfaceID dst, VASurfaceID src)
{ {
gboolean ret;
GstVaSample gst_src = { GstVaSample gst_src = {
.surface = src, .surface = src,
}; };
GstVaSample gst_dst = { GstVaSample gst_dst = {
.surface = dst, .surface = dst,
}; };
return gst_va_filter_process (filter, &gst_src, &gst_dst);
g_rec_mutex_lock (&self->lock);
ret = gst_va_filter_process (self->filter, &gst_src, &gst_dst);
g_rec_mutex_unlock (&self->lock);
return ret;
} }
gboolean gboolean
@ -126,7 +139,7 @@ gst_va_surface_copy (GstVaSurfaceCopy * self, VASurfaceID dst, VASurfaceID src)
return TRUE; return TRUE;
} }
if (self->filter && _vpp_copy_surface (self->filter, dst, src)) { if (self->filter && _vpp_copy_surface (self, dst, src)) {
GST_LOG ("VPP copy of %#x to %#x", src, dst); GST_LOG ("VPP copy of %#x to %#x", src, dst);
return TRUE; return TRUE;
} }