summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Dufresne <nicolas.dufresne@collabora.co.uk>2011-11-25 14:59:56 -0500
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>2011-12-12 18:34:57 +0100
commitc997607c6f34143af86d7a7a240a02aff3a60255 (patch)
tree01363176df82c0c1d41891e95fc6852cd58a0048
parent55738da35b684b3ebffa3f3510e347cc654b1cd9 (diff)
surface: add helper to handle GstVideoOverlayComposition.
This helper resets the subpictures to reflect the current composition layers provided with the buffers. Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
-rw-r--r--gst-libs/gst/vaapi/gstvaapisurface.c95
-rw-r--r--gst-libs/gst/vaapi/gstvaapisurface.h7
2 files changed, 95 insertions, 7 deletions
diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c
index 4d9c5b0f..f7e4b8c5 100644
--- a/gst-libs/gst/vaapi/gstvaapisurface.c
+++ b/gst-libs/gst/vaapi/gstvaapisurface.c
@@ -78,22 +78,29 @@ destroy_subpicture_cb(gpointer subpicture, gpointer surface)
}
static void
-gst_vaapi_surface_destroy(GstVaapiSurface *surface)
+gst_vaapi_surface_destroy_subpictures(GstVaapiSurface *surface)
{
- GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(surface);
GstVaapiSurfacePrivate * const priv = surface->priv;
- VASurfaceID surface_id;
- VAStatus status;
-
- surface_id = GST_VAAPI_OBJECT_ID(surface);
- GST_DEBUG("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(surface_id));
if (priv->subpictures) {
g_ptr_array_foreach(priv->subpictures, destroy_subpicture_cb, surface);
g_ptr_array_free(priv->subpictures, TRUE);
priv->subpictures = NULL;
}
+}
+static void
+gst_vaapi_surface_destroy(GstVaapiSurface *surface)
+{
+ GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(surface);
+ VASurfaceID surface_id;
+ VAStatus status;
+
+ surface_id = GST_VAAPI_OBJECT_ID(surface);
+ GST_DEBUG("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(surface_id));
+
+ gst_vaapi_surface_destroy_subpictures(surface);
+
if (surface_id != VA_INVALID_SURFACE) {
GST_VAAPI_DISPLAY_LOCK(display);
status = vaDestroySurfaces(
@@ -790,3 +797,77 @@ gst_vaapi_surface_query_status(
*pstatus = to_GstVaapiSurfaceStatus(surface_status);
return TRUE;
}
+
+/**
+ * gst_vaapi_surface_update_composition:
+ * @surface: a #GstVaapiSurface
+ * @compostion: a #GstVideoOverlayCompositon
+ *
+ * Helper to update the subpictures from #GstVideoOverlayCompositon. Sending
+ * a NULL composition will clear all the current subpictures. Note that this
+ * method will clear existing subpictures.
+ *
+ * Return value: %TRUE on success
+ */
+gboolean
+gst_vaapi_surface_update_composition(
+ GstVaapiSurface *surface,
+ GstVideoOverlayComposition *composition
+)
+{
+ GstVaapiDisplay *display;
+ guint n, nb_rectangles;
+
+ g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE);
+
+ display = GST_VAAPI_OBJECT_DISPLAY(surface);
+ if (!display)
+ return FALSE;
+
+ /* Clear current subpictures */
+ gst_vaapi_surface_destroy_subpictures(surface);
+
+ if (!composition)
+ return TRUE;
+
+ nb_rectangles = gst_video_overlay_composition_n_rectangles (composition);
+
+ /* Overlay all the rectangles cantained in the overlay composition */
+ for (n = 0; n < nb_rectangles; ++n) {
+ GstBuffer *buf;
+ GstVideoOverlayRectangle *rect;
+ guint stride;
+ GstVaapiImage *subtitle_image;
+ GstVaapiRectangle sub_rect;
+ GstVaapiSubpicture *subpicture;
+
+ rect = gst_video_overlay_composition_get_rectangle (composition, n);
+ buf = gst_video_overlay_rectangle_get_pixels_argb (rect,
+ &stride, GST_VIDEO_OVERLAY_FORMAT_FLAG_NONE);
+
+ gst_video_overlay_rectangle_get_render_rectangle (rect,
+ (gint *)&sub_rect.x, (gint *)&sub_rect.y,
+ &sub_rect.width, &sub_rect.height);
+ subtitle_image = gst_vaapi_image_new (display,
+ GST_VAAPI_IMAGE_RGBA, sub_rect.width, sub_rect.height);
+
+ if (!gst_vaapi_image_update_from_buffer (subtitle_image, buf, &sub_rect)) {
+ GST_WARNING ("could not update VA image with subtitle data");
+ return FALSE;
+ }
+
+ subpicture = gst_vaapi_subpicture_new (subtitle_image);
+ g_object_unref (subtitle_image);
+
+ if (!gst_vaapi_surface_associate_subpicture (surface, subpicture,
+ NULL, &sub_rect)) {
+ GST_WARNING ("could not render overlay rectangle %p", rect);
+ g_object_unref (subpicture);
+ return FALSE;
+ }
+
+ g_object_unref (subpicture);
+ }
+
+ return TRUE;
+}
diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h
index 05dffcfd..8a2b70b0 100644
--- a/gst-libs/gst/vaapi/gstvaapisurface.h
+++ b/gst-libs/gst/vaapi/gstvaapisurface.h
@@ -28,6 +28,7 @@
#include <gst/vaapi/gstvaapiimage.h>
#include <gst/vaapi/gstvaapisubpicture.h>
#include <gst/video/gstsurfacebuffer.h>
+#include <gst/video/video-overlay-composition.h>
G_BEGIN_DECLS
@@ -228,6 +229,12 @@ gst_vaapi_surface_query_status(
GstVaapiSurfaceStatus *pstatus
);
+gboolean
+gst_vaapi_surface_update_composition(
+ GstVaapiSurface *surface,
+ GstVideoOverlayComposition *composition
+);
+
G_END_DECLS
#endif /* GST_VAAPI_SURFACE_H */