diff options
author | U. Artie Eoff <ullysses.a.eoff@intel.com> | 2020-01-10 09:54:30 -0800 |
---|---|---|
committer | Víctor Manuel Jáquez Leal <vjaquez@igalia.com> | 2020-01-14 15:07:32 +0000 |
commit | 1363b53a9f3654f70dc63addaa15337a533c1ca2 (patch) | |
tree | 542d7c9836c445fc2429a20886ca63d0f9205b3c /gst-libs | |
parent | 36fd4d5d8ad17abdbb0388c2a23b6b786bb9d75f (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
Diffstat (limited to 'gst-libs')
-rw-r--r-- | gst-libs/gst/vaapi/gstvaapiblend.c | 98 | ||||
-rw-r--r-- | gst-libs/gst/vaapi/gstvaapiblend.h | 19 |
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); |