static void gst_gl_composition_overlay_add_transformation (GstGLCompositionOverlay * overlay, GstBuffer * video_buffer) { gint comp_x, comp_y; guint comp_width, comp_height; GstVideoMeta *meta; guint width, height; float rel_x, rel_y, rel_w, rel_h; meta = gst_buffer_get_video_meta (video_buffer); gst_video_overlay_rectangle_get_render_rectangle (overlay->rectangle, &comp_x, &comp_y, &comp_width, &comp_height); width = meta->width; height = meta->height; /* calculate relative position */ rel_x = (float) comp_x / (float) width; rel_y = (float) comp_y / (float) height; rel_w = (float) comp_width / (float) width; rel_h = (float) comp_height / (float) height; /* transform from [0,1] to [-1,1], invert y axis */ rel_x = rel_x * 2.0 - 1.0; rel_y = (1.0 - rel_y) * 2.0 - 1.0; rel_w = rel_w * 2.0; rel_h = rel_h * 2.0; /* initialize position array */ overlay->positions[0] = rel_x + rel_w; overlay->positions[1] = rel_y; overlay->positions[2] = 0.0; overlay->positions[3] = 1.0; overlay->positions[4] = rel_x; overlay->positions[5] = rel_y; overlay->positions[6] = 0.0; overlay->positions[7] = 1.0; overlay->positions[8] = rel_x; overlay->positions[9] = rel_y - rel_h; overlay->positions[10] = 0.0; overlay->positions[11] = 1.0; overlay->positions[12] = rel_x + rel_w; overlay->positions[13] = rel_y - rel_h; overlay->positions[14] = 0.0; overlay->positions[15] = 1.0; gst_gl_context_thread_add (overlay->context, gst_gl_composition_overlay_free_vertex_buffer, overlay); gst_gl_context_thread_add (overlay->context, gst_gl_composition_overlay_init_vertex_buffer, overlay); GST_DEBUG ("overlay position: (%d,%d) size: %dx%d video size: %dx%d", comp_x, comp_y, comp_width, comp_height, meta->width, meta->height); }
/** * gst_vaapi_surface_set_subpictures_from_composition: * @surface: a #GstVaapiSurface * @compostion: a #GstVideoOverlayCompositon * @propagate_context: a flag specifying whether to apply composition * to the parent context, if any * * 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_set_subpictures_from_composition( GstVaapiSurface *surface, GstVideoOverlayComposition *composition, gboolean propagate_context ) { GstVaapiDisplay *display; guint n, nb_rectangles; g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); if (propagate_context) { GstVaapiContext * const context = surface->priv->parent_context; if (context) return gst_vaapi_context_apply_composition(context, composition); } 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) { GstVideoOverlayRectangle *rect; GstVaapiRectangle sub_rect; GstVaapiSubpicture *subpicture; rect = gst_video_overlay_composition_get_rectangle (composition, n); subpicture = gst_vaapi_subpicture_new_from_overlay_rectangle (display, rect); gst_video_overlay_rectangle_get_render_rectangle (rect, (gint *)&sub_rect.x, (gint *)&sub_rect.y, &sub_rect.width, &sub_rect.height); 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; }