How combine uridecobin and videomixer with a videoscale for each sink? - gstreamer

I try to make a vector of image that I get to many URI. I have succeeded to display an image with videomixer and uridecodebin plus a videoscale cap.
gst-launch -e videomixer name = mixer \
sink_0::xpos = 0 sink_0::ypos = 0 \
! xvimagesink \
uridecodebin uri=http://www.logotheque.fr/6396-2/logo+RMC+INFO.jpg \
! ffmpegcolorspace ! imagefreeze ! videoscale method = 1 \
! video/x-raw-yuv,width=100,height=100 ! queue ! mixer.sink_0.
But when I add the same "uri_Image" on another position in the videomixer with the same videoscale cap :
gst-launch -e videomixer name = mixer \
sink_0::xpos = 0 sink_0::ypos = 0 \
sink_1::xpos = 100 sink_1::ypos = 0 \
! xvimagesink \
uridecodebin uri=http://www.logotheque.fr/6396-2/logo+RMC+INFO.jpg
! ffmpegcolorspace ! imagefreeze ! videoscale ! \
video/x-raw-yuv,width=100,height=100 ! queue2 ! mixer.sink_0. \
uridecodebin uri=http://www.logotheque.fr/6396-2/logo+RMC+INFO.jpg
! ffmpegcolorspace ! imagefreeze ! videoscale ! \
video/x-raw-yuv,width=100, height=100 ! queue2 ! mixer.sink_1.
I get this error : "videoscale1 : not negotiated
gstbasetransform.c(2541): gst_base_transform_handle_buffer (): /GstPipeline:pipeline0/GstVideoScale:videoscale1:
"
So I don't understand why this error appears on the second sink, because this is the same process in both cases.
Edit :
I have found a partial solution for those interested.
gst-launch -e videomixer name=mix ! ffmpegcolorspace ! xvimagesink \
uridecodebin uri=http://www.logotheque.fr/6396-2/logo+RMC+INFO.jpg ! videoscale ! video/x-raw-yuv,width=100,height=100 \
! videobox top=0 left=0 ! imagefreeze ! mix. \
uridecodebin uri=http://upload.wikimedia.org/wikipedia/fr/1/14/Logo_vibration.JPG ! videoscale ! video/x-raw- yuv,width=100,height=100 \
! videobox top=0 left=-100 ! imagefreeze ! mix.
But this solution doesn't work with png files, I don't know why because uridecodebin is an universal decoder...
If anybody have an idea...

ok try this pipeline. With pipeline you can add png file if you need:
gst-launch -e videomixer2 name=mixer sink_0::xpos=0 sink_0::ypos=0 sink_1::xpos=100 sink_1::ypos=0 ! ffmpegcolorspace ! xvimagesink uridecodebin uri=http://www.logotheque.fr/6396-2/logo+RMC+INFO.jpg ! ffmpegcolorspace ! imagefreeze ! videoscale ! "video/x-raw-yuv, format=(fourcc)AYUV, width=100, height=100" ! queue2 ! mixer.sink_0. uridecodebin uri=http://www.logotheque.fr/6396-2/logo+RMC+INFO.jpg ! ffmpegcolorspace ! imagefreeze ! videoscale ! "video/x-raw-yuv, format=(fourcc)AYUV, width=100, height=100" ! queue2 ! mixer.sink_1. -v

Related

Recording multiple RTSP streams h265 format to Kinesis Video Streams using Gstreamer and Kvssink

