GStreamer: receive/demultiplex multiple RTP streams on one port? - gstreamer

I'd like to use gstreamer to create a network sink for multiple UDP RTP streams. The basic setup (one sender, one receiver) works fine and looks like this:
# sender:
gst-launch-1.0 -vvtcm audiotestsrc ! rtpgstpay config-interval=1 ssrc=1 ! udpsink host=127.0.0.1 port=5000
# receiver:
gst-launch-1.0 -vvtcm udpsrc port=5000 caps="application/x-rtp,media=application,clock-rate=90000,encoding-name=X-GST" ! rtpssrcdemux ! rtpgstdepay ! autoaudiosink
However, I would like to have multiple senders that can dynamically start and stop streaming to the same port. AFAICT the SSRC field in RTP allows me to do exactly this, but I can't figure out how to configure rtpssrcdemux so that it will create additional sink pads.
E.g. when I start the following receiver pipeline:
gst-launch-1.0 -vvtcm udpsrc port=5000 caps="application/x-rtp,media=application,clock-rate=90000,encoding-name=X-GST" ! rtpssrcdemux name=demux demux.src_0 ! rtpgstdepay ! autoaudiosink demux.src_1 ! rtpgstdepay ! autoaudiosink
it will wait for the first audio stream, but when I start a second sender with a different SSRC, the pipeline stops with streaming task paused, reason not-linked (-1).
Hints welcome...?

For the record (and a few years late ;-), this is not possible using gst-launch alone, you need code to listen for the new-ssrc-pad signal as mentioned in the comment.

Related

Gstreamer rtsp isn't picking up audio through queues

I'm having an issue with pulling audio and video from an RTSP stream using gstreamer.
The command I am using to test is as follows:
gst-launch-1.0 rtspsrc location=rtsp://192.168.50.160/whp name=src src. ! queue ! rtph264depay ! h264parse ! avdec_h264 ! videoconvert ! x264enc bitrate=10000 ! rtph264pay ! udpsink host=192.168.50.164 port=8004 src. ! queue ! fakesink
The result of the above is that the pipe follows through for the first (video) stream. The second stream however is untouched and seems to sit in the rtspsrc plugin.
The way I am finding this is by looking at the resultant dot file:
If I am reading this right it looks like the queue connects correctly to rtpsession0, but seems to ignore rtpsession1 and the second queue doesn't connect to anything resulting in audio from my stream being completely ignored.
Am I reading this incorrectly? If not am I missing something in my pipeline command that would rectify this issue?
I am happy to provide any more information necessary
Thanks

How to record pipeline even if sender doesn't send data in gstreamer

I'm a newbie to gstreamer so i would be appreciated if you could help me.
I'm trying to listen to a pipeline and record frames to a file.
I have tried the following pipeline:
gst-launch-1.0 udpsrc port=5600 do-timestamp=true ! application/x-rtp, payload=96 ! rtph264depay ! avdec_h264 ! clockoverlay ! jpegenc ! avimux ! filesink location=stream.avi
I want to record whole timeline even if the sender doesn't provide any frame data.
In default, recorder appends the frames when pipeline receive some valid frames. But I want to see some black frames when sender doesn't send data.
I experimented a bit and I don't think you'll be able to do this with a plain gst-launch command. Unfortunately what it would probably involve is to write an application that detects when packets/buffers are not coming in any more, and then modifying the pipeline. If you want to give it a go I'd suggest the input-selector element in something like this:
gst-launch-1.0 videotestsrc pattern=black ! video/x-raw ! input-selector name=selector ! clockoverlay ! jpegenc ! avimux ! filesink location=stream.avi
Then I'd create a method to attach the stream to the input-selector:
udpsrc port=5600 do-timestamp=true ! application/x-rtp, payload=96 ! rtph264depay ! avdec_h264 ! identity name=buffer-checker
To detect no packets coming in, you can listen for the handoff signal on the identity element, and then remove the stream when it times out and switch over to the black test pattern from the videotestsrc by using the active-pad property on the input-selector.
Using the videomixer element almost works, but I don't believe it will handle multiple stops and starts of the stream.
Anyway, hope someone else comes up with a better idea. You could also re-analyze your top level approach and see if there is a way you can work with multiple video clips instead of the one.

Gstreamer - streaming with TCP sources

I am trying to stream video using TCP. Following is the server pipeline:
gst-launch filesrc location=<movie>.mkv ! decodebin ! ffenc_mpeg4 bitrate=5000000 ! rtpmp4vpay mtu=1400 pt=96 ssrc=0 timestamp-offset=0 seqnum-offset=0 send-config=true ! tcpserversink host=0.0.0.0 port=5000
And the client pipeline is:
gst-launch tcpclientsrc host=192.168.1.93 port=5000 ! capsfilter caps="application/x-rtp, media=(string)video, clock-rate=(int)2147483647, encoding-name=(string)MP4V-ES, profile-level-id=(string)1, config=(string)000001b001000001b58913000001000000012000c48d88007d0a041e1463000001b24c61766335322e3132332e30, payload=(int)96, ssrc=(uint)298758266, clock-base=(uint)3097828288, seqnum-base=(uint)63478" ! rtpmp4vdepay ! ffdec_mpeg4 ! autovideosink
I had to include a capsfilter between tcpclientsrc and rtpmp4vdepay. This does not seem to be required if I use the udpsrc however. (I cant seem to get the multicast based streaming to work through my BT router). When started the client starts to play the video, but it is garbage and I can see following warning in the client side.
WARNING: from element /GstPipeline:pipeline0/GstRtpMP4VDepay:rtpmp4vdepay0: Could not decode stream.
Additional debug info:
gstbasertpdepayload.c(387): gst_base_rtp_depayload_chain (): /GstPipeline:pipeline0/GstRtpMP4VDepay:rtpmp4vdepay0:
Received invalid RTP payload, dropping
This warning is emitted continuously.
What am I doing wrong here?

