I'm trying to display a video stream on a specific screen.
Right now I use the waylandsink
that has display
and fullscreen
properties so I have:
gst-launch-1.0 videotestsrc ! waylandsink display=wayland-0 fullscreen=TRUE
It works fine.
Then I check my display list using xrandr --listmonitors
and I get:
Monitors: 2
+*XWAYLAND0 1920/508x1080/286+0+0 XWAYLAND0
+XWAYLAND1 1920/508x1080/286+1920+0 XWAYLAND1
So I tried to replace wayland-0
by wayland-1
but the pipeline stops.
I'm not sure if my display name is correct or how I should obtain it (as for now I took wayland-0
and simply incremented it). Or if it is possible to do that using waylandsink
Edit: I did a lot more research (but still not enough). First I became aware that waylandsink may not be what I'm looking for. Second is I didn't understand how rendering works in Linux (and it's still not quite clear).
But I found:
I'll keep searching...
I finally found! And it's the kmssink
but I'll explain more why.
First I talked about the waylandsink
. The thing is I did not know was wayland is a protocol and it seems to only work for displaying content inside a Desktop Environment (DE). So I guess you could create windows for each display and then link your sink to those windows. But I was looking for a way to display without any DE so waylandsink
is a not an option.
For glimagesink
from what I tried it's also in a DE so I did not explore more about it.
Then there's the framebuffer using the fbdevsink
. It works without DE, but suffers from limitations... There seems to be only one framebuffer situated in /dev/fb0
and what we draw in it is displayed on every screen regardless of the display resolution. So if we have 2 displays with different resolution we cannot do fullscreen without having some cropping on one of them. Plus we cannot display different video on each screen because the framebuffer is duplicated. Finally while I was testing it, I found out some time there were frames that were drawn at the same time into the framebuffer, so it was causing the video to have some weird visual.
Maybe the issues I listed could have been fixed in some way but there are just too many so I discarded this option
When I checked the documentation for the kmssink
it says there are 2 main parameters I was interrested:
By specifying the bus-id
I though I could display on a specific screen. But all the displays use the same bus-id: 0000:00:02.0
so it's not the parameter to specify a display.
Then there is connector-id
. It's an integer and it can be used to specify the display. In my case it's 77
for HDMI-A-1
and 92
for HDMI-A-2
.
How do you get the connector-id
? Well that's not simple...
A command exists to get them and it's called modetest
. The thing is it seems to be only included in some embedded devices. I found out that the command was included in the package libdrm
but in my case installing it did not give me access to the command...
I'm using GStreamer with Rust so by importing the drm package I was able to get a list of connector-id and a lot of data about displays.
So in the end I can do:
gst-launch-1.0 videotestsrc ! kmssink connector-id=77
or:
gst-launch-1.0 videotestsrc ! kmssink connector-id=92
To display on the screen I want to. One last thing: kmssink need to be executed as root to work