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;
gboolean has_copy;
GRecMutex lock;
GstVaFilter *filter;
};
@ -77,6 +79,7 @@ gst_va_surface_copy_new (GstVaDisplay * display, GstVideoInfo * vinfo)
self->has_copy = _has_copy (display);
self->info = *vinfo;
self->filter = NULL;
g_rec_mutex_init (&self->lock);
if (gst_va_display_has_vpp (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_clear_object (&self->filter);
}
g_rec_mutex_clear (&self->lock);
g_slice_free (GstVaSurfaceCopy, self);
}
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 = {
.surface = src,
};
GstVaSample gst_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
@ -126,7 +139,7 @@ gst_va_surface_copy (GstVaSurfaceCopy * self, VASurfaceID dst, VASurfaceID src)
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);
return TRUE;
}