I need to record 4 RTSP streams into a single stream of the Kinesis Video Streams.
Streams must be placed in the video like this:
---------- ----------
| | |
| STREAM 1 | STREAM 2 |
| | |
|----------|----------|
| | |
| STREAM 3 | STREAM 4 |
| | |
---------- ----------
I was able to insert a single stream and make it work perfectly, using the command below:
gst-launch-1.0 rtspsrc user-id="admin" user-pw="password" location="rtsp://admin:password#192.168.0.1:554/cam/realmonitor?channel=1&subtype=0" short-header=TRUE ! rtph265depay ! h265parse ! video/x-h265, alignment=au ! kvssink stream-name="test-stream" storage-size=512 access-key="access-key" secret-key="secret-key" aws-region="us-east-1"
However, my goal is to insert an array of streams into the same stream in the Kinesis Video Streams.
For this I found the example with videomixer that's below:
gst-launch-1.0 -e rtspsrc location=rtsp_url1 ! rtph264depay ! h264parse ! decodebin ! videoconvert! m.sink_0 \
rtspsrc location=rtsp_url2 ! rtph264depay ! h264parse ! decodebin ! videoconvert! m.sink_1 \
rtspsrc location=rtsp_url3 ! rtph264depay ! h264parse ! decodebin ! videoconvert! m.sink_2 \
rtspsrc location=rtsp_url4 ! rtph264depay ! h264parse ! decodebin ! videoconvert! m.sink_3 \
videomixer name=m sink_1::xpos=1280 sink_2::ypos=720 sink_3::xpos=1280 sink_3::ypos=720 ! x264enc ! mp4mux ! filesink location=./out.mp4 sync=true
I adapted the example to just two streams and made it work inside the container, using a command like the one below:
gst-launch-1.0 -e rtspsrc user-id="admin" user-pw="password" location="rtsp://password#192.168.0.1:554/cam/realmonitor?channel=1&subtype=0" short-header=TRUE ! rtph265depay ! h265parse ! video/x-h265, alignment=au ! libde265dec ! videoconvert ! m.sink_0 \
rtspsrc user-id="admin" user-pw="password" location="rtsp://password#192.168.0.2:554/cam/realmonitor?channel=1&subtype=0" short-header=TRUE ! rtph265depay ! h265parse ! video/x-h265, alignment=au ! libde265dec ! videoconvert ! m.sink_1 \
videomixer name=m sink_0::xpos=1080 sink_1::ypos=1080 ! x265enc ! h265parse ! video/x-h265, alignment=au ! kvssink stream-name="test-stream" storage-size=512 access-key="access-key" secret-key="secret-key" aws-region="us-east-1"
And in another way:
gst-launch-1.0 -e videomixer name=mix sink_0::xpos=0 sink_0::ypos=0 sink_0::alpha=0 sink_1::xpos=0 sink_1::ypos=0 \
rtspsrc user-id="admin" user-pw="password" location="rtsp://password#192.168.0.1:554/cam/realmonitor?channel=1&subtype=0" short-header=TRUE ! rtph265depay ! h265parse ! video/x-h265, alignment=au ! libde265dec ! videoconvert ! videoscale ! video/x-raw,width=1920,height=1080 ! mix.sink_0 \
rtspsrc user-id="admin" user-pw="password" location="rtsp://password#192.168.0.2:554/cam/realmonitor?channel=1&subtype=0" short-header=TRUE ! rtph265depay ! h265parse ! video/x-h265, alignment=au ! libde265dec ! videoconvert ! videoscale ! video/x-raw,width=1920,height=1080 ! mix.sink_1 \
mix. ! queue ! videoconvert ! x265enc ! queue ! kvssink stream-name="test-stream" storage-size=512 access-key="access-key" secret-key="secret-key" aws-region="us-east-1"
The container in question is from: https://github.com/awslabs/amazon-kinesis-video-streams-producer-sdk-cpp
However, when I log into Kinesis Video Streams and try to download a getClip, in both cases I get this error:
MissingCodecPrivateDataException
Missing codec private data in fragment for track 1.
Status code: 400
The logs with GST_DEBUG=1 can be found at https://gist.github.com/vbbandeira/b15ec8af6986237a4cd7e382e4ede261
And the logs with GST_DEBUG=4 can be found at https://gist.github.com/vbbandeira/6bd4b7a014a69da5f46cd036eaf32aec
Can you guys please let me know what is going on there?
Or if possible, help me find the solution to this error.
Thanks!
for those looking for the same solution, I managed to make it work by replacing the videomixer which is deprecated by the composer, below is an example of the command I used and it worked:
gst-launch-1.0 rtspsrc location="rtsp://password#192.168.0.1:554/cam/realmonitor?channel=1&subtype=0" short-header=TRUE ! decodebin ! videoconvert ! comp.sink_0 \
rtspsrc location="rtsp://password#192.168.0.2:554/cam/realmonitor?channel=1&subtype=0" short-header=TRUE ! decodebin ! videoconvert ! comp.sink_1 \
compositor name=comp sink_0::xpos=0 sink_1::xpos=1280 ! x264enc ! kvssink stream-name="test-stream" storage-size=512 access-key="access-key" secret-key="secret-key" aws-region="us-east-1"
However, I was only able to do this using h264.

