mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-05 06:58:56 +00:00
context: move overlay composition to separate files.
Move GstVideoOverlayComposition handling to separate source files. This helps keeing GstVaapiContext core implementation to the bare minimal, i.e. simpy helpers to create a VA context and handle pool of associated VA surfaces.
This commit is contained in:
parent
c85b080688
commit
3b714c8913
6 changed files with 511 additions and 404 deletions
|
@ -47,6 +47,7 @@ libgstvaapi_libs = \
|
||||||
libgstvaapi_source_c = \
|
libgstvaapi_source_c = \
|
||||||
gstvaapicodec_objects.c \
|
gstvaapicodec_objects.c \
|
||||||
gstvaapicontext.c \
|
gstvaapicontext.c \
|
||||||
|
gstvaapicontext_overlay.c \
|
||||||
gstvaapidecoder.c \
|
gstvaapidecoder.c \
|
||||||
gstvaapidecoder_dpb.c \
|
gstvaapidecoder_dpb.c \
|
||||||
gstvaapidecoder_h264.c \
|
gstvaapidecoder_h264.c \
|
||||||
|
@ -110,6 +111,7 @@ libgstvaapi_source_priv_h = \
|
||||||
gstvaapicodec_objects.h \
|
gstvaapicodec_objects.h \
|
||||||
gstvaapicompat.h \
|
gstvaapicompat.h \
|
||||||
gstvaapicontext.h \
|
gstvaapicontext.h \
|
||||||
|
gstvaapicontext_overlay.h \
|
||||||
gstvaapidebug.h \
|
gstvaapidebug.h \
|
||||||
gstvaapidecoder_dpb.h \
|
gstvaapidecoder_dpb.h \
|
||||||
gstvaapidecoder_objects.h \
|
gstvaapidecoder_objects.h \
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "sysdeps.h"
|
#include "sysdeps.h"
|
||||||
#include "gstvaapicompat.h"
|
#include "gstvaapicompat.h"
|
||||||
#include "gstvaapicontext.h"
|
#include "gstvaapicontext.h"
|
||||||
|
#include "gstvaapicontext_overlay.h"
|
||||||
#include "gstvaapidisplay_priv.h"
|
#include "gstvaapidisplay_priv.h"
|
||||||
#include "gstvaapiobject_priv.h"
|
#include "gstvaapiobject_priv.h"
|
||||||
#include "gstvaapisurface.h"
|
#include "gstvaapisurface.h"
|
||||||
|
@ -37,324 +38,11 @@
|
||||||
#include "gstvaapisurfacepool.h"
|
#include "gstvaapisurfacepool.h"
|
||||||
#include "gstvaapisurfaceproxy.h"
|
#include "gstvaapisurfaceproxy.h"
|
||||||
#include "gstvaapivideopool_priv.h"
|
#include "gstvaapivideopool_priv.h"
|
||||||
#include "gstvaapiimage.h"
|
|
||||||
#include "gstvaapisubpicture.h"
|
|
||||||
#include "gstvaapiutils.h"
|
#include "gstvaapiutils.h"
|
||||||
|
|
||||||
#define DEBUG 1
|
#define DEBUG 1
|
||||||
#include "gstvaapidebug.h"
|
#include "gstvaapidebug.h"
|
||||||
|
|
||||||
typedef struct _GstVaapiOverlayRectangle GstVaapiOverlayRectangle;
|
|
||||||
struct _GstVaapiOverlayRectangle
|
|
||||||
{
|
|
||||||
GstVaapiContext *context;
|
|
||||||
GstVaapiSubpicture *subpicture;
|
|
||||||
GstVaapiRectangle render_rect;
|
|
||||||
guint seq_num;
|
|
||||||
guint layer_id;
|
|
||||||
GstBuffer *rect_buffer;
|
|
||||||
GstVideoOverlayRectangle *rect;
|
|
||||||
guint is_associated:1;
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gst_video_overlay_rectangle_replace (GstVideoOverlayRectangle ** old_rect_ptr,
|
|
||||||
GstVideoOverlayRectangle * new_rect)
|
|
||||||
{
|
|
||||||
gst_mini_object_replace ((GstMiniObject **) old_rect_ptr,
|
|
||||||
GST_MINI_OBJECT_CAST (new_rect));
|
|
||||||
}
|
|
||||||
|
|
||||||
#define overlay_rectangle_ref(overlay) \
|
|
||||||
gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(overlay))
|
|
||||||
|
|
||||||
#define overlay_rectangle_unref(overlay) \
|
|
||||||
gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(overlay))
|
|
||||||
|
|
||||||
#define overlay_rectangle_replace(old_overlay_ptr, new_overlay) \
|
|
||||||
gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_overlay_ptr), \
|
|
||||||
(GstVaapiMiniObject *)(new_overlay))
|
|
||||||
|
|
||||||
static void overlay_rectangle_finalize (GstVaapiOverlayRectangle * overlay);
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
overlay_rectangle_associate (GstVaapiOverlayRectangle * overlay);
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
overlay_rectangle_deassociate (GstVaapiOverlayRectangle * overlay);
|
|
||||||
|
|
||||||
static inline const GstVaapiMiniObjectClass *
|
|
||||||
overlay_rectangle_class (void)
|
|
||||||
{
|
|
||||||
static const GstVaapiMiniObjectClass GstVaapiOverlayRectangleClass = {
|
|
||||||
sizeof (GstVaapiOverlayRectangle),
|
|
||||||
(GDestroyNotify) overlay_rectangle_finalize
|
|
||||||
};
|
|
||||||
return &GstVaapiOverlayRectangleClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
static GstVaapiOverlayRectangle *
|
|
||||||
overlay_rectangle_new (GstVideoOverlayRectangle * rect,
|
|
||||||
GstVaapiContext * context, guint layer_id)
|
|
||||||
{
|
|
||||||
GstVaapiOverlayRectangle *overlay;
|
|
||||||
GstVaapiRectangle *render_rect;
|
|
||||||
guint width, height, flags;
|
|
||||||
gint x, y;
|
|
||||||
|
|
||||||
overlay = (GstVaapiOverlayRectangle *)
|
|
||||||
gst_vaapi_mini_object_new0 (overlay_rectangle_class ());
|
|
||||||
if (!overlay)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
overlay->context = context;
|
|
||||||
overlay->seq_num = gst_video_overlay_rectangle_get_seqnum (rect);
|
|
||||||
overlay->layer_id = layer_id;
|
|
||||||
overlay->rect = gst_video_overlay_rectangle_ref (rect);
|
|
||||||
|
|
||||||
flags = gst_video_overlay_rectangle_get_flags (rect);
|
|
||||||
gst_buffer_replace (&overlay->rect_buffer,
|
|
||||||
gst_video_overlay_rectangle_get_pixels_unscaled_raw (rect, flags));
|
|
||||||
if (!overlay->rect_buffer)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
overlay->subpicture =
|
|
||||||
gst_vaapi_subpicture_new_from_overlay_rectangle (GST_VAAPI_OBJECT_DISPLAY
|
|
||||||
(context), rect);
|
|
||||||
if (!overlay->subpicture)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
gst_video_overlay_rectangle_get_render_rectangle (rect,
|
|
||||||
&x, &y, &width, &height);
|
|
||||||
render_rect = &overlay->render_rect;
|
|
||||||
render_rect->x = x;
|
|
||||||
render_rect->y = y;
|
|
||||||
render_rect->width = width;
|
|
||||||
render_rect->height = height;
|
|
||||||
return overlay;
|
|
||||||
|
|
||||||
error:
|
|
||||||
overlay_rectangle_unref (overlay);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
overlay_rectangle_finalize (GstVaapiOverlayRectangle * overlay)
|
|
||||||
{
|
|
||||||
gst_buffer_replace (&overlay->rect_buffer, NULL);
|
|
||||||
gst_video_overlay_rectangle_unref (overlay->rect);
|
|
||||||
|
|
||||||
if (overlay->subpicture) {
|
|
||||||
overlay_rectangle_deassociate (overlay);
|
|
||||||
gst_vaapi_object_unref (overlay->subpicture);
|
|
||||||
overlay->subpicture = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
overlay_rectangle_associate (GstVaapiOverlayRectangle * overlay)
|
|
||||||
{
|
|
||||||
GstVaapiSubpicture *const subpicture = overlay->subpicture;
|
|
||||||
GPtrArray *const surfaces = overlay->context->surfaces;
|
|
||||||
guint i, n_associated;
|
|
||||||
|
|
||||||
if (overlay->is_associated)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
n_associated = 0;
|
|
||||||
for (i = 0; i < surfaces->len; i++) {
|
|
||||||
GstVaapiSurface *const surface = g_ptr_array_index (surfaces, i);
|
|
||||||
if (gst_vaapi_surface_associate_subpicture (surface, subpicture,
|
|
||||||
NULL, &overlay->render_rect))
|
|
||||||
n_associated++;
|
|
||||||
}
|
|
||||||
|
|
||||||
overlay->is_associated = TRUE;
|
|
||||||
return n_associated == surfaces->len;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
overlay_rectangle_deassociate (GstVaapiOverlayRectangle * overlay)
|
|
||||||
{
|
|
||||||
GstVaapiSubpicture *const subpicture = overlay->subpicture;
|
|
||||||
GPtrArray *const surfaces = overlay->context->surfaces;
|
|
||||||
guint i, n_associated;
|
|
||||||
|
|
||||||
if (!overlay->is_associated)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
n_associated = surfaces->len;
|
|
||||||
for (i = 0; i < surfaces->len; i++) {
|
|
||||||
GstVaapiSurface *const surface = g_ptr_array_index (surfaces, i);
|
|
||||||
if (gst_vaapi_surface_deassociate_subpicture (surface, subpicture))
|
|
||||||
n_associated--;
|
|
||||||
}
|
|
||||||
|
|
||||||
overlay->is_associated = FALSE;
|
|
||||||
return n_associated == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
overlay_rectangle_changed_pixels (GstVaapiOverlayRectangle * overlay,
|
|
||||||
GstVideoOverlayRectangle * rect)
|
|
||||||
{
|
|
||||||
guint flags;
|
|
||||||
GstBuffer *buffer;
|
|
||||||
|
|
||||||
if (overlay->seq_num == gst_video_overlay_rectangle_get_seqnum (rect))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
flags =
|
|
||||||
to_GstVideoOverlayFormatFlags (gst_vaapi_subpicture_get_flags
|
|
||||||
(overlay->subpicture));
|
|
||||||
|
|
||||||
buffer = gst_video_overlay_rectangle_get_pixels_unscaled_raw (rect, flags);
|
|
||||||
if (!buffer)
|
|
||||||
return FALSE;
|
|
||||||
#if GST_CHECK_VERSION(1,0,0)
|
|
||||||
{
|
|
||||||
const guint n_blocks = gst_buffer_n_memory (buffer);
|
|
||||||
gsize ofs;
|
|
||||||
guint i;
|
|
||||||
|
|
||||||
if (buffer == overlay->rect_buffer)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
if (n_blocks != gst_buffer_n_memory (overlay->rect_buffer))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
for (i = 0; i < n_blocks; i++) {
|
|
||||||
GstMemory *const mem1 = gst_buffer_peek_memory (buffer, i);
|
|
||||||
GstMemory *const mem2 = gst_buffer_peek_memory (overlay->rect_buffer, i);
|
|
||||||
if (!gst_memory_is_span (mem1, mem2, &ofs))
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (GST_BUFFER_DATA (overlay->rect_buffer) != GST_BUFFER_DATA (buffer))
|
|
||||||
return FALSE;
|
|
||||||
#endif
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
overlay_rectangle_changed_render_rect (GstVaapiOverlayRectangle * overlay,
|
|
||||||
GstVideoOverlayRectangle * rect)
|
|
||||||
{
|
|
||||||
GstVaapiRectangle *const render_rect = &overlay->render_rect;
|
|
||||||
guint width, height;
|
|
||||||
gint x, y;
|
|
||||||
|
|
||||||
gst_video_overlay_rectangle_get_render_rectangle (rect,
|
|
||||||
&x, &y, &width, &height);
|
|
||||||
|
|
||||||
if (x == render_rect->x &&
|
|
||||||
y == render_rect->y &&
|
|
||||||
width == render_rect->width && height == render_rect->height)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
render_rect->x = x;
|
|
||||||
render_rect->y = y;
|
|
||||||
render_rect->width = width;
|
|
||||||
render_rect->height = height;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline gboolean
|
|
||||||
overlay_rectangle_update_global_alpha (GstVaapiOverlayRectangle * overlay,
|
|
||||||
GstVideoOverlayRectangle * rect)
|
|
||||||
{
|
|
||||||
#ifdef HAVE_GST_VIDEO_OVERLAY_HWCAPS
|
|
||||||
const guint flags = gst_video_overlay_rectangle_get_flags (rect);
|
|
||||||
if (!(flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA))
|
|
||||||
return TRUE;
|
|
||||||
#endif
|
|
||||||
return gst_vaapi_subpicture_set_global_alpha (overlay->subpicture,
|
|
||||||
gst_video_overlay_rectangle_get_global_alpha (rect));
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
overlay_rectangle_update (GstVaapiOverlayRectangle * overlay,
|
|
||||||
GstVideoOverlayRectangle * rect, gboolean * reassociate_ptr)
|
|
||||||
{
|
|
||||||
if (overlay_rectangle_changed_pixels (overlay, rect))
|
|
||||||
return FALSE;
|
|
||||||
if (overlay_rectangle_changed_render_rect (overlay, rect))
|
|
||||||
*reassociate_ptr = TRUE;
|
|
||||||
if (!overlay_rectangle_update_global_alpha (overlay, rect))
|
|
||||||
return FALSE;
|
|
||||||
gst_video_overlay_rectangle_replace (&overlay->rect, rect);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline GPtrArray *
|
|
||||||
overlay_new (void)
|
|
||||||
{
|
|
||||||
return g_ptr_array_new_with_free_func (
|
|
||||||
(GDestroyNotify) gst_vaapi_mini_object_unref);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
overlay_destroy (GPtrArray ** overlay_ptr)
|
|
||||||
{
|
|
||||||
GPtrArray *const overlay = *overlay_ptr;
|
|
||||||
|
|
||||||
if (!overlay)
|
|
||||||
return;
|
|
||||||
g_ptr_array_unref (overlay);
|
|
||||||
*overlay_ptr = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
overlay_clear (GPtrArray * overlay)
|
|
||||||
{
|
|
||||||
if (overlay && overlay->len > 0)
|
|
||||||
g_ptr_array_remove_range (overlay, 0, overlay->len);
|
|
||||||
}
|
|
||||||
|
|
||||||
static GstVaapiOverlayRectangle *
|
|
||||||
overlay_lookup (GPtrArray * overlays, GstVideoOverlayRectangle * rect)
|
|
||||||
{
|
|
||||||
guint i;
|
|
||||||
|
|
||||||
for (i = 0; i < overlays->len; i++) {
|
|
||||||
GstVaapiOverlayRectangle *const overlay = g_ptr_array_index (overlays, i);
|
|
||||||
|
|
||||||
if (overlay->rect == rect)
|
|
||||||
return overlay;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
overlay_reassociate (GPtrArray * overlays)
|
|
||||||
{
|
|
||||||
guint i;
|
|
||||||
|
|
||||||
for (i = 0; i < overlays->len; i++)
|
|
||||||
overlay_rectangle_deassociate (g_ptr_array_index (overlays, i));
|
|
||||||
|
|
||||||
for (i = 0; i < overlays->len; i++) {
|
|
||||||
if (!overlay_rectangle_associate (g_ptr_array_index (overlays, i)))
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
context_clear_overlay (GstVaapiContext * context)
|
|
||||||
{
|
|
||||||
overlay_clear (context->overlays[0]);
|
|
||||||
overlay_clear (context->overlays[1]);
|
|
||||||
context->overlay_id = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
context_destroy_overlay (GstVaapiContext * context)
|
|
||||||
{
|
|
||||||
context_clear_overlay (context);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
unref_surface_cb (GstVaapiSurface * surface)
|
unref_surface_cb (GstVaapiSurface * surface)
|
||||||
{
|
{
|
||||||
|
@ -365,7 +53,7 @@ unref_surface_cb (GstVaapiSurface * surface)
|
||||||
static void
|
static void
|
||||||
context_destroy_surfaces (GstVaapiContext * context)
|
context_destroy_surfaces (GstVaapiContext * context)
|
||||||
{
|
{
|
||||||
context_destroy_overlay (context);
|
gst_vaapi_context_overlay_reset (context);
|
||||||
|
|
||||||
if (context->surfaces) {
|
if (context->surfaces) {
|
||||||
g_ptr_array_unref (context->surfaces);
|
g_ptr_array_unref (context->surfaces);
|
||||||
|
@ -405,16 +93,6 @@ context_destroy (GstVaapiContext * context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
context_create_overlay (GstVaapiContext * context)
|
|
||||||
{
|
|
||||||
if (!context->overlays[0] || !context->overlays[1])
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
context_clear_overlay (context);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
context_create_surfaces (GstVaapiContext * context)
|
context_create_surfaces (GstVaapiContext * context)
|
||||||
{
|
{
|
||||||
|
@ -426,7 +104,7 @@ context_create_surfaces (GstVaapiContext * context)
|
||||||
/* Number of scratch surfaces beyond those used as reference */
|
/* Number of scratch surfaces beyond those used as reference */
|
||||||
const guint SCRATCH_SURFACES_COUNT = 4;
|
const guint SCRATCH_SURFACES_COUNT = 4;
|
||||||
|
|
||||||
if (!context_create_overlay (context))
|
if (!gst_vaapi_context_overlay_reset (context))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
num_surfaces = cip->ref_frames + SCRATCH_SURFACES_COUNT;
|
num_surfaces = cip->ref_frames + SCRATCH_SURFACES_COUNT;
|
||||||
|
@ -556,17 +234,15 @@ gst_vaapi_context_init (GstVaapiContext * context,
|
||||||
{
|
{
|
||||||
context->info = *cip;
|
context->info = *cip;
|
||||||
context->va_config = VA_INVALID_ID;
|
context->va_config = VA_INVALID_ID;
|
||||||
context->overlays[0] = overlay_new ();
|
gst_vaapi_context_overlay_init (context);
|
||||||
context->overlays[1] = overlay_new ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_vaapi_context_finalize (GstVaapiContext * context)
|
gst_vaapi_context_finalize (GstVaapiContext * context)
|
||||||
{
|
{
|
||||||
overlay_destroy (&context->overlays[0]);
|
|
||||||
overlay_destroy (&context->overlays[1]);
|
|
||||||
context_destroy (context);
|
context_destroy (context);
|
||||||
context_destroy_surfaces (context);
|
context_destroy_surfaces (context);
|
||||||
|
gst_vaapi_context_overlay_finalize (context);
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_VAAPI_OBJECT_DEFINE_CLASS (GstVaapiContext, gst_vaapi_context);
|
GST_VAAPI_OBJECT_DEFINE_CLASS (GstVaapiContext, gst_vaapi_context);
|
||||||
|
@ -718,75 +394,6 @@ gst_vaapi_context_get_surface_count (GstVaapiContext * context)
|
||||||
return gst_vaapi_video_pool_get_size (context->surfaces_pool);
|
return gst_vaapi_video_pool_get_size (context->surfaces_pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* gst_vaapi_context_apply_composition:
|
|
||||||
* @context: a #GstVaapiContext
|
|
||||||
* @composition: a #GstVideoOverlayComposition
|
|
||||||
*
|
|
||||||
* Applies video composition planes to all surfaces bound to @context.
|
|
||||||
* This helper function resets any additional subpictures the user may
|
|
||||||
* have associated himself. A %NULL @composition will also clear all
|
|
||||||
* the existing subpictures.
|
|
||||||
*
|
|
||||||
* Return value: %TRUE if all composition planes could be applied,
|
|
||||||
* %FALSE otherwise
|
|
||||||
*/
|
|
||||||
gboolean
|
|
||||||
gst_vaapi_context_apply_composition (GstVaapiContext * context,
|
|
||||||
GstVideoOverlayComposition * composition)
|
|
||||||
{
|
|
||||||
GPtrArray *curr_overlay, *next_overlay;
|
|
||||||
guint i, n_rectangles;
|
|
||||||
gboolean reassociate = FALSE;
|
|
||||||
|
|
||||||
g_return_val_if_fail (context != NULL, FALSE);
|
|
||||||
|
|
||||||
if (!context->surfaces)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (!composition) {
|
|
||||||
context_clear_overlay (context);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
curr_overlay = context->overlays[context->overlay_id];
|
|
||||||
next_overlay = context->overlays[context->overlay_id ^ 1];
|
|
||||||
overlay_clear (next_overlay);
|
|
||||||
|
|
||||||
n_rectangles = gst_video_overlay_composition_n_rectangles (composition);
|
|
||||||
for (i = 0; i < n_rectangles; i++) {
|
|
||||||
GstVideoOverlayRectangle *const rect =
|
|
||||||
gst_video_overlay_composition_get_rectangle (composition, i);
|
|
||||||
GstVaapiOverlayRectangle *overlay;
|
|
||||||
|
|
||||||
overlay = overlay_lookup (curr_overlay, rect);
|
|
||||||
if (overlay && overlay_rectangle_update (overlay, rect, &reassociate)) {
|
|
||||||
overlay_rectangle_ref (overlay);
|
|
||||||
if (overlay->layer_id != i)
|
|
||||||
reassociate = TRUE;
|
|
||||||
} else {
|
|
||||||
overlay = overlay_rectangle_new (rect, context, i);
|
|
||||||
if (!overlay) {
|
|
||||||
GST_WARNING ("could not create VA overlay rectangle");
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
reassociate = TRUE;
|
|
||||||
}
|
|
||||||
g_ptr_array_add (next_overlay, overlay);
|
|
||||||
}
|
|
||||||
|
|
||||||
overlay_clear (curr_overlay);
|
|
||||||
context->overlay_id ^= 1;
|
|
||||||
|
|
||||||
if (reassociate && !overlay_reassociate (next_overlay))
|
|
||||||
return FALSE;
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
error:
|
|
||||||
context_clear_overlay (context);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_vaapi_context_get_attribute:
|
* gst_vaapi_context_get_attribute:
|
||||||
* @context: a #GstVaapiContext
|
* @context: a #GstVaapiContext
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
#ifndef GST_VAAPI_CONTEXT_H
|
#ifndef GST_VAAPI_CONTEXT_H
|
||||||
#define GST_VAAPI_CONTEXT_H
|
#define GST_VAAPI_CONTEXT_H
|
||||||
|
|
||||||
#include <gst/video/video-overlay-composition.h>
|
|
||||||
#include "gstvaapiobject.h"
|
#include "gstvaapiobject.h"
|
||||||
#include "gstvaapiobject_priv.h"
|
#include "gstvaapiobject_priv.h"
|
||||||
#include "gstvaapiprofile.h"
|
#include "gstvaapiprofile.h"
|
||||||
|
@ -115,11 +114,6 @@ G_GNUC_INTERNAL
|
||||||
guint
|
guint
|
||||||
gst_vaapi_context_get_surface_count (GstVaapiContext * context);
|
gst_vaapi_context_get_surface_count (GstVaapiContext * context);
|
||||||
|
|
||||||
G_GNUC_INTERNAL
|
|
||||||
gboolean
|
|
||||||
gst_vaapi_context_apply_composition (GstVaapiContext * context,
|
|
||||||
GstVideoOverlayComposition * composition);
|
|
||||||
|
|
||||||
G_GNUC_INTERNAL
|
G_GNUC_INTERNAL
|
||||||
gboolean
|
gboolean
|
||||||
gst_vaapi_context_get_attribute (GstVaapiContext * context,
|
gst_vaapi_context_get_attribute (GstVaapiContext * context,
|
||||||
|
|
451
gst-libs/gst/vaapi/gstvaapicontext_overlay.c
Normal file
451
gst-libs/gst/vaapi/gstvaapicontext_overlay.c
Normal file
|
@ -0,0 +1,451 @@
|
||||||
|
/*
|
||||||
|
* gstvaapicontext_overlay.c - VA context abstraction (overlay composition)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2011 Splitted-Desktop Systems
|
||||||
|
* Author: Gwenole Beauchesne <gwenole.beauchesne@splitted-desktop.com>
|
||||||
|
* Copyright (C) 2011-2014 Intel Corporation
|
||||||
|
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2.1
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free
|
||||||
|
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sysdeps.h"
|
||||||
|
#include "gstvaapicontext_overlay.h"
|
||||||
|
#include "gstvaapiutils.h"
|
||||||
|
#include "gstvaapiimage.h"
|
||||||
|
#include "gstvaapisubpicture.h"
|
||||||
|
|
||||||
|
#define DEBUG 1
|
||||||
|
#include "gstvaapidebug.h"
|
||||||
|
|
||||||
|
typedef struct _GstVaapiOverlayRectangle GstVaapiOverlayRectangle;
|
||||||
|
struct _GstVaapiOverlayRectangle
|
||||||
|
{
|
||||||
|
GstVaapiContext *context;
|
||||||
|
GstVaapiSubpicture *subpicture;
|
||||||
|
GstVaapiRectangle render_rect;
|
||||||
|
guint seq_num;
|
||||||
|
guint layer_id;
|
||||||
|
GstBuffer *rect_buffer;
|
||||||
|
GstVideoOverlayRectangle *rect;
|
||||||
|
guint is_associated:1;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gst_video_overlay_rectangle_replace (GstVideoOverlayRectangle ** old_rect_ptr,
|
||||||
|
GstVideoOverlayRectangle * new_rect)
|
||||||
|
{
|
||||||
|
gst_mini_object_replace ((GstMiniObject **) old_rect_ptr,
|
||||||
|
GST_MINI_OBJECT_CAST (new_rect));
|
||||||
|
}
|
||||||
|
|
||||||
|
#define overlay_rectangle_ref(overlay) \
|
||||||
|
gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(overlay))
|
||||||
|
|
||||||
|
#define overlay_rectangle_unref(overlay) \
|
||||||
|
gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(overlay))
|
||||||
|
|
||||||
|
#define overlay_rectangle_replace(old_overlay_ptr, new_overlay) \
|
||||||
|
gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_overlay_ptr), \
|
||||||
|
(GstVaapiMiniObject *)(new_overlay))
|
||||||
|
|
||||||
|
static void overlay_rectangle_finalize (GstVaapiOverlayRectangle * overlay);
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
overlay_rectangle_associate (GstVaapiOverlayRectangle * overlay);
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
overlay_rectangle_deassociate (GstVaapiOverlayRectangle * overlay);
|
||||||
|
|
||||||
|
static inline const GstVaapiMiniObjectClass *
|
||||||
|
overlay_rectangle_class (void)
|
||||||
|
{
|
||||||
|
static const GstVaapiMiniObjectClass GstVaapiOverlayRectangleClass = {
|
||||||
|
sizeof (GstVaapiOverlayRectangle),
|
||||||
|
(GDestroyNotify) overlay_rectangle_finalize
|
||||||
|
};
|
||||||
|
return &GstVaapiOverlayRectangleClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstVaapiOverlayRectangle *
|
||||||
|
overlay_rectangle_new (GstVideoOverlayRectangle * rect,
|
||||||
|
GstVaapiContext * context, guint layer_id)
|
||||||
|
{
|
||||||
|
GstVaapiOverlayRectangle *overlay;
|
||||||
|
GstVaapiRectangle *render_rect;
|
||||||
|
guint width, height, flags;
|
||||||
|
gint x, y;
|
||||||
|
|
||||||
|
overlay = (GstVaapiOverlayRectangle *)
|
||||||
|
gst_vaapi_mini_object_new0 (overlay_rectangle_class ());
|
||||||
|
if (!overlay)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
overlay->context = context;
|
||||||
|
overlay->seq_num = gst_video_overlay_rectangle_get_seqnum (rect);
|
||||||
|
overlay->layer_id = layer_id;
|
||||||
|
overlay->rect = gst_video_overlay_rectangle_ref (rect);
|
||||||
|
|
||||||
|
flags = gst_video_overlay_rectangle_get_flags (rect);
|
||||||
|
gst_buffer_replace (&overlay->rect_buffer,
|
||||||
|
gst_video_overlay_rectangle_get_pixels_unscaled_raw (rect, flags));
|
||||||
|
if (!overlay->rect_buffer)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
overlay->subpicture =
|
||||||
|
gst_vaapi_subpicture_new_from_overlay_rectangle (GST_VAAPI_OBJECT_DISPLAY
|
||||||
|
(context), rect);
|
||||||
|
if (!overlay->subpicture)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
gst_video_overlay_rectangle_get_render_rectangle (rect,
|
||||||
|
&x, &y, &width, &height);
|
||||||
|
render_rect = &overlay->render_rect;
|
||||||
|
render_rect->x = x;
|
||||||
|
render_rect->y = y;
|
||||||
|
render_rect->width = width;
|
||||||
|
render_rect->height = height;
|
||||||
|
return overlay;
|
||||||
|
|
||||||
|
error:
|
||||||
|
overlay_rectangle_unref (overlay);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
overlay_rectangle_finalize (GstVaapiOverlayRectangle * overlay)
|
||||||
|
{
|
||||||
|
gst_buffer_replace (&overlay->rect_buffer, NULL);
|
||||||
|
gst_video_overlay_rectangle_unref (overlay->rect);
|
||||||
|
|
||||||
|
if (overlay->subpicture) {
|
||||||
|
overlay_rectangle_deassociate (overlay);
|
||||||
|
gst_vaapi_object_unref (overlay->subpicture);
|
||||||
|
overlay->subpicture = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
overlay_rectangle_associate (GstVaapiOverlayRectangle * overlay)
|
||||||
|
{
|
||||||
|
GstVaapiSubpicture *const subpicture = overlay->subpicture;
|
||||||
|
GPtrArray *const surfaces = overlay->context->surfaces;
|
||||||
|
guint i, n_associated;
|
||||||
|
|
||||||
|
if (overlay->is_associated)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
n_associated = 0;
|
||||||
|
for (i = 0; i < surfaces->len; i++) {
|
||||||
|
GstVaapiSurface *const surface = g_ptr_array_index (surfaces, i);
|
||||||
|
if (gst_vaapi_surface_associate_subpicture (surface, subpicture,
|
||||||
|
NULL, &overlay->render_rect))
|
||||||
|
n_associated++;
|
||||||
|
}
|
||||||
|
|
||||||
|
overlay->is_associated = TRUE;
|
||||||
|
return n_associated == surfaces->len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
overlay_rectangle_deassociate (GstVaapiOverlayRectangle * overlay)
|
||||||
|
{
|
||||||
|
GstVaapiSubpicture *const subpicture = overlay->subpicture;
|
||||||
|
GPtrArray *const surfaces = overlay->context->surfaces;
|
||||||
|
guint i, n_associated;
|
||||||
|
|
||||||
|
if (!overlay->is_associated)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
n_associated = surfaces->len;
|
||||||
|
for (i = 0; i < surfaces->len; i++) {
|
||||||
|
GstVaapiSurface *const surface = g_ptr_array_index (surfaces, i);
|
||||||
|
if (gst_vaapi_surface_deassociate_subpicture (surface, subpicture))
|
||||||
|
n_associated--;
|
||||||
|
}
|
||||||
|
|
||||||
|
overlay->is_associated = FALSE;
|
||||||
|
return n_associated == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
overlay_rectangle_changed_pixels (GstVaapiOverlayRectangle * overlay,
|
||||||
|
GstVideoOverlayRectangle * rect)
|
||||||
|
{
|
||||||
|
guint flags;
|
||||||
|
GstBuffer *buffer;
|
||||||
|
|
||||||
|
if (overlay->seq_num == gst_video_overlay_rectangle_get_seqnum (rect))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
flags =
|
||||||
|
to_GstVideoOverlayFormatFlags (gst_vaapi_subpicture_get_flags
|
||||||
|
(overlay->subpicture));
|
||||||
|
|
||||||
|
buffer = gst_video_overlay_rectangle_get_pixels_unscaled_raw (rect, flags);
|
||||||
|
if (!buffer)
|
||||||
|
return FALSE;
|
||||||
|
#if GST_CHECK_VERSION(1,0,0)
|
||||||
|
{
|
||||||
|
const guint n_blocks = gst_buffer_n_memory (buffer);
|
||||||
|
gsize ofs;
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
if (buffer == overlay->rect_buffer)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (n_blocks != gst_buffer_n_memory (overlay->rect_buffer))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
for (i = 0; i < n_blocks; i++) {
|
||||||
|
GstMemory *const mem1 = gst_buffer_peek_memory (buffer, i);
|
||||||
|
GstMemory *const mem2 = gst_buffer_peek_memory (overlay->rect_buffer, i);
|
||||||
|
if (!gst_memory_is_span (mem1, mem2, &ofs))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (GST_BUFFER_DATA (overlay->rect_buffer) != GST_BUFFER_DATA (buffer))
|
||||||
|
return FALSE;
|
||||||
|
#endif
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
overlay_rectangle_changed_render_rect (GstVaapiOverlayRectangle * overlay,
|
||||||
|
GstVideoOverlayRectangle * rect)
|
||||||
|
{
|
||||||
|
GstVaapiRectangle *const render_rect = &overlay->render_rect;
|
||||||
|
guint width, height;
|
||||||
|
gint x, y;
|
||||||
|
|
||||||
|
gst_video_overlay_rectangle_get_render_rectangle (rect,
|
||||||
|
&x, &y, &width, &height);
|
||||||
|
|
||||||
|
if (x == render_rect->x &&
|
||||||
|
y == render_rect->y &&
|
||||||
|
width == render_rect->width && height == render_rect->height)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
render_rect->x = x;
|
||||||
|
render_rect->y = y;
|
||||||
|
render_rect->width = width;
|
||||||
|
render_rect->height = height;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline gboolean
|
||||||
|
overlay_rectangle_update_global_alpha (GstVaapiOverlayRectangle * overlay,
|
||||||
|
GstVideoOverlayRectangle * rect)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_GST_VIDEO_OVERLAY_HWCAPS
|
||||||
|
const guint flags = gst_video_overlay_rectangle_get_flags (rect);
|
||||||
|
if (!(flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA))
|
||||||
|
return TRUE;
|
||||||
|
#endif
|
||||||
|
return gst_vaapi_subpicture_set_global_alpha (overlay->subpicture,
|
||||||
|
gst_video_overlay_rectangle_get_global_alpha (rect));
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
overlay_rectangle_update (GstVaapiOverlayRectangle * overlay,
|
||||||
|
GstVideoOverlayRectangle * rect, gboolean * reassociate_ptr)
|
||||||
|
{
|
||||||
|
if (overlay_rectangle_changed_pixels (overlay, rect))
|
||||||
|
return FALSE;
|
||||||
|
if (overlay_rectangle_changed_render_rect (overlay, rect))
|
||||||
|
*reassociate_ptr = TRUE;
|
||||||
|
if (!overlay_rectangle_update_global_alpha (overlay, rect))
|
||||||
|
return FALSE;
|
||||||
|
gst_video_overlay_rectangle_replace (&overlay->rect, rect);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline GPtrArray *
|
||||||
|
overlay_new (void)
|
||||||
|
{
|
||||||
|
return g_ptr_array_new_with_free_func (
|
||||||
|
(GDestroyNotify) gst_vaapi_mini_object_unref);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
overlay_destroy (GPtrArray ** overlay_ptr)
|
||||||
|
{
|
||||||
|
GPtrArray *const overlay = *overlay_ptr;
|
||||||
|
|
||||||
|
if (!overlay)
|
||||||
|
return;
|
||||||
|
g_ptr_array_unref (overlay);
|
||||||
|
*overlay_ptr = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
overlay_clear (GPtrArray * overlay)
|
||||||
|
{
|
||||||
|
if (overlay && overlay->len > 0)
|
||||||
|
g_ptr_array_remove_range (overlay, 0, overlay->len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstVaapiOverlayRectangle *
|
||||||
|
overlay_lookup (GPtrArray * overlays, GstVideoOverlayRectangle * rect)
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
for (i = 0; i < overlays->len; i++) {
|
||||||
|
GstVaapiOverlayRectangle *const overlay = g_ptr_array_index (overlays, i);
|
||||||
|
|
||||||
|
if (overlay->rect == rect)
|
||||||
|
return overlay;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
overlay_reassociate (GPtrArray * overlays)
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
for (i = 0; i < overlays->len; i++)
|
||||||
|
overlay_rectangle_deassociate (g_ptr_array_index (overlays, i));
|
||||||
|
|
||||||
|
for (i = 0; i < overlays->len; i++) {
|
||||||
|
if (!overlay_rectangle_associate (g_ptr_array_index (overlays, i)))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
overlay_ensure (GPtrArray ** overlay_ptr)
|
||||||
|
{
|
||||||
|
GPtrArray *overlay = *overlay_ptr;
|
||||||
|
|
||||||
|
if (!overlay) {
|
||||||
|
overlay = overlay_new ();
|
||||||
|
if (!overlay)
|
||||||
|
return FALSE;
|
||||||
|
*overlay_ptr = overlay;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Initializes overlay resources */
|
||||||
|
gboolean
|
||||||
|
gst_vaapi_context_overlay_init (GstVaapiContext * context)
|
||||||
|
{
|
||||||
|
if (!overlay_ensure (&context->overlays[0]))
|
||||||
|
return FALSE;
|
||||||
|
if (!overlay_ensure (&context->overlays[1]))
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Destroys overlay resources */
|
||||||
|
void
|
||||||
|
gst_vaapi_context_overlay_finalize (GstVaapiContext * context)
|
||||||
|
{
|
||||||
|
overlay_destroy (&context->overlays[0]);
|
||||||
|
overlay_destroy (&context->overlays[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Resets overlay resources to a clean state */
|
||||||
|
gboolean
|
||||||
|
gst_vaapi_context_overlay_reset (GstVaapiContext * context)
|
||||||
|
{
|
||||||
|
guint num_errors = 0;
|
||||||
|
|
||||||
|
if (overlay_ensure (&context->overlays[0]))
|
||||||
|
overlay_clear (context->overlays[0]);
|
||||||
|
else
|
||||||
|
num_errors++;
|
||||||
|
|
||||||
|
if (overlay_ensure (&context->overlays[1]))
|
||||||
|
overlay_clear (context->overlays[1]);
|
||||||
|
else
|
||||||
|
num_errors++;
|
||||||
|
|
||||||
|
context->overlay_id = 0;
|
||||||
|
return num_errors == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_vaapi_context_apply_composition:
|
||||||
|
* @context: a #GstVaapiContext
|
||||||
|
* @composition: a #GstVideoOverlayComposition
|
||||||
|
*
|
||||||
|
* Applies video composition planes to all surfaces bound to @context.
|
||||||
|
* This helper function resets any additional subpictures the user may
|
||||||
|
* have associated himself. A %NULL @composition will also clear all
|
||||||
|
* the existing subpictures.
|
||||||
|
*
|
||||||
|
* Return value: %TRUE if all composition planes could be applied,
|
||||||
|
* %FALSE otherwise
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
gst_vaapi_context_apply_composition (GstVaapiContext * context,
|
||||||
|
GstVideoOverlayComposition * composition)
|
||||||
|
{
|
||||||
|
GPtrArray *curr_overlay, *next_overlay;
|
||||||
|
guint i, n_rectangles;
|
||||||
|
gboolean reassociate = FALSE;
|
||||||
|
|
||||||
|
g_return_val_if_fail (context != NULL, FALSE);
|
||||||
|
|
||||||
|
if (!context->surfaces)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (!composition) {
|
||||||
|
gst_vaapi_context_overlay_reset (context);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
curr_overlay = context->overlays[context->overlay_id];
|
||||||
|
next_overlay = context->overlays[context->overlay_id ^ 1];
|
||||||
|
overlay_clear (next_overlay);
|
||||||
|
|
||||||
|
n_rectangles = gst_video_overlay_composition_n_rectangles (composition);
|
||||||
|
for (i = 0; i < n_rectangles; i++) {
|
||||||
|
GstVideoOverlayRectangle *const rect =
|
||||||
|
gst_video_overlay_composition_get_rectangle (composition, i);
|
||||||
|
GstVaapiOverlayRectangle *overlay;
|
||||||
|
|
||||||
|
overlay = overlay_lookup (curr_overlay, rect);
|
||||||
|
if (overlay && overlay_rectangle_update (overlay, rect, &reassociate)) {
|
||||||
|
overlay_rectangle_ref (overlay);
|
||||||
|
if (overlay->layer_id != i)
|
||||||
|
reassociate = TRUE;
|
||||||
|
} else {
|
||||||
|
overlay = overlay_rectangle_new (rect, context, i);
|
||||||
|
if (!overlay) {
|
||||||
|
GST_WARNING ("could not create VA overlay rectangle");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
reassociate = TRUE;
|
||||||
|
}
|
||||||
|
g_ptr_array_add (next_overlay, overlay);
|
||||||
|
}
|
||||||
|
|
||||||
|
overlay_clear (curr_overlay);
|
||||||
|
context->overlay_id ^= 1;
|
||||||
|
|
||||||
|
if (reassociate && !overlay_reassociate (next_overlay))
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
error:
|
||||||
|
gst_vaapi_context_overlay_reset (context);
|
||||||
|
return FALSE;
|
||||||
|
}
|
52
gst-libs/gst/vaapi/gstvaapicontext_overlay.h
Normal file
52
gst-libs/gst/vaapi/gstvaapicontext_overlay.h
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* gstvaapicontext_overlay.h - VA context abstraction (overlay composition)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2011 Splitted-Desktop Systems
|
||||||
|
* Author: Gwenole Beauchesne <gwenole.beauchesne@splitted-desktop.com>
|
||||||
|
* Copyright (C) 2011-2014 Intel Corporation
|
||||||
|
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2.1
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free
|
||||||
|
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GST_VAAPI_CONTEXT_OVERLAY_H
|
||||||
|
#define GST_VAAPI_CONTEXT_OVERLAY_H
|
||||||
|
|
||||||
|
#include <gst/video/video-overlay-composition.h>
|
||||||
|
#include "gstvaapicontext.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
G_GNUC_INTERNAL
|
||||||
|
gboolean
|
||||||
|
gst_vaapi_context_overlay_init (GstVaapiContext * context);
|
||||||
|
|
||||||
|
G_GNUC_INTERNAL
|
||||||
|
void
|
||||||
|
gst_vaapi_context_overlay_finalize (GstVaapiContext * context);
|
||||||
|
|
||||||
|
G_GNUC_INTERNAL
|
||||||
|
gboolean
|
||||||
|
gst_vaapi_context_overlay_reset (GstVaapiContext * context);
|
||||||
|
|
||||||
|
G_GNUC_INTERNAL
|
||||||
|
gboolean
|
||||||
|
gst_vaapi_context_apply_composition (GstVaapiContext * context,
|
||||||
|
GstVideoOverlayComposition * composition);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* GST_VAAPI_CONTEXT_OVERLAY_H */
|
|
@ -35,6 +35,7 @@
|
||||||
#include "gstvaapicontext.h"
|
#include "gstvaapicontext.h"
|
||||||
#include "gstvaapiimage.h"
|
#include "gstvaapiimage.h"
|
||||||
#include "gstvaapiimage_priv.h"
|
#include "gstvaapiimage_priv.h"
|
||||||
|
#include "gstvaapicontext_overlay.h"
|
||||||
|
|
||||||
#define DEBUG 1
|
#define DEBUG 1
|
||||||
#include "gstvaapidebug.h"
|
#include "gstvaapidebug.h"
|
||||||
|
|
Loading…
Reference in a new issue