mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-18 22:36:33 +00:00
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
This commit is contained in:
parent
36fd4d5d8a
commit
1363b53a9f
2 changed files with 117 additions and 0 deletions
|
@ -367,3 +367,101 @@ gst_vaapi_blend_process_end (GstVaapiBlend * blend)
|
||||||
|
|
||||||
return TRUE;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -35,6 +35,21 @@ G_BEGIN_DECLS
|
||||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_BLEND))
|
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_BLEND))
|
||||||
|
|
||||||
typedef struct _GstVaapiBlend GstVaapiBlend;
|
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 *
|
GstVaapiBlend *
|
||||||
gst_vaapi_blend_new (GstVaapiDisplay * display);
|
gst_vaapi_blend_new (GstVaapiDisplay * display);
|
||||||
|
@ -43,6 +58,10 @@ void
|
||||||
gst_vaapi_blend_replace (GstVaapiBlend ** old_blend_ptr,
|
gst_vaapi_blend_replace (GstVaapiBlend ** old_blend_ptr,
|
||||||
GstVaapiBlend * new_blend);
|
GstVaapiBlend * new_blend);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_vaapi_blend_process (GstVaapiBlend * blend, GstVaapiSurface * output,
|
||||||
|
GstVaapiBlendSurfaceGenerator * generator);
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gst_vaapi_blend_process_begin (GstVaapiBlend * blend,
|
gst_vaapi_blend_process_begin (GstVaapiBlend * blend,
|
||||||
GstVaapiSurface * surface);
|
GstVaapiSurface * surface);
|
||||||
|
|
Loading…
Reference in a new issue