Gstreamer compositor using filesrc mp4 file

I'm trying to get used to using the gstreamer compositor.
I have this basic boilerplate example working. (Compositing 2 videotestsrc next to each other):
gst-launch-1.0 compositor name=comp \
sink_0::alpha=1 sink_0::xpos=0 sink_0::ypos=0 \
sink_1::alpha=0.5 sink_1::xpos=320 sink_1::ypos=0 ! \
queue2 ! video/x-raw, width=800, height=600 ! videoconvert ! xvimagesink \
videotestsrc pattern=1 ! "video/x-raw" ! comp.sink_0 \
videotestsrc pattern=8 ! "video/x-raw" ! comp.sink_1
Then I tried changing one of the video test src to a mp4 file
I know that this command line works:
gst-launch-1.0 filesrc location=tst.mp4 ! decodebin ! videoconvert ! autovideosink
So I tried combining these two working pipelines
gst-launch-1.0 compositor name=comp \
sink_0::alpha=1 sink_0::xpos=0 sink_0::ypos=0 \
sink_1::alpha=0.5 sink_1::xpos=320 sink_1::ypos=0 ! \
queue2 ! decodebin ! video/x-raw, width=800, height=600 ! videoconvert ! xvimagesink \
videotestsrc pattern=1 ! "video/x-raw" ! comp.sink_0 \
filesrc location=tst.mp4 ! "video/x-raw" ! comp.sink_1
When I run this I get an error saying that the filter caps do not complete specify the output format.... output caps are unfixed.
I'm positive this must be a simple syntax error. Does anyone know how to fix my pipeline?
No, you need to use most of the elements that made the standalone command line work. E.g.
gst-launch-1.0 compositor name=comp \
sink_0::alpha=1 sink_0::xpos=0 sink_0::ypos=0 \
sink_1::alpha=0.5 sink_1::xpos=320 sink_1::ypos=0 ! \
queue2 ! decodebin ! video/x-raw, width=800, height=600 ! videoconvert ! xvimagesink \
videotestsrc pattern=1 ! "video/x-raw" ! comp.sink_0 \
filesrc location=tst.mp4 ! decodebin ! videoconvert ! comp.sink_1

GStreamer Playing 3 videos side by side

