我正在尝试在自己创建的 Wayland 表面上播放视频文件,但没有进行渲染。我参考了 https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gst-plugins-base-libs-gstvideooverlay.html 和 https://git。 collabora.com/cgit/user/gkiagia/gst-wayland-gtk-demo.git/tree/main.c
创建管道后(filesrc->parser->decoder->waylandsink);我将 bus_set_sync_handler 设置为
gst_bus_set_sync_handler (bus, (GstBusSyncHandler) create_window_own,
gstreamerData.pipeline, NULL);
create_window_own 的实现如下
static GstBusSyncReply create_window_own (GstBus * bus, GstMessage * message, GstPipeline * pipeline)
{
if (counter == 0)
{
display = wl_display_connect(NULL);
if (display == NULL)
{
fprintf(stderr, "Can't connect to display\n");
exit(1);
}
printf("connected to display\n");
struct wl_registry *registry = wl_display_get_registry(display);
wl_registry_add_listener(registry, ®istry_listener, NULL);
wl_display_dispatch(display);
wl_display_roundtrip(display);
if (compositor == NULL) {
fprintf(stderr, "Can't find compositor\n");
exit(1);
} else {
fprintf(stderr, "Found compositor\n");
}
surface = wl_compositor_create_surface(compositor);
if (surface == NULL) {
fprintf(stderr, "Can't create surface\n");
exit(1);
} else {
fprintf(stderr, "Created surface\n");
}
shell_surface = wl_shell_get_shell_surface(shell, surface);
if (shell_surface == NULL) {
fprintf(stderr, "Can't create shell surface\n");
exit(1);
} else {
fprintf(stderr, "Created shell surface\n");
}
wl_shell_surface_set_toplevel(shell_surface);
wl_shell_surface_add_listener(shell_surface,
&shell_surface_listener, NULL);
create_window();
//paint_pixels();
wl_surface_attach(surface, buffer, 0, 0);
//wl_surface_attach(surface, NULL, 0, 0);
//wl_surface_damage(surface, 0, 0, WIDTH, HEIGHT);
//wl_surface_commit(surface);
printf("Before Thread\n");
pthread_create(&tid, NULL, myThreadFun, (void*)display);
printf("After Thread\n");
counter = 1;
}
if (gst_is_wayland_display_handle_need_context_message (message)) {
if (display != 0) {
GstContext *context;
printf("getting context\n");
context = gst_wayland_display_handle_context_new (display);
gst_element_set_context(GST_ELEMENT (GST_MESSAGE_SRC (message)), context);
/* HACK save the pointer to the sink (which implements GstWaylandVideo)
* from this point. Unfortunately, d->overlay can also be the playbin
* instead of waylandsink */
wlvideo = GST_WAYLAND_VIDEO (GST_MESSAGE_SRC (message));
} else {
g_warning ("Should have obtained display_handle by now!\n");
}
gst_message_unref (message);
return GST_BUS_DROP;
} else if (gst_is_video_overlay_prepare_window_handle_message (message)) {
if (surface != 0) {
/* GST_MESSAGE_SRC (message) will be the overlay object that we have to
* use. This may be waylandsink, but it may also be playbin. In the latter
* case, we must make sure to use playbin instead of waylandsink, because
* playbin resets the window handle and render_rectangle after restarting
* playback and the actual window size is lost */
overlay = GST_VIDEO_OVERLAY (GST_MESSAGE_SRC (message));
/*
g_print ("setting window handle and size (%d x %d)\n",
d->video_widget_allocation.width, d->video_widget_allocation.height);
*/
gst_video_overlay_set_window_handle (overlay, (guintptr) surface);
if (wlvideo && overlay ) {
gst_wayland_video_begin_geometry_change (wlvideo);
printf("setting rendrer rectangle\n");
gst_video_overlay_set_render_rectangle (overlay,
0, 0,
800, 480);
} else {
g_warning ("Should have obtained surface by now!\n");
}
gst_message_unref (message);
return GST_BUS_DROP;
}
}
printf("+++ret\n");
return GST_BUS_PASS;
}