我在embedded-linux上开发C ++应用程序,我需要在其中显示来自摄像头的视频。我使用gstreamer创建了一个窗口,并使用命令启动视频捕获(因为它在tegra上有硬件支持):
system("gst-launch -e v4l2src device=\"/dev/video0\" \
! \"video/x-raw-yuv,width=320,height=240\" \
! videoflip method=counterclockwise \
! nvvidconv \
! nvxvimagesink &")
设备上的主要应用程序是全屏运行的,因此我需要将此窗口放在屏幕上的特定位置,这样用户就会感觉它们都在同一个窗口中运行了#34;。我设法做到了这一点:
XMoveWindow(display, win_video, x, y); // x, y from top left point in landscape mode!
我面临的问题是gst-launch首先显示在0,0坐标上(因为它是从命令行运行)然后"快照"在应用程序中的正确位置(以编程方式)。我这样做是通过运行XQueryTree来搜索所有显示的窗口并找到具有gst-launch的窗口然后移动它。这需要一些时间并且看起来不太好,所以我正在寻找更好的解决方案。
我尝试在gst-launch管道中使用videobox将视频定位在屏幕上,但问题是它从0,0绘制黑色边框到视频窗口(border-alpha = 0应该解决这个问题,但它没有 - 我认为问题出在nvvidconv或nvxvimagesink中,但我无法知道):
gst-launch -e v4l2src device="/dev/video0" ! "video/x-raw-yuv,width=320,height=240" ! videobox border-alpha=0 top=-50 left=-50 ! nvvidconv ! nvxvimagesink
第二个解决方案是我将主应用程序窗口设置为始终位于顶部,在找到视频窗口后,将其移动到位置,然后将主应用程序恢复正常并将视频窗口移到顶部。 我已经尝试了两种方法,我在这里设置始终在顶部,但两者都没有用。 第一:
Status x11_window_set_on_top (Display* display, Window xid)
{
XEvent event;
event.xclient.type = ClientMessage;
event.xclient.serial = 0;
event.xclient.send_event = True;
event.xclient.display = display;
event.xclient.window = xid;
event.xclient.message_type = XInternAtom (display, "_NET_WM_STATE", False);
event.xclient.format = 32;
event.xclient.data.l[0] = _NET_WM_STATE_ADD;
event.xclient.data.l[1] = XInternAtom (display, "_NET_WM_STATE_ABOVE", False);
event.xclient.data.l[2] = 0; //unused.
event.xclient.data.l[3] = 0;
event.xclient.data.l[4] = 0;
return XSendEvent (display,
DefaultRootWindow(display),
False,
SubstructureRedirectMask | SubstructureNotifyMask,
&event);
}
第二
void Keep_Window_Always_Top(Display *dpy, Window w)
{
Atom stateAbove;
if (w) {
stateAbove = XInternAtom(dpy, "_NET_WM_STATE_ABOVE", False);
XChangeProperty(dpy, w, XInternAtom(dpy, "_NET_WM_STATE", False), XA_ATOM, 32, PropModeReplace, (unsigned char *) &stateAbove, 1);
}
}
我不知道为什么这不起作用。
问题是如何从控制台命令定位窗口,或者在显示窗口之前以编程方式拦截窗口并将其设置为正确的坐标,或者以某种方式让我的应用程序始终位于顶部,这样我就可以摆脱对齐实现
欢迎任何其他建议。