Here is the code for 2 mp4 videos playing in videoboxes.
gst-launch-1.0 filesrc location=1.mp4 ! decodebin ! queue !
videoconvert ! videobox border-alpha=0 right=-100 ! videomixer
name=mix ! videoconvert ! autovideosink filesrc location=2.mp4 !
decodebin ! queue ! videoconvert ! videobox border-alpha=0 left=-100 !
mix.
I have tried with this code to play 3 videos
gst-launch-1.0 filesrc location=Downloads/1.mp4 ! decodebin ! queue !
videoconvert ! videobox border-alpha=0 right=-100 ! videomixer
name=mix !
videoconvert ! autovideosink filesrc location=Downloads/2.mp4 !
decodebin ! queue ! videoconvert ! videobox border-alpha=0 left=-100 !
mix !
videoconvert ! autovideosink filesrc location=Downloads/3.mp4 !
decodebin ! queue ! videoconvert ! videobox border-alpha=0 left=-200 !
mix.
I get syntax error :(
Something like that with videomixer
gst-launch-1.0 -e \
videomixer name=mix background=0 \
sink_1::xpos=0 sink_1::ypos=0 \
sink_2::xpos=200 sink_2::ypos=0 \
sink_3::xpos=100 sink_3::ypos=100 \
! autovideosink \
uridecodebin uri='file:///data/big_buck_bunny_trailer-360p.mp4' \
! videoscale \
! video/x-raw,width=200,height=100 \
! mix.sink_1 \
uridecodebin uri='file:///data/sintel_trailer-480p.webm' \
! videoscale \
! video/x-raw,width=200,height=100 \
! mix.sink_2 \
uridecodebin uri='file:///data/the_daily_dweebs-720p.mp4' \
! videoscale \
! video/x-raw,width=200,height=100 \
! mix.sink_3
Once you instantiate an element with a name (eg. videomixer name=mix), you can later connect to it with . (eg. mix.). You don't need to repeat autovideosink 3 times after that.
gst-launch-1.0 filesrc location=Downloads/1.mp4 ! decodebin ! queue ! videoconvert ! videobox border-alpha=0 right=-100 ! videomixer name=mix ! videoconvert ! autovideosink
filesrc location=Downloads/2.mp4 ! decodebin ! queue ! videoconvert ! videobox border-alpha=0 left=-100 ! mix.
filesrc location=Downloads/3.mp4 ! decodebin ! queue ! videoconvert ! videobox border-alpha=0 left=-200 ! mix.
Here, we have initialized 3 pipes and merged three of them with mix element.

Getting rtmp streams in GStreamer, creating a mosaic and sending the resulting rtmp

I run the following code
gst-launch-1.0 -e \
videomixer name=mix \
sink_0::xpos=0 sink_0::ypos=0 sink_0::alpha=0\
sink_1::xpos=0 sink_1::ypos=0 \
sink_2::xpos=200 sink_2::ypos=0 \
sink_3::xpos=0 sink_3::ypos=100 \
sink_4::xpos=200 sink_4::ypos=100 \
rtmpsrc location='rtmp://streaming.example.com:1935/209147924'\
! decodebin ! videoconvert ! videoscale \
! video/x-raw,width=200,height=100 \
! mix.sink_1 \
rtmpsrc location='rtmp://streaming.example.com:1935/209147925'\
! decodebin ! videoconvert ! videoscale \
! video/x-raw,width=200,height=100 \
! mix.sink_2 \
rtmpsrc location='rtmp://streaming.example.com:1935/209147926'\
! decodebin ! videoconvert ! videoscale \
! video/x-raw,width=200,height=100 \
! mix.sink_3 \
rtmpsrc location='rtmp://streaming.example.com:1935/209147927'\
! decodebin ! videoconvert ! videoscale \
! video/x-raw,width=200,height=100 \
! mix.sink_4 \
mix. ! queue ! videoconvert ! x264enc ! flvmux streamable=true ! queue ! rtmpsink location='rtmp://streaming.example.com:1935/test'
Thank you. We solved the problem with the mosaic. This is the working version.
There are two issues.
1) Main issue is "videomixer" has only one src pad. You are connecting it to two pads.
-
gst-launch-1.0 -e \
videomixer name=mix \
sink_0::xpos=0 sink_0::ypos=0 sink_0::alpha=0\
sink_1::xpos=0 sink_1::ypos=0 \
sink_2::xpos=200 sink_2::ypos=0 \
sink_3::xpos=0 sink_3::ypos=100 \
sink_4::xpos=200 sink_4::ypos=100 \
! xvimagesink
By doing this, you are connecting videomixer src_pad to sink pad of sixvimagesink
Again at the end, you are trying to connect videomixer src_ to rtmpsink using queue and other elements.
So you have to remove one of the connections.
If you don't want to connect to xvimagesink, just remove "! xvimagesink"
If you dont want to connect to rtmpsink, remove the "mix ! queue ! videoconvert ..." part.
2) If you want to retain connection to queue, there is the following issue.
You are connecting mix.sink_4 to mix.src.
... ! mix.sink_4 \
! mix. ! queue ! videoconvert ! ...
Remove the first "!" and "." in the last line.
... ! mix.sink_4 \
mix ! queue ! videoconvert ! ...
Then it should not give syntax error.
EDIT 1
I think again you have made a mistake. You are connecting src of mix to mix.sink_0. I have corrected it.
gst-launch-1.0 -e \
videomixer name=mix \
sink_0::xpos=0 sink_0::ypos=0 sink_0::alpha=0\
sink_1::xpos=0 sink_1::ypos=0 \
sink_2::xpos=200 sink_2::ypos=0 \
sink_3::xpos=0 sink_3::ypos=100 \
sink_4::xpos=200 sink_4::ypos=100 \
\ /* You should not add "! .mix.sink_0" here. */
rtmpsrc location='rtmp://streaming.example.com:1935/209147924'\
! decodebin ! videoconvert ! videoscale \
! video/x-raw,width=200,height=100 \
! mix.sink_1 \
rtmpsrc location='rtmp://streaming.example.com:1935/209147925'\
! decodebin ! videoconvert ! videoscale \
! video/x-raw,width=200,height=100 \
! mix.sink_2 \
rtmpsrc location='rtmp://streaming.example.com:1935/209147926'\
! decodebin ! videoconvert ! videoscale \
! video/x-raw,width=200,height=100 \
! mix.sink_3 \
rtmpsrc location='rtmp://streaming.example.com:1935/209147927'\
! decodebin ! videoconvert ! videoscale \
! video/x-raw,width=200,height=100 \
! mix.sink_4 \
mix ! queue ! videoconvert ! x264enc ! flvmux streamable=true ! queue ! rtmpsink location='rtmp://streaming.example.com:1935/test'
Let me give some information about "name=" usage here.
You can name an element in gstreamer pipeline and use it to construct pipeline. It is mostly useful in complex pipelines. let me show its usage with a simple pipeline.
Assume the following is the required pipeline:
srcelem ! elem1 ! elem2 ! elem3 ! sinkelem
It can be written as below.
elem2 name=named_elem \ /* Naming elem2 */
named_elem ! elem3 ! sinkelem \ /* Connecting elem2 to downstream pipeline part. Note that there is no "!" before "named_elem" */
srcelem ! elem1 ! named_elem /* Connecting elem2 to upstream pipeline part. Note that there is no "!" after "named_elem" */
If you read it carefully, it constructs the same pipeline which is mentioned earlier.

