Meaning of the compositor and videomixer parameter

I would like to ask about the meaning of xpos, ypos, width, height parameters in the compositor parameter, and what are their units? If I specify a value at xpos and ypos, how does it map to the display? I noticed that when I specify a camera position, it automatically fills up the border area. Why? Also, regarding videomixer, I found only xpos and ypos parameters, so how does it map to the display? thanks for everyone

xpos, ypos, width and height are only related to the frame you’re composing.
Where it will be displayed on screen is mostly related to your display sink properties.

The units for xpos, ypos, width, and height are in pixels.

As the previous poster said, compositor positions input streams on an output frame, and the output frame can have different dimensions (larger or smaller) that are not related to any of the inputs, but it will pick some default if you don’t force a specific output resolution.

Don’t use videomixer, use compositor (or glvideomixer).

But how do I specify the xpos and ypos values? For example, if I arrange 8 cameras into a 4*2 interface, but find that the last camera image width of each line is the largest, and the other three have the same image width, the command is as follows:

./test "( compositor name=mix sink_0::alpha=1 sink_0::xpos=0 sink_0::ypos=0 sink_0::width=640 sink_0::height=480 sink_1::alpha=1 sink_1::xpos=640 sink_1::ypos=0 sink_1::width=640 sink_1::height=480 sink_2::alpha=1 sink_2::xpos=1280 sink_2::ypos=0 sink_2::width=640 sink_2::height=480 sink_3::alpha=1 sink_3::xpos=1920 sink_3::ypos=0 sink_3::width=640 sink_3::height=480 sink_4::alpha=1 sink_4::xpos=0 sink_4::ypos=486 sink_4::width=640 sink_4::height=480 sink_5::alpha=1 sink_5::xpos=640 sink_5::ypos=486 sink_5::width=640 sink_5::height=480 sink_6::alpha=1 sink_6::xpos=1280 sink_6::ypos=486 sink_6::width=640 sink_6::height=480 sink_7::alpha=1 sink_7::xpos=1920 sink_7::ypos=486 sink_7::width=640 sink_7::height=480 ! videoconvert ! mpph264enc bps-max=1000 ! h264parse ! rtph264pay name=pay0 pt=96 v4l2src device=/dev/video11 ! video/x-raw,format=NV12,width=1920,height=1080 ! videoscale ! video/x-raw,width=640,height=480 ! videorate ! video/x-raw,framerate=25/1 ! mix.sink_0 v4l2src device=/dev/video12 ! video/x-raw,format=NV12,width=1920,height=1080 ! videoscale ! video/x-raw,width=640,height=480 ! videorate ! video/x-raw,framerate=25/1 ! mix.sink_1 v4l2src device=/dev/video13 ! video/x-raw,format=NV12,width=1920,height=1080 ! videoscale ! video/x-raw,width=640,height=480 ! videorate ! video/x-raw,framerate=25/1 ! mix.sink_2 v4l2src device=/dev/video14 ! video/x-raw,format=NV12,width=1920,height=1080 ! videoscale ! video/x-raw,width=640,height=480 ! videorate ! video/x-raw,framerate=25/1 ! mix.sink_3 v4l2src device=/dev/video3 ! video/x-raw,format=NV12,width=1920,height=1080 ! videoscale ! video/x-raw,width=640,height=480 ! videorate ! video/x-raw,framerate=25/1 ! mix.sink_4 v4l2src device=/dev/video2 ! video/x-raw,format=NV12,width=1920,height=1080 ! videoscale ! video/x-raw,width=640,height=480 ! videorate ! video/x-raw,framerate=25/1 ! mix.sink_5 v4l2src device=/dev/video1 ! video/x-raw,format=NV12,width=1920,height=1080 ! videoscale ! video/x-raw,width=640,height=480 ! videorate ! video/x-raw,framerate=25/1 ! mix.sink_6 v4l2src device=/dev/video0 ! video/x-raw,format=NV12,width=1920,height=1080 ! videoscale ! video/x-raw,width=640,height=480 ! videorate ! video/x-raw,framerate=25/1 ! mix.sink_7)"

