void QGstreamerGLTextureRenderer::setWinId(WId id) { #ifdef GL_TEXTURE_SINK_DEBUG qDebug() << Q_FUNC_INFO << id; #endif if (m_winId == id) return; bool oldReady = isReady(); m_winId = id; if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) { //don't set winId in NULL state, //texture sink opens xvideo port on set_xwindow_id, //this fails if video resource is not granted by resource policy yet. //state is changed to READY/PAUSED/PLAYING only after resource is granted. GstState pendingState = GST_STATE_NULL; GstState newState = GST_STATE_NULL; GstStateChangeReturn res = gst_element_get_state(m_videoSink, &newState, &pendingState, 0);//don't block and return immediately if (res != GST_STATE_CHANGE_FAILURE && newState != GST_STATE_NULL && pendingState != GST_STATE_NULL) gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(m_videoSink), m_winId); } if (oldReady != isReady()) emit readyChanged(!oldReady); }
Window set_gst_sdl_video_overlay (GstElement *pipeline, int x, int y, int width, int height) { GstElement *videosink; SDL_SysWMinfo sdl_info; Window play_win; sdl_info = get_sdl_wm_info (); if (!sdl_info.version.major) return 0; g_object_get (pipeline, "video-sink", &videosink, NULL); if (videosink && GST_IS_X_OVERLAY (videosink)) { sdl_info.info.x11.lock_func (); play_win = create_x11_subwindow (sdl_info.info.x11.display, sdl_info.info.x11.window, x, y, width, height); sdl_info.info.x11.unlock_func (); gst_x_overlay_set_xwindow_id (GST_X_OVERLAY (videosink), play_win); } else play_win = 0; g_object_unref (videosink); return play_win; }
void GStreamerGWorld::setWindowOverlay(GstMessage* message) { GstObject* sink = GST_MESSAGE_SRC(message); #ifndef GST_API_VERSION_1 if (!GST_IS_X_OVERLAY(sink)) #else if (!GST_IS_VIDEO_OVERLAY(sink)) #endif return; if (g_object_class_find_property(G_OBJECT_GET_CLASS(sink), "force-aspect-ratio")) g_object_set(sink, "force-aspect-ratio", TRUE, NULL); if (m_videoWindow) { m_videoWindow->prepareForOverlay(message); #ifndef GST_API_VERSION_1 // gst_x_overlay_set_window_handle was introduced in -plugins-base // 0.10.31, just like the macro for checking the version. #ifdef GST_CHECK_PLUGINS_BASE_VERSION gst_x_overlay_set_window_handle(GST_X_OVERLAY(sink), m_videoWindow->videoWindowId()); #else gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(sink), m_videoWindow->videoWindowId()); #endif #else gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(sink), m_videoWindow->videoWindowId()); #endif } }
/** * gst_x_overlay_set_window_handle: * @overlay: a #GstXOverlay to set the window on. * @handle: a handle referencing the window. * * This will call the video overlay's set_window_handle method. You * should use this method to tell to a XOverlay to display video output to a * specific window (e.g. an XWindow on X11). Passing 0 as the @handle will * tell the overlay to stop using that window and create an internal one. * * Since: 0.10.31 */ void gst_x_overlay_set_window_handle (GstXOverlay * overlay, guintptr handle) { GstXOverlayClass *klass; g_return_if_fail (overlay != NULL); g_return_if_fail (GST_IS_X_OVERLAY (overlay)); klass = GST_X_OVERLAY_GET_CLASS (overlay); if (klass->set_window_handle) { klass->set_window_handle (overlay, handle); } else { #ifndef GST_REMOVE_DEPRECATED #ifdef GST_DISABLE_DEPRECATED #define set_xwindow_id set_xwindow_id_disabled #endif if (sizeof (guintptr) <= sizeof (gulong) && klass->set_xwindow_id) { GST_WARNING_OBJECT (overlay, "Calling deprecated set_xwindow_id() method"); klass->set_xwindow_id (overlay, handle); } else { g_warning ("Refusing to cast guintptr to smaller gulong"); } #endif } }
void BasePlatformInterface::PrepareVideoWindow(GstMessage *aMessage) { GstElement *element = NULL; GstXOverlay *xoverlay = NULL; if (GST_IS_BIN (mVideoSink)) { /* Get the actual implementing object from the bin */ element = gst_bin_get_by_interface(GST_BIN (mVideoSink), GST_TYPE_X_OVERLAY); } else { element = mVideoSink; } if (GST_IS_X_OVERLAY (element)) { xoverlay = GST_X_OVERLAY (element); LOG(("xoverlay interface found, setting video window")); } else { LOG(("No xoverlay interface found, cannot set video window")); return; } SetXOverlayWindowID(xoverlay); ResizeToWindow(); }
bool QGstreamerGLTextureRenderer::processSyncMessage(const QGstreamerMessage &message) { GstMessage* gm = message.rawMessage(); if ((GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ELEMENT) && gst_structure_has_name(gm->structure, "prepare-xwindow-id") && m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) { #ifdef GL_TEXTURE_SINK_DEBUG qDebug() << Q_FUNC_INFO; #endif GstXOverlay *overlay = GST_X_OVERLAY(m_videoSink); gst_x_overlay_set_xwindow_id(overlay, m_winId); if (!m_displayRect.isEmpty()) { gst_x_overlay_set_render_rectangle(overlay, m_displayRect.x(), m_displayRect.y(), m_displayRect.width(), m_displayRect.height()); } GstPad *pad = gst_element_get_static_pad(m_videoSink,"sink"); m_bufferProbeId = gst_pad_add_buffer_probe(pad, G_CALLBACK(padBufferProbe), this); return true; } return false; }
void QGstreamerGLTextureRenderer::repaintOverlay() { if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) { //don't call gst_x_overlay_expose if the sink is in null state GstState state = GST_STATE_NULL; GstStateChangeReturn res = gst_element_get_state(m_videoSink, &state, NULL, 1000000); if (res != GST_STATE_CHANGE_FAILURE && state != GST_STATE_NULL) { gst_x_overlay_expose(GST_X_OVERLAY(m_videoSink)); } } }
void VideoWidget::WindowExposed() { if (video_overlay_ && GST_IS_X_OVERLAY(video_overlay_)) { // Expose the overlay (some sort of update) qDebug() << name_ << " >> WindowExposed() called"; #ifdef Q_WS_X11 QApplication::syncX(); #endif gst_x_overlay_expose(GST_X_OVERLAY(video_overlay_)); } }
void X11Renderer::setOverlay() { if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) { WId windowId = m_renderWidget->winId(); // Even if we have created a winId at this point, other X applications // need to be aware of it. QApplication::syncX(); gst_x_overlay_set_xwindow_id ( GST_X_OVERLAY(m_videoSink) , windowId ); } windowExposed(); m_overlaySet = true; }
static GstStateChangeReturn gst_sdlvideosink_change_state (GstElement * element, GstStateChange transition) { GstSDLVideoSink *sdlvideosink; GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; g_return_val_if_fail (GST_IS_SDLVIDEOSINK (element), GST_STATE_CHANGE_FAILURE); sdlvideosink = GST_SDLVIDEOSINK (element); switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: sdlvideosink->is_xwindows = GST_IS_X_OVERLAY (sdlvideosink); g_mutex_lock (sdlvideosink->lock); if (!gst_sdlvideosink_initsdl (sdlvideosink)) { g_mutex_unlock (sdlvideosink->lock); goto init_failed; } GST_OBJECT_FLAG_SET (sdlvideosink, GST_SDLVIDEOSINK_OPEN); g_mutex_unlock (sdlvideosink->lock); break; default: /* do nothing */ break; } ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); switch (transition) { case GST_STATE_CHANGE_PAUSED_TO_READY: sdlvideosink->framerate_n = 0; sdlvideosink->framerate_d = 1; g_mutex_lock (sdlvideosink->lock); gst_sdlvideosink_destroy (sdlvideosink); g_mutex_unlock (sdlvideosink->lock); break; case GST_STATE_CHANGE_READY_TO_NULL: g_mutex_lock (sdlvideosink->lock); gst_sdlvideosink_deinitsdl (sdlvideosink); GST_OBJECT_FLAG_UNSET (sdlvideosink, GST_SDLVIDEOSINK_OPEN); g_mutex_unlock (sdlvideosink->lock); break; default: /* do nothing */ break; } return ret; init_failed: { /* method posted detailed error message */ GST_DEBUG_OBJECT (sdlvideosink, "init failed"); return GST_STATE_CHANGE_FAILURE; } }
/** * gst_x_overlay_prepare_xwindow_id: * @overlay: a #GstXOverlay which does not yet have an XWindow. * * This will post a "prepare-xwindow-id" element message on the bus * to give applications an opportunity to call * gst_x_overlay_set_xwindow_id() before a plugin creates its own * window. * * This function should only be used by video overlay plugin developers. */ void gst_x_overlay_prepare_xwindow_id (GstXOverlay * overlay) { GstStructure *s; GstMessage *msg; g_return_if_fail (overlay != NULL); g_return_if_fail (GST_IS_X_OVERLAY (overlay)); GST_LOG_OBJECT (GST_OBJECT (overlay), "prepare xwindow_id"); s = gst_structure_new ("prepare-xwindow-id", NULL); msg = gst_message_new_element (GST_OBJECT (overlay), s); gst_element_post_message (GST_ELEMENT (overlay), msg); }
/** * gst_x_overlay_set_xwindow_id: * @overlay: a #GstXOverlay to set the XWindow on. * @xwindow_id: a #XID referencing the XWindow. * * This will call the video overlay's set_xwindow_id method. You should * use this method to tell to a XOverlay to display video output to a * specific XWindow. Passing 0 as the xwindow_id will tell the overlay to * stop using that window and create an internal one. */ void gst_x_overlay_set_xwindow_id (GstXOverlay * overlay, gulong xwindow_id) { GstXOverlayClass *klass; g_return_if_fail (overlay != NULL); g_return_if_fail (GST_IS_X_OVERLAY (overlay)); klass = GST_X_OVERLAY_GET_CLASS (overlay); if (klass->set_xwindow_id) { klass->set_xwindow_id (overlay, xwindow_id); } }
static gboolean bp_video_find_xoverlay (BansheePlayer *player) { GstElement *video_sink = NULL; GstElement *xoverlay; GstXOverlay *previous_xoverlay; gboolean found_xoverlay; g_object_get (player->playbin, "video-sink", &video_sink, NULL); g_mutex_lock (player->video_mutex); previous_xoverlay = player->xoverlay; if (video_sink == NULL) { player->xoverlay = NULL; if (previous_xoverlay != NULL) { gst_object_unref (previous_xoverlay); } g_mutex_unlock (player->video_mutex); return FALSE; } xoverlay = GST_IS_BIN (video_sink) ? gst_bin_get_by_interface (GST_BIN (video_sink), GST_TYPE_X_OVERLAY) : video_sink; player->xoverlay = GST_IS_X_OVERLAY (xoverlay) ? GST_X_OVERLAY (xoverlay) : NULL; if (previous_xoverlay != NULL) { gst_object_unref (previous_xoverlay); } #if !defined(GDK_WINDOWING_WIN32) // We can't rely on aspect ratio from dshowvideosink if (player->xoverlay != NULL && g_object_class_find_property ( G_OBJECT_GET_CLASS (player->xoverlay), "force-aspect-ratio")) { g_object_set (G_OBJECT (player->xoverlay), "force-aspect-ratio", TRUE, NULL); } #endif if (player->xoverlay != NULL && g_object_class_find_property ( G_OBJECT_GET_CLASS (player->xoverlay), "handle-events")) { g_object_set (G_OBJECT (player->xoverlay), "handle-events", FALSE, NULL); } gst_object_unref (video_sink); found_xoverlay = (player->xoverlay != NULL) ? TRUE : FALSE; g_mutex_unlock (player->video_mutex); return found_xoverlay; }
/** * gst_x_overlay_handle_events: * @overlay: a #GstXOverlay to expose. * @handle_events: a #gboolean indicating if events should be handled or not. * * Tell an overlay that it should handle events from the window system. These * events are forwared upstream as navigation events. In some window system, * events are not propagated in the window hierarchy if a client is listening * for them. This method allows you to disable events handling completely * from the XOverlay. * * Since: 0.10.12 */ void gst_x_overlay_handle_events (GstXOverlay * overlay, gboolean handle_events) { GstXOverlayClass *klass; g_return_if_fail (overlay != NULL); g_return_if_fail (GST_IS_X_OVERLAY (overlay)); klass = GST_X_OVERLAY_GET_CLASS (overlay); if (klass->handle_events) { klass->handle_events (overlay, handle_events); } }
/** * gst_x_overlay_expose: * @overlay: a #GstXOverlay to expose. * * Tell an overlay that it has been exposed. This will redraw the current frame * in the drawable even if the pipeline is PAUSED. */ void gst_x_overlay_expose (GstXOverlay * overlay) { GstXOverlayClass *klass; g_return_if_fail (overlay != NULL); g_return_if_fail (GST_IS_X_OVERLAY (overlay)); klass = GST_X_OVERLAY_GET_CLASS (overlay); if (klass->expose) { klass->expose (overlay); } }
/** * gst_x_overlay_got_xwindow_id: * @overlay: a #GstXOverlay which got a XWindow. * @xwindow_id: a #XID referencing the XWindow. * * This will post a "have-xwindow-id" element message on the bus. * * This function should only be used by video overlay plugin developers. */ void gst_x_overlay_got_xwindow_id (GstXOverlay * overlay, gulong xwindow_id) { GstStructure *s; GstMessage *msg; g_return_if_fail (overlay != NULL); g_return_if_fail (GST_IS_X_OVERLAY (overlay)); GST_LOG_OBJECT (GST_OBJECT (overlay), "xwindow_id = %lu", xwindow_id); s = gst_structure_new ("have-xwindow-id", "xwindow-id", G_TYPE_ULONG, xwindow_id, NULL); msg = gst_message_new_element (GST_OBJECT (overlay), s); gst_element_post_message (GST_ELEMENT (overlay), msg); }
/** * gst_x_overlay_got_window_handle: * @overlay: a #GstXOverlay which got a window * @handle: a platform-specific handle referencing the window * * This will post a "have-xwindow-id" element message on the bus. * * This function should only be used by video overlay plugin developers. */ void gst_x_overlay_got_window_handle (GstXOverlay * overlay, guintptr handle) { GstStructure *s; GstMessage *msg; g_return_if_fail (overlay != NULL); g_return_if_fail (GST_IS_X_OVERLAY (overlay)); GST_LOG_OBJECT (GST_OBJECT (overlay), "xwindow_id = %p", (gpointer) handle); s = gst_structure_new ("have-xwindow-id", "xwindow-id", G_TYPE_ULONG, (unsigned long) handle, "window-handle", G_TYPE_UINT64, (guint64) handle, NULL); msg = gst_message_new_element (GST_OBJECT (overlay), s); gst_element_post_message (GST_ELEMENT (overlay), msg); }
static void empathy_video_widget_element_added_cb (FsElementAddedNotifier *notifier, GstBin *bin, GstElement *element, EmpathyVideoWidget *self) { EmpathyVideoWidgetPriv *priv = GET_PRIV (self); if (priv->overlay == NULL && GST_IS_X_OVERLAY (element)) { priv->overlay = element; gst_x_overlay_expose (GST_X_OVERLAY (priv->overlay)); } if (g_object_class_find_property ( G_OBJECT_GET_CLASS (element), "force-aspect-ratio")) { g_object_set (G_OBJECT (element), "force-aspect-ratio", TRUE, NULL); } }
void QGstreamerVideoWindow::setDisplayRect(const QRect &rect) { m_displayRect = rect; if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) { #if GST_VERSION_MICRO >= 29 if (m_displayRect.isEmpty()) gst_x_overlay_set_render_rectangle(GST_X_OVERLAY(m_videoSink), -1, -1, -1, -1); else gst_x_overlay_set_render_rectangle(GST_X_OVERLAY(m_videoSink), m_displayRect.x(), m_displayRect.y(), m_displayRect.width(), m_displayRect.height()); repaint(); #endif } }
bool QGstreamerVideoWindow::processSyncMessage(const QGstreamerMessage &message) { GstMessage* gm = message.rawMessage(); if ((GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ELEMENT) && gst_structure_has_name(gm->structure, "prepare-xwindow-id") && m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) { gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(m_videoSink), m_windowId); GstPad *pad = gst_element_get_static_pad(m_videoSink,"sink"); m_bufferProbeId = gst_pad_add_buffer_probe(pad, G_CALLBACK(padBufferProbe), this); return true; } return false; }
static void empathy_video_widget_element_added_cb (FsElementAddedNotifier *notifier, GstBin *bin, GstElement *element, EmpathyVideoWidget *self) { EmpathyVideoWidgetPriv *priv = GET_PRIV (self); /* We assume the overlay is the sink */ g_mutex_lock (priv->lock); if (priv->overlay == NULL && GST_IS_X_OVERLAY (element)) { priv->overlay = element; g_object_add_weak_pointer (G_OBJECT (element), (gpointer) &priv->overlay); empathy_video_widget_element_set_sink_properties_unlocked (self); gst_x_overlay_expose (GST_X_OVERLAY (priv->overlay)); } g_mutex_unlock (priv->lock); }
void QGstreamerGLTextureRenderer::precessNewStream() { if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) { GstXOverlay *overlay = GST_X_OVERLAY(m_videoSink); gst_x_overlay_set_xwindow_id(overlay, m_winId); if (!m_displayRect.isEmpty()) { gst_x_overlay_set_render_rectangle(overlay, m_displayRect.x(), m_displayRect.y(), m_displayRect.width(), m_displayRect.height()); } GstPad *pad = gst_element_get_static_pad(m_videoSink,"sink"); m_bufferProbeId = gst_pad_add_buffer_probe(pad, G_CALLBACK(padBufferProbe), this); } }
void GStreamerGWorld::setWindowOverlay(GstMessage* message) { GstObject* sink = GST_MESSAGE_SRC(message); if (!GST_IS_X_OVERLAY(sink)) return; if (g_object_class_find_property(G_OBJECT_GET_CLASS(sink), "force-aspect-ratio")) g_object_set(sink, "force-aspect-ratio", TRUE, NULL); if (m_videoWindow) { m_videoWindow->prepareForOverlay(message); #if GST_CHECK_VERSION(0, 10, 31) || GST_VERSION_NANO gst_x_overlay_set_window_handle(GST_X_OVERLAY(sink), m_videoWindow->videoWindowId()); #else gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(sink), m_videoWindow->videoWindowId()); #endif } }
void QGstreamerVideoWindow::setWinId(WId id) { if (m_windowId == id) return; WId oldId = m_windowId; m_windowId = id; if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) { gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(m_videoSink), m_windowId); } if (!oldId) emit readyChanged(true); if (!id) emit readyChanged(false); }
void VideoWidget::SetOverlay() { if (isVisible() && video_overlay_ && GST_IS_X_OVERLAY(video_overlay_)) { // Get window id from this widget and set it for video sink // so it renders to our widget id and does not open separate window (that is the default behaviour) qDebug() << name_ << " >> SetOverlay() called from showEvent()"; window_id_ = winId(); if (window_id_) { qDebug() << name_ << " >> Giving x overlay widgets window id " << window_id_; #ifdef Q_WS_X11 QApplication::syncX(); #endif gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(video_overlay_), (gulong)window_id_); WindowExposed(); } } }
void VideoWidget::OnElementAdded(FsElementAddedNotifier *notifier, GstBin *bin, GstElement *element, VideoWidget *self) { // If element implements GST_X_OVERLAY interface, set local video_overlay_ to element // If true element = the current video sink if (!self->video_overlay_ && GST_IS_X_OVERLAY(element)) { qDebug() << self->name_ << " >> element-added CALLBACK >> Got overlay element, storing"; self->video_overlay_ = element; QMetaObject::invokeMethod(self, "WindowExposed", Qt::QueuedConnection); } // If element has property force-aspect-ratio set it to true // If true element = the current video sink if (g_object_class_find_property(G_OBJECT_GET_CLASS(element), "force-aspect-ratio")) { qDebug() << self->name_ << " >> element-added CALLBACK >> found 'force-aspect-ratio' from element"; g_object_set(G_OBJECT(element), "force-aspect-ratio", TRUE, NULL); } }
/** * gst_x_overlay_set_render_rectangle: * @overlay: a #GstXOverlay * @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_x_overlay_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_x_overlay_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. * * Returns: %FALSE if not supported by the sink. * * Since: 0.10.29 */ gboolean gst_x_overlay_set_render_rectangle (GstXOverlay * overlay, gint x, gint y, gint width, gint height) { GstXOverlayClass *klass; g_return_val_if_fail (overlay != NULL, FALSE); g_return_val_if_fail (GST_IS_X_OVERLAY (overlay), FALSE); g_return_val_if_fail ((width == -1 && height == -1) || (width > 0 && height > 0), FALSE); klass = GST_X_OVERLAY_GET_CLASS (overlay); if (klass->set_render_rectangle) { klass->set_render_rectangle (overlay, x, y, width, height); return TRUE; } return FALSE; }
P_INVOKE void bp_video_window_expose (BansheePlayer *player, GdkWindow *window, gboolean direct) { g_return_if_fail (IS_BANSHEE_PLAYER (player)); if (direct && player->xoverlay != NULL && GST_IS_X_OVERLAY (player->xoverlay)) { gst_x_overlay_expose (player->xoverlay); return; } if (player->xoverlay == NULL && !bp_video_find_xoverlay (player)) { return; } gst_object_ref (player->xoverlay); gst_x_overlay_set_xwindow_id (player->xoverlay, player->video_window_xid); gst_x_overlay_expose (player->xoverlay); gst_object_unref (player->xoverlay); }
void QGstreamerGLTextureRenderer::setOverlayGeometry(const QRect &geometry) { if (m_displayRect != geometry) { #ifdef GL_TEXTURE_SINK_DEBUG qDebug() << Q_FUNC_INFO << geometry; #endif m_displayRect = geometry; if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) { if (m_displayRect.isEmpty()) gst_x_overlay_set_render_rectangle(GST_X_OVERLAY(m_videoSink), -1, -1, -1, -1); else gst_x_overlay_set_render_rectangle(GST_X_OVERLAY(m_videoSink), m_displayRect.x(), m_displayRect.y(), m_displayRect.width(), m_displayRect.height()); repaintOverlay(); } } }
void QGstreamerVideoWidgetControl::windowExposed() { if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) gst_x_overlay_expose(GST_X_OVERLAY(m_videoSink)); }