va: filter, vpp: add and use GstVaSample struct

This new struct describes the input and output GstBuffers to
post-process, including VA flags. It also contains the VASurfaceID and
VARectangle, but those are private, completed inside GstVaFilter.

It is used for pass arguments to gst_va_filter_convert_surface() function.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2058>
This commit is contained in:
Víctor Manuel Jáquez Leal 2021-01-23 12:53:25 +01:00
parent b2a4e066ab
commit c770469a8a
3 changed files with 60 additions and 26 deletions

View File

@ -28,6 +28,7 @@
#include <va/va_drmcommon.h> #include <va/va_drmcommon.h>
#include "gstvaallocator.h"
#include "gstvacaps.h" #include "gstvacaps.h"
#include "gstvavideoformat.h" #include "gstvavideoformat.h"
@ -1234,8 +1235,25 @@ gst_va_filter_drop_filter_buffers (GstVaFilter * self)
} }
static gboolean static gboolean
_create_pipeline_buffer (GstVaFilter * self, VASurfaceID surface, _fill_va_sample (GstVaFilter * self, GstVaSample * sample,
VARectangle * src_rect, VARectangle * dst_rect, VABufferID * buffer) GstPadDirection direction)
{
sample->surface = gst_va_buffer_get_surface (sample->buffer);
if (sample->surface == VA_INVALID_ID)
return FALSE;
/* TODO: handle GstVideoCropMeta */
GST_OBJECT_LOCK (self);
sample->rect = (direction == GST_PAD_SRC) ?
self->output_region : self->input_region;
GST_OBJECT_UNLOCK (self);
return TRUE;
}
static gboolean
_create_pipeline_buffer (GstVaFilter * self, GstVaSample * src,
GstVaSample * dst, VABufferID * buffer)
{ {
VADisplay dpy; VADisplay dpy;
VAStatus status; VAStatus status;
@ -1252,16 +1270,18 @@ _create_pipeline_buffer (GstVaFilter * self, VASurfaceID surface,
} }
params = (VAProcPipelineParameterBuffer) { params = (VAProcPipelineParameterBuffer) {
.surface = surface, .surface = src->surface,
.surface_region = src_rect, .surface_region = &src->rect,
.surface_color_standard = self->input_color_standard, .surface_color_standard = self->input_color_standard,
.output_region = dst_rect, .output_region = &dst->rect,
.output_background_color = 0xff000000, /* ARGB black */ .output_background_color = 0xff000000, /* ARGB black */
.output_color_standard = self->output_color_standard, .output_color_standard = self->output_color_standard,
.filters = filters, .filters = filters,
.num_filters = num_filters, .num_filters = num_filters,
.rotation_state = self->rotation, .rotation_state = self->rotation,
.mirror_state = self->mirror, .mirror_state = self->mirror,
.input_surface_flag = src->flags,
.output_surface_flag = dst->flags,
.input_color_properties = self->input_color_properties, .input_color_properties = self->input_color_properties,
.output_color_properties = self->output_color_properties, .output_color_properties = self->output_color_properties,
}; };
@ -1286,31 +1306,28 @@ _create_pipeline_buffer (GstVaFilter * self, VASurfaceID surface,
} }
gboolean gboolean
gst_va_filter_convert_surface (GstVaFilter * self, VASurfaceID in_surface, gst_va_filter_convert_surface (GstVaFilter * self, GstVaSample * src,
VASurfaceID out_surface) GstVaSample * dst)
{ {
VABufferID buffer; VABufferID buffer, *filters = NULL;
VADisplay dpy; VADisplay dpy;
VAProcPipelineCaps pipeline_caps = { 0, }; VAProcPipelineCaps pipeline_caps = { 0, };
VARectangle src_rect;
VARectangle dst_rect;
VAStatus status; VAStatus status;
VABufferID *filters = NULL;
guint32 num_filters = 0;
gboolean ret = FALSE; gboolean ret = FALSE;
guint32 num_filters = 0;
g_return_val_if_fail (GST_IS_VA_FILTER (self), FALSE); g_return_val_if_fail (GST_IS_VA_FILTER (self), FALSE);
g_return_val_if_fail (in_surface != VA_INVALID_ID g_return_val_if_fail (src && GST_IS_BUFFER (src->buffer), FALSE);
&& out_surface != VA_INVALID_ID, FALSE); g_return_val_if_fail (dst && GST_IS_BUFFER (dst->buffer), FALSE);
if (!gst_va_filter_is_open (self)) if (!gst_va_filter_is_open (self))
return FALSE; return FALSE;
GST_TRACE_OBJECT (self, "Processing %#x", in_surface); if (!(_fill_va_sample (self, src, GST_PAD_SINK)
&& _fill_va_sample (self, dst, GST_PAD_SRC)))
return FALSE;
GST_OBJECT_LOCK (self); GST_OBJECT_LOCK (self);
src_rect = self->input_region;
dst_rect = self->output_region;
if (self->filters) { if (self->filters) {
g_array_ref (self->filters); g_array_ref (self->filters);
@ -1331,12 +1348,11 @@ gst_va_filter_convert_surface (GstVaFilter * self, VASurfaceID in_surface,
return FALSE; return FALSE;
} }
if (!_create_pipeline_buffer (self, in_surface, &src_rect, &dst_rect, if (!_create_pipeline_buffer (self, src, dst, &buffer))
&buffer))
return FALSE; return FALSE;
gst_va_display_lock (self->display); gst_va_display_lock (self->display);
status = vaBeginPicture (dpy, self->context, out_surface); status = vaBeginPicture (dpy, self->context, dst->surface);
gst_va_display_unlock (self->display); gst_va_display_unlock (self->display);
if (status != VA_STATUS_SUCCESS) { if (status != VA_STATUS_SUCCESS) {
GST_ERROR_OBJECT (self, "vaBeginPicture: %s", vaErrorStr (status)); GST_ERROR_OBJECT (self, "vaBeginPicture: %s", vaErrorStr (status));

View File

@ -46,6 +46,17 @@ enum {
GST_VA_FILTER_PROP_LAST GST_VA_FILTER_PROP_LAST
}; };
typedef struct _GstVaSample GstVaSample;
struct _GstVaSample
{
GstBuffer *buffer;
guint32 flags;
/*< private >*/
VASurfaceID surface;
VARectangle rect;
};
GstVaFilter * gst_va_filter_new (GstVaDisplay * display); GstVaFilter * gst_va_filter_new (GstVaDisplay * display);
gboolean gst_va_filter_open (GstVaFilter * self); gboolean gst_va_filter_open (GstVaFilter * self);
gboolean gst_va_filter_close (GstVaFilter * self); gboolean gst_va_filter_close (GstVaFilter * self);
@ -72,7 +83,7 @@ gboolean gst_va_filter_add_filter_buffer (GstVaFilter * self,
guint num); guint num);
gboolean gst_va_filter_drop_filter_buffers (GstVaFilter * self); gboolean gst_va_filter_drop_filter_buffers (GstVaFilter * self);
gboolean gst_va_filter_convert_surface (GstVaFilter * self, gboolean gst_va_filter_convert_surface (GstVaFilter * self,
VASurfaceID in_surface, GstVaSample * src,
VASurfaceID out_surface); GstVaSample * dest);
G_END_DECLS G_END_DECLS

View File

@ -1235,7 +1235,7 @@ gst_va_vpp_transform (GstBaseTransform * trans, GstBuffer * inbuf,
GstVaVpp *self = GST_VA_VPP (trans); GstVaVpp *self = GST_VA_VPP (trans);
GstBuffer *buf = NULL; GstBuffer *buf = NULL;
GstFlowReturn res = GST_FLOW_OK; GstFlowReturn res = GST_FLOW_OK;
VASurfaceID in_surface, out_surface; GstVaSample src, dst;
if (G_UNLIKELY (!self->negotiated)) if (G_UNLIKELY (!self->negotiated))
goto unknown_format; goto unknown_format;
@ -1244,10 +1244,17 @@ gst_va_vpp_transform (GstBaseTransform * trans, GstBuffer * inbuf,
if (res != GST_FLOW_OK) if (res != GST_FLOW_OK)
return res; return res;
in_surface = gst_va_buffer_get_surface (buf); /* *INDENT-OFF* */
out_surface = gst_va_buffer_get_surface (outbuf); src = (GstVaSample) {
.buffer = buf,
};
if (!gst_va_filter_convert_surface (self->filter, in_surface, out_surface)) { dst = (GstVaSample) {
.buffer = outbuf,
};
/* *INDENT-ON* */
if (!gst_va_filter_convert_surface (self->filter, &src, &dst)) {
gst_buffer_set_flags (outbuf, GST_BUFFER_FLAG_CORRUPTED); gst_buffer_set_flags (outbuf, GST_BUFFER_FLAG_CORRUPTED);
} }