How can I have 4 videos as 1 using gstreamer, with 1 large to the left and 3 smaller to the right (these should have 1 above the other)?

This is what I'm trying to achieve
I've been trying with the videobox plugin but all I'm getting is 4 equally sized boxes
I previously did something similar to what you described using 3 cameras.
Here's the pipe I used for it:
gst-launch-1.0 v4l2src device=/dev/video0 ! video/x-raw, width=800, height=480, framerate=25/1 ! alpha alpha=1.0 ! videobox left=-800 ! videomixer name=mix sink_00::xpos=0 sink_01::xpos=800 sink_02::xpos=0 sink_02::ypos=480 sink_00::alpha=1.0 sink_01::alpha=1.0 sink_02::alpha=1.0 ! videoconvert ! xvimagesink \
v4l2src device=/dev/video1 ! video/x-raw, width=1600, height=1200, framerate=25/1 ! alpha alpha=1.0 ! videobox border-alpha=0 top=-480 ! mix. \
v4l2src device=/dev/video2 ! video/x-raw, width=800, height=480, framerate=25/1 ! alpha alpha=1.0 ! videobox border-alpha=0 left=-00 ! mix. -e
You need to use a videobox element for each videocapture (in this case I used v4l2src however you can use other sources like filesrc ! decodebin or a network source as well) pipe and combine them in a videomixer element.
In my case I used one video on the left and two videos on the right but you can adjust left and top parameters of videobox and sink_0x::xpos' and 'sink_0x::ypos elements of the videomixer element.
Remember to add alpha to each channel or your videos will be transparent.
So this depends very much on how and what you want to do. For example, this can be be as simple GUI application that presents 4 videos on 4 different surfaces and the GUI is responsible for the layout.
If you really want to create a new single image that contains these 4 video streams then videomixer sounds the way to go. See here for some example:
https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-good/html/gst-plugins-good-plugins-videomixer.html
I use something like this to mix running streams into a single one
/usr/local/bin/gst-launch-1.0 -vv -e videomixer name=mix background=2 \
sink_0::alpha=1.0 \
sink_0::ypos=0 \
sink_0::xpos=0 \
sink_1::alpha=1.0 \
sink_1::ypos=80 \
sink_1::xpos=40 \
sink_2::alpha=1.0 \
sink_2::ypos=80 \
sink_2::xpos=410 \
sink_3::alpha=1.0 \
sink_3::ypos=80 \
sink_3::xpos=780 \
sink_0::zorder=1 \
sink_1::zorder=3 \
sink_2::zorder=3 \
sink_3::zorder=4 \
! clockoverlay auto-resize=false draw-shadow=false draw-outline=false halignment=left valignment=top \
! timeoverlay auto-resize=false draw-shadow=false draw-outline=false halignment=left valignment=bottom \
! queue \
! nvh264enc preset=1 bitrate=1500 rc-mode=2 gop-size=10 \
! h264parse config-interval=-1 \
! mpegtsmux ! rtpmp2tpay pt=33 \
! udpsink host=239.255.42.61 port=5004 multicast-iface=10g-1 ttl=4 ttl-mc=4 \
multifilesrc location=/IMG/logo.jpg caps="image/jpeg,framerate=1/1" \
! jpegdec ! videoconvert ! videoscale \
! video/x-raw,width=1920,height=1080 \
! mix.sink_0 \
udpsrc multicast-group=239.255.42.60 address=239.255.42.60 port=5004 multicast-iface=eth0 caps="application/x-rtp,media=(string)video,clock-rate=(int)90000,encoding-name=(string)MP2T,payload=(int)33" \
! rtpjitterbuffer ! rtpmp2tdepay ! tsdemux ! h264parse config-interval=-1 \
! avdec_h264 skip-frame=1 output-corrupt=false ! videoconvert ! videoscale \
! video/x-raw,width=360,height=240 \
! mix.sink_1 \
udpsrc multicast-group=239.255.42.57 address=239.255.42.57 port=5004 multicast-iface=eth0 caps="application/x-rtp,media=(string)video,clock-rate=(int)90000,encoding-name=(string)MP2T,payload=(int)33" \
! rtpjitterbuffer ! rtpmp2tdepay ! tsdemux ! h264parse config-interval=-1 \
! avdec_h264 skip-frame=1 output-corrupt=false ! videoconvert ! videoscale \
! video/x-raw,width=360,height=240 \
! mix.sink_2 \
udpsrc multicast-group=239.255.42.62 address=239.255.42.62 port=5004 multicast-iface=eth0 caps="application/x-rtp,media=(string)video,clock-rate=(int)90000,encoding-name=(string)MP2T,payload=(int)33" \
! rtpjitterbuffer ! rtpmp2tdepay ! tsdemux ! h264parse config-interval=-1 \
! avdec_h264 skip-frame=1 output-corrupt=false ! videoconvert ! videoscale \
! video/x-raw,width=360,height=240 \
! mix.sink_3 \