When I adjust the width, xpos will also move,how can I modify the command to set the parameters of each sink, so as to achieve a 4*2 evenly split effect.thanks

You may try adjusting pixel-aspect-ratio into caps after videoscale, such as (assuming you have a display sink):

gst-launch-1.0 \
 videotestsrc is-live=1 ! video/x-raw,format=NV12,width=1920,height=1080 ! videoscale ! video/x-raw,width=640,height=480,pixel-aspect-ratio=1/1 ! videorate ! video/x-raw,framerate=25/1 ! queue ! mix.sink_0 \
 videotestsrc is-live=1 ! video/x-raw,format=NV12,width=1920,height=1080 ! videoscale ! video/x-raw,width=640,height=480,pixel-aspect-ratio=1/1 ! videorate ! video/x-raw,framerate=25/1 ! queue ! mix.sink_1 \
 videotestsrc is-live=1 ! video/x-raw,format=NV12,width=1920,height=1080 ! videoscale ! video/x-raw,width=640,height=480,pixel-aspect-ratio=1/1 ! videorate ! video/x-raw,framerate=25/1 ! queue ! mix.sink_2 \
 videotestsrc is-live=1 ! video/x-raw,format=NV12,width=1920,height=1080 ! videoscale ! video/x-raw,width=640,height=480,pixel-aspect-ratio=1/1 ! videorate ! video/x-raw,framerate=25/1 ! queue ! mix.sink_3 \
 videotestsrc is-live=1 ! video/x-raw,format=NV12,width=1920,height=1080 ! videoscale ! video/x-raw,width=640,height=480,pixel-aspect-ratio=1/1 ! videorate ! video/x-raw,framerate=25/1 ! queue ! mix.sink_4 \
 videotestsrc is-live=1 ! video/x-raw,format=NV12,width=1920,height=1080 ! videoscale ! video/x-raw,width=640,height=480,pixel-aspect-ratio=1/1 ! videorate ! video/x-raw,framerate=25/1 ! queue ! mix.sink_5 \
 videotestsrc is-live=1 ! video/x-raw,format=NV12,width=1920,height=1080 ! videoscale ! video/x-raw,width=640,height=480,pixel-aspect-ratio=1/1 ! videorate ! video/x-raw,framerate=25/1 ! queue ! mix.sink_6 \
 videotestsrc is-live=1 ! video/x-raw,format=NV12,width=1920,height=1080 ! videoscale ! video/x-raw,width=640,height=480,pixel-aspect-ratio=1/1 ! videorate ! video/x-raw,framerate=25/1 ! queue ! mix.sink_7 \
 compositor name=mix \
  sink_0::alpha=1 sink_0::xpos=0    sink_0::ypos=0   sink_0::width=640 sink_0::height=480 \
  sink_1::alpha=1 sink_1::xpos=640  sink_1::ypos=0   sink_1::width=640 sink_1::height=480 \
  sink_2::alpha=1 sink_2::xpos=1280 sink_2::ypos=0   sink_2::width=640 sink_2::height=480 \
  sink_3::alpha=1 sink_3::xpos=1920 sink_3::ypos=0   sink_3::width=640 sink_3::height=480 \
  sink_4::alpha=1 sink_4::xpos=0    sink_4::ypos=486 sink_4::width=640 sink_4::height=480 \
  sink_5::alpha=1 sink_5::xpos=640  sink_5::ypos=486 sink_5::width=640 sink_5::height=480 \
  sink_6::alpha=1 sink_6::xpos=1280 sink_6::ypos=486 sink_6::width=640 sink_6::height=480 \
  sink_7::alpha=1 sink_7::xpos=1920 sink_7::ypos=486 sink_7::width=640 sink_7::height=480 \
 ! videoconvert ! autovideosink

Note that rescaling to a different pixel-aspect-ratio may lead to black borders.

You may also try keeping the 16/9 pixel-aspect-ratio with rescaling to 640x360:

