I am developing a C ++ application on embedded Linux, and I need to display video from the camera. I used gstreamer to create a window and start capturing video (because it has hardware support on tegra) with the command:
system("gst-launch -e v4l2src device=\"/dev/video0\" \ ! \"video/x-raw-yuv,width=320,height=240\" \ ! videoflip method=counterclockwise \ ! nvvidconv \ ! nvxvimagesink &")
The main application on the device works in full screen mode, so I need to place this window in a certain place on the screen, so that the user feels that everything works in the same "window". I managed to do this with
XMoveWindow(display, win_video, x, y); // x, y from top left point in landscape mode!
The problem that I am facing is that the gst-start is first displayed in coordinates 0, 0 (since it is launched from the command line), and then is βboundβ to the correct location (programmatically) in the application. I do this by running XQueryTree to search for all the windows displayed and find one with gst start, and then move it. This takes some time and doesn't look very good, so I'm looking for the best solutions.
I tried using the video ad in the gst-launch pipeline to place the video on the screen, but the problem with this is that it draws a border from 0, 0 to the video window (border-alpha = 0 should solve this, but itβs not - I think the problem is somewhere in nvvidconv or nvxvimagesink, but I don't know):
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
The second solution was that I installed the main application window on top, as always, and after I found the video window, move it to the position, then return the main application to normal and move the video window on top. I tried two methods that I found here to set always on top, but both did not work. At first:
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;
Secondly:
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); } }
I do not know why this is not working as it should.
The question is how to position the window from the command console or reprogram the window programmatically before displaying it and set the correct coordinates or somehow make my application always be on top, so can I get rid of the binding effect?
Any other suggestions are welcome.