summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorU. Artie Eoff <ullysses.a.eoff@intel.com>2020-01-10 09:54:30 -0800
committerVíctor Manuel Jáquez Leal <vjaquez@igalia.com>2020-01-14 15:07:32 +0000
commit1363b53a9f3654f70dc63addaa15337a533c1ca2 (patch)
tree542d7c9836c445fc2429a20886ca63d0f9205b3c
parent36fd4d5d8ad17abdbb0388c2a23b6b786bb9d75f (diff)
libs: blend: add surface generator API
This new API allows the user to call a single method (process) which handles the [display] lock/unlock logic internally for them. This API supersedes the risky begin, render, end API. It eliminates the need for the user to call a lock method (process_begin) before processing the input buffers (process_render) and calling an unlock method (process_end) afterwards. See #219
-rw-r--r--gst-libs/gst/vaapi/gstvaapiblend.c98
-rw-r--r--gst-libs/gst/vaapi/gstvaapiblend.h19
2 files changed, 117 insertions, 0 deletions
diff --git a/gst-libs/gst/vaapi/gstvaapiblend.c b/gst-libs/gst/vaapi/gstvaapiblend.c
index 6a407f35..426785eb 100644
--- a/gst-libs/gst/vaapi/gstvaapiblend.c
+++ b/gst-libs/gst/vaapi/gstvaapiblend.c
@@ -367,3 +367,101 @@ gst_vaapi_blend_process_end (GstVaapiBlend * blend)
return TRUE;
}
+
+static gboolean
+gst_vaapi_blend_process_unlocked (GstVaapiBlend * blend,
+ GstVaapiSurface * output, GstVaapiBlendSurfaceGenerator * generator)
+{
+ VAStatus va_status;
+ VADisplay va_display;
+ GstVaapiBlendSurface *current;
+
+ va_display = GST_VAAPI_DISPLAY_VADISPLAY (blend->display);
+
+ va_status = vaBeginPicture (va_display, blend->va_context,
+ GST_VAAPI_SURFACE_ID (output));
+ if (!vaapi_check_status (va_status, "vaBeginPicture()"))
+ return FALSE;
+
+ current = generator->next (generator);
+ for (; current; current = generator->next (generator)) {
+ VAProcPipelineParameterBuffer *param = NULL;
+ VABufferID id = VA_INVALID_ID;
+ VARectangle src_rect = { 0, };
+ VARectangle dst_rect = { 0, };
+#if VA_CHECK_VERSION(1,1,0)
+ VABlendState blend_state;
+#endif
+
+ if (!current->surface)
+ return FALSE;
+
+ /* Build surface region (source) */
+ src_rect.width = GST_VAAPI_SURFACE_WIDTH (current->surface);
+ src_rect.height = GST_VAAPI_SURFACE_HEIGHT (current->surface);
+ if (current->crop) {
+ if ((current->crop->x + current->crop->width > src_rect.width) ||
+ (current->crop->y + current->crop->height > src_rect.height))
+ return FALSE;
+ src_rect.x = current->crop->x;
+ src_rect.y = current->crop->y;
+ src_rect.width = current->crop->width;
+ src_rect.height = current->crop->height;
+ }
+
+ /* Build output region (target) */
+ dst_rect.x = current->target.x;
+ dst_rect.y = current->target.y;
+ dst_rect.width = current->target.width;
+ dst_rect.height = current->target.height;
+
+ if (!vaapi_create_buffer (va_display, blend->va_context,
+ VAProcPipelineParameterBufferType, sizeof (*param), NULL, &id,
+ (gpointer *) & param))
+ return FALSE;
+
+ memset (param, 0, sizeof (*param));
+
+ param->surface = GST_VAAPI_SURFACE_ID (current->surface);
+ param->surface_region = &src_rect;
+ param->output_region = &dst_rect;
+ param->output_background_color = 0xff000000;
+
+#if VA_CHECK_VERSION(1,1,0)
+ blend_state.flags = VA_BLEND_GLOBAL_ALPHA;
+ blend_state.global_alpha = current->alpha;
+ param->blend_state = &blend_state;
+#endif
+
+ vaapi_unmap_buffer (va_display, id, NULL);
+
+ va_status = vaRenderPicture (va_display, blend->va_context, &id, 1);
+ vaapi_destroy_buffer (va_display, &id);
+ if (!vaapi_check_status (va_status, "vaRenderPicture()"))
+ return FALSE;
+ }
+
+ va_status = vaEndPicture (va_display, blend->va_context);
+ if (!vaapi_check_status (va_status, "vaEndPicture()"))
+ return FALSE;
+
+ return TRUE;
+}
+
+gboolean
+gst_vaapi_blend_process (GstVaapiBlend * blend, GstVaapiSurface * output,
+ GstVaapiBlendSurfaceGenerator * generator)
+{
+ gboolean result;
+
+ g_return_val_if_fail (blend != NULL, FALSE);
+ g_return_val_if_fail (output != NULL, FALSE);
+ g_return_val_if_fail (generator != NULL, FALSE);
+ g_return_val_if_fail (generator->next != NULL, FALSE);
+
+ GST_VAAPI_DISPLAY_LOCK (blend->display);
+ result = gst_vaapi_blend_process_unlocked (blend, output, generator);
+ GST_VAAPI_DISPLAY_UNLOCK (blend->display);
+
+ return result;
+}
diff --git a/gst-libs/gst/vaapi/gstvaapiblend.h b/gst-libs/gst/vaapi/gstvaapiblend.h
index 60c30c83..6119c794 100644
--- a/gst-libs/gst/vaapi/gstvaapiblend.h
+++ b/gst-libs/gst/vaapi/gstvaapiblend.h
@@ -35,6 +35,21 @@ G_BEGIN_DECLS
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_BLEND))
typedef struct _GstVaapiBlend GstVaapiBlend;
+typedef struct _GstVaapiBlendSurface GstVaapiBlendSurface;
+typedef struct _GstVaapiBlendSurfaceGenerator GstVaapiBlendSurfaceGenerator;
+
+struct _GstVaapiBlendSurface
+{
+ GstVaapiSurface const *surface;
+ const GstVaapiRectangle *crop;
+ GstVaapiRectangle target;
+ gdouble alpha;
+};
+
+struct _GstVaapiBlendSurfaceGenerator
+{
+ GstVaapiBlendSurface* (*next)();
+};
GstVaapiBlend *
gst_vaapi_blend_new (GstVaapiDisplay * display);
@@ -44,6 +59,10 @@ gst_vaapi_blend_replace (GstVaapiBlend ** old_blend_ptr,
GstVaapiBlend * new_blend);
gboolean
+gst_vaapi_blend_process (GstVaapiBlend * blend, GstVaapiSurface * output,
+ GstVaapiBlendSurfaceGenerator * generator);
+
+gboolean
gst_vaapi_blend_process_begin (GstVaapiBlend * blend,
GstVaapiSurface * surface);