gst-launch-1.0 \
 videotestsrc is-live=1 ! video/x-raw,format=NV12,width=1920,height=1080 ! videoscale ! video/x-raw,width=640,height=360 ! videorate ! video/x-raw,framerate=25/1 ! comp.sink_0 \
 videotestsrc is-live=1 ! video/x-raw,format=NV12,width=1920,height=1080 ! videoscale ! video/x-raw,width=640,height=360 ! videorate ! video/x-raw,framerate=25/1 ! comp.sink_1 \
 videotestsrc is-live=1 ! video/x-raw,format=NV12,width=1920,height=1080 ! videoscale ! video/x-raw,width=640,height=360 ! videorate ! video/x-raw,framerate=25/1 ! comp.sink_2 \
 videotestsrc is-live=1 ! video/x-raw,format=NV12,width=1920,height=1080 ! videoscale ! video/x-raw,width=640,height=360 ! videorate ! video/x-raw,framerate=25/1 ! comp.sink_3 \
 videotestsrc is-live=1 ! video/x-raw,format=NV12,width=1920,height=1080 ! videoscale ! video/x-raw,width=640,height=360 ! videorate ! video/x-raw,framerate=25/1 ! comp.sink_4 \
 videotestsrc is-live=1 ! video/x-raw,format=NV12,width=1920,height=1080 ! videoscale ! video/x-raw,width=640,height=360 ! videorate ! video/x-raw,framerate=25/1 ! comp.sink_5 \
 videotestsrc is-live=1 ! video/x-raw,format=NV12,width=1920,height=1080 ! videoscale ! video/x-raw,width=640,height=360 ! videorate ! video/x-raw,framerate=25/1 ! comp.sink_6 \
 videotestsrc is-live=1 ! video/x-raw,format=NV12,width=1920,height=1080 ! videoscale ! video/x-raw,width=640,height=360 ! videorate ! video/x-raw,framerate=25/1 ! comp.sink_7 \
 compositor name=comp \
  sink_0::alpha=1 sink_0::xpos=0    sink_0::ypos=0   sink_0::width=640 sink_0::height=360 \
  sink_1::alpha=1 sink_1::xpos=640  sink_1::ypos=0   sink_1::width=640 sink_1::height=360 \
  sink_2::alpha=1 sink_2::xpos=1280 sink_2::ypos=0   sink_2::width=640 sink_2::height=360 \
  sink_3::alpha=1 sink_3::xpos=1920 sink_3::ypos=0   sink_3::width=640 sink_3::height=360 \
  sink_4::alpha=1 sink_4::xpos=0    sink_4::ypos=360 sink_4::width=640 sink_4::height=360 \
  sink_5::alpha=1 sink_5::xpos=640  sink_5::ypos=360 sink_5::width=640 sink_5::height=360 \
  sink_6::alpha=1 sink_6::xpos=1280 sink_6::ypos=360 sink_6::width=640 sink_6::height=360 \
  sink_7::alpha=1 sink_7::xpos=1920 sink_7::ypos=360 sink_7::width=640 sink_7::height=360 \
 ! videoconvert ! autovideosink

Also note that this example uses NV12 format for composing. For using alpha composing, you may need RGBA format instead.

You may also try adjusting output resolution and pixel-aspect-ratio for your display in the compositor output caps or use videoscale then…depends on your sink.

1 Like

I would like to ask what is the purpose of using queue directive? Is it necessary?

Frankly speaking, I’m unsure if the queues are mandatory.
My second example seemed working without queues.
It may depend on your case.

My own understanding, as a gstreamer enthousiast hobbyist having learnt gstreamer in early 1.x releases but not aware of all code changes with years, is that it may help to have usage to put queues before each mux/compositor and after each tee/demux. I think that this helps solving some synchro issues/deadlock when something gets asynchronously different such as some ressource being slowed down.

In recent gst releases, I also felt that it was often better to have at least one queue in each pipeline or sub-pipeline. The queue may have some slight overhead in performance due to synchro and different scheduling, but may be safer when some things get delayed.

Someone better skilled may shed some more real light on this than what I believe :wink: .
You may create a separate new topic for this question.

1 Like