gstreamer to stream mp4 through the network - Could not determine type of stream

I'm really running out of ideas. Here is my problem: I need to stream on demand mp4 (H264) through the network. I'm new with gstreamer and after lot of tries with versions > 1.0 I decided to use 0.10 because seems to be most promising so far.
Command below works perfect ( I see window with my movie )
gst-launch filesrc location=/home/zuko/sintel_trailer-368p.mp4 ! decodebin2 name=dec ! queue ! ffmpegcolorspace ! autovideosink dec. ! queue ! audioconvert ! audioresample ! autoaudiosink
Now I'm trying to build TCP stream using commands (so far on localhost only):
Server side:
gst-launch filesrc location=/home/zuko/sintel_trailer-368p.mp4 ! decodebin2 name=dec ! tcpserversink host=127.0.0.1 port=5000
Client side:
gst-launch tcpclientsrc host=127.0.0.1 port=5000 ! decodebin2 name=dec ! queue ! ffmpegcolorspace ! autovideosink dec. ! queue ! audioconvert ! audioresample ! autoaudiosink
But response from the "client side" command is following:
Setting pipeline to PAUSED ...
Pipeline is PREROLLING ...
ERROR: from element /GstPipeline:pipeline0/GstDecodeBin2:dec/GstTypeFindElement:typefind: Could not determine type of stream.
Additional debug info:
gsttypefindelement.c(813): gst_type_find_element_chain_do_typefinding (): /GstPipeline:pipeline0/GstDecodeBin2:dec/GstTypeFindElement:typefind
ERROR: pipeline doesn't want to preroll.
Setting pipeline to NULL ...
Freeing pipeline ...
What is missing, or what I'm doing wrong?
I'm testing on: VirtualBox 4.3.12 with Ubuntu 14.04, kernel 3.13.0-24-generic #47-Ubuntu SMP Fri May 2 23:30:00 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
Full error with (GST_DEBUG_NO_COLOR=1 GST_DEBUG=*:3 ) attached here:
https://app.box.com/s/4ntyk6am2ibg0pohtg9h
First off, using 0.10 is an absolutely bad idea, you should really stick to 1.0, for which you will have community support.
Second, to your problem itself, you are trying to stream the decoded stream over the network ("decodebin2 ! tcpserversink") and to decode it again on the other side ("tcpclientsrc ! decodebin2"). Not only is it very wrong with respect to bandwidth usage, it also straight up won't work.
I'll advise you to have a look at the rtp plugins provided by gstreamer.
Using gstreamer 1.0 the server side can share h264 streams with:
gst-launch-1.0 filesrc location="C:\\Videos\\videotestsrc.avi" ! decodebin ! x264enc ! mpegtsmux ! queue ! tcpserversink host=127.0.0.1 port=8080
While the client side receives with:
gst-launch-1.0 tcpclientsrc host=127.0.0.1 port=8080 ! decodebin ! videoconvert ! autovideosink sync=false
Alternatively, the client could be simulated with VLC through:
Media >> Open Network Stream >> tcp://127.0.0.1:8080 >> Play

gstreamer rtpvp8depay cannot decode stream

I have two GStreamer instances : a sender and a receiver. I want to stream RTP / VP8 video. It works perfectly fine if I stream via UDP, like this :
sender
gst-launch-0.10 -v videotestsrc ! vp8enc ! rtpvp8pay ! udpsink host=127.0.0.1 port=9001
receiver
gst-launch-0.10 udpsrc port=9001 caps = "application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)VP8-DRAFT-IETF-01, payload=(int)96" ! rtpvp8depay ! vp8dec ! ffmpegcolorspace ! autovideosink
That works fine. But when I try to stream throug a FIFO / named pipe (done with mkfifo()) with :
sender
gst-launch-0.10 -v videotestsrc ! vp8enc ! rtpvp8pay ! filesink location = myPipe
receiver
gst-launch-0.10 filesrc location = myPipe ! capsfilter caps = application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)VP8-DRAFT-IETF-01, payload=(int)96 ! rtpvp8depay ! vp8dec ! ffmpegcolorspace ! autovideosink
It fails and my receiver continusouly outputs :
WARNING: from element /GstPipeline:pipeline0/GstRtpVP8Depay:rtpvp8depay0: Could not decode stream.
Additional debug info:
gstbasertpdepayload.c(387): gst_base_rtp_depayload_chain (): /GstPipeline:pipeline0/GstRtpVP8Depay:rtpvp8depay0:
Received invalid RTP payload, dropping
I think I read somewhere (but can't find it again) that it was because when using UDP, the RTP packets were separated properly, while using a named pipe like this, the packets being written are "chained" (not properly separated) and thus gstreamer doesn't know how much bytes to read to get a RTP packet.
Is this correct, and if yes, how can I change that ?
Thanks in advance !
When going through a named pipe, the RTP are not packetized properly. You could either,
Send the encoded stream directly through as a byte-stream, without using the rtpvp8pay element.
Use another RTP element in GStreamer that handles byte-stream format, such as rtpstreampay or rtpgdppay. (I believe the rtpstreampay might be a GStreamer 1.0 element though.)
I finally solved my problem.
I did not manage the byte-stream thing through a pipe, but I managed to use an AppSrc to feed the gst pipeline.
So my whole pipeline (might be useful for other people) looks like this : appsrc -> rtpvp8depay -> vp8dec -> videoconvert -> videoscale -> appsink (I'm using Gstreamer1.0 on ArchLinux).
Hope this helps !