我创建了一个简单的gstreamer + gtk应用程序来播放视频文件。 “filesrc”,“decodebin”,“autovideosink”,“autoaudiosink”gstreamer元素用于此。
主窗口使用gtk_window_new(GTK_WINDOW_TOPLEVEL)
创建,绘图区域使用gtk_drawing_area_new()
创建。绘图窗口嵌入在主窗口中。
要在gtk绘图窗口上渲染,使用gstreamer api gst_video_overlay_set_window_handle()
将其句柄作为叠加层传递给gstreamer视频插件
通过这样做,视频不会被渲染,只播放音频。
如果我将XCreateWindow()
句柄传递给gstreamer视频插件作为叠加层,那么一切正常,而不是GTK窗口。但我必须创建基于GTK的播放器。
现在,当我开始调试问题时,我发现了以下细节。
002:<:000f:52:Request(1):CreateWindow depth = 0x18 window = 0x01600001 parent = 0x01400007 x = 0 y = 0 width = 640 height = 368 border-width = 0 class = InputOutput(0x0001) visual = 0x00000021 value-list = {background-pixel = 0x00000000 border-pixel = 0x00000000 backing-store = NotUseful(0x00)override-redirect = false(0x00)colormap = CopyFromParent(0x00000000)}
002:<:0010:24:Request(16):InternAtom only-if-exists = true(0x01)name ='_ NET_WM_STATE'
002:>:000f:错误8 =匹配:major = 1,minor = 0,bad = 20971527
002:<:001d:8:Request(3):GetWindowAttributes window = 0x01600001
002:<:001e:8:Request(14):GetGeometry drawable = 0x01600001
002:>:001d:错误3 =窗口:major = 3,minor = 0,bad = 23068673
002:>:001e:错误9 = Drawable:major = 14,minor = 0,bad = 23068673
我不知道为什么这些请求因GTK窗口而失败。而在我的旧系统(ubuntu 14.04)中,我可以很好地运行同一个播放器。目前的系统是ubuntu 16.04
任何与X Server相关的配置设置都是这样做的吗? 请建议一些解决方案或任何想法如何进一步调试以捕捉真正的原因。
答案 0 :(得分:0)
原型:
XCreateWindow(display, parent, x, y, width, height, border_width, depth, class, visual, valuemask, attributes)
提到的autovideosink实际上是imxeglvivsink。 imxeglvivsink使用gtk-window作为父窗口创建子窗口(检查XCreateWindow api的第二个参数)。
现在GDK默认用于父Windodw(GTK)的Visual与X默认Visual不同,这就是X CreateWindow请求失败的原因。
我用2个解决方案解决了这个问题。
解决方案1: 在imxeglvivsink中,在创建子窗口时,我使用了' CopyFromParent'标志为' visual' XCreateWindow api的参数。通过这样做,Visual for Parent和Child匹配,X请求CreateWindow成功。
我不喜欢这个解决方案,因为我必须用我的新库替换原始的imxeglvivsink库。
解决方案2: 我的最终目标仍然是一样的。我必须为父窗口和子窗口保持相同的视觉效果。在此解决方案中,我将Visual of Parent窗口(GTK)更改为X Default Visual。我在应用程序级别进行了此更改,并且我没有依赖imxeglvivsink。更改GDK视觉的代码片段如下:
static int change_visual(GtkWidget *widget)
{
int nitems_return;
Display *x_display = XOpenDisplay(NULL);
Visual *x_visual = XDefaultVisual(x_display, DefaultScreen(x_display));
GdkScreen *gdk_screen = gdk_screen_get_default();
GList *gdk_visual_list = gdk_screen_list_visuals(gdk_screen);
GList *l;
for (l = gdk_visual_list; l != NULL; l = l->next)
{
Visual *temp = gdk_x11_visual_get_xvisual((GdkVisual *)l->data);
if(temp->visualid == x_visual->visualid) break;
}
//l is pointing the visual which is similar to system x visual. Lets change it.
gtk_widget_set_visual (widget, (GdkVisual *)l->data);
return 0;
}
我知道如果visualid在for循环中不匹配,我就不会小心。对我来说,我总是发现GDK视觉效果与X Default Visual相同。