Merge branch 'wxCtrlWayland' of https://github.com/martinetd/wxWidgets
Really fix wxMediaCtrl support when using Wayland. See https://github.com/wxWidgets/wxWidgets/pull/2383
This commit is contained in:
@@ -142,7 +142,24 @@ expose_event_callback(GtkWidget* widget, GdkEventExpose* event, wxGStreamerMedia
|
|||||||
// GST Doesn't redraw automatically while paused
|
// GST Doesn't redraw automatically while paused
|
||||||
// Plus, the video sometimes doesn't redraw when it looses focus
|
// Plus, the video sometimes doesn't redraw when it looses focus
|
||||||
// or is painted over so we just tell it to redraw...
|
// or is painted over so we just tell it to redraw...
|
||||||
gst_player_video_overlay_video_renderer_expose(GST_PLAYER_VIDEO_OVERLAY_VIDEO_RENDERER(be->m_video_renderer));
|
gst_player_video_overlay_video_renderer_expose(
|
||||||
|
GST_PLAYER_VIDEO_OVERLAY_VIDEO_RENDERER(be->m_video_renderer)
|
||||||
|
);
|
||||||
|
#ifdef __WXGTK3__
|
||||||
|
GdkWindow* window = gtk_widget_get_window(widget);
|
||||||
|
if (strcmp("GdkWaylandWindow", g_type_name(G_TYPE_FROM_INSTANCE(window))) == 0)
|
||||||
|
{
|
||||||
|
// on wayland we need to place the video
|
||||||
|
int x, y;
|
||||||
|
GtkAllocation allocation;
|
||||||
|
gdk_window_get_origin(window, &x, &y);
|
||||||
|
gtk_widget_get_allocation(widget, &allocation);
|
||||||
|
gst_player_video_overlay_video_renderer_set_render_rectangle(
|
||||||
|
GST_PLAYER_VIDEO_OVERLAY_VIDEO_RENDERER(be->m_video_renderer),
|
||||||
|
x, y, allocation.width, allocation.height
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -175,9 +192,25 @@ expose_event_callback(GtkWidget* widget, GdkEventExpose* event, wxGStreamerMedia
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
static void realize_callback(GtkWidget* widget, wxGStreamerMediaBackend* be)
|
static void realize_callback(GtkWidget* widget, wxGStreamerMediaBackend* be)
|
||||||
{
|
{
|
||||||
gst_player_video_overlay_video_renderer_set_window_handle(GST_PLAYER_VIDEO_OVERLAY_VIDEO_RENDERER(be->m_video_renderer),
|
gst_player_video_overlay_video_renderer_set_window_handle(
|
||||||
wxGtkGetIdFromWidget(widget)
|
GST_PLAYER_VIDEO_OVERLAY_VIDEO_RENDERER(be->m_video_renderer),
|
||||||
);
|
wxGtkGetIdFromWidget(widget)
|
||||||
|
);
|
||||||
|
#ifdef __WXGTK3__
|
||||||
|
GdkWindow* window = gtk_widget_get_window(widget);
|
||||||
|
if (strcmp("GdkWaylandWindow", g_type_name(G_TYPE_FROM_INSTANCE(window))) == 0)
|
||||||
|
{
|
||||||
|
// on wayland we need to place the video
|
||||||
|
int x, y;
|
||||||
|
GtkAllocation allocation;
|
||||||
|
gdk_window_get_origin(window, &x, &y);
|
||||||
|
gtk_widget_get_allocation(widget, &allocation);
|
||||||
|
gst_player_video_overlay_video_renderer_set_render_rectangle(
|
||||||
|
GST_PLAYER_VIDEO_OVERLAY_VIDEO_RENDERER(be->m_video_renderer),
|
||||||
|
x, y, allocation.width, allocation.height
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
GtkWidget* w = be->GetControl()->m_wxwindow;
|
GtkWidget* w = be->GetControl()->m_wxwindow;
|
||||||
#ifdef __WXGTK3__
|
#ifdef __WXGTK3__
|
||||||
g_signal_connect(w, "draw", G_CALLBACK(draw_callback), be);
|
g_signal_connect(w, "draw", G_CALLBACK(draw_callback), be);
|
||||||
@@ -217,7 +250,35 @@ static void end_of_stream_callback(GstPlayer * WXUNUSED(player), wxGStreamerMedi
|
|||||||
{
|
{
|
||||||
be->EndOfStream();
|
be->EndOfStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define GST_WAYLAND_DISPLAY_HANDLE_CONTEXT_TYPE "GstWaylandDisplayHandleContextType"
|
||||||
|
static GstBusSyncReply bus_sync_handler(GstBus * WXUNUSED(bus), GstMessage* msg, gpointer WXUNUSED(user_data))
|
||||||
|
{
|
||||||
|
const gchar *type = NULL;
|
||||||
|
|
||||||
|
if (GST_MESSAGE_TYPE(msg) == GST_MESSAGE_NEED_CONTEXT &&
|
||||||
|
gst_message_parse_context_type(msg, &type) &&
|
||||||
|
!g_strcmp0 (type, GST_WAYLAND_DISPLAY_HANDLE_CONTEXT_TYPE))
|
||||||
|
{
|
||||||
|
GstContext *context = gst_context_new (GST_WAYLAND_DISPLAY_HANDLE_CONTEXT_TYPE, TRUE);
|
||||||
|
GstStructure *s = gst_context_writable_structure(context);
|
||||||
|
wxDisplayInfo display_info = wxGetDisplayInfo();
|
||||||
|
/* On wayland we need to explicitely transmit the display handle to gstreamer,
|
||||||
|
* but attribute expected depends on which video sink got selected.
|
||||||
|
* "display" will likely remain as the normal way of doing for gst 1.19+
|
||||||
|
* but there is no harm in setting both for compatibility
|
||||||
|
*/
|
||||||
|
gst_structure_set(s, "handle", G_TYPE_POINTER, display_info.dpy, NULL);
|
||||||
|
gst_structure_set(s, "display", G_TYPE_POINTER, display_info.dpy, NULL);
|
||||||
|
gst_element_set_context(GST_ELEMENT(msg->src), context);
|
||||||
|
|
||||||
|
return GST_BUS_DROP;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GST_BUS_PASS;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool wxGStreamerMediaBackend::CreateControl(wxControl* ctrl, wxWindow* parent,
|
bool wxGStreamerMediaBackend::CreateControl(wxControl* ctrl, wxWindow* parent,
|
||||||
wxWindowID id,
|
wxWindowID id,
|
||||||
@@ -337,6 +398,33 @@ bool wxGStreamerMediaBackend::CreateControl(wxControl* ctrl, wxWindow* parent,
|
|||||||
m_video_renderer = gst_player_video_overlay_video_renderer_new(window_handle);
|
m_video_renderer = gst_player_video_overlay_video_renderer_new(window_handle);
|
||||||
m_player = gst_player_new(m_video_renderer, gst_player_g_main_context_signal_dispatcher_new(NULL));
|
m_player = gst_player_new(m_video_renderer, gst_player_g_main_context_signal_dispatcher_new(NULL));
|
||||||
|
|
||||||
|
wxDisplayInfo info = wxGetDisplayInfo();
|
||||||
|
if (info.type == wxDisplayWayland)
|
||||||
|
{
|
||||||
|
// wayland needs a specific handler to pass display to gstreamer
|
||||||
|
GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(gst_player_get_pipeline(m_player)));
|
||||||
|
gst_bus_add_signal_watch(bus);
|
||||||
|
gst_bus_set_sync_handler(bus, bus_sync_handler, this, NULL);
|
||||||
|
gst_object_unref(bus);
|
||||||
|
|
||||||
|
// xvimagesink is known to crash gstreamer with a wayland window
|
||||||
|
// if display is set; try to make it not load.
|
||||||
|
GstPluginFeature *feature;
|
||||||
|
feature = gst_registry_find_feature(
|
||||||
|
gst_registry_get(), "xvimagesink", GST_TYPE_ELEMENT_FACTORY
|
||||||
|
);
|
||||||
|
if (feature) {
|
||||||
|
gst_plugin_feature_set_rank(feature, GST_RANK_NONE);
|
||||||
|
}
|
||||||
|
// same for ximagesink
|
||||||
|
feature = gst_registry_find_feature(
|
||||||
|
gst_registry_get(), "ximagesink", GST_TYPE_ELEMENT_FACTORY
|
||||||
|
);
|
||||||
|
if (feature) {
|
||||||
|
gst_plugin_feature_set_rank(feature, GST_RANK_NONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
g_signal_connect(m_player, "video-dimensions-changed", G_CALLBACK(video_dimensions_changed_callback), this);
|
g_signal_connect(m_player, "video-dimensions-changed", G_CALLBACK(video_dimensions_changed_callback), this);
|
||||||
g_signal_connect(m_player, "state-changed", G_CALLBACK(state_changed_callback), this);
|
g_signal_connect(m_player, "state-changed", G_CALLBACK(state_changed_callback), this);
|
||||||
g_signal_connect(m_player, "end-of-stream", G_CALLBACK(end_of_stream_callback), this);
|
g_signal_connect(m_player, "end-of-stream", G_CALLBACK(end_of_stream_callback), this);
|
||||||
|
Reference in New Issue
Block a user