static GstBusSyncReply create_window (GstBus* bus, GstMessage* message, GtkWidget* widget) { GtkAllocation allocation; if (gst_gtk_handle_need_context (bus, message, NULL)) return GST_BUS_DROP; // ignore anything but 'prepare-window-handle' element messages if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT) return GST_BUS_PASS; if (!gst_is_video_overlay_prepare_window_handle_message (message)) return GST_BUS_PASS; g_print ("setting window handle %p\n", widget); gst_video_overlay_set_gtk_window (GST_VIDEO_OVERLAY (GST_MESSAGE_SRC (message)), widget); gtk_widget_get_allocation (widget, &allocation); gst_video_overlay_set_render_rectangle (GST_VIDEO_OVERLAY (GST_MESSAGE_SRC (message)), allocation.x, allocation.y, allocation.width, allocation.height); gst_message_unref (message); return GST_BUS_DROP; }
static void _overlay_set_render_rectangle (GstVideoOverlay * overlay, gint x, gint y, gint width, gint height) { GESPipeline *pipeline = GES_PIPELINE (overlay); gst_video_overlay_set_render_rectangle (GST_VIDEO_OVERLAY (pipeline->priv-> playsink), x, y, width, height); }
void gstreamer_expose_video_overlay(int x, int y, int w, int h) { if (video_window_overlay == NULL) return; // printf("Expose: offset (%d, %d), size (%d, %d)\n", x, y, w, h); gst_video_overlay_set_render_rectangle(video_window_overlay, x, y, w, h); // Expose events are handled automatically by plugins like // xvimagesink and eglglessink with the default property settings. // Calling expose explicitly causes lock-ups. }
static gboolean resize_cb (GtkWidget * widget, GdkEvent * event, gpointer sink) { GtkAllocation allocation; gtk_widget_get_allocation (widget, &allocation); gst_video_overlay_set_render_rectangle (GST_VIDEO_OVERLAY (sink), allocation.x, allocation.y, allocation.width, allocation.height); return FALSE; }
static gboolean on_click_drawing_area(GtkWidget* widget, GdkEventButton* event, GstElement* videosink) { GtkAllocation allocation; g_print ("switch the drawing area %p\n", widget); gst_video_overlay_set_gtk_window (GST_VIDEO_OVERLAY (videosink), widget); gtk_widget_get_allocation (widget, &allocation); gst_video_overlay_set_render_rectangle (GST_VIDEO_OVERLAY (videosink), allocation.x, allocation.y, allocation.width, allocation.height); return FALSE; }
static GstBusSyncReply bus_sync_handler(GstBus *bus, GstMessage *msg, gpointer data) { if (!gst_is_video_overlay_prepare_window_handle_message(msg)) return GST_BUS_PASS; guintptr video_window_handle = gui_get_video_window_handle(); g_assert(video_window_handle != 0); // GST_MESSAGE_SRC (message) will be the video sink element. video_window_overlay = GST_VIDEO_OVERLAY(GST_MESSAGE_SRC(msg)); gst_video_overlay_set_window_handle(video_window_overlay, video_window_handle); int x, y, w, h; gui_get_render_rectangle(&x, &y, &w, &h); gst_video_overlay_set_render_rectangle(video_window_overlay, x, y, w, h); return GST_BUS_DROP; }
/** * gst_player_video_overlay_video_renderer_set_render_rectangle: * @self: a #GstPlayerVideoOverlayVideoRenderer instance * @x: the horizontal offset of the render area inside the window * @y: the vertical offset of the render area inside the window * @width: the width of the render area inside the window * @height: the height of the render area inside the window * * Configure a subregion as a video target within the window set by * gst_player_video_overlay_video_renderer_set_window_handle(). If this is not * used or not supported the video will fill the area of the window set as the * overlay to 100%. By specifying the rectangle, the video can be overlayed to * a specific region of that window only. After setting the new rectangle one * should call gst_player_video_overlay_video_renderer_expose() to force a * redraw. To unset the region pass -1 for the @width and @height parameters. * * This method is needed for non fullscreen video overlay in UI toolkits that * do not support subwindows. * */ void gst_player_video_overlay_video_renderer_set_render_rectangle (GstPlayerVideoOverlayVideoRenderer * self, gint x, gint y, gint width, gint height) { g_return_if_fail (GST_IS_PLAYER_VIDEO_OVERLAY_VIDEO_RENDERER (self)); self->x = x; self->y = y; self->width = width; self->height = height; if (self->video_overlay) gst_video_overlay_set_render_rectangle (self->video_overlay, x, y, width, height); }
static void gst_gl_sink_bin_overlay_set_render_rectangle (GstVideoOverlay * overlay, gint x, gint y, gint width, gint height) { GstGLSinkBin *self = GST_GL_SINK_BIN (overlay); GstVideoOverlay *overlay_element = NULL; overlay_element = GST_VIDEO_OVERLAY (gst_bin_get_by_interface (GST_BIN (self), GST_TYPE_VIDEO_OVERLAY)); if (overlay_element) { gst_video_overlay_set_render_rectangle (overlay_element, x, y, width, height); gst_object_unref (overlay_element); } }
static gboolean resize_cb (GtkWidget * widget, GdkEvent * event, gpointer sink) { GtkAllocation allocation; gint scale = 1; #if GTK_CHECK_VERSION(3, 10, 0) scale = gtk_widget_get_scale_factor (widget); #endif gtk_widget_get_allocation (widget, &allocation); gst_video_overlay_set_render_rectangle (GST_VIDEO_OVERLAY (sink), allocation.x * scale, allocation.y * scale, allocation.width * scale, allocation.height * scale); return G_SOURCE_CONTINUE; }
static gboolean on_click_drawing_area(GtkWidget* widget, GdkEventButton* event, GstElement* videosink) { GtkAllocation allocation; GtkWidget *parent = gtk_widget_get_parent (widget); g_print ("switch the drawing area %p\n", widget); gst_video_overlay_set_gtk_window (GST_VIDEO_OVERLAY (videosink), widget); gtk_widget_get_allocation (widget, &allocation); gst_video_overlay_set_render_rectangle (GST_VIDEO_OVERLAY (videosink), allocation.x, allocation.y, allocation.width, allocation.height); /* XXX: required on wayland as changing the window handle (subsurface) * requires a wl_surface::commit from the parent */ if (parent) gtk_widget_queue_draw (parent); return FALSE; }
static gboolean animate_render_rect (gpointer user_data) { if (anim_state.running) { GstVideoRectangle *r = &anim_state.rect; gdouble s = sin (3.0 * anim_state.a); gdouble c = cos (2.0 * anim_state.a); anim_state.a += anim_state.p; if (anim_state.a > (G_PI + G_PI)) anim_state.a -= (G_PI + G_PI); r->w = anim_state.w / 2; r->x = (r->w - (r->w / 2)) + c * (r->w / 2); r->h = anim_state.h / 2; r->y = (r->h - (r->h / 2)) + s * (r->h / 2); gst_video_overlay_set_render_rectangle (anim_state.overlay, r->x, r->y, r->w, r->h); gtk_widget_queue_draw (anim_state.widget); } return TRUE; }
static GstElement *gst_player_video_overlay_video_renderer_create_video_sink (GstPlayerVideoRenderer * iface, GstPlayer * player) { GstElement *video_overlay; GstPlayerVideoOverlayVideoRenderer *self = GST_PLAYER_VIDEO_OVERLAY_VIDEO_RENDERER (iface); if (self->video_overlay) gst_object_unref (self->video_overlay); video_overlay = gst_player_get_pipeline (player); g_return_val_if_fail (GST_IS_VIDEO_OVERLAY (video_overlay), NULL); self->video_overlay = GST_VIDEO_OVERLAY (video_overlay); gst_video_overlay_set_window_handle (self->video_overlay, (guintptr) self->window_handle); if (self->width != -1 || self->height != -1) gst_video_overlay_set_render_rectangle (self->video_overlay, self->x, self->y, self->width, self->height); return NULL; }
int tsmf_window_resize(TSMFGstreamerDecoder *decoder, int x, int y, int width, int height, int nr_rects, RDP_RECT *rects) { if (decoder->media_type != TSMF_MAJOR_TYPE_VIDEO) return -3; else { #if GST_VERSION_MAJOR > 0 GstVideoOverlay *overlay = GST_VIDEO_OVERLAY(decoder->outsink); #else GstXOverlay *overlay = GST_X_OVERLAY(decoder->outsink); #endif struct X11Handle *hdl = (struct X11Handle *)decoder->platform; DEBUG_TSMF("resize: x=%d, y=%d, w=%d, h=%d", x, y, width, height); assert(decoder); assert(hdl); #if GST_VERSION_MAJOR > 0 if (!gst_video_overlay_set_render_rectangle(overlay, 0, 0, width, height)) { DEBUG_WARN("Could not resize overlay!"); } gst_video_overlay_expose(overlay); #else if (!gst_x_overlay_set_render_rectangle(overlay, 0, 0, width, height)) { DEBUG_WARN("Could not resize overlay!"); } gst_x_overlay_expose(overlay); #endif if (hdl->subwin) { XMoveResizeWindow(hdl->disp, hdl->subwin, x, y, width, height); #if defined(WITH_XEXT) if (hdl->has_shape) { int i; XRectangle *xrects = calloc(nr_rects, sizeof(XRectangle)); for (i=0; i<nr_rects; i++) { xrects[i].x = rects[i].x - x; xrects[i].y = rects[i].y - y; xrects[i].width = rects[i].width; xrects[i].height = rects[i].height; } XShapeCombineRectangles(hdl->disp, hdl->subwin, ShapeBounding, x, y, xrects, nr_rects, ShapeSet, 0); free(xrects); } #endif XSync(hdl->disp, FALSE); } return 0; } }