[Pkg-gstreamer-commits] [gstreamer-vaapi] 160/176: context: move overlay composition to separate files.
Vincent Cheng
vcheng at moszumanska.debian.org
Tue Jun 3 08:09:37 UTC 2014
This is an automated email from the git hooks/post-receive script.
vcheng pushed a commit to branch upstream
in repository gstreamer-vaapi.
commit 3b714c8913ff43370f7d7bd6ec0fdb85ef72328d
Author: Gwenole Beauchesne <gwenole.beauchesne at intel.com>
Date: Thu Jan 23 10:59:20 2014 +0100
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.
---
gst-libs/gst/vaapi/Makefile.am | 2 +
gst-libs/gst/vaapi/gstvaapicontext.c | 403 +-----------------------
gst-libs/gst/vaapi/gstvaapicontext.h | 6 -
gst-libs/gst/vaapi/gstvaapicontext_overlay.c | 451 +++++++++++++++++++++++++++
gst-libs/gst/vaapi/gstvaapicontext_overlay.h | 52 +++
gst-libs/gst/vaapi/gstvaapisurface.c | 1 +
6 files changed, 511 insertions(+), 404 deletions(-)
diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am
index 11efb4b..92b875a 100644
--- a/gst-libs/gst/vaapi/Makefile.am
+++ b/gst-libs/gst/vaapi/Makefile.am
@@ -47,6 +47,7 @@ libgstvaapi_libs = \
libgstvaapi_source_c = \
gstvaapicodec_objects.c \
gstvaapicontext.c \
+ gstvaapicontext_overlay.c \
gstvaapidecoder.c \
gstvaapidecoder_dpb.c \
gstvaapidecoder_h264.c \
@@ -110,6 +111,7 @@ libgstvaapi_source_priv_h = \
gstvaapicodec_objects.h \
gstvaapicompat.h \
gstvaapicontext.h \
+ gstvaapicontext_overlay.h \
gstvaapidebug.h \
gstvaapidecoder_dpb.h \
gstvaapidecoder_objects.h \
diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c
index a4cc1fb..8651e90 100644
--- a/gst-libs/gst/vaapi/gstvaapicontext.c
+++ b/gst-libs/gst/vaapi/gstvaapicontext.c
@@ -30,6 +30,7 @@
#include "sysdeps.h"
#include "gstvaapicompat.h"
#include "gstvaapicontext.h"
+#include "gstvaapicontext_overlay.h"
#include "gstvaapidisplay_priv.h"
#include "gstvaapiobject_priv.h"
#include "gstvaapisurface.h"
@@ -37,324 +38,11 @@
#include "gstvaapisurfacepool.h"
#include "gstvaapisurfaceproxy.h"
#include "gstvaapivideopool_priv.h"
-#include "gstvaapiimage.h"
-#include "gstvaapisubpicture.h"
#include "gstvaapiutils.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 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
unref_surface_cb (GstVaapiSurface * surface)
{
@@ -365,7 +53,7 @@ unref_surface_cb (GstVaapiSurface * surface)
static void
context_destroy_surfaces (GstVaapiContext * context)
{
- context_destroy_overlay (context);
+ gst_vaapi_context_overlay_reset (context);
if (context->surfaces) {
g_ptr_array_unref (context->surfaces);
@@ -406,16 +94,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
context_create_surfaces (GstVaapiContext * context)
{
const GstVaapiContextInfo *const cip = &context->info;
@@ -426,7 +104,7 @@ context_create_surfaces (GstVaapiContext * context)
/* Number of scratch surfaces beyond those used as reference */
const guint SCRATCH_SURFACES_COUNT = 4;
- if (!context_create_overlay (context))
+ if (!gst_vaapi_context_overlay_reset (context))
return FALSE;
num_surfaces = cip->ref_frames + SCRATCH_SURFACES_COUNT;
@@ -556,17 +234,15 @@ gst_vaapi_context_init (GstVaapiContext * context,
{
context->info = *cip;
context->va_config = VA_INVALID_ID;
- context->overlays[0] = overlay_new ();
- context->overlays[1] = overlay_new ();
+ gst_vaapi_context_overlay_init (context);
}
static void
gst_vaapi_context_finalize (GstVaapiContext * context)
{
- overlay_destroy (&context->overlays[0]);
- overlay_destroy (&context->overlays[1]);
context_destroy (context);
context_destroy_surfaces (context);
+ gst_vaapi_context_overlay_finalize (context);
}
GST_VAAPI_OBJECT_DEFINE_CLASS (GstVaapiContext, gst_vaapi_context);
@@ -719,75 +395,6 @@ gst_vaapi_context_get_surface_count (GstVaapiContext * context)
}
/**
- * 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:
* @context: a #GstVaapiContext
* @type: a VA config attribute type
diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h
index 4888a83..8112fd4 100644
--- a/gst-libs/gst/vaapi/gstvaapicontext.h
+++ b/gst-libs/gst/vaapi/gstvaapicontext.h
@@ -25,7 +25,6 @@
#ifndef GST_VAAPI_CONTEXT_H
#define GST_VAAPI_CONTEXT_H
-#include <gst/video/video-overlay-composition.h>
#include "gstvaapiobject.h"
#include "gstvaapiobject_priv.h"
#include "gstvaapiprofile.h"
@@ -117,11 +116,6 @@ gst_vaapi_context_get_surface_count (GstVaapiContext * context);
G_GNUC_INTERNAL
gboolean
-gst_vaapi_context_apply_composition (GstVaapiContext * context,
- GstVideoOverlayComposition * composition);
-
-G_GNUC_INTERNAL
-gboolean
gst_vaapi_context_get_attribute (GstVaapiContext * context,
VAConfigAttribType type, guint * out_value_ptr);
diff --git a/gst-libs/gst/vaapi/gstvaapicontext_overlay.c b/gst-libs/gst/vaapi/gstvaapicontext_overlay.c
new file mode 100644
index 0000000..b38e62e
--- /dev/null
+++ b/gst-libs/gst/vaapi/gstvaapicontext_overlay.c
@@ -0,0 +1,451 @@
+/*
+ * gstvaapicontext_overlay.c - VA context abstraction (overlay composition)
+ *
+ * Copyright (C) 2010-2011 Splitted-Desktop Systems
+ * Author: Gwenole Beauchesne <gwenole.beauchesne at splitted-desktop.com>
+ * Copyright (C) 2011-2014 Intel Corporation
+ * Author: Gwenole Beauchesne <gwenole.beauchesne at 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;
+}
diff --git a/gst-libs/gst/vaapi/gstvaapicontext_overlay.h b/gst-libs/gst/vaapi/gstvaapicontext_overlay.h
new file mode 100644
index 0000000..85440e9
--- /dev/null
+++ b/gst-libs/gst/vaapi/gstvaapicontext_overlay.h
@@ -0,0 +1,52 @@
+/*
+ * gstvaapicontext_overlay.h - VA context abstraction (overlay composition)
+ *
+ * Copyright (C) 2010-2011 Splitted-Desktop Systems
+ * Author: Gwenole Beauchesne <gwenole.beauchesne at splitted-desktop.com>
+ * Copyright (C) 2011-2014 Intel Corporation
+ * Author: Gwenole Beauchesne <gwenole.beauchesne at 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 */
diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c
index 40745ba..ba848cb 100644
--- a/gst-libs/gst/vaapi/gstvaapisurface.c
+++ b/gst-libs/gst/vaapi/gstvaapisurface.c
@@ -35,6 +35,7 @@
#include "gstvaapicontext.h"
#include "gstvaapiimage.h"
#include "gstvaapiimage_priv.h"
+#include "gstvaapicontext_overlay.h"
#define DEBUG 1
#include "gstvaapidebug.h"
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-gstreamer/gstreamer-vaapi.git
More information about the Pkg-gstreamer-commits
mailing list